/*
 * 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 StringBuilder = require("./../../unisharp/StringBuilder");

const GetTextAttr = require("./../core/GetTextAttr");
const ReferentsEqualType = require("./../core/ReferentsEqualType");
const Referent = require("./../Referent");
const PartTokenItemType = require("./internal/PartTokenItemType");
const ReferentClass = require("./../metadata/ReferentClass");
const MetaDecreePart = require("./internal/MetaDecreePart");
const MiscHelper = require("./../core/MiscHelper");

/**
 * Сущность, представляющая ссылку на структурную часть НПА
 * 
 */
class DecreePartReferent extends Referent {
    
    constructor() {
        super(DecreePartReferent.OBJ_TYPENAME);
        this.instanceOf = MetaDecreePart.GLOBAL_META;
    }
    
    toStringEx(shortVariant, lang = null, lev = 0) {
        let res = new StringBuilder();
        if (this.freetext !== null) 
            res.append(this.freetext);
        if (this.nameAsItem !== null) 
            res.append(" наименование");
        if (this.formula !== null) 
            res.append(" формула ").append(this.formula);
        if (this.subIndention !== null) 
            res.append(" подабз.").append(this.subIndention);
        if (this.indention !== null) 
            res.append(" абз.").append(this.indention);
        if (this.footnote !== null) 
            res.append(" сноска ").append(this.footnote);
        if (this.tableSubItem !== null) 
            res.append(" прографка \"").append(this.tableSubItem).append("\"");
        if (this.tableItem !== null) {
            if (this.tableItem.length > 5) 
                res.append(" графа \"").append(this.tableItem).append("\"");
            else 
                res.append(" графа ").append(this.tableItem);
        }
        if (this.tableRow !== null) {
            if (this.tableRow.length > 5) 
                res.append(" строка \"").append(this.tableRow).append("\"");
            else 
                res.append(" строка ").append(this.tableRow);
        }
        if (this.tableColumn !== null) 
            res.append(" столбец ").append(this.tableColumn);
        if (this.table !== null) {
            res.append(" таблица ").append(this.table);
            if (this.tableName !== null) 
                res.append(" \"").append(this.tableName).append("\"");
        }
        if (this.sentence !== null) 
            res.append(" предложение ").append(this.sentence);
        if (this.notice !== null) 
            res.append(" прим.").append(this.notice);
        let subs = this.getStringValues(DecreePartReferent.ATTR_SUBITEM);
        if (subs.length > 0) {
            for (const s of subs) {
                res.append(" пп.").append(s);
            }
        }
        if (this.item !== null) 
            res.append(" п.").append(this.item);
        if (this.part !== null) 
            res.append(" ч.").append(this.part);
        if (this.preamble !== null) 
            res.append(" преамб.").append((this.preamble === "0" ? "" : this.preamble));
        if (this.list !== null) 
            res.append(" лист ").append(this.list);
        if (this.form !== null) {
            res.append(" форма ").append(this.form);
            if (this.formName !== null) 
                res.append(" \"").append(this.formName).append("\"");
        }
        if (this.page !== null) 
            res.append(" стр.").append(this.page);
        if (this.clause !== null) {
            res.append(" ст.").append(this.clause);
            if (this.clauseName !== null) 
                res.append(" \"").append(this.clauseName).append("\"");
        }
        if (this.subParagraph !== null) 
            res.append(" подпар.").append(this.subParagraph);
        if (this.paragraph !== null) 
            res.append(" пар.").append(this.paragraph);
        if (this.chapter !== null) {
            res.append(" гл.").append(this.chapter);
            if (this.chapterName !== null) 
                res.append(" \"").append(this.chapterName).append("\"");
        }
        if (this.subSection !== null) {
            res.append(" подразд.").append(this.subSection);
            if (this.subSectionName !== null) 
                res.append(" \"").append(this.subSectionName).append("\"");
        }
        if (this.section !== null) {
            res.append(" разд.").append(this.section);
            if (this.sectionName !== null) 
                res.append(" \"").append(this.sectionName).append("\"");
        }
        if (this.docPart !== null) 
            res.append(" док.часть ").append(this.docPart);
        let app = this.appendix;
        let app2 = this.appendix2;
        if (app2 === null) {
            if (app === "0") 
                res.append(" приложение");
            else if (app !== null) 
                res.append(" приложение ").append(app);
            if (app !== null && this.appendixName !== null) 
                res.append(" \"").append(this.appendixName).append("\"");
        }
        else {
            if (app2 === "0") 
                res.append(" приложение к");
            else if (app2 !== null) 
                res.append(" приложение ").append(app2).append(" к");
            if (app === "0") 
                res.append(" приложению");
            else if (app !== null) 
                res.append(" приложению ").append(app);
        }
        if (this.subprogram !== null) {
            res.append(" подпрограмма ").append(this.subprogram);
            if (this.subprogramName !== null) 
                res.append(" \"").append(this.subprogramName).append("\"");
        }
        if (this.addagree !== null) {
            if (this.addagree === "0") 
                res.append(" допсоглашение");
            else 
                res.append(" допсоглашение ").append(this.addagree);
        }
        if (((this.owner !== null || res.length > 0)) && !shortVariant) {
            if (!shortVariant && this.subprogram === null) {
                let s = this.description;
                if (s !== null) 
                    res.append(" (").append(s).append(")");
            }
            if (this.owner !== null && (lev < 20)) {
                if (res.length > 0) 
                    res.append("; ");
                res.append(this.owner.toStringEx(shortVariant, lang, lev + 1));
            }
            else if (this.localTyp !== null) 
                res.append("; ").append(MiscHelper.convertFirstCharUpperAndOtherLower(this.localTyp));
        }
        return res.toString().trim();
    }
    
