{include file="./index_top.tpl"}
<script type="text/javascript">
    // значения для системной подсказки
    var help_section = 'Settings';
    var help_sub_section = 'Computation';
    var calcPeriod = '{$calc.period}';
    var calcCronId = '{$calc.cron_id}';
    var history_window;
    var customConds = new Set(); // Набор условий, добавленных пользователем (те, что не по умолчанию)
    const userParams = {if $user_params}{$user_params}{else}{}{/if}; // условия, установленные пользователем вручную
    const minMask = '* * * * *';
    const fiveMinMask = '1-59/5 * * * *';
    const tenMinMask = '1,15,30,45 * * * *';
    const hourMask = '1 * * * *';
    const threeDayMask = '1 3 * * *';
    const tenDayMask = '1 12 * * *';
    const twentyDayMask = '1 23 * * *';

    // Условия загружены, подцепляем события - меняющие список
    let s = { {$conditions} }; // заполняем массив условий
    let f = { {$fields_list} }; // заполняем массив полей
    let t; // временная переменна

    for (let el in userParams) customConds.add(userParams[el]);

    $(document).ready(function() {
        init_chosen();
    });

    function change_interval(select_obj) {
        const advancedPeriod = $('#period_advanced');

        if (!select_obj) {
            advancedPeriod.hide();
        } else {
            let val = select_obj.options[select_obj.selectedIndex].value;
            let r_obj = $('#period_val');

            if (val == "every_minute")        calcPeriod = minMask;
            if (val == "every_5_minute")      calcPeriod = fiveMinMask;
            if (val == "every_15_minute")     calcPeriod = tenMinMask;
            if (val == "every_hour")          calcPeriod = hourMask;
            if (val == "every_day_3_oclock")  calcPeriod = threeDayMask;
            if (val == "every_day_12_oclock") calcPeriod = tenDayMask;
            if (val == "every_day_23_oclock") calcPeriod = twentyDayMask;
            if (val == "advanced") advancedPeriod.css('display', '');
            else advancedPeriod.hide();

            r_obj.val(calcPeriod);
        }
    }

    //cron period validation
    function editPeriod() {
        $('#period_val').css('background-color', '');
        $('#save_data').removeAttr("disabled");
    }

    function checkPeriod() {
        let period = document.getElementById('period_val');
        let chunks = period.value.split(' ');
        let value_for_input = '';
        if(chunks.length > 5 || chunks.length < 5){
            period.style.backgroundColor = '#faa7a7';
            $('#save_data').attr('disabled', true);
        }
        else {
            let conformity = 0;
            for(let [i, value] of chunks.entries()){
                if(i == 0){
                    if(checkCronVar(value, 0, 59, 2)){
                        conformity++;
                    }
                }
                else if(i == 1){
                    if(checkCronVar(value, 0, 23, 2)){
                        conformity++;
                    }
                }
                else if(i == 2){
                    if(checkCronVar(value, 1, 31, 2)){
                        conformity++;
                    }
                }
                else if(i == 3){
                    let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
                    for(const [index, month] of months.entries()){
                        value = value.replace(new RegExp(month, 'g'), index + 1);
                    }
                    if(checkCronVar(value, 1, 12, 2)){
                        conformity++;
                    }
                }
                else {
                    let days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
                    for(const [index, day] of days.entries()){
                        value = value.replace(new RegExp(day, 'g'), index + 1);
                    }
                    if(checkCronVar(value, 1, 7, 1)){
                        conformity++;
                    }
                }
                value_for_input += i == chunks.length - 1 ? value : value + ' ';
            }
            if(conformity < 5){
                period.style.backgroundColor = '#faa7a7';
                $('#save_data').attr('disabled', true);
            }
            else {
                period.value = value_for_input;
            }
        }
    }

    function isRange(value, start, end){
        let chunks = value.split("-");
        if(chunks.length == 2 && chunks[0] >= start && chunks[1] <= end && (isFinite(chunks[0]) && isFinite(chunks[1]) && chunks[0] < chunks[1])){
            return true;
        }
        else {
            return false;
        }
    }

    function checkCronVar(variable, start, end, lenVar) {
        let len = variable.length;
        if(len > lenVar){
            let chunksSlash = variable.split("/");
            let chunksComma = variable.split(",");
            let chunksMinus = variable.split("-");
            if(chunksSlash.length == 2){
                if((isRange(chunksSlash[0], start, end) || chunksSlash[0] == '*') && chunksSlash[1] >= start && chunksSlash[1] <= end){
                    return true;
                }
                return false;
            }
            else if(chunksComma.length > 1){
                let conformity = 0;
                for(const chunk of chunksComma){
                    if(chunk == '*' || isFinite(chunk) && (chunk >= start && chunk <= end)){
                        conformity++;
                        continue;
                    }
                    return false;
                }
                if(conformity == chunksComma.length) {
                    return true;
                }
                else {
                    return false;
                }
            }
            else if(chunksMinus.length == 2 && isRange(variable, start, end)){
                return true;
            }
            else {
                return false;
            }
        }
        else {
            if(variable == '*' || isFinite(variable) && (variable >= start && variable <= end)){
                return true;
            }
            return false;
        }
    }

    function check_brackets() {
        var open_brackets = 0;
        var close_brackets = 0;
        for (var num = 0; num <= 100; num++) {
            if ($('[name="cond[' + num + '][field]"]').val() != 0 && $('[name="cond[' + num + '][field]"]').val() != undefined) {
                open_brackets += +$('#cond_ob_' + num).val();
                close_brackets += +$('#cond_cb_' + num).val();
                if (close_brackets && !open_brackets) break;
            }
        }
        if (open_brackets != close_brackets) {
            return false;
        } else {
            return true;
        }
    }
