"use strict";
const ADD_ROWS_ABOVE_AND_BELOW = 15;
const DBL_ADD_ROWS = ADD_ROWS_ABOVE_AND_BELOW * 2;
const MIN_ROW_FOR_RECREATE = 3;
const PICT_COL_SIZE_ADD = 6;
const LEVEL_OFFSET = 18;
class TDinTableRow extends HTMLTableRowElement {
    constructor() {
        super(...arguments);
        this.selfNumber = -1;
    }
}
function IsIntoEncOrZip(oBr) {
    if (oBr.bEncOrZip)
        return true;
    if (!oBr.pParent)
        return false;
    return IsIntoEncOrZip(oBr.pParent);
}
class TBrControl {
    constructor(i = -1, p) {
        this.dep_ind = -1;
        this.jsBody = [];
        this.indJs = i;
        this.pParent = p;
    }
    AbortWaitBr() {
        if (this.fWaitingExit) {
            this.fWaitingExit();
        }
    }
    fFindEl(sElName, sFieldName, eDrill, bCaseSens) {
        if (sElName && !this.cont)
            return;
        let ret;
        if (sFieldName) {
            if (!sElName) {
                if (sFieldName in this.fGetData()) {
                    ret = this;
                }
            }
            else if (bCaseSens) {
                ret = this.cont.find(it => it.fGetData()[sFieldName] == sElName);
            }
            else {
                ret = this.cont.find(it => it.fGetData()[sFieldName].toLowerCase() == sElName.toLowerCase());
            }
        }
        else if (sElName) {
            if (bCaseSens) {
                ret = this.cont.find(it => it.pathEl && it.pathEl == sElName);
            }
            else {
                ret = this.cont.find(it => it.pathEl && it.pathEl.toLowerCase() == sElName.toLowerCase());
            }
        }
        if (!ret) {
            if (eDrill == "down" && this.cont) {
                for (const oBr of this.cont) {
                    ret = oBr.fFindEl(sElName, sFieldName, "down", bCaseSens);
                    if (ret)
                        break;
                }
            }
            else if (eDrill == "up" && this.pParent) {
                ret = this.pParent.fFindEl(sElName, sFieldName, "up", bCaseSens);
            }
        }
        return ret;
    }
    fGetOpenFoldersTree() {
        const ret = {};
        if (!this.cont) {
            return undefined;
        }
        for (let it of this.cont) {
            if (it.folder == 1 && it.pathEl) {
                ret[it.pathEl] = it.fGetOpenFoldersTree();
            }
        }
        if (this.cont.length > 0 && this.cont[this.cont.length - 1].bNextDataButton) {
            ret["////"] = this.jsBody.length - 1;
        }
        else {
            ret["////"] = this.jsBody.length;
        }
        if (Object.keys(ret).length > 0)
            return ret;
    }
    fCurtail() {
        if (this.cont) {
            for (const it of this.cont) {
                if (it.oIsWaiting) {
                    const oData = it.fGetData();
                    if (oData.__oAbort__) {
                        oData.__oAbort__.abort();
                    }
                    delete it.oIsWaiting;
                    delete it.fWaitingExit;
                    it.folder = 0;
                }
                it.fCurtail();
                it.dep_ind = -1;
                delete it.bSelested;
            }
        }
    }
    fGetOpenBranchFolderArr() {
        if (!this.cont || !this.cont.length) {
            return [];
        }
        const ret = [];
        this.cont.map(it => { if (it.folder == 1) {
            ret.push(it.pathEl);
        } });
        return ret;
    }
    fSort(oDTP, sSortColName) {
        if (!this.cont || this.cont.length < 2) {
            return;
        }
        if (!sSortColName) {
            sSortColName = oDTP.sSortCol;
        }
        oDTP.SortBranch(this.cont, sSortColName);
    }
    fGetPathArr() {
        if (!this.pathEl)
            return [];
        if (this.pParent) {
            const ret = this.pParent.fGetPathArr();
            ret.push(this.pathEl);
            return ret;
        }
        else {
            return [this.pathEl];
        }
    }
    fGetPathStr(t) {
        return this.fGetPathArr().join(t);
    }
    fChangeAllData(xData, fDataProcessor) {
        const oJsBranch = this.fGetData();
        let oData = xData;
        if (fDataProcessor) {
            oData = fDataProcessor(xData);
        }
        SetSameObjFields(oData, oJsBranch);
    }
    fRecursiveOpen() {
        let ret = true;
        if (this.pParent) {
            const bParentFolderWasOpen = this.pParent.fRecursiveOpen();
            if (this.pParent.folder !== undefined) {
                ret = this.pParent.folder === 1 && bParentFolderWasOpen;
                this.pParent.folder = 1;
            }
        }
        return ret;
    }
    fSetWaitingTimer(sText, bNotExit) {
        this.oIsWaiting = { text: "<div class='waiting_text'> " + sText + "</div>" + GetWaitingSvg(16, 2), "bNotExit": bNotExit };
    }
    fAddDataArr(arr, oParams) {
        if (!Array.isArray(arr) || arr.length == 0)
            return;
        if (!oParams) {
            oParams = {};
        }
        if (!this.cont) {
            this.cont = [];
        }
        else if (this.cont && this.cont.length > 0 && this.cont[this.cont.length - 1].bNextDataButton) {
            this.cont.splice(this.cont.length - 1, 1);
            this.jsBody.splice(this.jsBody.length - 1, 1);
        }
        else if (oParams.bClean) {
            this.cont.splice(0);
            this.jsBody.splice(0);
        }
        let ind = this.jsBody.length;
        let ret = undefined;
        if (oParams.sSpecValue) {
            if (!oParams.sFieldNameOfSpecValue) {
                oParams.sFieldNameOfSpecValue = oParams.sPathFieldName;
            }
        }
        if (oParams.bOpenBrAuto) {
            this.pParent.folder = 1;
        }
        if (!oParams.fDataProcessor && oParams.oDTP && oParams.oDTP.fDataProcessor) {
            oParams.fDataProcessor = oParams.oDTP.fDataProcessor;
        }
        if (!oParams.sPathFieldName && oParams.oDTP && oParams.oDTP.sPathFieldName) {
            oParams.sPathFieldName = oParams.oDTP.sPathFieldName;
        }
        const bObjRows = IsObject(arr[0]);
        if (!oParams.fDataProcessor && bObjRows) {
            this.jsBody = this.jsBody.concat(arr);
        }
        for (let j = 0; j < arr.length; j++, ind++) {
            const oTBC = new TBrControl(ind, this);
            if (oParams.fDataProcessor) {
                const oData = oParams.fDataProcessor(oTBC, arr[j]);
                if (!oData) {
                    ind--;
                    continue;
                }
                this.jsBody.push(oData);
            }
            else if (!bObjRows) {
                this.jsBody.push({ "-": arr[j] });
            }
            if (oParams.sPathFieldName && oParams.sPathFieldName in arr[j]) {
                oTBC.pathEl = arr[j][oParams.sPathFieldName];
            }
            if (oParams.oTdProperties) {
                oTBC.oTdProperties = oParams.oTdProperties;
            }
            if (oParams.oFunc) {
                if (Array.isArray(oParams.oFunc)) {
                    SetObjFieldsFromAnotherObj(oParams.oFunc[j], oTBC);
                }
                else {
                    SetObjFieldsFromAnotherObj(oParams.oFunc, oTBC);
                }
            }
            if (oParams.nInsertAboveRow !== undefined && oParams.nInsertAboveRow >= 0 && oParams.nInsertAboveRow < this.cont.length) {
                this.cont.splice(oParams.nInsertAboveRow, 0, oTBC);
                oParams.nInsertAboveRow++;
            }
            else {
                this.cont.push(oTBC);
            }
            if (oParams.bNoSelectWithShiftOrCtrl) {
                oTBC.bNoSelectWithShiftOrCtrl = true;
            }
            if (oParams.sSpecValue && oParams.sFieldNameOfSpecValue && arr[j][oParams.sFieldNameOfSpecValue].toLowerCase() == oParams.sSpecValue.toLowerCase()) {
                ret = oTBC;
            }
        }
        return ret;
    }
    fAddDatToParent(obj, oProp) {
        if (this.pParent)
            return this.pParent.fAddData(obj, oProp);
        return null;
    }
    fAddData(obj, oProp) {
        let i = this.jsBody.length;
        if (!this.cont) {
            this.cont = [];
        }
        const tmp = new TBrControl(i, this);
        if (oProp.fDataProcessor) {
            this.jsBody.push(oProp.fDataProcessor(tmp, obj));
        }
        else {
            this.jsBody.push(obj);
        }
        if (oProp.sPathFieldName && obj[oProp.sPathFieldName]) {
            tmp.pathEl = obj[oProp.sPathFieldName];
        }
        if (oProp.bOpenBrAuto) {
            tmp.cont = [];
            tmp.folder = 1;
        }
        if (oProp.bNoSelectWithShiftOrCtrl) {
            tmp.bNoSelectWithShiftOrCtrl = true;
        }
        if (oProp.oFunc) {
            SetObjFieldsFromAnotherObj(oProp.oFunc, tmp);
        }
        this.cont.push(tmp);
        return tmp;
    }
    fGetData() {
        return (this.pParent) ? this.pParent.jsBody[this.indJs] : {};
    }
    fSetData(sFieldName, xNewData) {
        if (!this.pParent)
            return;
        const oData = this.pParent.jsBody[this.indJs];
        oData[sFieldName] = xNewData;
    }
    fGetFullSize() {
        if (!this.cont)
            return 0;
        let summ = this.cont.length;
        for (const child of this.cont) {
            if (child.folder) {
                summ += child.fGetFullSize();
            }
        }
        return summ;
    }
    fClear() {
        this.jsBody = [];
        if (this.cont) {
            this.cont = [];
            this.folder = 0;
        }
        delete this.oIsWaiting;
        delete this.fWaitingExit;
        delete this.bError;
    }
    fDeleteSelf() {
        if (!this.pParent || !this.pParent.cont)
            return;
        const indCont = this.pParent.cont.findIndex(it => it == this);
        this.pParent.jsBody.splice(this.indJs, 1);
        this.pParent.cont.map(it => { if (it.indJs > this.indJs)
            it.indJs--; });
        this.pParent.cont.splice(indCont, 1);
    }
    fGetDataAsStr(aHead, oDTP, bDrillDown) {
        if (oDTP) {
            oDTP._aSelectRow.sort(compareNum);
            return oDTP._aSelectRow.map(it => aHead.map(sFN => (oDTP.aDeploedTable[it]._branch_).fGetData()[sFN.field_name]).join('\t')).join('\n');
        }
        if (!this.cont) {
            return "";
        }
        return this.cont.map(it => aHead.map(sFN => it.fGetData()[sFN.field_name]).join('\t')).join('\n');
    }
    fIsEmpty() {
        return !this.cont || this.cont.length === 0;
    }
    fMarkSelf(oDTP) {
        oDTP.fSelTabClean();
        oDTP.fSelTabPush(this.dep_ind);
    }
    fMarkAndShow(oDTP, bOnlyOneSelRow) {
        if (oDTP.bOnlyOneSelRow || bOnlyOneSelRow) {
            oDTP.fSelTabClean();
        }
        this.fMarkSelf(oDTP);
        oDTP.ShowFirstSelectRow();
    }
}
class TDynamicTableProperties {
    constructor() {
        this.root = new TBrControl(-1);
        this.aDeploedTable = [];
        this.aHead = [];
        this._aSelectRow = [];
        this.aTableColsWidth = [];
        this.domContainer = undefined;
        this.domLimWindow = undefined;
        this.domTable = undefined;
        this.domBody = undefined;
        this.nBottomFalseRowHeight = 0;
        this.nFirstShowRow = 0;
        this.nLastColWidth = 0;
        this.nLastShowRow = -1;
        this.nRowHeight = 0;
        this.nScrollTop = 0;
        this.nSortDirect = 1;
        this.nTopFalseRowHeight = 0;
        this.ind = -1;
        this.nHeadHeight = 0;
        this.nHorizontalScroll = -1;
        this.nMinRowHeight = 1.25;
        this.sSortCol = "";
        this.unicId = "u" + GetCurrTime() + Math.random();
        this.bWithoutHead = false;
        this.bEditable = false;
        this.bNotSelRow = false;
        this.bOnlyOneSelRow = false;
        this.bSizesNotSetting = true;
        this.bWasStretch = false;
        this.bIsTree = false;
        this.bNeedSort = false;
        this.bNotObjRows = false;
        this.bStopScroll = false;
        this.bResetSelectIfClickOut = false;
        this.bLineNumbers = false;
        this.fRowClick = null;
        this.fUserResize = null;
        this.fRightBtn = null;
        this.fOpenFolder = null;
        this.fDblclick = null;
        this.fDataProcessor = null;
        this.fOnChange = null;
        this.fAutoDeploy = null;
        this.fFiltr = null;
        this.fSaveColsSize = null;
        this.fGetColsSizeFromLocStor = null;
        this.nLines = -1;
        this.nWindowHeight = -1;
    }
    ShowTableWithOpenFolder(oBr) {
        this.ShowTable({ start: oBr.dep_ind, finish: oBr.dep_ind + oBr.fGetFullSize(), bStartPriority: true });
    }
    fGetSelRowNum(i) {
        return this._aSelectRow[i];
    }
    fGetSelRow(i) {
        return this.aDeploedTable[this._aSelectRow[i]];
    }
    fGetSelTabLen() {
        return this._aSelectRow.length;
    }
    fSelTabClean(i) {
        if (i) {
            for (let it = i; it < this._aSelectRow.length; it++) {
                const j = this._aSelectRow[it];
                if (this.aDeploedTable.length > j && j >= 0) {
                    this.aDeploedTable[j]._branch_.bSelested = true;
                }
            }
            this._aSelectRow.splice(i);
        }
        else {
            this._aSelectRow.map(it => {
                if (it >= 0 && it < this.aDeploedTable.length) {
                    delete this.aDeploedTable[it]._branch_.bSelested;
                }
            });
            this._aSelectRow.splice(0);
        }
    }
    fSelTabPush(item, i) {
        if (typeof item != 'number' || this._aSelectRow.includes(item))
            return;
        if (i === undefined) {
            this._aSelectRow.push(item);
        }
        else {
            this._aSelectRow.splice(i, 0, item);
        }
        if (this.aDeploedTable.length >= item + 1 && item >= 0) {
            this.aDeploedTable[item]._branch_.bSelested = true;
        }
    }
    fSelTabReplace(item, i) {
        if (typeof item != 'number')
            return;
        if (this.aDeploedTable.length >= item + 1 && item >= 0) {
            this.aDeploedTable[item]._branch_.bSelested = true;
        }
        if (this.aDeploedTable.length >= this._aSelectRow[i] + 1 && this._aSelectRow[i] >= 0) {
            this.aDeploedTable[this._aSelectRow[i]]._branch_.bSelested = false;
        }
        this._aSelectRow[i] = item;
    }
    fSelRowEnter(i) {
        const oRow = this.aDeploedTable[this._aSelectRow[i]];
        if (this.bEditable && !oRow._branch_.cont) {
            if (oRow._row_ && oRow._row_.firstChild) {
                oRow._row_.firstChild.dispatchEvent(new Event('dblclick'));
            }
        }
        else if (oRow._branch_.cont) {
            if (oRow._branch_.folder === 0) {
                DeleteAllDropMenu();
                this._OpenFolder(oRow._branch_);
                if (oRow._branch_.fOpenFolder) {
                    oRow._branch_.fOpenFolder(oRow._branch_, this);
                }
                else if (this.fOpenFolder) {
                    this.fOpenFolder(oRow._branch_, this);
                }
                this.ShowTable();
            }
            else {
                DeleteAllDropMenu();
                this._CloseFolder(oRow._branch_);
            }
            this.ShowTableWithOpenFolder(oRow._branch_);
        }
    }
    fMarkBranch(oBr) {
        if (!oBr.fRecursiveOpen()) {
            this.ShowTable();
        }
        if (oBr.dep_ind >= 0) {
            this.fSelTabPush(oBr.dep_ind);
            this.ShowTable();
        }
    }
    _CreateRows() {
        if (!this.domBody) {
            return;
        }
        const t1 = GetCurrTime();
        this.nHorizontalScroll = this.domLimWindow.scrollLeft;
        this.domBody.innerHTML = "";
        let sRowH = (this.nMinRowHeight * rem2px) + "px";
        if (this.nRowHeight > 0) {
            sRowH = this.nRowHeight + "px";
        }
        let i = 0;
        let row = this.domBody.insertRow(-1);
        let tdf = row.insertCell(-1);
        tdf.style.height = (this.nFirstShowRow * this.nRowHeight) + "px";
        tdf.style.verticalAlign = "bottom";
        tdf.style.maxWidth = "1px";
        tdf.style.whiteSpace = "nowrap";
        tdf.innerHTML = "Please wait...";
        if (this.nFirstShowRow > 0) {
            i += this.nFirstShowRow;
        }
        else {
            row.style.display = "none";
        }
        let bNeedBreak = false;
        for (; i < this.aDeploedTable.length && !bNeedBreak; i++) {
            let oTableRow = this.aDeploedTable[i];
            row = this.domBody.insertRow(-1);
            row.className = "dyn_tab_row";
            oTableRow._row_ = row;
            if (oTableRow._branch_.bDeadRow) {
                row.className += " dead_img";
            }
            row["selfNumber"] = i;
            row.style.height = sRowH;
            const oDTP1 = this;
            const oBr = oTableRow._branch_;
            const row1 = row;
            row.fOpenFolder = function () {
                DeleteAllDropMenu();
                oDTP1._OpenFolder(oBr);
                if (oBr.fOpenFolder) {
                    oBr.fOpenFolder(oBr, oDTP1);
                }
                else if (oDTP1.fOpenFolder) {
                    oDTP1.fOpenFolder(oBr, oDTP1);
                }
                oDTP1.ShowTableWithOpenFolder(oBr);
            };
            row.addEventListener('click', function (e) {
                e.preventDefault();
                e.stopPropagation();
                const nThisRowNumber = this.selfNumber;
                if (e.shiftKey) {
                    if (document) {
                        const tmp = document.getSelection();
                        if (tmp) {
                            tmp.empty();
                        }
                    }
                }
                if ((e.ctrlKey || e.shiftKey) && oDTP1.aDeploedTable[nThisRowNumber]._branch_.bNoSelectWithShiftOrCtrl)
                    return;
                if ((e.ctrlKey || e.shiftKey) && oDTP1._aSelectRow.length == 1 && oDTP1.aDeploedTable[oDTP1._aSelectRow[0]]._branch_.bNoSelectWithShiftOrCtrl) {
                    oDTP1.fSelTabClean();
                }
                if (e.shiftKey && oDTP1._aSelectRow.length == 1 && !oDTP1.bOnlyOneSelRow) {
                    let nInc = (nThisRowNumber > oDTP1._aSelectRow[0]) ? 1 : -1;
                    for (let i = oDTP1._aSelectRow[0] + nInc; i != (nThisRowNumber + nInc); i += nInc) {
                        if (oDTP1.aDeploedTable[i]._branch_.bNoSelectWithShiftOrCtrl || oDTP1.aDeploedTable[i]._level_ != oDTP1.aDeploedTable[oDTP1._aSelectRow[0]]._level_)
                            break;
                        oDTP1.fSelTabPush(i);
                    }
                    oDTP1._aSelectRow.sort(compareNum);
                }
                else if ((e.ctrlKey || e.shiftKey) && !oDTP1.bOnlyOneSelRow) {
                    if (nThisRowNumber !== undefined) {
                        if (oDTP1._aSelectRow.length > 0) {
                            let nInc = (nThisRowNumber > oDTP1._aSelectRow[0]) ? 1 : -1;
                            for (let i = oDTP1._aSelectRow[0] + nInc; i != (nThisRowNumber + nInc); i += nInc) {
                                if (oDTP1.aDeploedTable[i]._branch_.bNoSelectWithShiftOrCtrl || oDTP1.aDeploedTable[i]._level_ != oDTP1.aDeploedTable[oDTP1._aSelectRow[0]]._level_) {
                                    oDTP1.fSelTabClean();
                                    break;
                                }
                            }
                        }
                        oDTP1.fSelTabPush(nThisRowNumber);
                        oDTP1._aSelectRow.sort(compareNum);
                    }
                }
                else {
                    oDTP1.fSelTabClean();
                    oDTP1.fSelTabPush(nThisRowNumber);
                    TableRowClick(oDTP1, oBr, true);
                }
                if (!oDTP1.bNotSelRow)
                    oDTP1.SetRowAsSelect();
            });
            row.addEventListener('contextmenu', function (e) {
                e.preventDefault();
                DeleteAllDropMenu();
                const nThisRowNumber = this.selfNumber;
                if (!oDTP1._aSelectRow.includes(nThisRowNumber) || oDTP1.bOnlyOneSelRow) {
                    oDTP1.fSelTabClean();
                    oDTP1.fSelTabPush(nThisRowNumber);
                    if (!oDTP1.bNotSelRow)
                        oDTP1.SetRowAsSelect();
                }
                if (oTableRow._branch_ && oTableRow._branch_["fRightBtn"])
                    oTableRow._branch_.fRightBtn(e, nThisRowNumber, oDTP1);
                else if (oDTP1["fRightBtn"])
                    oDTP1.fRightBtn(e, nThisRowNumber, oDTP1);
            });
            if (oTableRow._branch_.fDblclick) {
                row.addEventListener('dblclick', () => oTableRow._branch_.fDblclick(oTableRow, oDTP1));
            }
            else if (oDTP1.fDblclick) {
                row.addEventListener('dblclick', () => oDTP1.fDblclick(oTableRow, oDTP1));
            }
            else if (!oDTP1.bEditable && oDTP1.bIsTree && "folder" in oTableRow._branch_) {
                row.addEventListener('dblclick', (e) => {
                    e.stopPropagation();
                    if (oBr.folder === 0) {
                        row1.fOpenFolder();
                    }
                    else {
                        DeleteAllDropMenu();
                        oDTP1._CloseFolder(oBr);
                    }
                    oDTP1.ShowTable();
                });
            }
            let span = "";
            if (oDTP1.bIsTree) {
                span = document.createElement("span");
                span.className = "tree_control nonselect";
                span.style.marginLeft = (oTableRow._level_ * LEVEL_OFFSET) + "px";
                if ("folder" in oTableRow._branch_) {
                    if (oTableRow._branch_["folder"] == 2) {
                        bNeedBreak = true;
                        oTableRow._branch_["folder"] = 1;
                        if (oDTP1.fAutoDeploy) {
                            oDTP1.fAutoDeploy(oTableRow._branch_);
                        }
                        span.onclick = function (e) {
                            DeleteAllDropMenu();
                            oDTP1._CloseFolder(oBr);
                            e.stopPropagation();
                        };
                        const img = SetImg("chevron-down", "var(--horizontal-img-btn-size)");
                        if (img) {
                            span.append(img);
                        }
                        else {
                            span.innerHTML = "&#128899;";
                        }
                    }
                    else if (oTableRow._branch_["folder"] == 1) {
                        span.onclick = function (e) {
                            DeleteAllDropMenu();
                            oDTP1._CloseFolder(oBr);
                            e.stopPropagation();
                        };
                        const img = SetImg("chevron-down", "var(--horizontal-img-btn-size)");
                        if (img) {
                            span.append(img);
                        }
                        else {
                            span.innerHTML = "&#128899;";
                        }
                    }
                    else {
                        span.onclick = function (e) {
                            row1.fOpenFolder();
                            e.stopPropagation();
                        };
                        const img = SetImg("chevron-right", "var(--horizontal-img-btn-size)");
                        if (img) {
                            span.append(img);
                        }
                        else {
                            span.innerHTML = "&#128898;";
                        }
                    }
                }
            }
            let td;
            if (this.bLineNumbers) {
                td = row.insertCell(-1);
                td.style.background = "#ddd";
                td.innerHTML = i + "";
            }
            let aTmpHead = this.aHead;
            if (aTmpHead.length == 0)
                aTmpHead = [{ "field_name": "-", "col_name": "-" }];
            for (let j = 0; j < aTmpHead.length; j++) {
                let oColHead = aTmpHead[j];
                td = row.insertCell(-1);
                let cell = document.createElement("div");
                cell.className = "dyn_tab_cell " + this.unicId + oColHead.field_name;
                if (this.sCellClass) {
                    cell.className += " " + this.sCellClass;
                }
                if (oColHead.class) {
                    cell.classList.add(oColHead.class);
                }
                td.append(cell);
                let data = oTableRow._branch_.fGetData();
                if (!data) {
                    data = {};
                }
                let sCellInner = "" + data[oColHead.field_name];
                if (sCellInner == "undefined")
                    sCellInner = " ";
                if (j == 0) {
                    cell.append(span);
                    if (oTableRow._text_) {
                        let span2 = document.createElement("span");
                        span2.className = "nonselect flex_gor";
                        span2.innerHTML += oTableRow._text_;
                        span2.onclick = function () {
                            if (oTableRow._branch_.fGetData()["fWaitingExit"]) {
                                oTableRow._branch_.fGetData().fWaitingExit(oTableRow._branch_);
                            }
                        };
                        cell.append(span2);
                        continue;
                    }
                }
                if ("img" in oColHead) {
                    if (sCellInner != "-" && sCellInner.trim()) {
                        let img = SetImg(sCellInner, "var(--horizontal-img-btn-size)");
                        if (img) {
                            cell.style.width = "var(--horizontal-img-btn-size)";
                            cell.style.marginLeft = "2px";
                            if (oTableRow._branch_.oTdProperties) {
                                img.classList.add(oTableRow._branch_.oTdProperties[aTmpHead[j].field_name]);
                            }
                            cell.append(img);
                        }
                    }
                }
                else if (oColHead.bool) {
                    let img;
                    if (!sCellInner || sCellInner === 'false') {
                        img = SetImg("checkbox-false", "var(--horizontal-img-btn-size)");
                    }
                    else {
                        img = SetImg("checkbox-true", "var(--horizontal-img-btn-size)");
                    }
                    cell.style.width = "var(--horizontal-img-btn-size)";
                    cell.style.marginLeft = "45%";
                    if (img) {
                        if (oTableRow._branch_.oTdProperties) {
                            img.classList.add(oTableRow._branch_.oTdProperties[aTmpHead[j].field_name]);
                        }
                        cell.append(img);
                    }
                    if (this.bEditable) {
                        cell["i"] = i;
                        cell["j"] = j;
                        td.addEventListener('dblclick', function () {
                            oDTP1.SetEditableBool(cell);
                        });
                    }
                }
                else {
                    const nPercent = (!oColHead.progressbar) ? null : GetPercent(sCellInner);
                    let div2;
                    if (nPercent !== null) {
                        cell.classList.add("cell_for_pb");
                        div2 = document.createElement("div");
                        let def_pb_class;
                        if (oTableRow._branch_.oTdProperties) {
                            def_pb_class = oTableRow._branch_.oTdProperties[aTmpHead[j].field_name + "_pb_class"];
                        }
                        if (!def_pb_class) {
                            def_pb_class = "def_pb_color";
                        }
                        div2.classList.add(def_pb_class);
                        div2.style.width = nPercent + "%";
                        div2.style.height = "1rem";
                        cell.append(div2);
                        let div3 = document.createElement("span");
                        div3.className = "table_percent_num";
                        div3.innerHTML = sCellInner;
                        cell.append(div3);
                    }
                    else {
                        if (oColHead.align) {
                            switch (oColHead.align) {
                                case "right":
                                    cell.style.justifyContent = "flex-end";
                                    break;
                                case "center":
                                    cell.style.justifyContent = "center";
                                    break;
                            }
                        }
                        if (("icon" in oColHead) && (oColHead.icon in data)) {
                            let img = SetImg(data[oColHead.icon], "var(--horizontal-img-btn-size)");
                            if (img) {
                                img.classList.add("dyn_tab_cell_icon");
                                if (oTableRow._branch_.oTdProperties && oTableRow._branch_.oTdProperties[oColHead.icon]) {
                                    img.classList.add(oTableRow._branch_.oTdProperties[oColHead.icon]);
                                }
                                cell.append(img);
                            }
                        }
                        if ("time" in oColHead) {
                            if (sCellInner == "-1" || sCellInner == " ")
                                sCellInner = "";
                            else if (sCellInner == "") { }
                            else
                                sCellInner = GetDTString(sCellInner);
                        }
                        else if ("locale_number" in oColHead) {
                            sCellInner = ToLocaleNumber(sCellInner, oColHead.locale_number);
                        }
                        div2 = document.createElement("span");
                        cell.append(div2);
                        div2.className = "dyn_tab_cell_inner dyn_cell";
                        div2.innerHTML = sCellInner;
                        if (oTableRow._branch_.oTdProperties && oTableRow._branch_.oTdProperties[aTmpHead[j].field_name]) {
                            const aClasses = oTableRow._branch_.oTdProperties[aTmpHead[j].field_name].trim().split(' ');
                            for (const sClass of aClasses) {
                                div2.classList.add(sClass);
                            }
                        }
                        div2["i"] = i;
                        div2["j"] = j;
                        if (this.bEditable) {
                            td.addEventListener('dblclick', () => {
                                oDTP1.EditDinTableCell(div2, div2.innerText, cell.getBoundingClientRect().width);
                            });
                        }
                    }
                    if ((j + 1) < aTmpHead.length) {
                        if (this.bWithoutHead) {
                            cell.classList.add("stretch_x");
                            cell["sDriven"] = this.unicId + oColHead.field_name;
                            cell["domLimEl"] = this.domLimWindow;
                        }
                        else {
                            let dom = document.getElementById(this.unicId + aTmpHead[j].field_name + "_head");
                            if (dom) {
                                let width = dom.style.width;
                                if (width)
                                    cell.style.width = width;
                            }
                        }
                    }
                    else {
                        let nLastSpanWidth = div2.getBoundingClientRect().width;
                        if (this.nLastColWidth < nLastSpanWidth)
                            this.nLastColWidth = nLastSpanWidth;
                    }
                    cell.title = sCellInner;
                }
                if (oColHead.button && cell.innerHTML.trim() && sCellInner != "-") {
                    cell.classList.add("dyn_tab_cell_button");
                    try {
                        cell.title = GetLocaleText(eval("GetHint" + oColHead.button + "('" + oColHead.field_name + "', oDTP1.aDeploedTable[" + i + "]._branch_.fGetData())"));
                    }
                    catch (_a) { }
                    let nI = i;
                    let nJ = j;
                    cell.onclick = function (e) {
                        e.stopPropagation();
                        oBr.fMarkSelf(oDTP1);
                        oDTP1.ShowRows();
                        const cell1 = oDTP1.aDeploedTable[nI]._row_.childNodes[nJ];
                        eval(oColHead.button + "('" + oColHead.field_name + "', oDTP1.aDeploedTable[" + nI + "], oDTP1, cell1)");
                    };
                }
            }
            td.style.width = "90%";
            if (oBr.bSelested) {
                this.SetRowAsSelect();
            }
            if (this.bSizesNotSetting) {
                this.bSizesNotSetting = false;
                let nHeadHeight = (this.domHead) ? this.domHead.getBoundingClientRect().height : 0;
                if (this.nRowHeight <= 0) {
                    this.nRowHeight = Math.ceil(row.getBoundingClientRect().height + 0.1);
                    const computedStyle = window.getComputedStyle(td);
                    const nSysFontSize = parseFloat(computedStyle.getPropertyValue('font-size'));
                    if (this.nRowHeight < nSysFontSize) {
                        this.nRowHeight += nSysFontSize;
                    }
                    sRowH = this.nRowHeight + "px";
                    row.style.height = sRowH;
                    this.domContainer.style.minHeight = (this.aDeploedTable.length * this.nRowHeight + nHeadHeight) + "px";
                }
                if (this.nWindowHeight > 0) {
                    this.nLines = Math.ceil((this.nWindowHeight - nHeadHeight) / this.nRowHeight);
                    this.domLimWindow.style.height = this.nWindowHeight + "px";
                    this.domLimWindow.style.maxHeight = this.nWindowHeight + "px";
                }
                else if (this.nLines > 0) {
                    this.nWindowHeight = nHeadHeight + this.nLines * this.nRowHeight;
                    this.domLimWindow.style.height = this.nWindowHeight + "px";
                    this.domLimWindow.style.maxHeight = this.nWindowHeight + "px";
                }
                else {
                    this.nWindowHeight = this.domLimWindow.getBoundingClientRect().height;
                    this.nLines = Math.ceil((this.nWindowHeight - nHeadHeight) / this.nRowHeight);
                }
            }
            if (this.nLastShowRow <= 0 && this.nRowHeight > 0 && this.domLimWindow.clientHeight > this.nRowHeight &&
                (this.domLimWindow.scrollHeight / this.domLimWindow.clientHeight) >= 2) {
                this.nLastShowRow = Math.ceil(this.domLimWindow.clientHeight / this.nRowHeight) + 2;
            }
            if (this.nLastShowRow > 0 && i > this.nLastShowRow) {
                row = this.domBody.insertRow(-1);
                let tdf = row.insertCell(-1);
                tdf.innerHTML = "Please wait...";
                tdf.style.maxWidth = "1px";
                tdf.style.whiteSpace = "nowrap";
                break;
            }
        }
        this.domLimWindow.scrollLeft = this.nHorizontalScroll;
        const dT = GetCurrTime() - t1;
        if (bDebugMode) {
            table_create.innerHTML = "Table " + this.domLimWindow.id + " creating time = " + dT + "ms";
        }
    }
    _DeployTable(level, pParent) {
        let brCont = this.root.cont;
        let brBody = this.root.jsBody;
        if (pParent) {
            brCont = pParent.cont;
            if (pParent.jsBody) {
                brBody = pParent.jsBody;
            }
            else {
                return false;
            }
        }
        if (!brBody || !brCont) {
            return false;
        }
        if (IsObject(brBody[0])) {
            if (this.bNeedSort && (!this.nLevelNotSort || level >= this.nLevelNotSort)) {
                this.SortBranch(brCont);
            }
            for (let i = 0; i < brCont.length; i++) {
                let oBranch = brCont[i];
                const oDB = { "_level_": level, "_branch_": oBranch, };
                oBranch["dep_ind"] = this.aDeploedTable.length;
                if (oBranch.bSelested) {
                    this._aSelectRow.push(oBranch.dep_ind);
                }
                if (oBranch.oIsWaiting) {
                    this.aDeploedTable.push(oDB);
                    if (oBranch.oIsWaiting.bNotExit) {
                        this.aDeploedTable.push({ "_level_": level + 1, "_branch_": oEmptyBranch, _text_: oBranch.oIsWaiting.text });
                    }
                    else {
                        this.aDeploedTable.push({ "_level_": level + 1, "_branch_": oEmptyBranch, _text_: oBranch.oIsWaiting.text +
                                "<div class='waiting_exit' onclick='AbortWait(\"" + this.unicId + "_whole_table\", " + this.aDeploedTable.length + ")'>X</div>" });
                    }
                }
                else if ("cont" in oBranch && Array.isArray(oBranch.cont)) {
                    this.bIsTree = true;
                    if (!("folder" in oBranch)) {
                        if (this.sAutoDeploy && oAutoDeploy[this.sAutoDeploy] && this.fAutoDeploy) {
                            oBranch["folder"] = 2;
                        }
                        else {
                            oBranch["folder"] = 0;
                        }
                        this.aDeploedTable.push(oDB);
                    }
                    else {
                        this.aDeploedTable.push(oDB);
                        if (oBranch["folder"] == 1) {
                            this._DeployTable(level + 1, oBranch);
                        }
                    }
                }
                else {
                    this.aDeploedTable.push(oDB);
                }
            }
        }
        else {
            for (let i = 0; i < brCont.length; i++) {
                this.aDeploedTable.push({ _level_: 0, _branch_: brCont[i] });
                brCont[i].dep_ind = i;
                if (brCont[i].bSelested) {
                    this._aSelectRow.push(i);
                }
            }
        }
        return true;
    }
    _SetColsWidth(nContainerWidth) {
        if (!this.root.cont || this.root.cont.length === 0 || this.aHead.length === 0 || this.aDeploedTable.length == 0) {
            return;
        }
        let nWidthSumm = 0;
        let nNotImgColsNum = 0;
        let nPercentSumm = 0;
        while (!this.bWasStretch && this.domBody.children.length > 1) {
            this.bWasStretch = true;
            if (this.fGetColsSizeFromLocStor && this.fGetColsSizeFromLocStor())
                break;
            const aTableColls = this.domBody.children[1].cells;
            let i = 0;
            if (this.bLineNumbers) {
                i = 1;
                nWidthSumm = 50;
            }
            for (; (i + 1) < aTableColls.length; i++) {
                const oHead = this.aHead[i];
                const nColWidth = aTableColls[i].getBoundingClientRect().width;
                nWidthSumm += nColWidth;
                nNotImgColsNum += (oHead.img || oHead.bool) ? 0 : 1;
                nPercentSumm += (oHead.auto_ext) ? oHead.auto_ext : 0;
                this.aTableColsWidth[i] = (nColWidth);
            }
            const oHead = this.aHead[i];
            nPercentSumm += (oHead.auto_ext) ? oHead.auto_ext : 0;
            nWidthSumm += this.nLastColWidth + 20;
            if (nWidthSumm > nContainerWidth) {
                let delta = nWidthSumm - nContainerWidth;
                const nAlignStep = Math.min(delta / 10, 20);
                TableAlign(this.aTableColsWidth, delta, nAlignStep, 60);
            }
            else if (nNotImgColsNum > 0) {
                let delta = nContainerWidth - nWidthSumm;
                if (nPercentSumm) {
                    for (let i = 0; i < this.aTableColsWidth.length; i++) {
                        const oHead = this.aHead[i];
                        if (oHead.auto_ext) {
                            this.aTableColsWidth[i] += delta * oHead.auto_ext / nPercentSumm - 30;
                        }
                    }
                }
                else {
                    for (let i = 0; i < this.aTableColsWidth.length; i++) {
                        const oHead = this.aHead[i];
                        if (!oHead.img && !oHead.bool) {
                            this.aTableColsWidth[i] += delta;
                        }
                    }
                }
            }
        }
        for (let i = 0; i < this.aTableColsWidth.length; i++) {
            const oHead = this.aHead[i];
            if (!oHead.img && !oHead.bool) {
                const tmp = document.getElementById(this.unicId + oHead.field_name + "_head");
                if (tmp) {
                    tmp.style.width = this.aTableColsWidth[i] + "px";
                }
                else {
                    console.error("No document.getElementById(" + this.unicId + oHead.field_name + "'_head')!");
                }
                SetClassWidth(this.unicId + oHead.field_name, this.aTableColsWidth[i] + "px");
            }
        }
    }
    SetEditableBool(domCell) {
        const tmp = this.aDeploedTable[domCell.i]._branch_.fGetData()[this.aHead[domCell.j].field_name];
        this.aDeploedTable[domCell.i]._branch_.fGetData()[this.aHead[domCell.j].field_name] = !tmp;
        this._CreateRows();
        if (this.fOnChange) {
            this.fOnChange();
        }
    }
    SetEditableCell(domCell, el) {
        let newVal = el.value;
        domCell.innerHTML = newVal;
        const tmp = el;
        this.aDeploedTable[tmp.i]._branch_.fGetData()[this.aHead[tmp.j].field_name] = newVal;
        this._CreateRows();
        if (this.fOnChange) {
            this.fOnChange();
        }
    }
    EditDinTableCell(domCell, value, nWidth) {
        let edit = document.createElement("input");
        edit.type = 'text';
        edit.style.width = (nWidth - 10) + "px";
        edit.style.border = "none";
        domCell.innerHTML = "";
        domCell.append(edit);
        edit["i"] = domCell.i;
        edit["j"] = domCell.j;
        edit.value = value + "";
        const oDTP = this;
        edit.onblur = function () {
            oDTP.SetEditableCell(domCell, edit);
        };
        edit.addEventListener('keydown', function (key) {
            if (key.code == "Enter") {
                oDTP.bStopScroll = false;
                this.onblur = null;
                oDTP.SetEditableCell(domCell, this);
                oDTP.domLimWindow.focus();
                key.preventDefault();
                key.stopImmediatePropagation();
            }
            else if (key.code == "Escape") {
                oDTP.bStopScroll = false;
                this.onblur = null;
                domCell.innerHTML = value + "";
                key.preventDefault();
                key.stopImmediatePropagation();
                oDTP.domLimWindow.focus();
            }
        });
        edit.focus();
        oDTP.bStopScroll = true;
    }
    CreateDomElements() {
        if (!this.domLimWindow && !this.domContainer)
            return;
        if (!this.domLimWindow) {
            this.domLimWindow = this.domContainer;
        }
        else if (!this.domContainer) {
            this.domLimWindow.innerHTML = "";
            this.domContainer = document.createElement('div');
            this.domLimWindow.append(this.domContainer);
        }
        else if (!this.domLimWindow.contains(this.domContainer)) {
            this.domLimWindow.innerHTML = "";
            this.domLimWindow.append(this.domContainer);
        }
        this.domContainer.innerHTML = "";
        this.domLimWindow.style.overflow = "auto";
        this.domLimWindow.tabIndex = 1;
        this.domLimWindow.classList.add("dt_lim_window");
        this.domLimWindow.fKeyDown = (e) => {
            if (e.code == "ArrowUp" || e.code == "ArrowDown") {
                e.preventDefault();
                if (this.fGetSelTabLen() === 0) {
                    this.fSelTabPush(0);
                    this.ShowFirstSelectRow();
                    TableRowClick(this, this.aDeploedTable[0]._branch_);
                }
                else if (this.fGetSelTabLen() === 1) {
                    this.TableMoveSelRow(e.code);
                }
            }
            else if (e.code == "Enter") {
                if (this.fGetSelTabLen() === 1) {
                    if (e.ctrlKey) {
                        const oDepBranch = this.fGetSelRow(0);
                        if (oDepBranch && oDepBranch._row_) {
                            DeleteAllDropMenu();
                            const rect = oDepBranch._row_.getBoundingClientRect();
                            const oE = { clientX: rect.right, clientY: rect.bottom, target: oDepBranch._row_ };
                            if (oDepBranch._branch_.fRightBtn) {
                                oDepBranch._branch_.fRightBtn(oE, this.fGetSelRowNum(0), this);
                            }
                            else if (this.fRightBtn) {
                                this.fRightBtn(oE, this.fGetSelRowNum(0), this);
                            }
                        }
                    }
                    else {
                        this.fSelRowEnter(0);
                    }
                    e.preventDefault();
                }
            }
        };
        const oDTP1 = this;
        this.domLimWindow.onscroll = function (e) {
            if (oDTP1.bStopScroll) {
                oDTP1.domLimWindow.scrollTop = oDTP1.nScrollTop;
                return false;
            }
            DrawDragAfterScrolling();
            oDTP1.ShowTableAfterScroll();
        };
        const oDomLimWin = this.domLimWindow;
        if (oDomLimWin.fUserResize) {
            if (oDomLimWin.fUserResize.name != "LimWindowUserResize") {
                const fPrev = oDomLimWin.fUserResize;
                oDomLimWin.fUserResize = function LimWindowUserResize() {
                    if (WasResize(oDomLimWin)) {
                        if (oDomLimWin.firstChild && oDomLimWin.firstChild.firstChild &&
                            oDomLimWin.firstChild.firstChild.pTable &&
                            "ShowTableAfterResize" in oDomLimWin.firstChild.firstChild.pTable) {
                            oDomLimWin.firstChild.firstChild.pTable.ShowTableAfterResize();
                        }
                        if (fPrev) {
                            fPrev();
                        }
                    }
                };
            }
        }
        else {
            this.domLimWindow.fUserResize = function LimWindowUserResize() {
                if (WasResize(oDomLimWin)) {
                    if (oDomLimWin.firstChild && oDomLimWin.firstChild.firstChild &&
                        oDomLimWin.firstChild.firstChild.pTable &&
                        "ShowTableAfterResize" in oDomLimWin.firstChild.firstChild.pTable) {
                        oDomLimWin.firstChild.firstChild.pTable.ShowTableAfterResize();
                    }
                }
            };
        }
        this.domLimWindow.classList.add("I_have_user_resise");
        let table = document.createElement('table');
        table.style.width = "100%";
        if (this.bResetSelectIfClickOut) {
            table.classList.add("ResetSelectIfClickOut");
        }
        table.pTable = this;
        table.id = this.unicId + "_whole_table";
        this.domContainer.append(table);
        let head;
        if (!this.bWithoutHead && this.aHead.length > 0) {
            head = table.createTHead();
            let row = head.insertRow(0);
            if (this.bLineNumbers)
                row.insertCell(-1);
            head.className = "dyn_tab_head";
            head.ondblclick = function () {
                oDTP1.bWasStretch = false;
                oDTP1.CreateDomElements();
            };
            for (let i = 0; i < this.aHead.length; i++) {
                const td = row.insertCell(-1);
                let cell = document.createElement('div');
                td.append(cell);
                if (this.bNeedSort && this.aHead[i].field_name == this.sSortCol)
                    cell.innerHTML += (this.nSortDirect > 0) ? "&#9650" : "&#9660;";
                cell.className = "dyn_tab_col_head dyn_cell";
                if (this.aHead[i].align) {
                    cell.style.textAlign = this.aHead[i].align;
                }
                else if (this.aHead[i].bool) {
                    cell.style.textAlign = "center";
                }
                if ((i + 1) < this.aHead.length) {
                    if (!this.aHead[i].img) {
                        cell.className += " stretch_x";
                        cell.style.width = "100%";
                        cell["sDriven"] = this.unicId + this.aHead[i].field_name;
                        cell["domLimEl"] = this.domLimWindow;
                        if (!this.aTableColsWidth[i])
                            this.aTableColsWidth[i] = -1;
                        cell["oFeedback"] = { arr: this.aTableColsWidth, i: i, oControl: this };
                    }
                }
                else {
                    cell.style.display = "inline-block";
                    this.nLastColWidth = cell.getBoundingClientRect().width;
                    cell.style.display = "";
                    cell.style.width = "100%";
                }
                if ("img" in this.aHead[i]) {
                    cell.style.width = "calc(var(--horizontal-img-btn-size)*1.4)";
                    cell.innerHTML = "&nbsp;";
                }
                else {
                    cell.innerHTML = "<span class='dyn_tab_head_cell_inner'>" + GetLocaleText(this.aHead[i].col_name) + "</span>";
                }
                cell["id"] = this.unicId + this.aHead[i].field_name + "_head";
                if (oDTP1.bNeedSort) {
                    let sFieldName = this.aHead[i].field_name;
                    cell.onclick = function () {
                        if (oDTP1.sSortCol == sFieldName) {
                            oDTP1.nSortDirect = -oDTP1.nSortDirect;
                        }
                        else {
                            oDTP1.sSortCol = sFieldName;
                        }
                        oDTP1.SortFunc(sFieldName);
                    };
                }
            }
            this.nHeadHeight = head.getBoundingClientRect().height;
        }
        let body = table.createTBody();
        body.className = "dyn_tab_body";
        if (this.bStriped) {
            body.className += " striped_children";
        }
        this["domTable"] = table;
        this["domHead"] = head;
        this["domBody"] = body;
        this.ShowTable();
        this.domLimWindow.scrollTop = this.nScrollTop;
        this._SetColsWidth(this.domLimWindow.getBoundingClientRect().width);
        SetStretchEl();
    }
    SetColsWidth() {
        if (this.domLimWindow) {
            this._SetColsWidth(this.domLimWindow.getBoundingClientRect().width);
        }
    }
    fGetCont(oBranch) {
        if (!oBranch) {
            oBranch = this.root;
        }
        if (!oBranch.cont) {
            return [];
        }
        const ret = [];
        for (const it of oBranch.cont) {
            ret.push(it.fGetData());
        }
        return ret;
    }
    fFindBranchStr(sPath, t, oBranch) {
        let aPath;
        if (t) {
            aPath = SplitWithTrim(sPath, t);
        }
        else {
            return;
        }
        return this.fFindBranchArr(aPath, oBranch);
    }
    fFindBranchArr(aPath, oBr) {
        if (aPath.length === 0) {
            return this.root;
        }
        let oBranch = this.root;
        if (oBr) {
            oBranch = oBr;
        }
        if (aPath[0] == "") {
            aPath.splice(0, 1);
        }
        for (let i = 0; i < aPath.length; i++) {
            if (!oBranch.cont) {
                return;
            }
            let tmp = oBranch.cont.findIndex(it1 => it1.pathEl && it1.pathEl.toLowerCase() == aPath[i].toLowerCase());
            if (tmp < 0) {
                return;
            }
            if (i + 1 == aPath.length) {
                return oBranch.cont[tmp];
            }
            oBranch = oBranch.cont[tmp];
        }
    }
    fSetNewBranchData(oNewData, fDataProcessor, oBranch) {
        if (!oBranch.pParent)
            return;
        if (fDataProcessor) {
            oNewData = fDataProcessor(oBranch, oNewData);
        }
        else if (this.fDataProcessor) {
            oNewData = this.fDataProcessor(oBranch, oNewData);
        }
        SetSameObjFields(oNewData, oBranch.pParent.jsBody[oBranch.indJs]);
    }
    fIsNotEmpty() {
        return this.root.cont && this.root.cont.length > 0;
    }
    fClear(pParent) {
        if (pParent) {
            pParent.cont = [];
            pParent.jsBody = [];
        }
        else {
            this.root.cont = [];
            this.root.jsBody = [];
        }
    }
    ResetAllSelects() {
        this.fSelTabClean();
    }
    fGetBrLen(oBranch) {
        if (!oBranch) {
            oBranch = this.root;
        }
        return oBranch.jsBody.length;
    }
    ShowTableAfterScroll() {
        const td = GetCurrTime();
        if (Math.abs(td - scrollCnt) < 10) {
            return;
        }
        scrollCnt = td;
        if (scrollCnt === null && Math.abs(this.nScrollTop - this.domLimWindow.scrollTop) < this.nRowHeight)
            return;
        DeleteDropMenuDuringScroll();
        this.nScrollTop = this.domLimWindow.scrollTop;
        this.ShowTableAfterResize();
    }
    ShowTableAfterResize() {
        this.nLines = Math.floor(this.domLimWindow.clientHeight / this.nRowHeight);
        let firstRow = Math.floor(this.domLimWindow.scrollTop / this.nRowHeight);
        let lastRow = this.nLines + firstRow;
        if ((this.nLastShowRow - lastRow) < MIN_ROW_FOR_RECREATE || (firstRow - this.nFirstShowRow) < MIN_ROW_FOR_RECREATE) {
            this.nLastShowRow = (lastRow + ADD_ROWS_ABOVE_AND_BELOW < this.aDeploedTable.length) ? lastRow + ADD_ROWS_ABOVE_AND_BELOW : this.aDeploedTable.length - 1;
            this.nFirstShowRow = (firstRow - ADD_ROWS_ABOVE_AND_BELOW > 0) ? firstRow - ADD_ROWS_ABOVE_AND_BELOW : 0;
            this._CreateRows();
        }
    }
    SortFunc(sFieldName) {
        for (let i = 0; i < this.aHead.length; i++) {
            let cell = document.getElementById(this.unicId + this.aHead[i].field_name + "_head");
            if (cell) {
                if (this.aHead[i].field_name == sFieldName) {
                    cell.innerHTML = "<span class='dyn_tab_head_cell_inner'>" + GetLocaleText(this.aHead[i].col_name) + " " + ((this.nSortDirect > 0) ? "&#9650" : "&#9660;") + "</span>";
                }
                else {
                    cell.innerHTML = "<span class='dyn_tab_head_cell_inner'>" + GetLocaleText(this.aHead[i].col_name) + "</span>";
                }
            }
        }
        this.ShowTable();
    }
    ShowFirstSelectRow() {
        if (this._aSelectRow.length == 0) {
            return;
        }
        this._aSelectRow.sort(compareNum);
        this._CalcScroll({ start: this._aSelectRow[0], finish: this._aSelectRow[this._aSelectRow.length - 1], bStartPriority: true });
    }
    _CalcScroll(oRange) {
        const nRealLimWimHeight = this.domLimWindow.getBoundingClientRect().height - this.nHeadHeight;
        if (this.nRowHeight <= 1) {
            this._CreateRows();
            return;
        }
        const nLines = Math.floor(nRealLimWimHeight / this.nRowHeight) - 2;
        if (this.aDeploedTable.length <= nLines ||
            ((oRange.start === undefined || oRange.start < 0) && (oRange.finish === undefined || oRange.finish < 0))) {
            this._CreateRows();
            return;
        }
        if (oRange.start === undefined) {
            oRange.start = -1;
        }
        if (oRange.finish === undefined) {
            oRange.finish = -1;
        }
        const firstRow = Math.floor((this.domLimWindow.scrollTop + this.nHeadHeight) / this.nRowHeight);
        const lastRow = firstRow + nLines;
        this.nScrollTop = this.domLimWindow.scrollTop;
        if (oRange.start >= 0 && oRange.finish >= 0) {
            if (oRange.start > oRange.finish) {
                oRange = { "start": oRange.finish, "finish": oRange.start, "bStartPriority": oRange.bStartPriority };
            }
            if (oRange.start >= firstRow && oRange.finish <= lastRow) {
                this._CreateRows();
                return;
            }
            if ((oRange.finish - oRange.start) <= nLines) {
                if (oRange.start < firstRow) {
                    oRange.bStartPriority = true;
                }
                else {
                    oRange.bStartPriority = false;
                }
            }
            if (oRange.bStartPriority) {
                oRange.finish = -1;
            }
            else {
                oRange.start = -1;
            }
        }
        if (this.aDeploedTable.length <= nLines + DBL_ADD_ROWS) {
            this._CreateRows();
            if (oRange.start >= 0) {
                this.nScrollTop += (oRange.start - firstRow) * this.nRowHeight;
            }
            else if (oRange.finish >= 0) {
                this.nScrollTop += (oRange.finish - lastRow) * this.nRowHeight;
            }
            this.domLimWindow.scrollTop = this.nScrollTop;
            return;
        }
        if (oRange.start >= 0) {
            let nNewFirstRow = (oRange.start - ADD_ROWS_ABOVE_AND_BELOW - 1 > 0) ? oRange.start - ADD_ROWS_ABOVE_AND_BELOW - 1 : 0;
            if (nNewFirstRow + nLines + DBL_ADD_ROWS <= this.aDeploedTable.length) {
                this.nLastShowRow = nLines + DBL_ADD_ROWS;
            }
            else {
                this.nLastShowRow = this.aDeploedTable.length - 1;
                nNewFirstRow = this.nLastShowRow - (nLines + DBL_ADD_ROWS);
            }
            this.nFirstShowRow = nNewFirstRow;
            this.nScrollTop += (oRange.start - firstRow - 1) * this.nRowHeight;
        }
        else if (oRange.finish >= 0) {
            let nNewLastRow = (oRange.finish + ADD_ROWS_ABOVE_AND_BELOW < this.aDeploedTable.length) ? oRange.finish + ADD_ROWS_ABOVE_AND_BELOW : this.aDeploedTable.length - 1;
            if (nNewLastRow - (nLines + DBL_ADD_ROWS) >= 0) {
                this.nFirstShowRow = nNewLastRow - (nLines + DBL_ADD_ROWS);
            }
            else {
                this.nFirstShowRow = 0;
                nNewLastRow = this.nFirstShowRow + (nLines + DBL_ADD_ROWS);
            }
            this.nLastShowRow = nNewLastRow;
            this.nScrollTop += (oRange.finish - lastRow) * this.nRowHeight;
        }
        else {
            this._CreateRows();
            return;
        }
        this._CreateRows();
        this.domLimWindow.scrollTop = this.nScrollTop;
    }
    ShowRows(oRange) {
        if (oRange) {
            this._CalcScroll(oRange);
        }
        else {
            this._CreateRows();
        }
    }
    ShowTable(oRange) {
        this.aDeploedTable.splice(0);
        this._aSelectRow.splice(0);
        this._DeployTable(0);
        if (this.aDeploedTable.length <= this.nLines) {
            this.nFirstShowRow = 0;
            this.nLastShowRow = this.aDeploedTable.length - 1;
        }
        else if (this.nFirstShowRow > this.aDeploedTable.length - 1) {
            this.nLastShowRow = this.aDeploedTable.length - 1;
            this.nFirstShowRow = (this.nLastShowRow - this.nLines - DBL_ADD_ROWS >= 0) ? this.nLastShowRow - this.nLines - DBL_ADD_ROWS : 0;
        }
        else if (this.nLines > 0) {
            this.nLastShowRow = this.nFirstShowRow + this.nLines + DBL_ADD_ROWS;
        }
        if (this.nRowHeight > 0) {
            this.domContainer.style.minHeight = ((this.aDeploedTable.length + 2) * this.nRowHeight) + "px";
        }
        this.ShowRows(oRange);
        DrawDrag();
    }
    SetRowAsSelect() {
        for (let item of this.domBody.children) {
            if (this._aSelectRow.includes(item.selfNumber)) {
                item.classList.add("sel_row");
            }
            else {
                item.classList.remove("sel_row");
            }
        }
    }
    _OpenFolder(oNode) {
        oNode.folder = 1;
    }
    _CloseFolder(oNode) {
        oNode.folder = 0;
        oNode.fCurtail();
        this.ShowTable();
    }
    AddDinTableRow() {
        let nInd = this.aDeploedTable.length - 1;
        if (nInd < 0 || IsObjNotEmpty(this.aDeploedTable[nInd]._branch_.fGetData())) {
            this.root.jsBody.push({});
            if (!this.root.cont)
                this.root.cont = [];
            this.root.cont.push(new TBrControl(this.root.jsBody.length - 1, this.root));
            nInd++;
            this.ShowTable({ finish: nInd });
        }
        if (this.fOnChange) {
            this.fOnChange();
        }
        if (this.bEditable && this.aDeploedTable[nInd] && this.aDeploedTable[nInd]._row_.firstChild) {
            this.aDeploedTable[nInd]._row_.firstChild.dispatchEvent(new Event('dblclick'));
        }
    }
    DeleteSelectRows() {
        if (this._aSelectRow.length == 0)
            return;
        this._aSelectRow.sort(compareNum);
        for (let i = this._aSelectRow.length - 1; i >= 0; i--) {
            this.aDeploedTable[this._aSelectRow[i]]._branch_.fDeleteSelf();
        }
        this.fSelTabClean();
        this.ShowTable();
        if (this.fOnChange) {
            this.fOnChange();
        }
    }
    fGetBranchByName(sName, sFieldName, branch) {
        if (!sName || !sFieldName) {
            return null;
        }
        let arr;
        let cont;
        if (branch && branch.cont) {
            arr = branch.jsBody;
            cont = branch.cont;
        }
        else {
            arr = this.root.jsBody;
            cont = this.root.cont;
        }
        const i = arr.findIndex(item => item[sFieldName] == sName);
        if (i >= 0) {
            const control = cont.find(it => it.indJs == i);
            if (!control)
                return null;
            return { "data": arr[i], "control": control };
        }
        return null;
    }
    fGetOpendFolders() {
        return this.root.fGetOpenFoldersTree();
    }
    AddDinTableRowsFromText(sText, pBranch) {
        const aLines = sText.split(/\r?\n/);
        if (aLines.length == 0) {
            return;
        }
        if (aLines[aLines.length - 1].trim() == "") {
            aLines.splice(-1);
        }
        if (aLines.length == 0) {
            return;
        }
        let aRows = [];
        for (let i = 0; i < aLines.length; i++) {
            let aCells = aLines[i].split("\t");
            let oRow = {};
            for (let j = 0; j < aCells.length && j < this.aHead.length; j++) {
                oRow[this.aHead[j].field_name] = aCells[j];
            }
            aRows.push(oRow);
        }
        if (!pBranch) {
            pBranch = this.root;
        }
        if (this._aSelectRow.length > 0 && pBranch.cont) {
            const nSel = this._aSelectRow[0], nStart = pBranch.cont[0].dep_ind, nFinish = pBranch.cont[pBranch.cont.length - 1].dep_ind;
            if (nSel >= nStart && nSel <= nFinish) {
                pBranch.fAddDataArr(aRows, { nInsertAboveRow: nSel - nStart });
            }
            else {
                pBranch.fAddDataArr(aRows);
            }
        }
        else {
            const nLastRow = this.aDeploedTable[this.aDeploedTable.length - 1]._branch_;
            if (!IsObjNotEmpty(nLastRow.fGetData())) {
                nLastRow.fDeleteSelf();
            }
            pBranch.fAddDataArr(aRows);
        }
        this.ShowTable();
        if (this.fOnChange) {
            this.fOnChange();
        }
    }
    MarkTabRow(sFieldName, sMarkName, oBranch, bNotDrillDown, bCaseSens) {
        if (!sMarkName)
            return null;
        let oLocalBranch;
        if (!oBranch) {
            oLocalBranch = this.root;
        }
        else if ("_branch_" in oBranch) {
            oLocalBranch = oBranch._branch_;
        }
        else {
            oLocalBranch = oBranch;
        }
        if (!oLocalBranch.cont || !oLocalBranch.cont.length)
            return null;
        let oMarkBranch = oLocalBranch.fFindEl(sMarkName, sFieldName, bNotDrillDown ? "none" : "down", bCaseSens);
        if (oMarkBranch) {
            oMarkBranch.fMarkAndShow(this);
            TableRowClick(this, oMarkBranch);
        }
        return oMarkBranch;
    }
}
let scrollCnt;
let resizeCnt = 0;
function CreateTable(oDTP) {
    if (!oDTP.domContainer && !oDTP.domLimWindow) {
        return null;
    }
    if (!oDTP.root.cont) {
        oDTP.root.cont = [];
    }
    if (oDTP.aHead.length == 0) {
        if (IsObject(oDTP.root.jsBody[0])) {
            for (let key in oDTP.root.jsBody[0]) {
                if (_IsValidFildName(oDTP.root.jsBody[0][key])) {
                    oDTP.aHead.push({ "field_name": key, "col_name": key });
                }
            }
        }
        else {
            oDTP.bWithoutHead = true;
            oDTP.aHead.push({ "field_name": "-", "col_name": "-" });
            oDTP.bNotObjRows = true;
        }
    }
    if (oDTP.fDblclick) {
        oDTP.bEditable = false;
    }
    oDTP.CreateDomElements();
    return oDTP;
}
const oEmptyBranch = new TBrControl(-1);
TDynamicTableProperties.prototype.SortBranch = function (brCont, sFieldName) {
    if (!sFieldName) {
        sFieldName = this.sSortCol;
    }
    if (sFieldName == "")
        return;
    let nDirect = this.nSortDirect;
    brCont.sort(function (a, b) {
        if (("cont" in a) && !("cont" in b))
            return -nDirect;
        if (("cont" in b) && !("cont" in a))
            return nDirect;
        const cA = a.fGetData()[sFieldName];
        const cB = b.fGetData()[sFieldName];
        const bA_undef = (cA === undefined);
        const bB_undef = (cB === undefined);
        if (bB_undef && !bA_undef)
            return -nDirect;
        if (bA_undef && !bB_undef)
            return nDirect;
        if (bA_undef && bB_undef)
            return 0;
        const bA_IsNumber = (typeof cA) === "number";
        const bB_IsNumber = (typeof cB) === "number";
        if (bA_IsNumber && bB_IsNumber)
            return (cA - cB) * nDirect;
        if (bA_IsNumber && !bB_IsNumber)
            return -nDirect;
        if (!bA_IsNumber && bB_IsNumber)
            return nDirect;
        return CompareTextWithNumbers(cA, cB, nDirect);
    });
};
TDynamicTableProperties.prototype.SetRowsAsSelect = function (aRows, bResetOldSelects = false) {
    if (aRows.length <= 0)
        return;
    if (bResetOldSelects) {
        this.fSelTabClean();
    }
    for (const it of aRows) {
        this.fSelTabPush(it);
    }
    this._aSelectRow.sort(compareNum);
    this.ShowFirstSelectRow();
};
TDynamicTableProperties.prototype.TableMoveSelRow = function (eDirect) {
    if (this._aSelectRow.length != 1) {
        return;
    }
    if (eDirect == "ArrowUp") {
        if (this._aSelectRow[0] > 0) {
            this.fSelTabReplace(this._aSelectRow[0] - 1, 0);
        }
    }
    else {
        if ((this._aSelectRow[0] + 1) < this.aDeploedTable.length) {
            this.fSelTabReplace(this._aSelectRow[0] + 1, 0);
        }
    }
    this.ShowRows();
    TableRowClick(this, this.aDeploedTable[this._aSelectRow[0]]._branch_);
    const domSelRow = this.fGetSelRow(0)._row_;
    if (domSelRow) {
        const oRowRect = domSelRow.getBoundingClientRect();
        if (oRowRect.top < 1 && oRowRect.bottom < 1) {
            this.ShowFirstSelectRow();
        }
        else if (eDirect == "ArrowUp") {
            let nRowTop = oRowRect.top;
            let nLimWinTop = this.domLimWindow.getBoundingClientRect().top;
            if (this.domHead) {
                nLimWinTop += this.domHead.getBoundingClientRect().height;
            }
            if (nLimWinTop > nRowTop) {
                this.nScrollTop -= (nLimWinTop - nRowTop);
                this.domLimWindow.scrollTop = this.nScrollTop;
            }
        }
        else {
            let nRowBottom = oRowRect.bottom;
            let nLimWinBottom = this.domLimWindow.getBoundingClientRect().top + this.domLimWindow.clientHeight;
            if (nRowBottom > nLimWinBottom) {
                this.nScrollTop += (nRowBottom - nLimWinBottom);
                this.domLimWindow.scrollTop = this.nScrollTop;
            }
        }
    }
    else {
        this.ShowTableAfterResize();
    }
};
function _IsValidFildName(fildName) {
    return (typeof fildName === 'string' && fildName.slice(0, 1) != "__");
}
function _IsCellNotEmpty(xCellInner) {
    let sType = typeof xCellInner;
    return (sType === 'string' && xCellInner != "" && xCellInner != "undefined") ||
        sType === 'number' || sType === 'boolean' || sType === 'bigint' || sType === 'symbol';
}
function ExternCopyAll(id, sMenuId) {
    if (sMenuId) {
        id += "_" + sMenuId;
    }
    bStopDeselect = true;
    let table = document.getElementById(id);
    if (!table || !table.pTable || !table.pTable.root.cont)
        return;
    let sClipBoard;
    if (table.pTable.fGetSelTabLen() > 0) {
        sClipBoard = table.pTable.root.fGetDataAsStr(table.pTable.aHead, table.pTable);
    }
    else {
        sClipBoard = table.pTable.root.fGetDataAsStr(table.pTable.aHead);
    }
    if (!sClipBoard) {
        HtmlMsgbox('Nothing was copied', 'Warning!', { bNoCurrJobName: true });
    }
    navigator.clipboard.writeText(sClipBoard)
        .then(() => { }).catch(err => {
        alert('Something went wrong: ' + err);
    });
}
function ExternPaste(id, sMenuId) {
    if (sMenuId) {
        id += "_" + sMenuId;
    }
    bStopDeselect = true;
    let table = document.getElementById(id);
    if (!table || !table.pTable || table.pTable.bIsTree)
        return;
    navigator.clipboard.readText()
        .then(text => {
        table.pTable.AddDinTableRowsFromText(text);
    })
        .catch(err => {
        alert('Something went wrong: ' + err);
    });
}
function ExternDelDinTableRow(id, sMenuId) {
    if (sMenuId) {
        id += "_" + sMenuId;
    }
    bStopDeselect = true;
    let table = document.getElementById(id);
    if (!table || !table.pTable) {
        return;
    }
    table.pTable.DeleteSelectRows();
}
function ExternAddDinTableRow(id, sMenuId) {
    if (sMenuId) {
        id += "_" + sMenuId;
    }
    bStopDeselect = true;
    let table = document.getElementById(id);
    if (!table || !table.pTable)
        return;
    table.pTable.AddDinTableRow();
}
function DeleteSpaceFromTable(brCont) {
    if (IsObject(brCont[0])) {
        for (let i = brCont.length - 1; i >= 0; i--) {
            let bIsEmpty = true;
            for (let key in brCont[i]) {
                if (key != "__cont__" && _IsValidFildName(key) && _IsCellNotEmpty(brCont[i][key])) {
                    bIsEmpty = false;
                    break;
                }
            }
            if (bIsEmpty) {
                brCont.splice(i, 1);
            }
        }
    }
    else {
        for (let i = brCont.length - 1; i >= 0; i--) {
            if (!_IsCellNotEmpty(brCont[i])) {
                brCont.splice(i, 1);
            }
        }
    }
}
function TableAlign(arr, d, x, minLen) {
    if (arr.length < 2)
        return;
    let longest = 0, subLongest = 1;
    for (let i = 1; i < arr.length; i++) {
        if (arr[i] >= arr[longest]) {
            subLongest = longest;
            longest = i;
        }
    }
    if (arr[longest] <= minLen)
        return;
    if (longest == 0 && arr.length > 2) {
        for (let i = 2; i < arr.length; i++) {
            if (arr[i] > arr[subLongest]) {
                subLongest = i;
            }
        }
    }
    let d2 = arr[longest] - arr[subLongest];
    if (d2 >= d) {
        arr[longest] -= d;
        return;
    }
    arr[longest] -= d2;
    d -= d2;
    if (d <= x) {
        arr[subLongest] -= d;
        return;
    }
    arr[subLongest] -= x;
    d -= x;
    TableAlign(arr, d, x, minLen);
}
function AbortWait(sTableId, nRowNum) {
    const domTable = document.getElementById(sTableId);
    if (domTable && domTable.pTable) {
        const oBr = domTable.pTable.aDeploedTable[nRowNum - 1]._branch_;
        if (oBr.fWaitingExit) {
            oBr.fWaitingExit();
        }
    }
}
function TableRowClick(table, branch, bMouseClick) {
    DeleteAllDropMenu();
    if (branch && branch["fRowClick"]) {
        branch.fRowClick(branch, bMouseClick);
    }
    else if (table && table["fRowClick"]) {
        table.fRowClick(branch, bMouseClick);
    }
}
function TableOpenFolder(table, branch) {
    if (branch && branch["fOpenFolder"]) {
        branch.fOpenFolder(branch, table);
    }
    else if (table["fOpenFolder"]) {
        table.fOpenFolder(branch, table);
    }
}
function TableSelRoweNum(xAddArgs) {
    if (!xAddArgs || !xAddArgs.DTP)
        return -1;
    return xAddArgs.DTP.fGetSelTabLen();
}