    get description() {
        return this.getStringValue(DecreePartReferent.ATTR_DESCRIPTION);
    }
    set description(value) {
        if (value !== null) 
            value = value.trim();
        if (Utils.isNullOrEmpty(value)) 
            value = null;
        this.addSlot(DecreePartReferent.ATTR_DESCRIPTION, value, true, 0);
        return value;
    }
    
    get localTyp() {
        return this.getStringValue(DecreePartReferent.ATTR_LOCALTYP);
    }
    set localTyp(value) {
        this.addSlot(DecreePartReferent.ATTR_LOCALTYP, value, true, 0);
        return value;
    }
    
    addSlot(attrName, attrValue, clearOldValue, statCount = 0) {
        const PartToken = require("./internal/PartToken");
        let _tag = null;
        if (attrValue instanceof PartToken.PartValue) {
            _tag = attrValue.sourceValue;
            attrValue = attrValue.value;
        }
        let s = super.addSlot(attrName, attrValue, clearOldValue, statCount);
        if (_tag !== null) 
            s.tag = _tag;
        return s;
    }
    
    get clause() {
        return this.getStringValue(DecreePartReferent.ATTR_CLAUSE);
    }
    set clause(value) {
        this.addSlot(DecreePartReferent.ATTR_CLAUSE, value, true, 0);
        return value;
    }
    
    get clauseName() {
        return this.getStringValue(DecreePartReferent.ATTR_CLAUSENAME);
    }
    set clauseName(value) {
        this.addSlot(DecreePartReferent.ATTR_CLAUSENAME, value, true, 0);
        return value;
    }
    
    get part() {
        return this.getStringValue(DecreePartReferent.ATTR_PART);
    }
    set part(value) {
        this.addSlot(DecreePartReferent.ATTR_PART, value, true, 0);
        return value;
    }
    
    get docPart() {
        return this.getStringValue(DecreePartReferent.ATTR_DOCPART);
    }
    set docPart(value) {
        this.addSlot(DecreePartReferent.ATTR_DOCPART, value, true, 0);
        return value;
    }
    
    get section() {
        return this.getStringValue(DecreePartReferent.ATTR_SECTION);
    }
    set section(value) {
        this.addSlot(DecreePartReferent.ATTR_SECTION, value, true, 0);
        return value;
    }
    
    get sectionName() {
        return this.getStringValue(DecreePartReferent.ATTR_SECTIONNAME);
    }
    set sectionName(value) {
        this.addSlot(DecreePartReferent.ATTR_SECTIONNAME, value, true, 0);
        return value;
    }
    
    get subSection() {
        return this.getStringValue(DecreePartReferent.ATTR_SUBSECTION);
    }
    set subSection(value) {
        this.addSlot(DecreePartReferent.ATTR_SUBSECTION, value, true, 0);
        return value;
    }
    
    get subSectionName() {
        return this.getStringValue(DecreePartReferent.ATTR_SUBSECTIONNAME);
    }
    set subSectionName(value) {
        this.addSlot(DecreePartReferent.ATTR_SUBSECTIONNAME, value, true, 0);
        return value;
    }
    