</script>
<script type="text/javascript" src="include/js/ConditionsConstruct.js?{$revision}"></script>
<br>
<div align=center>
    {if $no_save_mode}<img src="images/lock.svg" style="width:20px; padding-right:5px;" title="{$lang.Element_no_edit_msg}">{/if}
    {if $calc_id eq -1}{$lang.Create_calc}{else}{$lang.Edit_calc} "{$calc.name}"{/if}{if $table_id} {$lang.use_number_field2} "{$name_table}"{/if}
    {if $calc_id != -1 && !$blocked}
        <div style="left: 10px; top: 2px; float: none;"
            onclick="switchOnObject('{$calc_id}')"
            class="switch-btn {if !$disabled}switch-on{/if}"
            id="switch-on-btn_{$calc_id}"></div>
        <script>
            let ajaxObj = new XMLHTTP("edit_calc.php");
            ajaxObj.format = 0;
            ajaxObj.method = "POST";
            function switchOnObject(calc_id) {
                $('#switch-on-btn_'+calc_id).toggleClass('switch-on');
                $('#switch-on-btn_'+calc_id).trigger('on.switch');
                ajaxObj.call('calc_id='+calc_id+'&sel=disable&enbl='+($('#switch-on-btn_'+calc_id).hasClass('switch-on')?1:0)+'&csrf={$csrf}',()=>{});
            }
        </script>
    {/if}
