/*
 * SDK Pullenti Unitext, 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# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

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

const UnitextContainerType = require("./../../UnitextContainerType");
const UnitextContainer = require("./../../UnitextContainer");
const UnitextPlaintextType = require("./../../UnitextPlaintextType");
const SymbolHelper = require("./../misc/SymbolHelper");
const GetPlaintextParam = require("./../../GetPlaintextParam");
const UnitextFootnote = require("./../../UnitextFootnote");
const UnitextComment = require("./../../UnitextComment");
const UnitextHyperlink = require("./../../UnitextHyperlink");
const RichTextItem = require("./RichTextItem");
const RichTextCell = require("./RichTextCell");
const UnitextTable = require("./../../UnitextTable");
const RichTextRow = require("./RichTextRow");
const UnitextPlaintext = require("./../../UnitextPlaintext");
const UnitextMiscType = require("./../../UnitextMiscType");
const UnitextMisc = require("./../../UnitextMisc");
const RichTextTable = require("./RichTextTable");
const MiscHelper = require("./../../../util/MiscHelper");
const FileFormat = require("./../../FileFormat");
const RtfItem = require("./RtfItem");
const EncodingStandard = require("./../../../util/EncodingStandard");
const RftItemTyp = require("./RftItemTyp");
const UnitextItem = require("./../../UnitextItem");
const UnitextGen = require("./../uni/UnitextGen");
const UnitextDocument = require("./../../UnitextDocument");
const EncodingWrapper = require("./../../../util/EncodingWrapper");
const UnitextImage = require("./../../UnitextImage");
const RtfItemImage = require("./RtfItemImage");
const WingdingsHelper = require("./../misc/WingdingsHelper");
const HtmlParser = require("./../html/HtmlParser");
const UnitextPagesectionItem = require("./../../UnitextPagesectionItem");
const UnitextPagesection = require("./../../UnitextPagesection");
const HtmlHelper = require("./../html/HtmlHelper");

/**
 * Поддержка формата RTF
 */
class RtfHelper {
    