    get appendix() {
        return this.getStringValue(DecreePartReferent.ATTR_APPENDIX);
    }
    set appendix(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_APPENDIX, value, true, 0);
        return value;
    }
    
    get appendixName() {
        return this.getStringValue(DecreePartReferent.ATTR_APPENDIXNAME);
    }
    set appendixName(value) {
        this.addSlot(DecreePartReferent.ATTR_APPENDIXNAME, value, true, 0);
        return value;
    }
    
    get appendix2() {
        return this.getStringValue(DecreePartReferent.ATTR_APPENDIX2);
    }
    set appendix2(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_APPENDIX2, value, true, 0);
        return value;
    }
    
    get appendix2Name() {
        return this.getStringValue(DecreePartReferent.ATTR_APPENDIX2NAME);
    }
    set appendix2Name(value) {
        this.addSlot(DecreePartReferent.ATTR_APPENDIX2NAME, value, true, 0);
        return value;
    }
    
    get chapter() {
        return this.getStringValue(DecreePartReferent.ATTR_CHAPTER);
    }
    set chapter(value) {
        this.addSlot(DecreePartReferent.ATTR_CHAPTER, value, true, 0);
        return value;
    }
    
    get chapterName() {
        return this.getStringValue(DecreePartReferent.ATTR_CHAPTERNAME);
    }
    set chapterName(value) {
        this.addSlot(DecreePartReferent.ATTR_CHAPTERNAME, value, true, 0);
        return value;
    }
    
    get paragraph() {
        return this.getStringValue(DecreePartReferent.ATTR_PARAGRAPH);
    }
    set paragraph(value) {
        this.addSlot(DecreePartReferent.ATTR_PARAGRAPH, value, true, 0);
        return value;
    }
    
    get subParagraph() {
        return this.getStringValue(DecreePartReferent.ATTR_SUBPARAGRAPH);
    }
    set subParagraph(value) {
        this.addSlot(DecreePartReferent.ATTR_SUBPARAGRAPH, value, true, 0);
        return value;
    }
    
    get item() {
        return this.getStringValue(DecreePartReferent.ATTR_ITEM);
    }
    set item(value) {
        this.addSlot(DecreePartReferent.ATTR_ITEM, value, true, 0);
        return value;
    }
    
    get subItem() {
        return this.getStringValue(DecreePartReferent.ATTR_SUBITEM);
    }
    set subItem(value) {
        this.addSlot(DecreePartReferent.ATTR_SUBITEM, value, true, 0);
        return value;
    }
    
    get indention() {
        return this.getStringValue(DecreePartReferent.ATTR_INDENTION);
    }
    set indention(value) {
        this.addSlot(DecreePartReferent.ATTR_INDENTION, value, true, 0);
        return value;
    }
    
    get subIndention() {
        return this.getStringValue(DecreePartReferent.ATTR_SUBINDENTION);
    }
    set subIndention(value) {
        this.addSlot(DecreePartReferent.ATTR_SUBINDENTION, value, true, 0);
        return value;
    }
    
    get preamble() {
        return this.getStringValue(DecreePartReferent.ATTR_PREAMBLE);
    }
    set preamble(value) {
        this.addSlot(DecreePartReferent.ATTR_PREAMBLE, value, true, 0);
        return value;
    }
    
    get nameAsItem() {
        return this.getStringValue(DecreePartReferent.ATTR_NAMEASITEM);
    }
    set nameAsItem(value) {
        this.addSlot(DecreePartReferent.ATTR_NAMEASITEM, value, true, 0);
        return value;
    }
    
    get freetext() {
        return this.getStringValue(DecreePartReferent.ATTR_FREETEXT);
    }
    set freetext(value) {
        this.addSlot(DecreePartReferent.ATTR_FREETEXT, value, true, 0);
        return value;
    }
    
    get notice() {
        return this.getStringValue(DecreePartReferent.ATTR_NOTICE);
    }
    set notice(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_NOTICE, value, true, 0);
        return value;
    }
    
    get footnote() {
        return this.getStringValue(DecreePartReferent.ATTR_FOOTNOTE);
    }
    set footnote(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_FOOTNOTE, value, true, 0);
        return value;
    }
    
    get formula() {
        return this.getStringValue(DecreePartReferent.ATTR_FORMULA);
    }
    set formula(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_FORMULA, value, true, 0);
        return value;
    }
    
    get form() {
        return this.getStringValue(DecreePartReferent.ATTR_FORM);
    }
    set form(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_FORM, value, true, 0);
        return value;
    }
    
    get formName() {
        return this.getStringValue(DecreePartReferent.ATTR_FORMNAME);
    }
    set formName(value) {
        this.addSlot(DecreePartReferent.ATTR_FORMNAME, value, true, 0);
        return value;
    }
    
    get list() {
        return this.getStringValue(DecreePartReferent.ATTR_LIST);
    }
    set list(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_LIST, value, true, 0);
        return value;
    }
    
    get table() {
        return this.getStringValue(DecreePartReferent.ATTR_TABLE);
    }
    set table(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_TABLE, value, true, 0);
        return value;
    }
    
    get tableName() {
        return this.getStringValue(DecreePartReferent.ATTR_TABLENAME);
    }
    set tableName(value) {
        this.addSlot(DecreePartReferent.ATTR_TABLENAME, value, true, 0);
        return value;
    }
    
    get tableColumn() {
        return this.getStringValue(DecreePartReferent.ATTR_TABLECOLUMN);
    }
    set tableColumn(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_TABLECOLUMN, value, true, 0);
        return value;
    }
    
    get tableRow() {
        return this.getStringValue(DecreePartReferent.ATTR_TABLEROW);
    }
    set tableRow(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_TABLEROW, value, true, 0);
        return value;
    }
    
    get tableItem() {
        return this.getStringValue(DecreePartReferent.ATTR_TABLEITEM);
    }
    set tableItem(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_TABLEITEM, value, true, 0);
        return value;
    }
    
    get tableSubItem() {
        return this.getStringValue(DecreePartReferent.ATTR_TABLESUBITEM);
    }
    set tableSubItem(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_TABLESUBITEM, value, true, 0);
        return value;
    }
    
    get sentence() {
        return this.getStringValue(DecreePartReferent.ATTR_SENTENCE);
    }
    set sentence(value) {
        if (value !== null && value.length === 0) 
            value = "0";
        this.addSlot(DecreePartReferent.ATTR_SENTENCE, value, true, 0);
        return value;
    }
    
    get page() {
        return this.getStringValue(DecreePartReferent.ATTR_PAGE);
    }
    set page(value) {
        this.addSlot(DecreePartReferent.ATTR_PAGE, value, true, 0);
        return value;
    }
    
    get subprogram() {
        return this.getStringValue(DecreePartReferent.ATTR_SUBPROGRAM);
    }
    set subprogram(value) {
        this.addSlot(DecreePartReferent.ATTR_SUBPROGRAM, value, true, 0);
        return value;
    }
    
    get subprogramName() {
        return this.getStringValue(DecreePartReferent.ATTR_SUBPROGRAMNAME);
    }
    set subprogramName(value) {
        this.addSlot(DecreePartReferent.ATTR_SUBPROGRAMNAME, value, true, 0);
        return value;
    }
    
    get addagree() {
        return this.getStringValue(DecreePartReferent.ATTR_ADDAGREE);
    }
    set addagree(value) {
        this.addSlot(DecreePartReferent.ATTR_ADDAGREE, value, true, 0);
        return value;
    }
    
    get owner() {
        const DecreeReferent = require("./DecreeReferent");
        let res = Utils.as(this.getSlotValue(DecreePartReferent.ATTR_OWNER), DecreeReferent);
        if (res === null) 
            return null;
        return res;
    }
    set owner(value) {
        this.addSlot(DecreePartReferent.ATTR_OWNER, value, true, 0);
        if (value !== null && this.localTyp !== null) 
            this.localTyp = null;
        return value;
    }
    
    get parentReferent() {
        return this.owner;
    }
    
    mergeSlots(obj, mergeStatistic = true) {
        super.mergeSlots(obj, mergeStatistic);
        if (this.owner !== null && this.localTyp !== null) 
            this.localTyp = null;
    }
    
    _getLevel(typ) {
        if (typ === DecreePartReferent.ATTR_ADDAGREE || typ === DecreePartReferent.ATTR_SUBPROGRAM) 
            return 0;
        if (typ === DecreePartReferent.ATTR_DOCPART) 
            return 1;
        if (typ === DecreePartReferent.ATTR_APPENDIX || typ === DecreePartReferent.ATTR_APPENDIXNAME) 
            return 1;
        if (typ === DecreePartReferent.ATTR_APPENDIX2 || typ === DecreePartReferent.ATTR_APPENDIX2NAME) 
            return 2;
        if (typ === DecreePartReferent.ATTR_SUBPROGRAM || typ === DecreePartReferent.ATTR_SUBPROGRAMNAME) 
            return 2;
        if (typ === DecreePartReferent.ATTR_SECTION || typ === DecreePartReferent.ATTR_SECTIONNAME) 
            return 2;
        if (typ === DecreePartReferent.ATTR_SUBSECTION || typ === DecreePartReferent.ATTR_SUBSECTIONNAME) 
            return 3;
        if (typ === DecreePartReferent.ATTR_CHAPTER || typ === DecreePartReferent.ATTR_CHAPTERNAME) 
            return 4;
        if (typ === DecreePartReferent.ATTR_PARAGRAPH) 
            return 5;
        if (typ === DecreePartReferent.ATTR_SUBPARAGRAPH) 
            return 6;
        if (typ === DecreePartReferent.ATTR_PAGE) 
            return 6;
        if (typ === DecreePartReferent.ATTR_CLAUSE) 
            return 7;
        if (typ === DecreePartReferent.ATTR_FORM || typ === DecreePartReferent.ATTR_FORMNAME) 
            return 8;
        if (typ === DecreePartReferent.ATTR_TABLE || typ === DecreePartReferent.ATTR_TABLENAME) 
            return 8;
        if (typ === DecreePartReferent.ATTR_LIST) 
            return 9;
        if (typ === DecreePartReferent.ATTR_PREAMBLE) 
            return 9;
        if (typ === DecreePartReferent.ATTR_PART) 
            return 9;
        if (typ === DecreePartReferent.ATTR_NOTICE) 
            return 10;
        if (typ === DecreePartReferent.ATTR_ITEM) 
            return 11;
        if (typ === DecreePartReferent.ATTR_TABLEROW) 
            return 11;
        if (typ === DecreePartReferent.ATTR_TABLEITEM) 
            return 11;
        if (typ === DecreePartReferent.ATTR_TABLESUBITEM) 
            return 12;
        if (typ === DecreePartReferent.ATTR_SUBITEM) 
            return 12;
        if (typ === DecreePartReferent.ATTR_INDENTION) 
            return 13;
        if (typ === DecreePartReferent.ATTR_SUBINDENTION) 
            return 14;
        if (typ === DecreePartReferent.ATTR_SENTENCE) 
            return 15;
        if (typ === DecreePartReferent.ATTR_FORMULA) 
            return 15;
        if (typ === DecreePartReferent.ATTR_TABLECOLUMN) 
            return 17;
        if (typ === DecreePartReferent.ATTR_FOOTNOTE) 
            return 17;
        if (typ === DecreePartReferent.ATTR_NAMEASITEM) 
            return 18;
        if (typ === DecreePartReferent.ATTR_FREETEXT) 
            return 19;
        return -1;
    }
    
    _hasLessLevelAttr(typ) {
        let l = this._getLevel(typ);
        if (l < 0) 
            return false;
        for (const s of this.slots) {
            let l1 = this._getLevel(s.typeName);
            if (l1 >= 0 && l1 > l) 
                return true;
        }
        return false;
    }
    
    addName(p, val = null) {
        if (p === null || ((p.name === null && val === null))) 
            return;
        let typ = null;
        let typ1 = null;
        if (p.typ === PartTokenItemType.APPENDIX) 
            typ = DecreePartReferent.ATTR_APPENDIXNAME;
        else if (p.typ === PartTokenItemType.APPENDIX2) 
            typ = DecreePartReferent.ATTR_APPENDIX2NAME;
        else if (p.typ === PartTokenItemType.SECTION) 
            typ = DecreePartReferent.ATTR_SECTIONNAME;
        else if (p.typ === PartTokenItemType.SUBSECTION) 
            typ = DecreePartReferent.ATTR_SUBSECTIONNAME;
        else if (p.typ === PartTokenItemType.SUBPROGRAM) 
            typ = DecreePartReferent.ATTR_SUBPROGRAMNAME;
        else if (p.typ === PartTokenItemType.CHAPTER) 
            typ = DecreePartReferent.ATTR_CHAPTERNAME;
        else if (p.typ === PartTokenItemType.CLAUSE) 
            typ = DecreePartReferent.ATTR_CLAUSENAME;
        else if (p.typ === PartTokenItemType.FORM) 
            typ = DecreePartReferent.ATTR_FORMNAME;
        else if (p.typ === PartTokenItemType.TABLE) 
            typ = DecreePartReferent.ATTR_TABLENAME;
        else 
            return;
        if (val === null) 
            val = p.name;
        let nam = MiscHelper.getTextValueOfMetaToken(val, GetTextAttr.FIRSTNOUNGROUPTONOMINATIVE);
        let s = this.addSlot(typ, nam, true, 0);
        if (val !== null) 
            s.tag = val.getSourceText();
        if (p.values.length === 0) 
            this.addSlot(typ.substring(0, 0 + typ.length - 4), "0", true, 0);
    }
    
    addNamedLevelInfo(dp) {
        for (const s of dp.slots) {
            if (this._getLevel(s.typeName) > 7 || s.typeName === DecreePartReferent.ATTR_DOCPART) {
            }
            else 
                this.addSlot(s.typeName, s.value, false, 0);
        }
    }
    
    _addSlot(dp, attr) {
        let s = dp.findSlot(attr, null, true);
        if (s === null) 
            return;
        let ss = this.addSlot(attr, s.value, true, 0);
        ss.tag = s.tag;
    }
    
    // Добавить информацию о вышележащих элементах
    addHighLevelInfo(dp) {
        if (dp.addagree !== null && this.addagree === null) 
            this.addagree = dp.addagree;
        else if (dp.addagree !== this.addagree) 
            return;
        if (dp.appendix !== null && this.appendix === null) {
            this._addSlot(dp, DecreePartReferent.ATTR_APPENDIX);
            this._addSlot(dp, DecreePartReferent.ATTR_APPENDIXNAME);
        }
        else if (this.appendix !== dp.appendix) 
            return;
        else if (this.appendix === "0" && this.appendixName !== dp.appendixName) 
            return;
        if (dp.appendix2 !== null && this.appendix2 === null) {
            this._addSlot(dp, DecreePartReferent.ATTR_APPENDIX2);
            this._addSlot(dp, DecreePartReferent.ATTR_APPENDIX2NAME);
        }
        else if (this.appendix2 !== dp.appendix2) 
            return;
        else if (this.appendix2 === "0" && this.appendix2Name !== dp.appendix2Name) 
            return;
        if (dp.subprogram !== null && this.subprogram === null) {
            this._addSlot(dp, DecreePartReferent.ATTR_SUBPROGRAM);
            this._addSlot(dp, DecreePartReferent.ATTR_SUBPROGRAMNAME);
        }
        else if (this.subprogram !== dp.subprogram) 
            return;
        if (this.subprogramName !== dp.subprogramName) 
            return;
        if (dp.docPart !== null && this.docPart === null) 
            this._addSlot(dp, DecreePartReferent.ATTR_DOCPART);
        else if (this.docPart !== dp.docPart) {
            if (dp.docPart !== null) 
                return;
        }
        if (dp.section !== null && this.section === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_SECTION)) {
            this._addSlot(dp, DecreePartReferent.ATTR_SECTION);
            this._addSlot(dp, DecreePartReferent.ATTR_SECTIONNAME);
        }
        else if (this.section !== dp.section) 
            return;
        else if (this.section === "0" && this.sectionName !== dp.sectionName) 
            return;
        if (dp.subSection !== null && this.subSection === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_SUBSECTION)) {
            this._addSlot(dp, DecreePartReferent.ATTR_SUBSECTION);
            this._addSlot(dp, DecreePartReferent.ATTR_SUBSECTIONNAME);
        }
        else if (this.subSection !== dp.subSection) 
            return;
        else if (this.subSection === "0" && this.subSectionName !== dp.subSectionName) 
            return;
        if (dp.chapter !== null && this.chapter === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_CHAPTER)) {
            this._addSlot(dp, DecreePartReferent.ATTR_CHAPTER);
            this._addSlot(dp, DecreePartReferent.ATTR_CHAPTERNAME);
        }
        else if (dp.chapter !== this.chapter) 
            return;
        else if (dp.chapter === "0" && dp.chapterName !== this.chapterName) 
            return;
        if (dp.paragraph !== null && this.paragraph === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_PARAGRAPH)) 
            this._addSlot(dp, DecreePartReferent.ATTR_PARAGRAPH);
        else if (this.paragraph !== dp.paragraph) 
            return;
        if (dp.subParagraph !== null && this.subParagraph === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_SUBPARAGRAPH)) 
            this.subParagraph = dp.subParagraph;
        else if (this.subParagraph !== dp.subParagraph) 
            return;
        if (dp.clause !== null && this.clause === null && ((this._hasLessLevelAttr(DecreePartReferent.ATTR_CLAUSE) || (this.slots.length < 2)))) 
            this._addSlot(dp, DecreePartReferent.ATTR_CLAUSE);
        else if (dp.clause !== this.clause) 
            return;
        if (dp.part !== null && this.part === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_PART)) 
            this._addSlot(dp, DecreePartReferent.ATTR_PART);
        else if (dp.part !== this.part) 
            return;
        if (dp.form !== null && this.form === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_FORM)) {
            this._addSlot(dp, DecreePartReferent.ATTR_FORM);
            this._addSlot(dp, DecreePartReferent.ATTR_FORMNAME);
        }
        if (dp.table !== null && this.table === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_TABLE)) {
            this._addSlot(dp, DecreePartReferent.ATTR_TABLE);
            this._addSlot(dp, DecreePartReferent.ATTR_TABLENAME);
        }
        if (dp.list !== null && this.list === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_LIST)) 
            this._addSlot(dp, DecreePartReferent.ATTR_LIST);
        if (dp.item !== null && this.item === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_ITEM)) 
            this._addSlot(dp, DecreePartReferent.ATTR_ITEM);
        else if (dp.item !== this.item) {
            if ((dp.tableItem !== null && dp.item === null && this.tableRow === null) && this.item !== null) {
                this.tableRow = this.item;
                this.item = null;
            }
            else if ((dp.item !== null && this.item === null && this.tableRow === null) && ((dp.tableItem !== null || this.tableItem !== null))) 
                this.tableRow = dp.item;
            else 
                return;
        }
        if (dp.tableRow !== null && this.tableRow === null && ((this._hasLessLevelAttr(DecreePartReferent.ATTR_TABLEROW) || this.tableItem !== null))) 
            this._addSlot(dp, DecreePartReferent.ATTR_TABLEROW);
        if (dp.subItem !== null && this.subItem === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_SUBITEM)) 
            this._addSlot(dp, DecreePartReferent.ATTR_SUBITEM);
        else if (dp.subItem !== this.subItem) 
            return;
        if (dp.notice !== null && this.notice === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_NOTICE)) 
            this._addSlot(dp, DecreePartReferent.ATTR_NOTICE);
        else if (dp.notice !== this.notice) 
            return;
        if (dp.preamble !== null && this.preamble === null) 
            this._addSlot(dp, DecreePartReferent.ATTR_PREAMBLE);
        if (dp.indention !== null && this.indention === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_INDENTION)) 
            this._addSlot(dp, DecreePartReferent.ATTR_INDENTION);
        if (dp.tableColumn !== null && this.tableColumn === null && this._hasLessLevelAttr(DecreePartReferent.ATTR_TABLECOLUMN)) 
            this._addSlot(dp, DecreePartReferent.ATTR_TABLECOLUMN);
        if (dp.tableItem !== null && this.tableItem === null && ((this._hasLessLevelAttr(DecreePartReferent.ATTR_TABLEITEM) || this.tableRow !== null || this.item !== null))) 
            this._addSlot(dp, DecreePartReferent.ATTR_TABLEITEM);
        if (dp.tableSubItem !== null && this.tableSubItem === null && ((this._hasLessLevelAttr(DecreePartReferent.ATTR_TABLESUBITEM) || this.tableRow !== null || this.item !== null))) 
            this._addSlot(dp, DecreePartReferent.ATTR_TABLESUBITEM);
    }
    
    // Проверить, что все элементы находятся на более низком уровне, чем у аргумента
    isAllItemsLessLevel(upperParts, ignoreEquals) {
        const DecreeReferent = require("./DecreeReferent");
        if (upperParts instanceof DecreeReferent) 
            return true;
        let maxLev = 0;
        let maxTyp = null;
        for (const s of this.slots) {
            let l = this._getLevel(s.typeName);
            if (l > maxLev) {
                maxLev = l;
                maxTyp = s.typeName;
            }
        }
        for (const s of this.slots) {
            let l = this._getLevel(s.typeName);
            if (l < 0) 
                continue;
            if (upperParts.findSlot(s.typeName, null, true) !== null) {
                if (ignoreEquals) {
                    if (l === maxLev) 
                        continue;
                }
                if (upperParts.findSlot(s.typeName, s.value, true) === null) 
                    return false;
                continue;
            }
            for (const ss of upperParts.slots) {
                let ll = this._getLevel(ss.typeName);
                if (ll >= l) 
                    return false;
            }
        }
        return true;
    }
    
    // удалить все значения уровня больше или равно
    removeSlots(typ) {
        const PartToken = require("./internal/PartToken");
        let l0 = this._getLevel(PartToken._getAttrNameByTyp(typ));
        if (l0 <= 0) 
            return;
        for (let i = this.slots.length - 1; i >= 0; i--) {
            let l = this._getLevel(this.slots[i].typeName);
            if (l >= l0) {
                if (((typ === PartTokenItemType.TABLEITEM || typ === PartTokenItemType.TABLESUBITEM)) && ((this.slots[i].typeName === "TABLEROW" || this.slots[i].typeName === "ITEM"))) {
                }
                else if (((typ === PartTokenItemType.TABLEROW || typ === PartTokenItemType.ITEM)) && this.slots[i].typeName === "TABLEITEM") {
                }
                else 
                    this.slots.splice(i, 1);
            }
        }
    }
    
    isAllItemsOverThisLevel(typ) {
        const PartToken = require("./internal/PartToken");
        let l0 = this._getLevel(PartToken._getAttrNameByTyp(typ));
        if (l0 <= 0) 
            return false;
        for (const s of this.slots) {
            let l = this._getLevel(s.typeName);
            if (l <= 0) 
                continue;
            if (l >= l0) {
                if (typ === PartTokenItemType.FOOTNOTE && l > l0) {
                }
                else 
                    return false;
            }
        }
        return true;
    }
    
    getMinLevel() {
        let min = 0;
        for (const s of this.slots) {
            let l = this._getLevel(s.typeName);
            if (l <= 0) 
                continue;
            if (min === 0) 
                min = l;
            else if (min > l) 
                min = l;
        }
        return min;
    }
    
    canBeEquals(obj, typ) {
        let b = this._CanBeEquals(obj, typ, false);
        return b;
    }
    
    _CanBeEquals(obj, typ, ignoreGeo) {
        let dr = Utils.as(obj, DecreePartReferent);
        if (dr === null) 
            return false;
        if (this.owner !== null && dr.owner !== null) {
            if (this.owner !== dr.owner) 
                return false;
        }
        else if (typ === ReferentsEqualType.DIFFERENTTEXTS) 
            return false;
        else {
            let ty1 = (this.owner === null ? this.localTyp : this.owner.typ);
            let ty2 = (dr.owner === null ? dr.localTyp : dr.owner.typ);
            if (ty1 !== ty2) {
                ty1 = (this.owner === null ? this.localTyp : this.owner.typ0);
                ty2 = (dr.owner === null ? dr.localTyp : dr.owner.typ0);
                if (ty1 !== ty2) 
                    return false;
            }
        }
        if (this.clause !== dr.clause) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.clause === null || dr.clause === null))) {
            }
            else 
                return false;
        }
        else if (this.clause === "0" && this.clauseName !== dr.clauseName) 
            return false;
        if (this.part !== dr.part) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.part === null || dr.part === null))) {
            }
            else 
                return false;
        }
        if (this.paragraph !== dr.paragraph) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.paragraph === null || dr.paragraph === null))) {
            }
            else 
                return false;
        }
        if (this.subParagraph !== dr.subParagraph) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.subParagraph === null || dr.subParagraph === null))) {
            }
            else 
                return false;
        }
        if (this.nameAsItem !== dr.nameAsItem) 
            return false;
        if (this.item !== dr.item) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.item === null || dr.item === null))) {
            }
            else 
                return false;
        }
        if (this.freetext !== dr.freetext) 
            return false;
        if (this.subItem !== dr.subItem) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.subItem === null || dr.subItem === null))) {
            }
            else 
                return false;
        }
        if (this.notice !== dr.notice) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.notice === null || dr.notice === null))) {
            }
            else 
                return false;
        }
        if (this.footnote !== dr.footnote) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.footnote === null || dr.footnote === null))) {
            }
            else 
                return false;
        }
        if (this.form !== dr.form) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.form === null || dr.form === null))) {
            }
            else 
                return false;
        }
        if (this.form === "0" && this.formName !== dr.formName) 
            return false;
        if (this.list !== dr.list) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.list === null || dr.list === null))) {
            }
            else 
                return false;
        }
        if (this.table !== dr.table) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.table === null || dr.table === null))) {
            }
            else 
                return false;
        }
        if (this.table === "0" && this.tableName !== dr.tableName) 
            return false;
        if (this.tableColumn !== dr.tableColumn) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.tableColumn === null || dr.tableColumn === null))) {
            }
            else 
                return false;
        }
        if (this.tableRow !== dr.tableRow) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.tableRow === null || dr.tableRow === null))) {
            }
            else 
                return false;
        }
        if (this.tableItem !== dr.tableItem) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.tableItem === null || dr.tableItem === null))) {
            }
            else 
                return false;
        }
        if (this.tableSubItem !== dr.tableSubItem) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.tableSubItem === null || dr.tableSubItem === null))) {
            }
            else 
                return false;
        }
        if (this.formula !== dr.formula) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.formula === null || dr.formula === null))) {
            }
            else 
                return false;
        }
        if (this.sentence !== dr.sentence) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.sentence === null || dr.sentence === null))) {
            }
            else 
                return false;
        }
        if (this.indention !== dr.indention) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.indention === null || dr.indention === null))) {
            }
            else 
                return false;
        }
        if (this.subIndention !== dr.subIndention) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.subIndention === null || dr.subIndention === null))) {
            }
            else 
                return false;
        }
        if (this.appendix !== dr.appendix) {
            if (this.appendix !== null && dr.appendix !== null) 
                return false;
            if (this.clause === null && this.paragraph === null && this.item === null) 
                return false;
            if (typ !== ReferentsEqualType.FORMERGING) 
                return false;
        }
        if (this.appendixName !== dr.appendixName && this.appendixName !== null && dr.appendixName !== null) 
            return false;
        if (this.appendix2 !== dr.appendix2) {
            if (this.appendix2 !== null && dr.appendix2 !== null) 
                return false;
            if (this.clause === null && this.paragraph === null && this.item === null) 
                return false;
            if (typ !== ReferentsEqualType.FORMERGING) 
                return false;
        }
        if (this.appendix2Name !== dr.appendix2Name) 
            return false;
        if (this.chapter !== dr.chapter) {
            if (this.chapter !== null && dr.chapter !== null) 
                return false;
            if (this.clause === null && this.paragraph === null && this.item === null) 
                return false;
            if (typ !== ReferentsEqualType.FORMERGING) 
                return false;
        }
        if (this.chapter === "0" && this.chapterName !== dr.chapterName) 
            return false;
        if (this.section !== dr.section) {
            if (this.section !== null && dr.section !== null) 
                return false;
            if ((this.clause === null && this.paragraph === null && this.item === null) && this.subSection === null) 
                return false;
            if (typ !== ReferentsEqualType.FORMERGING) 
                return false;
        }
        if (this.section === "0" && this.sectionName !== dr.sectionName) 
            return false;
        if (this.subSection !== dr.subSection) {
            if (this.subSection !== null && dr.subSection !== null) 
                return false;
            if (this.clause === null && this.paragraph === null && this.item === null) 
                return false;
            if (typ !== ReferentsEqualType.FORMERGING) 
                return false;
        }
        if (this.subSection === "0" && this.subSectionName !== dr.subSectionName) 
            return false;
        if (this.subprogram !== null || dr.subprogram !== null) {
            if (this.subprogram !== dr.subprogram) 
                return false;
            if (this.subprogramName !== dr.subprogramName) 
                return false;
            return true;
        }
        if (this.addagree !== null || dr.addagree !== null) {
            if (this.addagree !== dr.addagree) 
                return false;
        }
        if (this.docPart !== dr.docPart) {
            if (typ === ReferentsEqualType.FORMERGING && ((this.docPart === null || dr.docPart === null))) {
            }
            else 
                return false;
        }
        if (this.page !== dr.page) 
            return false;
        return true;
    }
    
    static createRangeReferent(min, max) {
        let res = Utils.as(min.clone(), DecreePartReferent);
        let cou = 0;
        for (const s of res.slots) {
            let ss = max.findSlot(s.typeName, null, true);
            if (ss === null) 
                return null;
            if (ss.value === s.value) 
                continue;
            if (max.findSlot(s.typeName, s.value, true) !== null) 
                continue;
            if ((++cou) > 1) 
                return null;
            res.uploadSlot(s, (String(s.value) + "-" + ss.value));
        }
        if (cou !== 1) 
            return null;
        return res;
    }
    
    static _new1460(_arg1) {
        let res = new DecreePartReferent();
        res.owner = _arg1;
        return res;
    }
    
    static static_constructor() {
        DecreePartReferent.OBJ_TYPENAME = "DECREEPART";
        DecreePartReferent.ATTR_OWNER = "OWNER";
        DecreePartReferent.ATTR_LOCALTYP = "LOCALTYP";
        DecreePartReferent.ATTR_DOCPART = "DOCPART";
        DecreePartReferent.ATTR_APPENDIX = "APPENDIX";
        DecreePartReferent.ATTR_APPENDIXNAME = "APPENDIXNAME";
        DecreePartReferent.ATTR_APPENDIX2 = "APPENDIX2";
        DecreePartReferent.ATTR_APPENDIX2NAME = "APPENDIX2NAME";
        DecreePartReferent.ATTR_SECTION = "SECTION";
        DecreePartReferent.ATTR_SECTIONNAME = "SECTIONNAME";
        DecreePartReferent.ATTR_SUBSECTION = "SUBSECTION";
        DecreePartReferent.ATTR_SUBSECTIONNAME = "SUBSECTIONNAME";
        DecreePartReferent.ATTR_CHAPTER = "CHAPTER";
        DecreePartReferent.ATTR_CHAPTERNAME = "CHAPTERNAME";
        DecreePartReferent.ATTR_CLAUSE = "CLAUSE";
        DecreePartReferent.ATTR_CLAUSENAME = "CLAUSENAME";
        DecreePartReferent.ATTR_PARAGRAPH = "PARAGRAPH";
        DecreePartReferent.ATTR_SUBPARAGRAPH = "SUBPARAGRAPH";
        DecreePartReferent.ATTR_PART = "PART";
        DecreePartReferent.ATTR_ITEM = "ITEM";
        DecreePartReferent.ATTR_SUBITEM = "SUBITEM";
        DecreePartReferent.ATTR_INDENTION = "INDENTION";
        DecreePartReferent.ATTR_SUBINDENTION = "SUBINDENTION";
        DecreePartReferent.ATTR_PREAMBLE = "PREAMPLE";
        DecreePartReferent.ATTR_NOTICE = "NOTICE";
        DecreePartReferent.ATTR_FOOTNOTE = "FOOTNOTE";
        DecreePartReferent.ATTR_FORMULA = "FORMULA";
        DecreePartReferent.ATTR_FORM = "FORM";
        DecreePartReferent.ATTR_FORMNAME = "FORMNAME";
        DecreePartReferent.ATTR_LIST = "LIST";
        DecreePartReferent.ATTR_TABLE = "TABLE";
        DecreePartReferent.ATTR_TABLENAME = "TABLENAME";
        DecreePartReferent.ATTR_TABLECOLUMN = "TABLECOLUMN";
        DecreePartReferent.ATTR_TABLEROW = "TABLEROW";
        DecreePartReferent.ATTR_TABLEITEM = "TABLEITEM";
        DecreePartReferent.ATTR_TABLESUBITEM = "TABLESUBITEM";
        DecreePartReferent.ATTR_SENTENCE = "SENTENCE";
        DecreePartReferent.ATTR_NAMEASITEM = "NAMEASITEM";
        DecreePartReferent.ATTR_SUBPROGRAM = "SUBPROGRAM";
        DecreePartReferent.ATTR_SUBPROGRAMNAME = "SUBPROGRAMNAME";
        DecreePartReferent.ATTR_ADDAGREE = "ADDAGREE";
        DecreePartReferent.ATTR_FREETEXT = "FREETEXT";
        DecreePartReferent.ATTR_PAGE = "PAGE";
        DecreePartReferent.ATTR_DESCRIPTION = "DESCRIPTION";
    }
}


DecreePartReferent.static_constructor();

module.exports = DecreePartReferent