/*
 * SDK Pullenti Lingvo, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software.
 * This class is generated using the converter Unisharping (www.unisharping.ru) from Pullenti C#.NET project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Utils = require("./../../../unisharp/Utils");
const RefOutArgWrapper = require("./../../../unisharp/RefOutArgWrapper");

const ReferentToken = require("./../../ReferentToken");
const TextToken = require("./../../TextToken");
const NumberSpellingType = require("./../../NumberSpellingType");
const NumberToken = require("./../../NumberToken");
const MiscHelper = require("./../../core/MiscHelper");
const InstrToken1StdTitleType = require("./InstrToken1StdTitleType");
const NumberTypes = require("./NumberTypes");
const NumberHelper = require("./../../core/NumberHelper");
const InstrumentKind = require("./../InstrumentKind");
const InstrToken1Types = require("./InstrToken1Types");
const PartToken = require("./../../decree/internal/PartToken");
const InstrToken1 = require("./InstrToken1");

// Поддержка анализа нумерации
class NumberingHelper {
    
    static calcDelta(prev, next, canSubNumbers) {
        let n1 = prev.lastNumber;
        let n2 = next.lastNumber;
        if (next.lastMinNumber > 0) 
            n2 = next.lastMinNumber;
        if (prev.numbers.length === next.numbers.length) {
            if (prev.typContainerRank > 0 && prev.typContainerRank === next.typContainerRank) {
            }
            else if (prev.numTyp === next.numTyp) {
            }
            else 
                return 0;
            if (prev.numbers.length > 1) {
                for (let i = 0; i < (prev.numbers.length - 1); i++) {
                    if (prev.numbers[i] !== next.numbers[i]) 
                        return 0;
                }
            }
            if (n1 >= n2) 
                return 0;
            return n2 - n1;
        }
        if (!canSubNumbers) 
            return 0;
        if ((prev.numbers.length + 1) === next.numbers.length && next.numbers.length > 0) {
            if (prev.typContainerRank > 0 && prev.typContainerRank === next.typContainerRank) {
            }
            else if (prev.numTyp === NumberTypes.DIGIT && next.numTyp === NumberTypes.TWODIGITS) {
            }
            else if (prev.numTyp === NumberTypes.TWODIGITS && next.numTyp === NumberTypes.THREEDIGITS) {
            }
            else if (prev.numTyp === NumberTypes.THREEDIGITS && next.numTyp === NumberTypes.FOURDIGITS) {
            }
            else if (prev.numTyp === NumberTypes.LETTER && next.numTyp === NumberTypes.TWODIGITS && Utils.isLetter(next.numbers[0][0])) {
            }
            else if (prev.numTyp === NumberTypes.ROMAN && next.numTyp === NumberTypes.ROMAN) {
            }
            else 
                return 0;
            for (let i = 0; i < prev.numbers.length; i++) {
                if (prev.numbers[i] !== next.numbers[i]) 
                    return 0;
            }
            return n2;
        }
        if ((prev.numbers.length - 1) === next.numbers.length && prev.numbers.length > 1) {
            if (prev.typContainerRank > 0 && prev.typContainerRank === next.typContainerRank) {
            }
            else if (prev.numTyp === NumberTypes.TWODIGITS) {
                if (next.numTyp === NumberTypes.DIGIT) {
                }
                else if (next.numTyp === NumberTypes.LETTER && Utils.isLetter(prev.numbers[0][0])) {
                }
            }
            else if (prev.numTyp === NumberTypes.THREEDIGITS && next.numTyp === NumberTypes.TWODIGITS) {
            }
            else if (prev.numTyp === NumberTypes.FOURDIGITS && next.numTyp === NumberTypes.THREEDIGITS) {
            }
            else if (prev.numTyp === NumberTypes.ROMAN && next.numTyp === NumberTypes.ROMAN) {
            }
            else 
                return 0;
            for (let i = 0; i < (prev.numbers.length - 2); i++) {
                if (prev.numbers[i] !== next.numbers[i]) 
                    return 0;
            }
            let wrapn12247 = new RefOutArgWrapper();
            let inoutres2248 = Utils.tryParseInt(prev.numbers[prev.numbers.length - 2], wrapn12247);
            n1 = wrapn12247.value;
            if (!inoutres2248) {
                if (prev.numbers.length === 2) 
                    n1 = prev.firstNumber;
                else 
                    return 0;
            }
            if ((n1 + 1) !== n2) 
                return 0;
            return n2 - n1;
        }
        if ((prev.numbers.length - 2) === next.numbers.length && prev.numbers.length > 2) {
            if (prev.typContainerRank > 0 && prev.typContainerRank === next.typContainerRank) {
            }
            else if (prev.numTyp === NumberTypes.THREEDIGITS && next.numTyp === NumberTypes.DIGIT) {
            }
            else if (prev.numTyp === NumberTypes.FOURDIGITS && next.numTyp === NumberTypes.TWODIGITS) {
            }
            else 
                return 0;
            for (let i = 0; i < (prev.numbers.length - 3); i++) {
                if (prev.numbers[i] !== next.numbers[i]) 
                    return 0;
            }
            let wrapn12249 = new RefOutArgWrapper();
            let inoutres2250 = Utils.tryParseInt(prev.numbers[prev.numbers.length - 3], wrapn12249);
            n1 = wrapn12249.value;
            if (!inoutres2250) 
                return 0;
            if ((n1 + 1) !== n2) 
                return 0;
            return n2 - n1;
        }
        if ((prev.numbers.length - 3) === next.numbers.length && prev.numbers.length > 3) {
            if (prev.typContainerRank > 0 && prev.typContainerRank === next.typContainerRank) {
            }
            else if (prev.numTyp === NumberTypes.FOURDIGITS && next.numTyp === NumberTypes.DIGIT) {
            }
            else 
                return 0;
            for (let i = 0; i < (prev.numbers.length - 4); i++) {
                if (prev.numbers[i] !== next.numbers[i]) 
                    return 0;
            }
            let wrapn12251 = new RefOutArgWrapper();
            let inoutres2252 = Utils.tryParseInt(prev.numbers[prev.numbers.length - 4], wrapn12251);
            n1 = wrapn12251.value;
            if (!inoutres2252) 
                return 0;
            if ((n1 + 1) !== n2) 
                return 0;
            return n2 - n1;
        }
        return 0;
    }
    
    static extractMainSequence(lines, checkSpecTexts, canSubNumbers) {
        let res = null;
        let manySpecCharLines = 0;
        let noticeRegime = false;
        for (let i = 0; i < lines.length; i++) {
            let li = lines[i];
            if (li.allUpper && li.titleTyp !== InstrToken1StdTitleType.UNDEFINED) {
                if (res !== null && res.length > 0 && res[res.length - 1].tag === null) 
                    res[res.length - 1].tag = li;
            }
            if (li.numbers.length === 0) 
                continue;
            if (li.numTyp === NumberTypes.ROMAN) {
            }
            if (li.lastNumber === 901) {
            }
            if (noticeRegime) {
                if (li.typ !== InstrToken1Types.NOTICE) 
                    continue;
            }
            else {
                if (li.numTyp === NumberTypes.LETTER) {
                }
                if (li.typ !== InstrToken1Types.LINE) {
                    if (i === 0 && li.typ === InstrToken1Types.NOTICE) 
                        noticeRegime = true;
                    else 
                        continue;
                }
            }
            if (res === null) {
                res = new Array();
                if (li.numbers.length === 1 && li.numbers[0] === "1" && li.numTyp === NumberTypes.DIGIT) {
                    if ((((i + 1) < lines.length) && lines[i + 1].numbers.length === 1 && lines[i + 1].numbers[0] === "1") && lines[i + 1].numTyp === NumberTypes.DIGIT) {
                        for (let ii = i + 2; ii < lines.length; ii++) {
                            if (lines[ii].numTyp === NumberTypes.ROMAN && lines[ii].numbers.length > 0) {
                                if (lines[ii].numbers[0] === "2") 
                                    li.numTyp = NumberTypes.ROMAN;
                                break;
                            }
                        }
                    }
                }
            }
            else {
                if (res[0].numSuffix !== null) {
                    if (li.numSuffix !== null && li.numSuffix !== res[0].numSuffix) 
                        continue;
                }
                if (res[0].numTyp === NumberTypes.ROMAN) 
                    canSubNumbers = true;
                if (res[0].numbers.length !== li.numbers.length) {
                    if (li.beginToken.previous !== null && li.beginToken.previous.isChar(':')) 
                        continue;
                    if (res[0].numSuffix === null || NumberingHelper.calcDelta(res[res.length - 1], li, true) !== 1) 
                        continue;
                    if (!canSubNumbers) {
                        if (((i + 1) < lines.length) && NumberingHelper.calcDelta(res[res.length - 1], lines[i + 1], false) === 1 && NumberingHelper.calcDelta(li, lines[i + 1], true) === 1) {
                        }
                        else 
                            continue;
                    }
                }
                else {
                    if (res[0].numTyp === NumberTypes.ROMAN && li.numTyp !== NumberTypes.ROMAN) 
                        continue;
                    if (res[0].numTyp !== NumberTypes.ROMAN && li.numTyp === NumberTypes.ROMAN) {
                        if (li.numbers.length === 1 && li.numbers[0] === "1" && res.length === 1) {
                            res.splice(0, res.length);
                            res.push(li);
                            continue;
                        }
                        continue;
                    }
                    if (res[0].numTyp !== NumberTypes.LETTER && li.numTyp === NumberTypes.LETTER) 
                        continue;
                }
            }
            res.push(li);
            if (li.hasManySpecChars) 
                manySpecCharLines++;
        }
        if (res === null) 
            return null;
        if (checkSpecTexts) {
            if (manySpecCharLines > (Utils.intDiv(res.length, 2))) 
                return null;
        }
        for (let i = 0; i < (res.length - 1); i++) {
            if (NumberingHelper.calcDelta(res[i], res[i + 1], false) === 2) {
                let ii0 = lines.indexOf(res[i]);
                let ii1 = lines.indexOf(res[i + 1], ii0);
                for (let j = ii0 + 1; j < ii1; j++) {
                    if (lines[j].numbers.length > 0) {
                        if (NumberingHelper.calcDelta(res[i], lines[j], true) === 1 && NumberingHelper.calcDelta(lines[j], res[i + 1], true) === 1) {
                            res.splice(i + 1, 0, lines[j]);
                            break;
                        }
                    }
                }
            }
        }
        let ch = true;
        while (ch) {
            ch = false;
            for (let i = 1; i < res.length; i++) {
                let d = NumberingHelper.calcDelta(res[i - 1], res[i], false);
                if (res[i - 1].numSuffix === res[i].numSuffix) {
                    if (d === 1) 
                        continue;
                    if (((d > 1 && (d < 20))) || ((d === 0 && res[i - 1].numTyp === res[i].numTyp && res[i - 1].numbers.length === res[i].numbers.length))) {
                        if (NumberingHelper.calcDelta(res[i], res[i - 1], false) > 0) {
                            if (res[i - 1].tag !== null && i > 2) {
                                res.splice(i, res.length - i);
                                ch = true;
                                i--;
                                continue;
                            }
                        }
                        if ((i + 1) < res.length) {
                            let dd = NumberingHelper.calcDelta(res[i], res[i + 1], false);
                            if (dd === 1) {
                                if (res[i].lastNumber === 1 && res[i].numbers.length === res[i - 1].numbers.length) {
                                }
                                else 
                                    continue;
                            }
                            else {
                                dd = NumberingHelper.calcDelta(res[i - 1], res[i + 1], false);
                                if (dd === 1) {
                                    res.splice(i, 1);
                                    i--;
                                    ch = true;
                                    continue;
                                }
                            }
                        }
                        else if (d > 3) {
                            res.splice(i, 1);
                            i--;
                            ch = true;
                            continue;
                        }
                        else 
                            continue;
                    }
                }
                let j = 0;
                for (j = i + 1; j < res.length; j++) {
                    let dd = NumberingHelper.calcDelta(res[j - 1], res[j], false);
                    if (dd !== 1 && dd !== 2) 
                        break;
                    if (res[j - 1].numSuffix !== res[j].numSuffix) 
                        break;
                }
                if ((d === 0 && NumberingHelper.calcDelta(res[i - 1], res[i], true) === 1 && res[i - 1].numSuffix !== null) && res[i].numSuffix === res[i - 1].numSuffix) 
                    d = 1;
                if (d !== 1 && j > (i + 1)) {
                    if (i === 1 && j > 3) 
                        res.splice(0, 1);
                    else 
                        res.splice(i, j - i);
                    i--;
                    ch = true;
                    continue;
                }
                if (d === 1) {
                    if ((i + 1) >= res.length) 
                        continue;
                    let dd = NumberingHelper.calcDelta(res[i], res[i + 1], false);
                    if (dd === 1 && res[i - 1].numSuffix === res[i + 1].numSuffix) {
                        if (res[i].numSuffix !== res[i - 1].numSuffix) {
                            res[i].numSuffix = res[i - 1].numSuffix;
                            res[i].isNumDoubt = false;
                            ch = true;
                        }
                        continue;
                    }
                }
                if ((i + 1) < res.length) {
                    let dd = NumberingHelper.calcDelta(res[i - 1], res[i + 1], false);
                    if (dd === 1 && res[i - 1].numSuffix === res[i + 1].numSuffix) {
                        if (d === 1 && NumberingHelper.calcDelta(res[i], res[i + 1], true) === 1) {
                        }
                        else {
                            res.splice(i, 1);
                            ch = true;
                            continue;
                        }
                    }
                }
                else if (d === 0 || d > 10 || res[i - 1].numSuffix !== res[i].numSuffix) {
                    res.splice(i, 1);
                    ch = true;
                    continue;
                }
            }
        }
        let hasSuf = 0;
        for (const r of res) {
            if ((r.numSuffix !== null || r.typContainerRank > 0 || r.numbers.length > 1) || r.allUpper || r.numTyp === NumberTypes.ROMAN) 
                hasSuf++;
        }
        if (hasSuf === 0) {
            if (res.length < 5) 
                return null;
        }
        if (res.length >= 2) {
            let i0 = 0;
            for (; i0 < lines.length; i0++) {
                if (lines[i0].typ !== InstrToken1Types.COMMENT && lines[i0].typ !== InstrToken1Types.EDITIONS) 
                    break;
            }
            if (res[0] !== lines[i0]) {
                let tot = res[0].beginToken.beginChar - lines[i0].beginToken.beginChar;
                tot += (lines[lines.length - 1].endToken.endChar - res[res.length - 1].endToken.endChar);
                let blk = res[res.length - 1].endToken.endChar - res[0].beginToken.beginChar;
                let i = lines.indexOf(res[res.length - 1]);
                if (i > 0) {
                    let lines1 = Array.from(lines);
                    lines1.splice(0, i + 1);
                    let res1 = NumberingHelper.extractMainSequence(lines1, checkSpecTexts, canSubNumbers);
                    if (res1 !== null && res1.length > 2) 
                        blk += (res1[res1.length - 1].endChar - res1[0].beginChar);
                }
                if ((blk * 3) < tot) {
                    if ((blk * 5) < tot) 
                        return null;
                    for (const r of res) {
                        if (!r.allUpper && !r.hasChanges) 
                            return null;
                    }
                }
            }
            if (res[0].lastNumber === 1 && res[0].numbers.length === 1) {
                let res0 = new Array();
                res0.push(res[0]);
                let i = 0;
                for (i = 1; i < res.length; i++) {
                    let j = 0;
                    for (j = i + 1; j < res.length; j++) {
                        if (res[j].lastNumber === 1 && res[j].numbers.length === 1) 
                            break;
                    }
                    if ((j - i) < 3) 
                        break;
                    j--;
                    let jj = 0;
                    let errs = 0;
                    for (jj = i + 1; jj < j; jj++) {
                        let d = NumberingHelper.calcDelta(res[jj - 1], res[jj], false);
                        if (d === 1) {
                        }
                        else if (d > 1 && (d < 3)) 
                            errs++;
                        else 
                            break;
                    }
                    if ((jj < j) || errs > 1) 
                        break;
                    if (j < (res.length - 1)) {
                        if (NumberingHelper.calcDelta(res0[res0.length - 1], res[j], false) !== 1) 
                            break;
                        res0.push(res[j]);
                    }
                    i = j;
                }
                if (i >= res.length && res0.length > 1) 
                    return res0;
            }
            if (res.length > 1000) 
                return null;
            return res;
        }
        if (res.length === 1 && lines[0] === res[0]) {
            if (hasSuf > 0) 
                return res;
            if (lines.length > 1 && lines[1].numbers.length === (lines[0].numbers.length + 1)) {
                for (let i = 0; i < lines[0].numbers.length; i++) {
                    if (lines[1].numbers[i] !== lines[0].numbers[i]) 
                        return null;
                }
                return res;
            }
        }
        return null;
    }
    
    static createNumber(owner, itok) {
        const FragToken = require("./FragToken");
        if ((itok.numBeginToken === null || itok.numEndToken === null || itok.numbers === null) || itok.numbers.length === 0) 
            return;
        let num = FragToken._new2253(itok.numBeginToken, itok.numEndToken, InstrumentKind.NUMBER, true, itok);
        owner.children.push(num);
        owner.number = itok.firstNumber;
        if (itok.numbers.length > 1) {
            owner.subNumber = PartToken.getNumber(itok.numbers[1]);
            if (itok.numbers.length > 2) {
                owner.subNumber2 = PartToken.getNumber(itok.numbers[2]);
                if (itok.numbers.length > 3) 
                    owner.subNumber3 = PartToken.getNumber(itok.numbers[3]);
            }
        }
        owner.minNumber = itok.lastMinNumber;
        owner.itok = itok;
    }
    
    static parseNumber(t, res, prev) {
        NumberingHelper._parseNumber(t, res, prev);
        if ((res.numbers.length > 0 && res.numEndToken !== null && !res.isNewlineAfter) && res.numEndToken.next !== null && res.numEndToken.next.isHiphen) {
            let res1 = new InstrToken1(res.numEndToken.next.next, res.numEndToken.next.next);
            NumberingHelper._parseNumber(res1.beginToken, res1, res);
            if (res1.numbers.length === res.numbers.length) {
                let i = 0;
                for (i = 0; i < (res.numbers.length - 1); i++) {
                    if (res.numbers[i] !== res1.numbers[i]) 
                        break;
                }
                if (i >= (res.numbers.length - 1) && (res.lastNumber < res1.lastNumber) && res1.numEndToken !== null) {
                    res.minNumber = res.numbers[res.numbers.length - 1];
                    res.numbers[res.numbers.length - 1] = res1.numbers[res.numbers.length - 1];
                    res.numSuffix = res1.numSuffix;
                    res.endToken = (res.numEndToken = res1.numEndToken);
                }
            }
        }
        if (res.numbers.length > 0 && res.numEndToken !== null && res.typ === InstrToken1Types.LINE) {
            let tt = res.numEndToken;
            let ok = true;
            if (tt.next !== null && tt.next.isHiphen) 
                ok = false;
            else if (!tt.isWhitespaceAfter) {
                if (tt.next !== null && ((tt.next.chars.isCapitalUpper || tt.next.chars.isAllUpper || (tt.next instanceof ReferentToken)))) {
                }
                else 
                    ok = false;
            }
            if (!ok) {
                res.numbers.splice(0, res.numbers.length);
                res.numEndToken = (res.numBeginToken = null);
            }
        }
        if ((res.numbers.length === 0 && res.typ === InstrToken1Types.LINE && res.beginToken.isChar('<')) && res.beginToken.next !== null) {
            let tt = res.beginToken.next;
            if (tt instanceof NumberToken) {
                NumberingHelper._parseNumber(tt, res, prev);
                if (res.numEndToken.next !== null && res.numEndToken.next.isChar('>')) {
                    res.typ = InstrToken1Types.FOOTNOTE;
                    res.numBeginToken = res.beginToken;
                    res.endToken = (res.numEndToken = res.numEndToken.next);
                }
            }
            else if (tt.isChar('*')) {
                let num = 1;
                for (let tt2 = tt; tt2 !== null; tt2 = tt2.next,num++) {
                    if (tt2.isChar('*')) {
                        if (tt2.next !== null && tt2.next.isChar('>')) {
                            res.typ = InstrToken1Types.FOOTNOTE;
                            res.numbers.push(num.toString());
                            res.numBeginToken = tt.previous;
                            res.numEndToken = tt2.next;
                            res.endToken = tt2.next;
                        }
                    }
                    else 
                        break;
                }
            }
        }
    }
    
    static _parseNumber(t, res, prev) {
        if (res.beginToken.isValue("ФОРМА", null)) {
            let tt = MiscHelper.checkNumberPrefix(t);
            if (tt !== null) 
                t = tt;
        }
        if (((t instanceof NumberToken) && t.intValue !== null && t.typ === NumberSpellingType.DIGIT) && (t.intValue < 3000)) {
            if (res.numbers.length >= 4) {
            }
            if (t.morph._class.isAdjective && res.typContainerRank === 0) 
                return;
            let nwp = NumberHelper.tryParseNumberWithPostfix(t);
            if (nwp !== null) {
                if (nwp.endToken.isWhitespaceBefore && nwp.endToken.chars.isCapitalUpper) {
                }
                else 
                    return;
            }
            if ((t.next !== null && (t.whitespacesAfterCount < 3) && t.next.chars.isLetter) && t.next.chars.isAllLower) {
                if (!t.isWhitespaceAfter && t.next.lengthChar === 1) {
                }
                else if (res.numbers.length === 0) {
                    res.numTyp = NumberTypes.DIGIT;
                    res.numbers.push(t.value.toString());
                    res.numBeginToken = (res.numEndToken = res.endToken = t);
                    return;
                }
                else 
                    return;
            }
            if (res.numTyp === NumberTypes.UNDEFINED) 
                res.numTyp = NumberTypes.DIGIT;
            else 
                res.numTyp = NumberTypes.COMBO;
            if (res.numbers.length > 0 && t.isWhitespaceBefore) 
                return;
            if (res.numbers.length === 0) 
                res.numBeginToken = t;
            if ((t.next !== null && t.next.isHiphen && (t.next.next instanceof NumberToken)) && t.next.next.intValue !== null && t.next.next.intValue > t.intValue) {
                res.minNumber = t.value.toString();
                t = t.next.next;
            }
            else if (((t.next !== null && t.next.isCharOf(")") && t.next.next !== null) && t.next.next.isHiphen && (t.next.next.next instanceof NumberToken)) && t.next.next.next.intValue !== null && t.next.next.next.intValue > t.intValue) {
                res.minNumber = t.value.toString();
                t = t.next.next.next;
            }
            res.numbers.push(t.value.toString());
            res.endToken = (res.numEndToken = t);
            res.numSuffix = null;
            for (let ttt = t.next; ttt !== null && (res.numbers.length < 4); ttt = ttt.next) {
                let ok1 = false;
                let ok2 = false;
                let ok3 = false;
                if ((ttt.isCharOf("._") && !ttt.isWhitespaceAfter && (ttt.next instanceof NumberToken)) && ((ttt.next.typ === NumberSpellingType.DIGIT || ((ttt.next.typ === NumberSpellingType.WORDS) && ttt.next.chars.isLatinLetter && !ttt.isWhitespaceAfter)))) 
                    ok1 = true;
                else if (ttt.isCharOf("(<") && (ttt.next instanceof NumberToken) && ttt.next.next !== null) {
                    if (ttt.next.next.isCharOf(")>")) 
                        ok2 = true;
                    else if ((ttt.next.next.isCharOf(".-") && (ttt.next.next.next instanceof NumberToken) && ttt.next.next.next.next !== null) && ttt.next.next.next.next.isCharOf(")>")) 
                        ok3 = true;
                }
                if (ok1 || ok2 || ok3) {
                    ttt = ttt.next;
                    res.numbers.push(ttt.value.toString());
                    if (ok3) {
                        ttt = ttt.next.next;
                        res.numbers.push(ttt.value.toString());
                    }
                    res.numTyp = (res.numbers.length === 2 ? NumberTypes.TWODIGITS : (res.numbers.length === 3 ? NumberTypes.THREEDIGITS : NumberTypes.FOURDIGITS));
                    if ((ttt.next !== null && ttt.next.isCharOf(")>") && ttt.next.next !== null) && ttt.next.next.isChar('.')) 
                        ttt = ttt.next;
                    else if (ok2 || ok3) 
                        ttt = ttt.next;
                    t = res.endToken = (res.numEndToken = ttt);
                    continue;
                }
                if (((ttt instanceof TextToken) && ttt.lengthChar === 1 && ttt.chars.isLetter) && !ttt.isWhitespaceBefore && res.numbers.length === 1) {
                    res.numbers.push(ttt.term);
                    res.numTyp = NumberTypes.COMBO;
                    t = res.endToken = (res.numEndToken = ttt);
                    continue;
                }
                if ((((ttt.isHiphen && res.numbers.length > 1 && (ttt.previous instanceof NumberToken)) && !ttt.isWhitespaceAfter && !ttt.isWhitespaceBefore) && (ttt.next instanceof NumberToken) && ttt.next.next !== null) && ttt.next.next.isChar('.') && !(ttt.next.next.next instanceof NumberToken)) {
                    res.numbers.push(ttt.next.value.toString());
                    t = res.endToken = (res.numEndToken = ttt.next.next);
                    res.numTyp = NumberTypes.THREEDIGITS;
                    break;
                }
                if ((res.typ === InstrToken1Types.FORM && (ttt.whitespacesBeforeCount < 3) && (ttt instanceof TextToken)) && ttt.lengthChar >= 2 && ttt.lengthChar <= 3) {
                    if (ttt.chars.isAllUpper || ttt.isValue("ГПК", null) || ttt.isValue("КАС", null)) {
                        t = res.endToken = (res.numEndToken = ttt);
                        continue;
                    }
                }
                break;
            }
            if (t.next !== null && t.next.isCharOf(").")) {
                res.numSuffix = t.next.getSourceText();
                t = res.endToken = (res.numEndToken = t.next);
            }
            return;
        }
        if (((t instanceof NumberToken) && t.typ === NumberSpellingType.WORDS && res.typContainerRank > 0) && res.numbers.length === 0) {
            res.numbers.push(t.value.toString());
            res.numTyp = NumberTypes.DIGIT;
            res.numBeginToken = t;
            if (t.next !== null && t.next.isChar('.')) {
                t = t.next;
                res.numSuffix = ".";
            }
            res.endToken = (res.numEndToken = t);
            return;
        }
        let nt = NumberHelper.tryParseRoman(t);
        if ((nt !== null && nt.value === "10" && t.next !== null) && t.next.isChar(')')) 
            nt = null;
        if (nt !== null && nt.value === "100") 
            nt = null;
        if (nt !== null && nt.typ === NumberSpellingType.ROMAN) {
            if (res.numTyp === NumberTypes.UNDEFINED) 
                res.numTyp = NumberTypes.ROMAN;
            else 
                res.numTyp = NumberTypes.COMBO;
            if (res.numbers.length > 0 && t.isWhitespaceBefore) 
                return;
            if (res.numbers.length === 0) 
                res.numBeginToken = t;
            res.numbers.push(nt.value.toString());
            t = res.endToken = (res.numEndToken = nt.endToken);
            if (res.numTyp === NumberTypes.ROMAN && (((!res.numEndToken.isWhitespaceAfter || res.typ === InstrToken1Types.CHAPTER || res.typ === InstrToken1Types.SECTION) || res.typ === InstrToken1Types.LINE))) {
                if ((t.next !== null && t.next.isCharOf("._<(") && (t.next.next instanceof NumberToken)) && t.next.next.typ === NumberSpellingType.DIGIT) {
                    t = t.next.next;
                    res.numbers.push(t.value.toString());
                    if (t.next !== null && t.next.isCharOf(">)")) 
                        t = t.next;
                    res.endToken = (res.numEndToken = t);
                    if ((t.next !== null && t.next.isCharOf("._<(") && (t.next.next instanceof NumberToken)) && t.next.next.typ === NumberSpellingType.DIGIT) {
                        t = t.next.next;
                        res.numbers.push(t.value.toString());
                        if (t.next !== null && t.next.isCharOf(">)")) 
                            t = t.next;
                        res.endToken = (res.numEndToken = t);
                    }
                    let ttt = t.next;
                    if (((((ttt !== null && ttt.isHiphen && res.numbers.length > 1) && (ttt.previous instanceof NumberToken) && !ttt.isWhitespaceAfter) && !ttt.isWhitespaceBefore && (ttt.next instanceof NumberToken)) && ttt.next.next !== null && ttt.next.next.isChar('.')) && !(ttt.next.next.next instanceof NumberToken)) {
                        res.numbers.push(ttt.next.value.toString());
                        t = res.endToken = (res.numEndToken = ttt.next.next);
                    }
                }
            }
            if (t.next !== null && t.next.isCharOf(").")) {
                res.numSuffix = t.next.getSourceText();
                t = res.endToken = (res.numEndToken = t.next);
            }
            return;
        }
        if (((t instanceof TextToken) && t.lengthChar === 1 && t.chars.isLetter) && t === res.beginToken) {
            if (t.isValue("И", null)) {
            }
            if ((!t.isWhitespaceAfter && (t.next instanceof NumberToken) && t.next.next !== null) && t.next.next.isChar('.')) {
                res.numBeginToken = t;
                res.numTyp = NumberTypes.DIGIT;
                res.numbers.push(t.next.value.toString());
                res.numSuffix = t.term + ".";
                t = res.endToken = (res.numEndToken = t.next.next);
                return;
            }
            if ((t.next !== null && t.next.isHiphen && (t.next.next instanceof TextToken)) && t.next.next.chars === t.chars) {
                res.numTyp = NumberTypes.LETTER;
                res.numbers.push(t.term);
                res.numBeginToken = (res.numEndToken = t);
                return;
            }
            if (t.next !== null && t.next.isCharOf("(.)")) {
                if (t.next.isChar('(') && t.isValue("И", null) && !(t.next.next instanceof NumberToken)) 
                    return;
                if (((t.next.isCharOf("(.") && (t.next.next instanceof NumberToken) && t.next.next.next !== null) && t.next.next.next.isChar(')') && !t.next.isWhitespaceAfter) && !t.next.next.isWhitespaceAfter) {
                    res.numTyp = NumberTypes.TWODIGITS;
                    res.numbers.push(t.term);
                    res.numbers.push(t.next.next.value.toString());
                    res.numSuffix = ")";
                    res.numBeginToken = t;
                    t = t.next.next.next;
                    if ((t.next instanceof TextToken) && t.next.isCharOf(").")) {
                        t = t.next;
                        res.numSuffix = t.term;
                    }
                    res.endToken = (res.numEndToken = t);
                    return;
                }
                if (t.next.isChar('.') && ((t.chars.isAllUpper || (t.next.next instanceof NumberToken)))) {
                }
                else {
                    let tmp1 = new InstrToken1(t, t.next);
                    tmp1.numbers.push(t.term);
                    if (tmp1.lastNumber > 1 && t.next.isCharOf(".") && ((prev === null || (prev.lastNumber + 1) !== tmp1.lastNumber))) {
                    }
                    else {
                        if (res.numbers.length === 0) 
                            res.numBeginToken = t;
                        res.numTyp = NumberTypes.LETTER;
                        res.numbers.push(t.term);
                        res.numBeginToken = t;
                        t = res.endToken = (res.numEndToken = t.next);
                        res.numSuffix = t.getSourceText();
                        return;
                    }
                }
            }
        }
    }
    
    static correctChildNumbers(root, children) {
        let hasNum = false;
        if (root.number > 0) {
            for (const ch of root.children) {
                if (ch.kind === InstrumentKind.NUMBER) {
                    hasNum = true;
                    break;
                }
                else if (ch.kind !== InstrumentKind.KEYWORD) 
                    break;
            }
        }
        if (!hasNum) 
            return false;
        if (root.subNumber === 0) {
            let ok = true;
            for (const ch of children) {
                if (ch.number > 0) {
                    if (ch.number === root.number && ch.subNumber > 0) {
                    }
                    else 
                        ok = false;
                }
            }
            if (ok) {
                for (const ch of children) {
                    if (ch.number > 0) {
                        ch.number = ch.subNumber;
                        ch.subNumber = ch.subNumber2;
                        ch.subNumber2 = ch.subNumber3;
                        ch.subNumber3 = 0;
                    }
                }
            }
            return ok;
        }
        if (root.subNumber > 0 && root.subNumber2 === 0) {
            let ok = true;
            for (const ch of children) {
                if (ch.number > 0) {
                    if (ch.number === root.number && ch.subNumber === root.subNumber && ch.subNumber2 > 0) {
                    }
                    else 
                        ok = false;
                }
            }
            if (ok) {
                for (const ch of children) {
                    if (ch.number > 0) {
                        ch.number = ch.subNumber2;
                        ch.subNumber = ch.subNumber3;
                        ch.subNumber2 = (ch.subNumber3 = 0);
                    }
                }
            }
            return ok;
        }
        if (root.subNumber > 0 && root.subNumber2 > 0 && root.subNumber3 === 0) {
            let ok = true;
            for (const ch of children) {
                if (ch.number > 0) {
                    if ((ch.number === root.number && ch.subNumber === root.subNumber && ch.subNumber2 === root.subNumber2) && ch.subNumber3 > 0) {
                    }
                    else 
                        ok = false;
                }
            }
            if (ok) {
                for (const ch of children) {
                    if (ch.number > 0) {
                        ch.number = ch.subNumber3;
                        ch.subNumber = (ch.subNumber2 = (ch.subNumber3 = 0));
                    }
                }
            }
            return ok;
        }
        return false;
    }
    
    static createDiap(s1, s2) {
        let n1 = 0;
        let n2 = 0;
        let i = 0;
        let pref = null;
        if (s2.startsWith(s1)) {
            i = s1.length;
            if (((i + 1) < s2.length) && s2[i] === '.' && Utils.isDigit(s2[i + 1])) {
                let wrapn22254 = new RefOutArgWrapper();
                let inoutres2255 = Utils.tryParseInt(s2.substring(i + 1), wrapn22254);
                n2 = wrapn22254.value;
                if (inoutres2255) {
                    let res0 = new Array();
                    res0.push(s1);
                    for (i = 1; i <= n2; i++) {
                        res0.push((s1 + "." + i));
                    }
                    return res0;
                }
            }
        }
        if ((((i = s1.lastIndexOf('.')))) > 0) {
            pref = s1.substring(0, 0 + i + 1);
            let wrapn12258 = new RefOutArgWrapper();
            let inoutres2259 = Utils.tryParseInt(s1.substring(i + 1), wrapn12258);
            n1 = wrapn12258.value;
            if (!inoutres2259) 
                return null;
            if (!s2.startsWith(pref)) 
                return null;
            let wrapn22256 = new RefOutArgWrapper();
            let inoutres2257 = Utils.tryParseInt(s2.substring(i + 1), wrapn22256);
            n2 = wrapn22256.value;
            if (!inoutres2257) 
                return null;
        }
        else {
            let wrapn12262 = new RefOutArgWrapper();
            let inoutres2263 = Utils.tryParseInt(s1, wrapn12262);
            n1 = wrapn12262.value;
            if (!inoutres2263) 
                return null;
            let wrapn22260 = new RefOutArgWrapper();
            let inoutres2261 = Utils.tryParseInt(s2, wrapn22260);
            n2 = wrapn22260.value;
            if (!inoutres2261) 
                return null;
        }
        if (n2 <= n1) 
            return null;
        let res = new Array();
        for (i = n1; i <= n2; i++) {
            if (pref === null) 
                res.push(i.toString());
            else 
                res.push(pref + (i.toString()));
        }
        return res;
    }
}


module.exports = NumberingHelper