    static _manageEncodings(items) {
        let fontCharsets = new Hashtable();
        let fontEncodings = new Hashtable();
        let fontName = null;
        let defs = new Array();
        let curs = new Array();
        let isAnsi = false;
        for (let i = 0; i < items.length; i++) {
            let it = items[i];
            while (curs.length > 0) {
                if (curs[0].level > it.level) 
                    curs.splice(0, 1);
                else 
                    break;
            }
            while (defs.length > 0) {
                if (defs[0].level > it.level) 
                    defs.splice(0, 1);
                else 
                    break;
            }
            if (it.typ === RftItemTyp.TEXT) {
                if (it.text === null && it.codes !== null && it.codes.length > 0) {
                    if (it.codes.length > 5) {
                    }
                    let cur = (curs.length > 0 ? curs[0] : null);
                    if (cur !== null && cur.level > it.level) 
                        cur = null;
                    let def = (defs.length > 0 ? defs[0] : null);
                    if (def !== null && def.level > it.level) 
                        def = null;
                    let enc = (cur === null ? null : cur.encoding);
                    if (fontName !== null && fontEncodings.containsKey(fontName)) 
                        enc = fontEncodings.get(fontName);
                    if (enc === null && def !== null) 
                        enc = def.encoding;
                    if (enc === null) 
                        enc = new EncodingWrapper(EncodingStandard.CP1252);
                    try {
                        let str = enc.getString(it.codes, 0, -1);
                        it.text = str;
                    } catch (ex252) {
                    }
                }
                else if (i > 0 && items[i - 1].typ === RftItemTyp.COMMAND && items[i - 1].text[0] === 'f') {
                    if (it.text !== null && it.text.endsWith(" Cyr;") && fontName !== null) {
                        if (!fontEncodings.containsKey(fontName)) 
                            fontEncodings.put(fontName, new EncodingWrapper(EncodingStandard.CP1251));
                    }
                }
                continue;
            }
            if (it.typ !== RftItemTyp.COMMAND) 
                continue;
            let cmd = it.text;
            if (cmd === null) 
                continue;
            if (cmd === "plain") {
                if (curs.length > 0) 
                    curs.splice(0, 1);
                continue;
            }
            if (cmd === "ansi") {
                isAnsi = true;
                continue;
            }
            if (cmd.startsWith("ansicpg")) {
                let cp = 0;
                let wrapcp254 = new RefOutArgWrapper();
                let inoutres255 = Utils.tryParseInt(cmd.substring(7), wrapcp254);
                cp = wrapcp254.value;
                if (!inoutres255) 
                    continue;
                defs.splice(0, 0, RtfHelper.RtfEncoder._new253(it.level, new EncodingWrapper(EncodingStandard.UNDEFINED, null, cp)));
                continue;
            }
            if (cmd.startsWith("deflangfe")) {
                let cp = 0;
                let wrapcp259 = new RefOutArgWrapper();
                let inoutres260 = Utils.tryParseInt(cmd.substring(9), wrapcp259);
                cp = wrapcp259.value;
                if (!inoutres260) 
                    continue;
                let wrapcp257 = new RefOutArgWrapper();
                let inoutres258 = RtfHelper.m_LangIdToCodepage.tryGetValue(cp, wrapcp257);
                cp = wrapcp257.value;
                if (!inoutres258) 
                    continue;
                defs.splice(0, 0, RtfHelper.RtfEncoder._new253(it.level, new EncodingWrapper(EncodingStandard.UNDEFINED, null, cp)));
                continue;
            }
            if (cmd.startsWith("deflang")) {
                let cp = 0;
                let wrapcp264 = new RefOutArgWrapper();
                let inoutres265 = Utils.tryParseInt(cmd.substring(7), wrapcp264);
                cp = wrapcp264.value;
                if (!inoutres265) 
                    continue;
                let wrapcp262 = new RefOutArgWrapper();
                let inoutres263 = RtfHelper.m_LangIdToCodepage.tryGetValue(cp, wrapcp262);
                cp = wrapcp262.value;
                if (!inoutres263) 
                    continue;
                defs.splice(0, 0, RtfHelper.RtfEncoder._new253(it.level, new EncodingWrapper(EncodingStandard.UNDEFINED, null, cp)));
                continue;
            }
            if (cmd.startsWith("langfe")) 
                continue;
            if (cmd.startsWith("lang")) {
                let cp = 0;
                let wrapcp269 = new RefOutArgWrapper();
                let inoutres270 = Utils.tryParseInt(cmd.substring(4), wrapcp269);
                cp = wrapcp269.value;
                if (!inoutres270) 
                    continue;
                let wrapcp267 = new RefOutArgWrapper();
                let inoutres268 = RtfHelper.m_LangIdToCodepage.tryGetValue(cp, wrapcp267);
                cp = wrapcp267.value;
                if (!inoutres268) 
                    continue;
                if ((i > 0 && items[i - 1].typ === RftItemTyp.COMMAND && items[i - 1].text.startsWith("f")) && curs.length > 0 && curs[0].level === it.level) 
                    continue;
                curs.splice(0, 0, RtfHelper.RtfEncoder._new253(it.level, new EncodingWrapper(EncodingStandard.UNDEFINED, null, cp)));
                continue;
            }
            if (cmd.length >= 2 && cmd[0] === 'f' && Utils.isDigit(cmd[1])) {
                if (cmd === "f674") {
                }
                if (fontCharsets.containsKey(cmd)) {
                    let cs = fontCharsets.get(cmd);
                    let enc = null;
                    switch (cs) { 
                    case 204: {
                        enc = new EncodingWrapper(EncodingStandard.CP1251);
                        break;
                    }
                    case 238: {
                        enc = new EncodingWrapper(EncodingStandard.UNDEFINED, null, 1250);
                        break;
                    }
                    case 161: {
                        enc = new EncodingWrapper(EncodingStandard.UNDEFINED, null, 1253);
                        break;
                    }
                    case 162: {
                        enc = new EncodingWrapper(EncodingStandard.UNDEFINED, null, 1254);
                        break;
                    }
                    }
                    if (enc !== null) 
                        curs.splice(0, 0, RtfHelper.RtfEncoder._new253(it.level, enc));
                }
                else 
                    fontName = cmd;
                continue;
            }
            if (cmd.startsWith("fcharset") && fontName !== null) {
                let cod = 0;
                let wrapcod272 = new RefOutArgWrapper();
                let inoutres273 = Utils.tryParseInt(cmd.substring(8), wrapcod272);
                cod = wrapcod272.value;
                if (inoutres273) {
                    if (!fontCharsets.containsKey(fontName)) 
                        fontCharsets.put(fontName, cod);
                }
                continue;
            }
        }
        let tmp = new StringBuilder();
        for (let i = 0; i < (items.length - 1); i++) {
            let it = items[i];
            let it1 = items[i + 1];
            if ((it1.typ === RftItemTyp.TEXT && it.typ === RftItemTyp.TEXT && it1.text !== null) && it.text !== null) {
                tmp.length = 0;
                tmp.append(it.text);
                for (let j = i + 1; j < items.length; j++) {
                    it1 = items[j];
                    if (it1.typ !== RftItemTyp.TEXT || it1.text === null) 
                        break;
                    tmp.append(it1.text);
                    items[j] = null;
                    i = j;
                }
                it.text = tmp.toString();
            }
        }
        let k = 0;
        for (let i = 0; i < items.length; i++) {
            if (items[i] !== null) {
                items[k] = items[i];
                k++;
            }
        }
        if (k < items.length) 
            items.splice(k, items.length - k);
    }
    