</div>
<br>
<form id="calc_form" action="edit_calc.php?{if $archive}archive&{/if}table={$table_id}&calc_id={$calc_id}" method="post" table-id="{$table_id}">
    {if $updater_status}
        <div style="display:flex; width: 100%; flex-direction: column; align-items: center; justify-content: space-between; height: 100px;">
            <span>Невозможно редактировать вычисление, т.к. запущен процесс обновления записей.</span>
            <input class="btn btn-default btn-sm" name="cancel_lines_updater" type="submit" value="{$lang.Cancel}">
            <a href="{$calc_url}">{$lang.Return}</a>
        </div>
    {else}
        <table align="center" border=0 cellpadding=3 cellspacing=0 width=100% class="edit_block_tbl">
            {if $error}
                <tr>
                    <td align=center colspan=2 style="color:red;padding-bottom:15px">{$error}</td>
                </tr>
            {/if}
            {if $message}
                <tr>
                    <td colspan=2 align=center>
                        <span id="edit_config__info-maessage" style="color:green">{$message}</span><br><br>
                    </td>
                </tr>
            {/if}
            {if $blocked}
                <tr>
                    <td colspan=2 align=center>
                        <a href="edit_calc.php?table={$table_id}">{$lang.Return}</a>
                    </td>
                </tr>
            {else}
            {if $last_log}
                <tr>
                    <td align=center colspan=2 style="padding-bottom:15px">{$lang.Last_modified}: {$last_log.date}
                        , {$last_log.user}, IP {$last_log.ip} <a
                                href="edit_log.php?f_text=calc_id={$calc_id}'&st_date=01.01.2000&f_event[]=admin&f_event[]=change_parameter_calc"
                                target=_blanc>{$lang.Log}</a></td>
                </tr>
            {/if}
            <tr>
                <td align=right width=45%>{$lang.Calc_name}<span class='help_bt' h_id='Calc_name'></span>:</td>
                <td><input class="form-control form-control-250" type=text name="calc_name" id="calc_name" value="{$calc.name}" size="40"></td>
            </tr>
            {if isset($mode) && ($mode === 0)}
            <tbody data-type="construct">
                <tr>
                    <td align=right>{$lang.Set_conds}<span class='help_bt' h_id='Conditions'></span>:</td>
                    <td>
                        <div class="flex-box">
                            <label class="radio-inline flex-box flex-direction--column flex-wrap--center">
                                <input type="radio" name="set_conds" value="0" {if !$calc['set_conds']} checked{/if}>
                                <span>{$lang['No']}</span>
                            </label>
                            <label class="radio-inline flex-box flex-direction--column flex-wrap--center">
                                <input type="radio" name="set_conds" value="1"{if $calc['set_conds']} checked{/if}>
                                <span>{$lang['Yes']}</span>
                            </label>
                        </div>
                    </td>
                </tr>
                <tr id="cond_block">
                    <td align=right>{$lang.Conditions}<span class='help_bt' h_id='Conditions'></span>:</td>
                    <td id="cond_construct">

                    </td>
                </tr>
            </tbody>
            {/if}
            {if $user.group_id == 1 || $user.sub_admin_rights.edit_php}
            <tr id="calc_code">
                <td align=right>{$lang.Mode}<span class='help_bt' h_id='Mode'></span>:</td>
                <td>
                    <div class="flex-box">
                        <label class="radio-inline flex-box flex-direction--column flex-wrap--center">
                            <input id="construct_mode" type="radio" {if !($mode === 0)}disabled style="color: #999;"{/if} name="calc_mode" value=0 {if ($mode === 0)}checked{/if}>
                            <span {if !($mode === 0)}style="color: #999;"{/if}>{$lang.construct_mode}</span>
                        </label>
                        <label class="radio-inline flex-box flex-direction--column flex-wrap--center">
                            <input id="expert_mode" type="radio" {if !$all_modules.pro_tariff && $mode === 0}disabled style="color: #999;"{/if} name="calc_mode" value=1 {if !($mode === 0)}checked{/if}>
                            <span {if !$all_modules.pro_tariff && $mode === 0}style="color: #999;" title="{$lang.Pro_tariff_func_message}"{/if}>{$lang.Expert_mode}</span>
                        </label>
                    </div>
                </td>
            </tr>
            <tr data-type="expert">
                <td align=right>{$lang.Computation}<span class='help_bt' h_id='Computation'></span>:</td>
                <td>
                    {if $calc_id > 0}
                        <a href="#"
                           onclick="open_calc('calc_id={$calc.id}',{$calc.calculate|strlen}{if ($mode === 0)}, 1{/if});return false;">{$lang.Edit}</a>
                        <input type="hidden" name="calculate" value="dont_save">
                    {else}
                        <textarea class="form-control form-control-250" name="calculate" rows=5 cols=38>{$calc.calculate}</textarea>
                    {/if}
                </td>
            </tr>
            {/if}
            {if isset($mode) && ($mode === 0)}
                <tr data-type="construct">
                    <td align=right>{$lang.Template}<span class='help_bt' h_id='Template'></span>:</td>
                    <td id="calc_tpl_area">

                    </td>
                </tr>
                <tr data-type="construct" id="calc_tpl_tr" class="calc_tpl_class">

                </tr>
                {if $calc.calc_end_msg}
                    <tr data-type="construct">
                        <td align=right>{$lang.Calc_end_message}<span class='help_bt' h_id='calc_end_msg'></span>:</td>
                        <td><input class="form-control form-control-250" name="calc_end_msg" value="{$calc.calc_end_msg}"></td>
                    </tr>
                {/if}
                {if $calc.calc_fail_msg}
                    <tr data-type="construct">
                        <td align=right>{$lang.Calc_fail_message}<span class='help_bt' h_id='calc_fail_msg'></span>:</td>
                        <td><input class="form-control form-control-250" name="calc_fail_msg" value="{$calc.calc_fail_msg}"></td>
                    </tr>
                {/if}
            {/if}
            <tr>
                <td></td>
                <td>
                    <a href="" id="open_add_set" style="width: 110px;display: inline-block">{$lang.Additional}</a>
                    {if $config.protect_of_elements && $user.id == 1}<a href="" id="protect_switch">{$lang.Protect}</a>{/if}
                </td>
            </tr>
            <tbody id="additional_settings" style="display:none;">
            {if $mode !== 'untable'}
                <tr>
                    <td align=right width=45%>
                        {$lang.Filter}<span class='help_bt' h_id='filter_calc'></span>:
                    </td>
                    <td align=left>
                        <select class="form-control form-control-160" name="filter">
                            <option value="0"></option>
                            {foreach from=$filters item=v key=k}
                                <option value="{$k}" {if $k == $calc.filter_id}selected{/if}>{$v}</option>
                            {/foreach}
                        </select>
                    </td>
                </tr>
                {if $mode === 0 && !$calc.calc_end_msg}
                    <tr data-type="construct">
                        <td align=right>{$lang.Calc_end_message}<span class='help_bt' h_id='calc_end_msg'></span>:</td>
                        <td><input class="form-control form-control-250" name="calc_end_msg" value="{$calc.calc_end_msg}"></td>
                    </tr>
                {/if}
                {if $mode === 0 && !$calc.calc_fail_msg}
                    <tr data-type="construct">
                        <td align=right>{$lang.Calc_fail_message}<span class='help_bt' h_id='calc_fail_msg'></span>:</td>
                        <td><input class="form-control form-control-250" name="calc_fail_msg" value="{$calc.calc_fail_msg}"></td>
                    </tr>
                {/if}
                <tr>
                    <td align=right width=45% style='line-height:25px;'>{$lang.Calc_conditions}<br><span
                                id='or_conditions'></span></td>
                    <td style='line-height:25px;'>
                        <span id='conditions'></span>
                    </td>
                </tr>
                <tr id="period_advanced"
                    {if $calc.period neq "* * * * *" and $calc.period neq "1-59/5 * * * *" and
                        $calc.period neq "1,15,30,45 * * * *" and $calc.period neq "1 * * * *" and
                        $calc.period neq "1 3 * * *" and $calc.period neq "1 12 * * *" and
                        $calc.period neq "1 23 * * *"}
                    {else}
                        style="display:none;"
                    {/if}>
                    <td align=right width=45% style='line-height:25px;'>{$lang.Enter_cron_interval}:</td>
                    <td style='line-height:25px;'>
                        <input class="form-control form-control-160 cron-input"
                               type="text"
                               id="period_val"
                               name="period"
                               value="{$calc.period}"
                               onblur="checkPeriod();"
                               onfocus="editPeriod();">
                    </td>
                </tr>
                <tr>
                    <td align=right width=45%>
                        {$lang.Start_calc}<span class='help_bt' h_id='start_calc'></span>:
                    </td>
                    <td>
                        <input type="checkbox" name="linesUpdater" onclick="$('.filter_block').toggle()">
                    </td>
                </tr>
                <tr class="filter_block" style="display:none">
                    <td align=right width=45%>
                        {$lang.Filtered}<span class='help_bt' h_id='filter_calc'></span>:
                    </td>
                    <td align=left>
                        <select class="form-control form-control-160" name="run_filter">
                            <option value="0"></option>
                            {foreach from=$filters item=v key=k}
                                <option value="{$k}">{$v}</option>
                            {/foreach}
                        </select>
                    </td>
                </tr>
                <tr class="filter_block" style="display:none">
                    <td align=right width=45%>
                        {$lang.Use_records}<span class='help_bt' h_id='Use_records_in_calc'></span>:
                    </td>
                    <td>
                        <input type=checkbox name="use_records[]" value=0 checked> {$lang.active}<br>
                        <input type=checkbox name="use_records[]" value=1> {$lang.archive}<br>
                        <input type=checkbox name="use_records[]" value=2> {$lang.deleted}
                    </td>
                </tr>
                <tr>
                    <td align=right width=45%>{$lang.calc_recursion_disabled}<span class='help_bt'
                                                                                   h_id='recursion_disabled'></span>:
                    </td>
                    <td><input type="checkbox" name="recursion_disabled" id="recursion_disabled" value="1"
                               {if $calc.recursion_disabled}checked="1"{/if} /></td>
                </tr>
            {/if}
            <tr>
                <td align=right width=45%>
                    {$lang.Last_run_time}<span class='help_bt' h_id='calc_last_runtime'></span>:
                </td>
                <td>
                    {$last_runtime} {$lang.seconds}
                </td>
            </tr>
            <tr>
                <td align=right width=45%>
                    {$lang.Day_run_time}<span class='help_bt' h_id='calc_day_runtime'></span>:
                </td>
                <td>
                    {$day_runtime} {$lang.seconds}
                </td>
            </tr>
            <tr>
                <td align="right">{$lang.Help}<span class="help_bt" h_id="cond_help"></span>:</td>
                <td><textarea class="form-control" name="help" rows="5" cols="38">{$calc.help}</textarea></td>
            </tr>
            <tr>
                <td>
                    <input type='hidden' name='user_params' value='' id='custom_user_params'>
                </td>
            </tr>
            </tbody>
            {if $config.protect_of_elements && $user.id == 1}
            <tbody id="protect_block" style="display:none">
                <tr>
                    <td align="right">{$lang.Protected}<span class='help_bt' h_id='Protect_of_element'></span>:</td>
                    <td>
                        <input type="checkbox" name="protected" {if $protected}checked{/if} onclick="$('[id^=pr_]').prop('disabled', !this.checked)">
                        <span class="access_param_wrapper">{$lang.View2}<span class='help_bt' h_id='protect_of_view'></span></span>
                        <span class="access_param_wrapper">{$lang.Edit3}<span class='help_bt' h_id='protect_of_edit'></span></span>
                    </td>
                </tr>
                <tr>
                    <td align="right"></td>
                    <td>
                        <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 15px; text-align: center;">
                            <input type="checkbox" id="pr_view_all" {if !$protected}disabled{/if}
                                   onclick="$('[id^=pr_view]').prop('checked', this.checked); if (!this.checked) $('[id^=pr_edit]').prop('checked', 0);">
                        </div>
                        <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 0; text-align: center;">
                            <input type="checkbox" id="pr_edit_all" {if !$protected}disabled{/if}
                                   onclick="$('[id^=pr_edit]').prop('checked', this.checked); if ( this.checked) $('[id^=pr_view]').prop('checked', 1);">
                        </div>
                    </td>
                </tr>
                {foreach from=$protect key=gid item=acc}
                    <tr>
                        <td align="right" style="padding-top: 11px;">{$acc.name}:</td>
                        <td style="display: flex; flex-wrap: nowrap;">
                            <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 15px; text-align: center;">
                                <input type="checkbox" name="protect_rights[{$gid}][view]" id="pr_view{$gid}" value="1"
                                       {if $acc.view}checked{/if} {if !$protected}disabled{/if}
                                       onclick="if (!this.checked) $('#pr_edit{$gid}').prop('checked', 0)">
                            </div>
                            <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 0; text-align: center;">
                                <input type="checkbox" name="protect_rights[{$gid}][edit]" id="pr_edit{$gid}" value="1"
                                       {if $acc.edit}checked{/if} {if !$protected}disabled{/if}
                                       onclick="if ( this.checked) $('#pr_view{$gid}').prop('checked', 1)">
                            </div>
                        </td>
                    </tr>
                {/foreach}
                <tr><td></td></tr>
                <tr>
                    <td align=right>{$lang.Comment}<span class='help_bt' h_id='protect_comment'></span>:</td>
                    <td><textarea class="form-control form-control-250" name="protect_comment" rows=5>{$protect_comment}</textarea></td>
                </tr>
            </tbody>
            {/if}
            <tr>
                <td colspan=2 align=center>
                    <br>
                    <input type=hidden name='sel' value='save' id="save_data">
                    <input class="btn btn-default btn-sm" type="button" id="submit_button" value="{$lang.Save}"
                           {if $no_save_mode}disabled title="{$lang.Element_no_edit_msg}"{/if}>
                    <br>
                    <br>
                    <a href="edit_calc.php?table={$table_id}">{$lang.Return}</a>
                </td>
            </tr>
            {/if}{*blocked*}
        </table>
    {/if}
    {if $user.group_id != 1 && !$user.sub_admin_rights.edit_php}
    <input type="hidden" name="calc_mode" value="{$mode}">
    {/if}
    <input type="hidden" name=back_url value='{$base64_back_url}'>
    <input type="hidden" name=csrf value='{$csrf}'>
    <input type="hidden" name=calc_type value='{$calc_type}'>