    static createUniDoc(stream, pars) {
        let doc = UnitextDocument._new47(FileFormat.RTF);
        stream.position = 0;
        let items = RtfItem.parseList(stream);
        RtfHelper._manageEncodings(items);
        let cntGen = new UnitextGen();
        let headGen = null;
        let footGen = null;
        let _html = null;
        let i = 0;
        if (items.length > 100 && items[1].typ === RftItemTyp.COMMAND && items[1].text === "rtf1") {
            for (let ii = 2; ii < 20; ii++) {
                if (items[ii].typ === RftItemTyp.COMMAND && items[ii].text === "fromhtml1") {
                    _html = new StringBuilder();
                    cntGen = null;
                    for (; (ii < 500) && ((ii + 1) < items.length); ii++) {
                        if ((items[ii].typ === RftItemTyp.COMMAND && items[ii].text === "*" && items[ii + 1].typ === RftItemTyp.COMMAND) && items[ii + 1].text.startsWith("htmltag")) {
                            i = ii;
                            break;
                        }
                    }
                    break;
                }
            }
        }
        for (; i < items.length; i++) {
            let it = items[i];
            if (it.typ === RftItemTyp.COMMAND) {
                let cmd = it.text;
                if (cmd === null) 
                    continue;
                if (cmd.startsWith("header") || cmd.startsWith("footer")) {
                    if (!cmd.startsWith("headery") && !cmd.startsWith("footery")) {
                        let ii = 0;
                        for (ii = i + 1; ii < items.length; ii++) {
                            if (items[ii].level < it.level) 
                                break;
                        }
                        if (headGen === null && cmd.startsWith("head")) {
                            headGen = new UnitextGen();
                            RtfHelper._manageUni(items, _html, headGen, i + 1, ii, false, 0);
                        }
                        else if (footGen === null && cmd.startsWith("foot")) {
                            footGen = new UnitextGen();
                            RtfHelper._manageUni(items, _html, footGen, i + 1, ii, false, 0);
                        }
                        i = ii - 1;
                        continue;
                    }
                }
            }
            if (items[i] instanceof RtfHelper.RtfTablerow) {
            }
            let j = RtfHelper._manageUni(items, _html, cntGen, i, i + 1, false, 0);
            i = j - 1;
        }
        if (_html === null) {
            doc.content = cntGen.finish(true, null);
            let sect = new UnitextPagesection();
            if (headGen !== null) {
                let fi = headGen.finish(true, null);
                if (fi !== null) 
                    sect.items.push(UnitextPagesectionItem._new48(fi));
            }
            if (footGen !== null) {
                let fi = footGen.finish(true, null);
                if (fi !== null) 
                    sect.items.push(UnitextPagesectionItem._new276(fi, true));
            }
            if (sect.items.length > 0) 
                doc.sections.push(sect);
        }
        else {
            let txt = _html.toString();
            let nod = HtmlParser.parse(_html, false);
            if (nod === null) 
                return null;
            doc = HtmlHelper.create(nod, null, null, pars);
            doc.sourceFormat = FileFormat.RTF;
        }
        doc.optimize(false, null);
        return doc;
    }
    