</form><br>
<script>
    /**
     Состояние, аналогичное React, для отслеживания и обновления значения.
     * 
     * @param any initialValue - Начальное значение состояния.
    * @returns Array Массив, содержащий:
    *  - Функция для получения текущего значения состояния.
    *  - Функция для обновления состояния.
    *  - Функция для подписки на изменение состояния.
    */
    const useState = (initialValue) => {
      let value = initialValue; // Храним текущее состояние
      const listeners = new Set(); // Множество слушателей изменений состояния

      // Функция для обновления состояния
      const setState = (newValue) => {
        // Если передано как функция, вызываем её с текущим значением
        if (typeof newValue === 'function') {
          value = newValue(value);
        } 
        // Если передан объект, создаем новый объект для предотвращения мутации
        else if (typeof newValue === 'object' && newValue !== null) {
          value = JSON.parse(JSON.stringify(newValue)); // Создаем новый объект (глубокое копирование)
        } else {
          // Для примитивных значений просто присваиваем
          value = newValue;
        }
        
        // Уведомляем всех подписчиков о новом значении
        listeners.forEach((listener) => listener(value));
      };

      // Функция для подписки на изменения состояния
      const onStateChange = (listener) => {
        listeners.add(listener);
        return () => listeners.delete(listener); // Возвращаем функцию для отмены подписки
      };

      // Возвращаем массив с функцией для получения значения, функцией для его обновления и функцией подписки
      return [() => value, setState, onStateChange]; 
    };


    {if $mode === 0}
        cond_mode();
        view_mode(0, 'calc');
        var params = null;
        {if isset($calc.construct_params)}
            var params = JSON.parse(`{$calc.construct_params_for_json|replace:"\\r\\n":"\\\\r\\\\n"}`);
        {/if}
        var CondConstruct = new ConditionsConstruct({$table_id}, params);
        CondConstruct.build_cond_construct($('#cond_construct'));
        createConstructorTemplates({
            tableId: '{$table_id}', 
            $parent: $('#calc_tpl_area'), 
            calcId: {$calc.id}, 
            type: 'calc',
            params, 
            calcType: {$calc_type}
        });
    {/if}
    $('input[name=set_conds]').click(function () {
        cond_mode();
    });
    $('#submit_button').on('click', function() {
        // Проверка на заполненость поля получатель
        let valConstructTml = $('[name="construct_tpl[0]"]').val();
        // value конкретного шаблона, из valConstructTml
        let arrRestrict = ['78','5','77','42','31'];
        for (let restrict of arrRestrict) {
          if (valConstructTml == restrict) {
            let recipientField = $('.construct__field-recipient--select').val();
            if (recipientField === '' || recipientField === null) {
              jalert(lang.text_filling_warning_calc);
              return;
            }
          }
        }

        let table_id = {$table_id};
        let is_start_calc = $('input[name=linesUpdater]').prop('checked');
        if (is_start_calc) {
            var filter = $('select[name=filter]').val();
            var use_records = [];
            $('[name="use_records[]"]').each(function() {
                if (this.checked) use_records.push(this.value);
            });
            $.ajax({
                type: 'POST',
                url: 'edit_calc.php',
                data: {
                    'csrf': csrf,
                    'filter_id': filter,
                    'table_id': table_id,
                    'use_records': use_records,
                    'ajax': 1,
                    'action': 'getCountLinesUpdater',
                },
                success: function (data) {
                    if (Number(data) > 0) {
                        if (Number(data) > 5000) {
                            jconfirm('{$lang.Count_lines} ' + data + '.', function () {
                                $('#calc_form').submit();
                            }, function () {
                                $('input[name=linesUpdater]').prop('checked', false);
                                $('#calc_form').submit();
                            });
                        } else {
                            $('#calc_form').submit();
                        }
                    } else {
                        $('input[name=linesUpdater]').prop('checked', false);
                        $('#calc_form').submit();
                    }
                }
            });
        } else {
            $('input[name=linesUpdater]').prop('checked', false);
            if (!check_brackets()) {
                jalert('{$lang.Incorrect_brackets_alert}');
            } else {
                $('#calc_form').submit();
            }
        }
    });
    // Тупизм Javascript, по другому нельзя получить количество элементов
    function numKeys(obj) {
        var count = 0;
        for (var prop in obj) {
            count++;
        }
        return count;
    }

    function onchane_cond_type(obj) {
        var i = intval(obj.id.substr(5, 255)); // 5 символов занимает cond_
        var v = obj.value;
        const curType = $(obj).attr('ct_type');

        if (s[i]) {
            s[i]['type'] = parseInt(v);
            customConds.add(s[i]);
        }

        if (v == '0') { // Пустое значение, удаляем данное условие
            delete s[i];
            // Переформируем таблицу, чтобы небыло разрыва
            var vl, i = 1;
            var new_s = {};
            for (keyVar in s) {
                vl = s[keyVar];
                new_s[i] = vl;
                i++;
            }
            s = new_s;
        } else { // Выбрано значение
            var sz = numKeys(s);

            if (v === '8') $('#period_advanced').css('display', '');
            else $('#period_advanced').hide();
            if (sz == i) { // последний элемент
                // добавляем в конце еще один
                s[i + 1] = { 'type': 0, 'param': 0 };
            }
        }
        form_s_array();
    }

    function onchange_cond_param(obj) {
        var i = intval(obj.id.substr(11, 255)); // 11 символов занимает cond_param_
        var v = obj.value;
        s[i]['param'] = v.length > 0 ? parseInt(v) : 0;
        form_s_array();
    }

    // Сформировать массив, и подписаться на события изменения
    function form_s_array() {
        var cond, html, or_html, ct, i, one_field;
        i = 1;
        html = "";
        or_html = "";
        var once_cond ={};
        var once_show_field ={};
        var once_change_field ={};
        var disbl;
        let allConds = new Set();
        let condCount = 1;
        let emptyCond = true;
        let customCondsObj = {};
        let customCondsCount = 1;
        let no_once_cond = 0;
        for (let key in s) {
            if (s[key]['type'] != 0) allConds.add(s[key]);
            else delete s[key];
        }

        {* for (let value of customConds) {
            if (value['type'] == 0) customConds.delete(value);
            if (value['param'] == 0) customConds.delete(value);
            else {
                let dubl = false;

                for (let el in s) {
                    if (value['type'] == s[el]['type'] && value['param'] == s[el]['param']) dubl = true;
                }
                if (!dubl) allConds.add(value);
            }
        } *}

        s = {};
        for (let elem of allConds) {
            const type = elem['type'];
            if (type == 0) emptyCond = false;
            if (type == 1 || type == 4 || type == 5 || type == 7) elem['param'] = {$table_id};
            s[condCount++] = elem;
        }

        if (emptyCond) s[condCount] = { 'type': 0, 'param': 0 };

        for (keyVar in s) {
            cond = s[keyVar];
            ct = cond['type'];
            if (ct == 2) once_show_field[cond['param']] = cond['param'];
            if (ct == 3) once_change_field[cond['param']] = cond['param'];
        }

        for (keyVar in s) {
            cond = s[keyVar];
            ct = cond['type'];
            html += "<span><select name=cond_" + i + " id='cond_" + i + "' class='conditions_select form-control form-control-160' ct_type='" + ct + "' " +
                    "onchange='onchane_cond_type(this);'>";
            html += "<option value='0'></option>\n";
            html += "<option value='1' " + (ct == 1 ? "selected" : "") + (once_cond[1] ? "disabled" : "") + " >{$lang.Save_in_table}</option>\n";
            html += "<option value='2' " + (ct == 2 ? "selected" : "") + " >{$lang.Show_field}</option>\n";
            html += "<option value='3' " + (ct == 3 ? "selected" : "") + (once_cond[3] ? "disabled" : "") + " >{$lang.Field_changed}</option>\n";
            html += "<option value='4' " + (ct == 4 ? "selected" : "") + (once_cond[4] ? "disabled" : "") + " >{$lang.Delete_in_table}</option>\n";
            html += "<option value='5' " + (ct == 5 ? "selected" : "") + (once_cond[5] ? "disabled" : "") + " >{$lang.Import_in_table}</option>\n";
            html += "<option value='7' " + (ct == 7 ? "selected" : "") + (once_cond[7] ? "disabled" : "") + " >{$lang.Restore_in_table}</option>\n";
            html += "<option value='8' " + (ct == 8 ? "selected" : "") + (once_cond[8] ? "disabled" : "") + " >{$lang.On_schedule}</option>\n";
            html += "</select></span>\n";
            if ((ct == 1) || (ct == 4) || (ct == 5) || (ct == 7) || (ct == 8) || (ct == 3 && cond['param'] == '-1')) once_cond[ct] = ct;
            if ((ct == 2) || (ct == 3)) { // выводим список полей
                html += "<span><select class='form-control form-control-160' name=cond_param_" + i + " id='cond_param_" + i +
                        "' onchange='onchange_cond_param(this);'>";
                if (ct == 3) {
                    html += "<option value='-1' ";
                    if (cond['param'] == -1) {
                        html += "selected";
                    } else if (no_once_cond) {
                        html += "disabled";
                    } else {
                        no_once_cond = 1;
                    }
                    html += " >{ldelim}{$lang.any_field}{rdelim}</option>\n";
                }
                for (keyVar2 in f) {
                    one_field = f[keyVar2];
                    if (s[keyVar]['param'] == 0 && Object.values(f[keyVar2])[0] == one_field['id']) s[keyVar]['param'] = one_field['id'];
                    html += "<option value='" + one_field['id'] + "' ";
                    disbl = 0;
                    if ((ct == 2) && (once_show_field[one_field['id']]) && (one_field['id'] != cond['param'])) {
                        html += "disabled";
                        disbl = 1;
                        if (one_field['id'] == cond['param']) cond['param'] = 0;
                    }
                    if ((ct == 3) && (once_change_field[one_field['id']]) && (one_field['id'] != cond['param'])) {
                        html += "disabled";
                        disbl = 1;
                        if (one_field['id'] == cond['param']) cond['param'] = 0;
                    }

                    if ((disbl == 0) && (one_field['id'] == cond['param'])) html += "selected";
                    html += " >" + one_field["name"] + "</option>\n";
                }
                html += "</select></span>\n";
            }
            if (ct == 8) {
                const minSelected  = calcPeriod === minMask ? 'selected' : '';
                const fiveMinSelected  = calcPeriod === fiveMinMask ? 'selected' : '';
                const fifeteenMinSelected  = calcPeriod === tenMinMask ? 'selected' : '';
                const hourSelected  = calcPeriod === hourMask ? 'selected' : '';
                const day3Selected  = calcPeriod === threeDayMask ? 'selected' : '';
                const day12Selected  = calcPeriod === tenDayMask ? 'selected' : '';
                const day23Selected  = calcPeriod === twentyDayMask ? 'selected' : '';
                const isAdvanced = (calcPeriod != minMask && calcPeriod != fiveMinMask && calcPeriod != tenMinMask && calcPeriod != hourMask &&
                                    calcPeriod != threeDayMask && calcPeriod != tenDayMask && calcPeriod != twentyDayMask) ? 'selected' : '';
                if (isAdvanced === '') $('#period_advanced').hide();

                html += '<span><select class="form-control form-control-160" id="period_block" onchange="change_interval(this);">' +
                            '<option value="every_minute" ' + minSelected + '>' + lang.Every_minute + '</option>' +
                            '<option value="every_5_minute" ' + fiveMinSelected + '>' + lang.Every_5_minute +'</option>' +
                            '<option value="every_15_minute" ' + fifeteenMinSelected + '>' + lang.Every_15_minute + '</option>' +
                            '<option value="every_hour" ' + hourSelected + '>' + lang.Every_hour + '</option>' +
                            '<option value="every_day_3_oclock" ' + day3Selected + '>' + lang.Every_day_3_oclock + '</option>' +
                            '<option value="every_day_12_oclock" ' + day12Selected + '>' + lang.Every_day_12_oclock + '</option>' +
                            '<option value="every_day_23_oclock" ' + day23Selected + '>' + lang.Every_day_23_oclock + '</option>' +
                            '<option value="advanced" ' + isAdvanced + '>' + lang.Advanced + '</option>' +
                        '</select>';
                html += '<br>Убедитесь, что настройки вычисления выполнены верно. Информацию о настройках можно найти в <a href="https://doc.clientbase.ru/calc/start_steps#shedule" target="_blank">статье</a></span>';
                if (calcCronId) {
                    html += '<a href="edit_cron.php?cron_id=' + calcCronId + '" title="' + lang.Edit_cron_php + '" class="no_print" target="_blank">' +
                                '<img class="settings_t" src="images/settings_b.gif" border="0" style="margin: 0px 0px 4px 8px;">' +
                            '</a>';
                }
            }
            html += "<br>\n";
            if (i > 1) or_html += "{$lang.or}<br>\n";
            i++;
        }

        for (let value of customConds) {
            if (value['type'] != 0) customCondsObj[customCondsCount++] = value;
        }

        $('input#custom_user_params').val(JSON.stringify(customCondsObj));
        $('#conditions').html(html);
        $('#or_conditions').html(or_html);
        const periodCond = $('#period_block');

        if (void 0 === periodCond.prop('tagName')) {
            $('#period_val').removeAttr('value');
            $('#period_val').val('');
        } else if ($('#period_val').val() === '') {
            change_interval(periodCond.get(0));
        }
        init_chosen();
    }
    form_s_array();

    // автоустановка событий для шаблонов
    var change_tpl = 0; // запускаем функцию только при изменениях в шаблоне
    var tpl_events = {}; // массив событий из параметров шаблона
    /* @deprecated
        Это объект в глобальной видмости 
        Хранит информацию о полях измененных при взаимодействии с пользователем

        Формируется в подгружаемом шаблоне (Пример: /construct/calc/math_functions.tpl)
        При смене шаблона обнуляется в (см. include/js/scripts.js > load_tpl())
        Обрабатывается здесь, в функции set_tpl_events

        Исправить не переделав все вычисления не получится.
     */
    // var eventFields = [];
    // Создаем состояние на замену eventFields
    {literal}
    const [getStartCalcFields, setStartCalcFields, onChangeStartCalcFields] = 
        useState(([ ...Object.values(s)].map(({param}) => String(param)).filter(param => param !== '0')) || []);
    {/literal}
    /* @todo: доработать на работу с состояниями как с startCalcFields
      динамику поместить в слушатели состояний
      а в связанных дом элементах события должны 
      менять состояния вместо вызова ветвленных функций как эта 
    */
    function set_tpl_events() {
        s = {};
        var i = 1;
        var sel_events = { 2: {}, 3: {} };
        for (var k = 0; k <= CondConstruct.count; k++) {
            var elem = document.querySelector('[name="cond[' + k + '][field]"]');
            if (elem && elem.value != 0 && !sel_events[3][elem.value]) {
                s[i++] = { 'type': 3, 'param': elem.value.length > 0 ? parseInt(elem.value) : 0  };
                sel_events[3][elem.value] = 1;
            }
        }
        {literal}
            var select_filters = $('select.construct_select-filter');
            select_filters.each(function() {
                var sel_filter = $(this).find('option:selected');
                var change_fields = sel_filter.data('change_fields')
                if (Array.isArray(change_fields) === true && change_fields.length > 0) {
                    for(var field in change_fields) {
                        change_fields[field] = Number(change_fields[field]);
                        if (change_fields[field] && !sel_events[3][change_fields[field]]) {
                            s[i++] = { 'type': 3, 'param': change_fields[field].length > 0 ? parseInt(change_fields[field]) : 0 };
                            sel_events[3][change_fields[field]] = 1;
                        }
                    }
                }
            });
        {/literal}
        for (tpl_num in tpl_events) {
            for (event_num in tpl_events[tpl_num]) {
                var event = tpl_events[tpl_num][event_num];
                if (event.field) {
                    if(event.field != -1){
                        var elem = document.querySelector('[name="calc_params[' + tpl_num + '][' + event.field + ']"]');
                        if (!elem) {
                            elem = document.querySelector('[name="calc_params[' + tpl_num + '][' + event.field + '][table]"]');
                            if (!elem) {
                                elem = document.querySelector('[name="calc_params[' + tpl_num + '][' + event.field + '][field]"]');
                            }
                        }
                        var field_id;
                            if (elem && elem.querySelector('[value="' + elem.value + '"]')) {
                                field_id = elem.querySelector('[value="' + elem.value + '"]').getAttribute('data-id');
                            } else {
                                field_id = 0;
                            }
                        if (field_id != 0 && !sel_events[event.type][field_id] && field_id !== null) {
                            s[i++] = { 'type': parseInt(event.type), 'param': field_id.length > 0 ? parseInt(field_id) : 0 };
                            sel_events[event.type][field_id] = 1;
                    }
                    } else if(event.field == -1){
                        s[i++] = { 'type': parseInt(event.type), 'param': -1 };
                    }
                } else {
                    if (!sel_events[event.type]) {
                        s[i++] = { 'type': parseInt(event.type), 'param': 0 };
                        sel_events[event.type] = 1;
                    }
                }
            }
        }
        // Меняем динамику текущего шаблона по eventFields 
        getStartCalcFields().forEach((fieldId) => {
          if(!fieldId || sel_events[3][fieldId]) return;

          s[i++] = { 
            type: 3, 
            param: fieldId.length > 0 ? parseInt(fieldId) : 0 
          };
          sel_events[3][fieldId] = 1;
        });
        s[i] = { 'type': 0, 'param': 0 };
        form_s_array(); // Устанавливает по умолчанию действия для запуска вычисления
    }
</script>
<script type="text/javascript">
    // Определение глобальной переменной для хранения значения def_val
    var params = {$calc.construct_params_for_json|replace:"\\r\\n":"\\\\r\\\\n"|json_decode|json_encode|@print_r:true}?.params[0]
    let globalDefVal = '';

    if (params){
        if(params.correlation) {
            globalDefVal = params.correlation.def_val;
        } else if (params.gen_field && params.gen_field.set_value) {
            globalDefVal = params.gen_field.set_value;
        }
    }
</script>
<script src="include/js/configuration.js?{$revision}"></script>