    static _manageUni(items, _html, gen, i0, i1, inTab, lev) {
        let i = 0;
        for (i = i0; i < i1; i++) {
            let it = items[i];
            if (it.typ === RftItemTyp.BRACKETOPEN || it.typ === RftItemTyp.BRACKETCLOSE) 
                continue;
            if (it.typ === RftItemTyp.PROXY) {
                gen.append(it.uni, null, -1, false);
                continue;
            }
            if (it.typ === RftItemTyp.TEXT) {
                if (it.text !== null) {
                    if (_html !== null) 
                        MiscHelper.correctHtmlValue(_html, it.text, false, false, false);
                    else 
                        gen.appendText(it.text, false);
                }
                continue;
            }
            if (it instanceof RtfItemImage) {
                let im = Utils.as(it, RtfItemImage);
                let img = UnitextImage._new277(im.codes);
                if (im.width > 0 && im.height > 0) {
                    img.width = (String(im.width) + "pt");
                    img.height = (String(im.height) + "pt");
                }
                gen.append(img, null, -1, false);
                continue;
            }
            if (it.typ !== RftItemTyp.COMMAND) 
                continue;
            let cmd = it.text;
            if (cmd === null) 
                continue;
            if (cmd === "annotation") {
            }
            if ((cmd === "*" || cmd.startsWith("fonttbl") || cmd === "stylesheet") || cmd.startsWith("nonshppict") || cmd === "deleted") {
                let htmlOutLev = -1;
                let lastOutInd = -1;
                for (++i; i < items.length; i++) {
                    if (items[i].level < it.level) {
                        i--;
                        break;
                    }
                    else if (items[i] instanceof RtfItemImage) {
                        if (cmd === "*") {
                            let im = Utils.as(items[i], RtfItemImage);
                            let img = UnitextImage._new277(items[i].codes);
                            if (im.width > 0 && im.height > 0) {
                                img.width = (String(im.width) + "pt");
                                img.height = (String(im.height) + "pt");
                            }
                            gen.append(img, null, -1, false);
                        }
                    }
                    else if (items[i].typ === RftItemTyp.COMMAND) {
                        if (items[i].text === "footnote") {
                            i--;
                            break;
                        }
                        if (items[i].text === "annotation") {
                            i--;
                            break;
                        }
                        if (items[i].text === "shptxt") {
                            i--;
                            break;
                        }
                        if (items[i].text === "fldinst") {
                            i--;
                            break;
                        }
                        if (_html !== null && items[i].text.startsWith("htmltag")) 
                            htmlOutLev = items[i].level;
                    }
                    else if (items[i].typ === RftItemTyp.TEXT && _html !== null) {
                        _html.append(items[i].text);
                        lastOutInd = i;
                    }
                }
                continue;
            }
            if (cmd === "fldinst") {
                let iii = new Array();
                let ii = 0;
                for (ii = i + 1; (ii < items.length) && (ii < i1); ii++) {
                    if (items[ii].level < it.level) 
                        break;
                    else {
                        iii.push(items[ii]);
                        if (items[ii].text !== null && items[ii].text.startsWith("SYMBOL")) {
                            let sss = items[ii].text.substring(6).trim();
                            let jj = sss.indexOf(' ');
                            if (jj > 0) 
                                sss = sss.substring(0, 0 + jj);
                            let wrapjj279 = new RefOutArgWrapper();
                            let inoutres280 = Utils.tryParseInt(sss, wrapjj279);
                            jj = wrapjj279.value;
                            if (inoutres280) {
                                let chu = String.fromCharCode(0);
                                if (items[ii].text.includes("Wingdings")) 
                                    chu = WingdingsHelper.getUnicode(jj);
                                else 
                                    chu = SymbolHelper.getUnicode(jj);
                                if (chu === (String.fromCharCode(0))) 
                                    chu = '?';
                                gen.appendText((chu), false);
                            }
                        }
                    }
                }
                i = ii - 1;
                continue;
            }
            if (cmd === "field") {
                let iii = new Array();
                let ii = 0;
                let ur = null;
                for (ii = i + 1; ii < items.length; ii++) {
                    if (items[ii].level < it.level) 
                        break;
                    else {
                        iii.push(items[ii]);
                        if (items[ii].typ === RftItemTyp.TEXT && items[ii].text !== null && items[ii].text.trim().startsWith("HYPERLINK")) {
                            let fff = items[ii].text;
                            let jj0 = fff.indexOf('"');
                            let jj1 = fff.lastIndexOf('"');
                            if (jj0 > 0 && jj1 > jj0) {
                                let hy = fff.substring(jj0 + 1, jj0 + 1 + jj1 - jj0 - 1);
                                ur = hy;
                            }
                            else {
                                fff = fff.substring(9).trim();
                                if (fff.startsWith("http")) 
                                    ur = fff;
                                else {
                                }
                            }
                            if (ur === null) {
                            }
                        }
                    }
                }
                let gg = new UnitextGen();
                RtfHelper._manageUni(iii, null, gg, 0, iii.length, false, lev + 1);
                let cnt = gg.finish(true, null);
                if (cnt !== null) {
                    let tmp = new StringBuilder();
                    cnt.getPlaintext(tmp, new GetPlaintextParam());
                    if (ur === null || tmp.length > 300) 
                        gen.append(cnt, null, -1, false);
                    else {
                        let hr = UnitextHyperlink._new59(ur);
                        hr.content = cnt;
                        if (gen !== null) 
                            gen.append(hr, null, -1, false);
                        else if (_html !== null) 
                            cnt.getPlaintext(_html, null);
                    }
                    i = ii - 1;
                }
                continue;
            }
            if (cmd === "annotation") {
                let iii = new Array();
                let ii = 0;
                for (ii = i; ii < items.length; ii++) {
                    if (items[ii].level < (it.level - 1)) 
                        break;
                    else 
                        iii.push(items[ii]);
                }
                let gg = new UnitextGen();
                RtfHelper._manageUni(items, _html, gg, i + 1, ii, false, lev);
                let cnt = gg.finish(false, null);
                if (cnt !== null) {
                    let tmp = new StringBuilder();
                    cnt.getPlaintext(tmp, null);
                    if (tmp.length > 0) 
                        gen.append(UnitextComment._new50(tmp.toString()), null, -1, false);
                }
                i = ii - 1;
                continue;
            }
            if (cmd === "shptxt") {
                let iii = new Array();
                let ii = 0;
                for (ii = i; (ii < items.length) && (ii < i1); ii++) {
                    if (items[ii].level < (it.level - 1)) 
                        break;
                    else 
                        iii.push(items[ii]);
                }
                let gg = new UnitextGen();
                RtfHelper._manageUni(items, _html, gg, i + 1, ii, false, lev);
                let cnt = gg.finish(true, null);
                if (cnt instanceof UnitextContainer) 
                    cnt.typ = UnitextContainerType.SHAPE;
                else if (cnt !== null) {
                    let cnt2 = UnitextContainer._new94(UnitextContainerType.SHAPE);
                    cnt2.children.push(cnt);
                    cnt = cnt2.optimize(false, null);
                }
                if (cnt !== null) 
                    gen.append(cnt, null, -1, false);
                i = ii - 1;
                continue;
            }
            if (cmd === "footnote") {
                let iii = new Array();
                let ii = 0;
                let endnote = false;
                for (ii = i; (ii < items.length) && (ii < i1); ii++) {
                    if (items[ii].level <= (it.level - 1)) 
                        break;
                    else {
                        iii.push(items[ii]);
                        if (items[ii].typ === RftItemTyp.COMMAND && items[ii].text === "ftnalt") 
                            endnote = true;
                    }
                }
                let gg = new UnitextGen();
                RtfHelper._manageUni(items, _html, gg, i + 1, ii, false, lev);
                let cnt = gg.finish(false, null);
                if (cnt !== null) {
                    let fn = UnitextFootnote._new284(cnt, endnote);
                    if (cnt instanceof UnitextContainer) {
                        let cc = Utils.as(cnt, UnitextContainer);
                        if (cc.children.length > 1 && (cc.children[0] instanceof UnitextPlaintext) && cc.children[0].typ === UnitextPlaintextType.SUP) {
                            fn.customMark = cc.children[0].text;
                            cc.children.splice(0, 1);
                            fn.content = cc.optimize(true, null);
                        }
                    }
                    gen.append(fn, null, -1, false);
                }
                i = ii - 1;
                continue;
            }
            if (cmd.startsWith("listtext")) {
                let listId = null;
                let listLevel = 0;
                let ii = 0;
                let ok = false;
                let endOfNum = false;
                let num = new StringBuilder();
                let tmp = new Array();
                for (ii = i + 1; ii < items.length; ii++) {
                    let itt = items[ii];
                    tmp.push(itt);
                    if (itt.typ === RftItemTyp.TEXT) {
                        if (listId !== null || endOfNum) {
                            ok = true;
                            break;
                        }
                        num.append((itt.text != null ? itt.text : ""));
                        continue;
                    }
                    if (itt.typ === RftItemTyp.BRACKETCLOSE && num.length > 0) 
                        endOfNum = true;
                    if (itt.typ !== RftItemTyp.COMMAND) 
                        continue;
                    if (inTab) {
                        if ((itt.text === "cell" || itt.text === "row" || itt.text === "trowd") || itt.text === "intbl" || itt.text === "nestcell") 
                            break;
                    }
                    if (itt.text.startsWith("ls") && itt.text.length > 2 && Utils.isDigit(itt.text[2])) {
                        if (listId !== null) 
                            break;
                        listId = itt.text.substring(2);
                        continue;
                    }
                    if (itt.text.startsWith("ilvl") && itt.text.length > 4 && Utils.isDigit(itt.text[4])) {
                        let wraplistLevel285 = new RefOutArgWrapper();
                        Utils.tryParseInt(itt.text.substring(4), wraplistLevel285);
                        listLevel = wraplistLevel285.value;
                        continue;
                    }
                    if (itt.text === "listtext") 
                        break;
                }
                if (ok) {
                    let jj = 0;
                    for (jj = ii + 1; jj < items.length; jj++) {
                        let itt = items[jj];
                        tmp.push(itt);
                        if (itt.typ !== RftItemTyp.COMMAND) 
                            continue;
                        if (itt.text === "par") {
                            jj++;
                            break;
                        }
                        if (itt.text === "sect") 
                            break;
                        if (itt.text === "listtext" || itt.text === "trowd") 
                            break;
                        if (itt.text.startsWith("ls")) 
                            break;
                    }
                    if ((ii > 2 && items[ii - 1].typ === RftItemTyp.COMMAND && items[ii - 2].typ === RftItemTyp.COMMAND) && items[ii - 2].text === "*") 
                        ii -= 2;
                    let gg = new UnitextGen();
                    RtfHelper._manageUni(items, _html, gg, ii, jj, false, lev);
                    gen.appendListItem(gg.finish(true, null), num.toString().trim(), listId, listLevel, null);
                    i = jj - 1;
                    continue;
                }
            }
            if (cmd === "line") {
                if (_html !== null) 
                    _html.append("\r\n");
                else 
                    gen.appendNewline(false, false);
                continue;
            }
            if (cmd === "page" || cmd === "sect") {
                gen.appendPagebreak();
                continue;
            }
            if (cmd === "par") {
                if (_html !== null) 
                    _html.append("\r\n");
                else 
                    gen.appendNewline(false, false);
                continue;
            }
            if (cmd === "brdrt" || cmd === "brdrb") {
                if (_html !== null) 
                    _html.append("\r\n<hr/>");
                else 
                    gen.append(UnitextMisc._new286(UnitextMiscType.HORIZONTALLINE), null, -1, false);
                continue;
            }
            if (cmd === "intbl" && !inTab) {
            }
            if (((cmd === "trowd" && !inTab)) || ((cmd === "intbl" && !inTab))) {
                if (lev < 5) {
                    if (lev > 10) {
                    }
                    let rtfTab = new RichTextTable();
                    let rtfRow = new RichTextRow();
                    let ii = RtfHelper._manageTableRow(items, i, rtfRow, lev + 1);
                    if (ii > i) {
                        rtfTab.addChild(rtfRow);
                        i = ii;
                        while (i < items.length) {
                            if (rtfRow.lastRow) 
                                break;
                            rtfRow = new RichTextRow();
                            ii = RtfHelper._manageTableRow(items, i, rtfRow, lev + 1);
                            if (ii < 0) 
                                break;
                            rtfTab.addChild(rtfRow);
                            if (ii <= i) 
                                break;
                            i = ii;
                        }
                        rtfTab.correct();
                        let tab = RtfHelper._createTable(rtfTab);
                        if (gen !== null) 
                            gen.append(tab, null, -1, false);
                        continue;
                    }
                }
            }
            let sub = -1;
            if (cmd.startsWith("super") || cmd.startsWith("up")) 
                sub = 0;
            else if (cmd.startsWith("sub")) 
                sub = 1;
            if (sub >= 0) {
                let ii = 0;
                let ok = false;
                let tmp = new StringBuilder();
                for (ii = i + 1; ii < items.length; ii++) {
                    if (items[ii].typ === RftItemTyp.BRACKETCLOSE || items[ii].typ === RftItemTyp.BRACKETOPEN) {
                        ok = true;
                        break;
                    }
                    else if (items[ii].typ === RftItemTyp.TEXT) 
                        tmp.append((items[ii].text != null ? items[ii].text : ""));
                    else if (items[ii].typ !== RftItemTyp.COMMAND) 
                        break;
                    else if (items[ii].text === "pard") {
                        ok = true;
                        break;
                    }
                    else if (items[ii].text === "footnote") 
                        break;
                }
                if (ok) {
                    let tt = tmp.toString().trim();
                    if (tt.length > 0 && (tt.length < 10)) {
                        gen.append(UnitextPlaintext._new58(tt, (sub > 0 ? UnitextPlaintextType.SUB : UnitextPlaintextType.SUP)), null, -1, false);
                        i = ii - 1;
                    }
                }
                continue;
            }
        }
        return i;
    }
    
    static _createTable(tbl) {
        let res = new UnitextTable();
        let rn = 0;
        for (const rr of tbl.children) {
            let cn = 0;
            for (const c of rr.children) {
                for (; ; cn++) {
                    if (res.getCell(rn, cn) === null) 
                        break;
                }
                let cel = res.addCell(rn, (rn + c.rowsSpan) - 1, cn, (cn + c.colsSpan) - 1, Utils.as(c.tag, UnitextItem), false);
                if (cel !== null) 
                    c.resColIndex = cel.colBegin;
            }
            rn++;
        }
        if (res.colsCount > 1) {
            let wi = new Int32Array(res.colsCount);
            for (let kk = 0; kk < 3; kk++) {
                for (const rr of tbl.children) {
                    let r = Utils.as(rr, RichTextRow);
                    if (r === null) 
                        continue;
                    if (r.cellsInfo.length !== r.children.length) 
                        continue;
                    let sum = 0;
                    for (const ci of r.cellsInfo) {
                        sum += ci.width;
                    }
                    if (sum <= 0) 
                        continue;
                    for (let i = 0; i < r.children.length; i++) {
                        let c = Utils.as(r.children[i], RichTextCell);
                        if ((c.resColIndex < 0) || c.resColIndex >= wi.length) 
                            continue;
                        let w = Utils.intDiv(r.cellsInfo[i].width * 100, sum);
                        let co = 0;
                        for (let j = c.resColIndex; (j < (c.resColIndex + c.colsSpan)) && (j < wi.length); j++) {
                            if (wi[j] > 0) 
                                w -= wi[j];
                            else 
                                co++;
                        }
                        if (co === 1 && w > 0) {
                            for (let j = c.resColIndex; (j < (c.resColIndex + c.colsSpan)) && (j < wi.length); j++) {
                                if (wi[j] === 0) {
                                    wi[j] = w;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            for (let i = 0; i < wi.length; i++) {
                if (wi[i] > 0) 
                    res.setColWidth(i, (String(wi[i]) + "%"));
            }
        }
        return res;
    }
    
    static _manageTableRow(items, i, rtfRow, lev) {
        let ok = false;
        for (; i < items.length; i++) {
            let it = items[i];
            if (it.typ === RftItemTyp.COMMAND && ((it.text === "trowd" || it.text === "intbl"))) {
                ok = true;
                break;
            }
            if (it.typ === RftItemTyp.TEXT || it.typ === RftItemTyp.IMAGE) 
                break;
        }
        if (!ok) 
            return -1;
        let colWidth = new Array();
        for (; i < items.length; i++) {
            let it = items[i];
            if (it.typ === RftItemTyp.COMMAND && it.text === "row") 
                return i + 1;
            let j = 0;
            ok = false;
            for (j = i; j < items.length; j++) {
                let itt = items[j];
                if (itt.typ !== RftItemTyp.COMMAND) 
                    continue;
                if (itt.text === "cell") {
                    ok = true;
                    break;
                }
                if (itt.text === "row") {
                    j--;
                    break;
                }
                if (itt.text === "nestcell") {
                    let nRow = new RichTextRow();
                    let jj = RtfHelper._manageNestedTableRow(items, i, nRow, lev + 1);
                    if (jj > 0) {
                        let nTab = new RichTextTable();
                        nTab.addChild(nRow);
                        while (true) {
                            nRow = new RichTextRow();
                            let jjj = RtfHelper._manageNestedTableRow(items, jj, nRow, lev + 1);
                            if (jjj < 0) 
                                break;
                            nTab.addChild(nRow);
                            jj = jjj;
                        }
                        nTab.correct();
                        let ppp = RtfHelper.RtfItemProxy._new288(RftItemTyp.PROXY);
                        ppp.uni = RtfHelper._createTable(nTab);
                        items.splice(i + 1, jj - i - 1);
                        items[i] = ppp;
                        continue;
                    }
                }
                if (rtfRow !== null) 
                    rtfRow._addCmd(itt.text);
            }
            if (ok && rtfRow !== null) {
                let gg = new UnitextGen();
                RtfHelper._manageUni(items, null, gg, i, j, true, lev);
                let cel = new RichTextCell();
                cel.tag = gg.finish(true, null);
                cel.endOf = true;
                rtfRow.addChild(cel);
            }
            i = j;
        }
        return -1;
    }
    
    static _manageNestedTableRow(items, i, rtfRow, lev) {
        let endOfRow = false;
        for (; i < items.length; i++) {
            let it = items[i];
            if (it.typ === RftItemTyp.COMMAND && ((it.text === "row" || it.text === "cell"))) 
                return -1;
            let j = 0;
            let ok = false;
            for (j = i; j < items.length; j++) {
                let itt = items[j];
                if (itt.typ !== RftItemTyp.COMMAND) 
                    continue;
                if (itt.text === "nestcell") {
                    ok = true;
                    break;
                }
                if (itt.text === "row" || itt.text === "cell") 
                    return -1;
                if (itt.text === "nesttableprops" || itt.text === "nestrow") {
                    endOfRow = true;
                    break;
                }
            }
            if (ok) {
                let gg = new UnitextGen();
                RtfHelper._manageUni(items, null, gg, i, j, true, lev + 1);
                let cel = new RichTextCell();
                cel.tag = gg.finish(true, null);
                cel.endOf = true;
                rtfRow.addChild(cel);
            }
            i = j;
            if (endOfRow) 
                break;
        }
        if (!endOfRow) 
            return -1;
        for (; i < items.length; i++) {
            let it = items[i];
            if (it.typ !== RftItemTyp.COMMAND) 
                continue;
            if (it.text === "row" || it.text === "cell") 
                return -1;
            if (it.text === "nestrow") 
                return i + 1;
            rtfRow._addCmd(it.text);
        }
        return -1;
    }
    
    static static_constructor() {
        RtfHelper.m_LangIdToCodepage = new Hashtable();
        for (const i of new Int32Array([1052, 1050, 1029, 1038, 1045, 1048, 2074, 1051, 1060])) {
            RtfHelper.m_LangIdToCodepage.put(i, 1250);
        }
        for (const i of new Int32Array([2092, 1059, 1026, 1071, 1087, 1088, 1104, 1049, 3098, 1092, 1058, 2115])) {
            RtfHelper.m_LangIdToCodepage.put(i, 1251);
        }
        for (const i of new Int32Array([1078, 1069, 1027, 1030, 2067, 1043, 3081, 10249, 4105, 9225, 2057, 6153, 8201, 5129, 13321, 7177, 11273, 1033, 12297, 1080, 1035, 2060, 3084, 1036, 5132, 6156, 4108, 1110, 3079, 1031, 5127, 4103, 2055, 1039, 1057, 1040, 2064, 2110, 1086, 1044, 2068, 1046, 2070, 11274, 16394, 13322, 9226, 5130, 7178, 12298, 17418, 4106, 18442, 2058, 19466, 6154, 15370, 10250, 20490, 1034, 14346, 8202, 1089, 2077, 1053])) {
            RtfHelper.m_LangIdToCodepage.put(i, 1252);
        }
        RtfHelper.m_LangIdToCodepage.put(1032, 1253);
        for (const i of new Int32Array([1068, 1055, 1091])) {
            RtfHelper.m_LangIdToCodepage.put(i, 1254);
        }
        RtfHelper.m_LangIdToCodepage.put(1037, 1255);
        for (const i of new Int32Array([5121, 15361, 3073, 2049, 11265, 13313, 12289, 4097, 6145, 8193, 16385, 1025, 10241, 7169, 14337, 9217, 1065, 1056])) {
            RtfHelper.m_LangIdToCodepage.put(i, 1256);
        }
        for (const i of new Int32Array([1061, 1062, 1063, 1066])) {
            RtfHelper.m_LangIdToCodepage.put(i, 1257);
        }
    }
}


RtfHelper.RtfEncoder = class  {
    
    constructor() {
        this.level = 0;
        this.encoding = null;
    }
    
    toString() {
        return (String(this.level) + ": " + this.encoding.toString());
    }
    
    static _new253(_arg1, _arg2) {
        let res = new RtfHelper.RtfEncoder();
        res.level = _arg1;
        res.encoding = _arg2;
        return res;
    }
}


RtfHelper.RtfTablerow = class  extends RtfItem {
    
    constructor() {
        super();
        this.props = new Array();
    }
    
    get isLast() {
        return this.props.includes("lastrow");
    }
    
    toString() {
        return (String(this.level) + ": TableRow" + (this.isLast ? " Last" : ""));
    }
}


RtfHelper.RtfListinf = class  extends RtfItem {
    
    constructor() {
        super();
        this.props = new Array();
    }
    
    toString() {
        return (String(this.level) + ": Listitem " + this.text);
    }
}


RtfHelper.RtfItemProxy = class  extends RtfItem {
    
    constructor() {
        super();
        this.uni = null;
    }
    
    static _new288(_arg1) {
        let res = new RtfHelper.RtfItemProxy();
        res.typ = _arg1;
        return res;
    }
}


RtfHelper.static_constructor();

module.exports = RtfHelper