react-xml-viewer
Version:
Simple xml viewer component for React
1,428 lines • 68.8 kB
JavaScript
import { jsx as f, jsxs as w, Fragment as se } from "react/jsx-runtime";
import * as J from "react";
import { useRef as $, useEffect as x, useCallback as L, createContext as ie, useState as _, useMemo as k, useContext as oe, memo as Se } from "react";
const Q = ":@", R = "#text", K = "#comment", Z = "#cdata", ae = "DECLARATION_TAG", xe = "TAG", F = {
tagColor: "#d43900",
textColor: "#333",
attributeKeyColor: "#2a7ab0",
attributeValueColor: "#008000",
separatorColor: "#333",
commentColor: "#aaa",
cdataColor: "#1d781d",
fontFamily: "monospace",
lineNumberBackground: "#eee",
lineNumberColor: "#222"
};
function le(n, e) {
const t = $(n), r = $();
return x(() => {
t.current = n;
}, [n]), x(() => () => {
r.current && clearTimeout(r.current);
}, []), L(
(...i) => {
r.current && clearTimeout(r.current), r.current = setTimeout(() => {
t.current(...i);
}, e);
},
[e]
);
}
const Ae = {
lines: {},
push: () => {
}
}, ue = ie(Ae), Pe = ({ children: n, enabled: e = !1 }) => {
const [t, r] = _({}), i = $({}), s = L(() => {
r(i.current);
}, []), l = le(s, 100), a = L((c, u) => {
var h;
e && (((h = i.current[c]) == null ? void 0 : h.element) !== u.element && (i.current[c] = u), l());
}, []), o = k(() => ({ lines: t, push: a }), [t, a, e]);
return /* @__PURE__ */ f(ue.Provider, { value: o, children: n });
}, ce = () => oe(ue), Oe = {
theme: F,
collapsible: !1,
indentSize: 2
}, he = ie(Oe), T = () => oe(he);
function $e(n, e) {
return new Array(e * n + 1).join(" ");
}
function fe(n) {
return typeof n == "string" && n.includes(`
`);
}
function _e(n) {
return typeof n == "string" ? !1 : n.length === 1 && R in n[0] && !fe(n[0][R]);
}
function ke(n) {
switch (n) {
case R:
case Z:
case K:
return n;
default:
return n.startsWith("?") ? ae : xe;
}
}
function Me(n, e) {
const t = {};
for (const r in n)
r !== e && (t[r] = n[r]);
return t;
}
function Ve(n) {
const e = n[Q], t = Me(n, Q), [[r, i]] = Object.entries(t), s = ke(r);
return { attributes: e, tagKey: r, subElements: i, type: s };
}
function Le(n, e) {
return Object.keys(F).every((r) => n[r] === e[r]);
}
const de = ":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD", Re = de + "\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040", Fe = "[" + de + "][" + Re + "]*", je = new RegExp("^" + Fe + "$");
function pe(n, e) {
const t = [];
let r = e.exec(n);
for (; r; ) {
const i = [];
i.startIndex = e.lastIndex - r[0].length;
const s = r.length;
for (let l = 0; l < s; l++)
i.push(r[l]);
t.push(i), r = e.exec(n);
}
return t;
}
const U = function(n) {
const e = je.exec(n);
return !(e === null || typeof e > "u");
};
function Ue(n) {
return typeof n < "u";
}
const q = [
// '__proto__',
// 'constructor',
// 'prototype',
"hasOwnProperty",
"toString",
"valueOf",
"__defineGetter__",
"__defineSetter__",
"__lookupGetter__",
"__lookupSetter__"
], ge = ["__proto__", "constructor", "prototype"], Be = {
allowBooleanAttributes: !1,
//A tag can have attributes without any value
unpairedTags: []
};
function be(n, e) {
e = Object.assign({}, Be, e);
const t = [];
let r = !1, i = !1;
n[0] === "\uFEFF" && (n = n.substr(1));
for (let s = 0; s < n.length; s++)
if (n[s] === "<" && n[s + 1] === "?") {
if (s += 2, s = D(n, s), s.err)
return s;
} else if (n[s] === "<") {
let l = s;
if (s++, n[s] === "!") {
s = ee(n, s);
continue;
} else {
let a = !1;
n[s] === "/" && (a = !0, s++);
let o = "";
for (; s < n.length && n[s] !== ">" && n[s] !== " " && n[s] !== " " && n[s] !== `
` && n[s] !== "\r"; s++)
o += n[s];
if (o = o.trim(), o[o.length - 1] === "/" && (o = o.substring(0, o.length - 1), s--), !qe(o)) {
let h;
return o.trim().length === 0 ? h = "Invalid space after '<'." : h = "Tag '" + o + "' is an invalid name.", b("InvalidTag", h, m(n, s));
}
const c = Ye(n, s);
if (c === !1)
return b("InvalidAttr", "Attributes for '" + o + "' have open quote.", m(n, s));
let u = c.value;
if (s = c.index, u[u.length - 1] === "/") {
const h = s - u.length;
u = u.substring(0, u.length - 1);
const d = te(u, e);
if (d === !0)
r = !0;
else
return b(d.err.code, d.err.msg, m(n, h + d.err.line));
} else if (a)
if (c.tagClosed) {
if (u.trim().length > 0)
return b("InvalidTag", "Closing tag '" + o + "' can't have attributes or invalid starting.", m(n, l));
if (t.length === 0)
return b("InvalidTag", "Closing tag '" + o + "' has not been opened.", m(n, l));
{
const h = t.pop();
if (o !== h.tagName) {
let d = m(n, h.tagStartPos);
return b(
"InvalidTag",
"Expected closing tag '" + h.tagName + "' (opened in line " + d.line + ", col " + d.col + ") instead of closing tag '" + o + "'.",
m(n, l)
);
}
t.length == 0 && (i = !0);
}
} else
return b("InvalidTag", "Closing tag '" + o + "' doesn't have proper closing.", m(n, s));
else {
const h = te(u, e);
if (h !== !0)
return b(h.err.code, h.err.msg, m(n, s - u.length + h.err.line));
if (i === !0)
return b("InvalidXml", "Multiple possible root nodes found.", m(n, s));
e.unpairedTags.indexOf(o) !== -1 || t.push({ tagName: o, tagStartPos: l }), r = !0;
}
for (s++; s < n.length; s++)
if (n[s] === "<")
if (n[s + 1] === "!") {
s++, s = ee(n, s);
continue;
} else if (n[s + 1] === "?") {
if (s = D(n, ++s), s.err)
return s;
} else
break;
else if (n[s] === "&") {
const h = Ke(n, s);
if (h == -1)
return b("InvalidChar", "char '&' is not expected.", m(n, s));
s = h;
} else if (i === !0 && !H(n[s]))
return b("InvalidXml", "Extra text at the end", m(n, s));
n[s] === "<" && s--;
}
} else {
if (H(n[s]))
continue;
return b("InvalidChar", "char '" + n[s] + "' is not expected.", m(n, s));
}
if (r) {
if (t.length == 1)
return b("InvalidTag", "Unclosed tag '" + t[0].tagName + "'.", m(n, t[0].tagStartPos));
if (t.length > 0)
return b("InvalidXml", "Invalid '" + JSON.stringify(t.map((s) => s.tagName), null, 4).replace(/\r?\n/g, "") + "' found.", { line: 1, col: 1 });
} else
return b("InvalidXml", "Start tag expected.", 1);
return !0;
}
function H(n) {
return n === " " || n === " " || n === `
` || n === "\r";
}
function D(n, e) {
const t = e;
for (; e < n.length; e++)
if (n[e] == "?" || n[e] == " ") {
const r = n.substr(t, e - t);
if (e > 5 && r === "xml")
return b("InvalidXml", "XML declaration allowed only at the start of the document.", m(n, e));
if (n[e] == "?" && n[e + 1] == ">") {
e++;
break;
} else
continue;
}
return e;
}
function ee(n, e) {
if (n.length > e + 5 && n[e + 1] === "-" && n[e + 2] === "-") {
for (e += 3; e < n.length; e++)
if (n[e] === "-" && n[e + 1] === "-" && n[e + 2] === ">") {
e += 2;
break;
}
} else if (n.length > e + 8 && n[e + 1] === "D" && n[e + 2] === "O" && n[e + 3] === "C" && n[e + 4] === "T" && n[e + 5] === "Y" && n[e + 6] === "P" && n[e + 7] === "E") {
let t = 1;
for (e += 8; e < n.length; e++)
if (n[e] === "<")
t++;
else if (n[e] === ">" && (t--, t === 0))
break;
} else if (n.length > e + 9 && n[e + 1] === "[" && n[e + 2] === "C" && n[e + 3] === "D" && n[e + 4] === "A" && n[e + 5] === "T" && n[e + 6] === "A" && n[e + 7] === "[") {
for (e += 8; e < n.length; e++)
if (n[e] === "]" && n[e + 1] === "]" && n[e + 2] === ">") {
e += 2;
break;
}
}
return e;
}
const Xe = '"', ze = "'";
function Ye(n, e) {
let t = "", r = "", i = !1;
for (; e < n.length; e++) {
if (n[e] === Xe || n[e] === ze)
r === "" ? r = n[e] : r !== n[e] || (r = "");
else if (n[e] === ">" && r === "") {
i = !0;
break;
}
t += n[e];
}
return r !== "" ? !1 : {
value: t,
index: e,
tagClosed: i
};
}
const We = new RegExp(`(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['"])(([\\s\\S])*?)\\5)?`, "g");
function te(n, e) {
const t = pe(n, We), r = {};
for (let i = 0; i < t.length; i++) {
if (t[i][1].length === 0)
return b("InvalidAttr", "Attribute '" + t[i][2] + "' has no space in starting.", P(t[i]));
if (t[i][3] !== void 0 && t[i][4] === void 0)
return b("InvalidAttr", "Attribute '" + t[i][2] + "' is without value.", P(t[i]));
if (t[i][3] === void 0 && !e.allowBooleanAttributes)
return b("InvalidAttr", "boolean attribute '" + t[i][2] + "' is not allowed.", P(t[i]));
const s = t[i][2];
if (!Ze(s))
return b("InvalidAttr", "Attribute '" + s + "' is an invalid name.", P(t[i]));
if (!Object.prototype.hasOwnProperty.call(r, s))
r[s] = 1;
else
return b("InvalidAttr", "Attribute '" + s + "' is repeated.", P(t[i]));
}
return !0;
}
function Ge(n, e) {
let t = /\d/;
for (n[e] === "x" && (e++, t = /[\da-fA-F]/); e < n.length; e++) {
if (n[e] === ";")
return e;
if (!n[e].match(t))
break;
}
return -1;
}
function Ke(n, e) {
if (e++, n[e] === ";")
return -1;
if (n[e] === "#")
return e++, Ge(n, e);
let t = 0;
for (; e < n.length; e++, t++)
if (!(n[e].match(/\w/) && t < 20)) {
if (n[e] === ";")
break;
return -1;
}
return e;
}
function b(n, e, t) {
return {
err: {
code: n,
msg: e,
line: t.line || t,
col: t.col
}
};
}
function Ze(n) {
return U(n);
}
function qe(n) {
return U(n);
}
function m(n, e) {
const t = n.substring(0, e).split(/\r?\n/);
return {
line: t.length,
// column number is last line's length + 1, because column numbering starts at 1:
col: t[t.length - 1].length + 1
};
}
function P(n) {
return n.startIndex + n[1].length;
}
const Ee = (n) => q.includes(n) ? "__" + n : n, Je = {
preserveOrder: !1,
attributeNamePrefix: "@_",
attributesGroupName: !1,
textNodeName: "#text",
ignoreAttributes: !0,
removeNSPrefix: !1,
// remove NS from tag name or attribute name if true
allowBooleanAttributes: !1,
//a tag can have attributes without any value
//ignoreRootElement : false,
parseTagValue: !0,
parseAttributeValue: !1,
trimValues: !0,
//Trim string values of tag and attributes
cdataPropName: !1,
numberParseOptions: {
hex: !0,
leadingZeros: !0,
eNotation: !0
},
tagValueProcessor: function(n, e) {
return e;
},
attributeValueProcessor: function(n, e) {
return e;
},
stopNodes: [],
//nested tags will not be parsed even for errors
alwaysCreateTextNode: !1,
isArray: () => !1,
commentPropName: !1,
unpairedTags: [],
processEntities: !0,
htmlEntities: !1,
ignoreDeclaration: !1,
ignorePiTags: !1,
transformTagName: !1,
transformAttributeName: !1,
updateTag: function(n, e, t) {
return n;
},
// skipEmptyListItem: false
captureMetaData: !1,
maxNestedTags: 100,
strictReservedNames: !0,
jPath: !0,
// if true, pass jPath string to callbacks; if false, pass matcher instance
onDangerousProperty: Ee
};
function Qe(n, e) {
if (typeof n != "string")
return;
const t = n.toLowerCase();
if (q.some((r) => t === r.toLowerCase()))
throw new Error(
`[SECURITY] Invalid ${e}: "${n}" is a reserved JavaScript keyword that could cause prototype pollution`
);
if (ge.some((r) => t === r.toLowerCase()))
throw new Error(
`[SECURITY] Invalid ${e}: "${n}" is a reserved JavaScript keyword that could cause prototype pollution`
);
}
function me(n) {
return typeof n == "boolean" ? {
enabled: n,
// true or false
maxEntitySize: 1e4,
maxExpansionDepth: 10,
maxTotalExpansions: 1e3,
maxExpandedLength: 1e5,
maxEntityCount: 100,
allowedTags: null,
tagFilter: null
} : typeof n == "object" && n !== null ? {
enabled: n.enabled !== !1,
maxEntitySize: Math.max(1, n.maxEntitySize ?? 1e4),
maxExpansionDepth: Math.max(1, n.maxExpansionDepth ?? 10),
maxTotalExpansions: Math.max(1, n.maxTotalExpansions ?? 1e3),
maxExpandedLength: Math.max(1, n.maxExpandedLength ?? 1e5),
maxEntityCount: Math.max(1, n.maxEntityCount ?? 100),
allowedTags: n.allowedTags ?? null,
tagFilter: n.tagFilter ?? null
} : me(!0);
}
const He = function(n) {
const e = Object.assign({}, Je, n), t = [
{ value: e.attributeNamePrefix, name: "attributeNamePrefix" },
{ value: e.attributesGroupName, name: "attributesGroupName" },
{ value: e.textNodeName, name: "textNodeName" },
{ value: e.cdataPropName, name: "cdataPropName" },
{ value: e.commentPropName, name: "commentPropName" }
];
for (const { value: r, name: i } of t)
r && Qe(r, i);
return e.onDangerousProperty === null && (e.onDangerousProperty = Ee), e.processEntities = me(e.processEntities), e.stopNodes && Array.isArray(e.stopNodes) && (e.stopNodes = e.stopNodes.map((r) => typeof r == "string" && r.startsWith("*.") ? ".." + r.substring(2) : r)), e;
};
let j;
typeof Symbol != "function" ? j = "@@xmlMetadata" : j = Symbol("XML Node Metadata");
class C {
constructor(e) {
this.tagname = e, this.child = [], this[":@"] = /* @__PURE__ */ Object.create(null);
}
add(e, t) {
e === "__proto__" && (e = "#__proto__"), this.child.push({ [e]: t });
}
addChild(e, t) {
e.tagname === "__proto__" && (e.tagname = "#__proto__"), e[":@"] && Object.keys(e[":@"]).length > 0 ? this.child.push({ [e.tagname]: e.child, ":@": e[":@"] }) : this.child.push({ [e.tagname]: e.child }), t !== void 0 && (this.child[this.child.length - 1][j] = { startIndex: t });
}
/** symbol used for metadata */
static getMetaDataSymbol() {
return j;
}
}
class De {
constructor(e) {
this.suppressValidationErr = !e, this.options = e;
}
readDocType(e, t) {
const r = /* @__PURE__ */ Object.create(null);
let i = 0;
if (e[t + 3] === "O" && e[t + 4] === "C" && e[t + 5] === "T" && e[t + 6] === "Y" && e[t + 7] === "P" && e[t + 8] === "E") {
t = t + 9;
let s = 1, l = !1, a = !1, o = "";
for (; t < e.length; t++)
if (e[t] === "<" && !a) {
if (l && v(e, "!ENTITY", t)) {
t += 7;
let c, u;
if ([c, u, t] = this.readEntityExp(e, t + 1, this.suppressValidationErr), u.indexOf("&") === -1) {
if (this.options.enabled !== !1 && this.options.maxEntityCount != null && i >= this.options.maxEntityCount)
throw new Error(
`Entity count (${i + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`
);
const h = c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
r[c] = {
regx: RegExp(`&${h};`, "g"),
val: u
}, i++;
}
} else if (l && v(e, "!ELEMENT", t)) {
t += 8;
const { index: c } = this.readElementExp(e, t + 1);
t = c;
} else if (l && v(e, "!ATTLIST", t))
t += 8;
else if (l && v(e, "!NOTATION", t)) {
t += 9;
const { index: c } = this.readNotationExp(e, t + 1, this.suppressValidationErr);
t = c;
} else if (v(e, "!--", t))
a = !0;
else
throw new Error("Invalid DOCTYPE");
s++, o = "";
} else if (e[t] === ">") {
if (a ? e[t - 1] === "-" && e[t - 2] === "-" && (a = !1, s--) : s--, s === 0)
break;
} else
e[t] === "[" ? l = !0 : o += e[t];
if (s !== 0)
throw new Error("Unclosed DOCTYPE");
} else
throw new Error("Invalid Tag instead of DOCTYPE");
return { entities: r, i: t };
}
readEntityExp(e, t) {
t = N(e, t);
const r = t;
for (; t < e.length && !/\s/.test(e[t]) && e[t] !== '"' && e[t] !== "'"; )
t++;
let i = e.substring(r, t);
if (O(i), t = N(e, t), !this.suppressValidationErr) {
if (e.substring(t, t + 6).toUpperCase() === "SYSTEM")
throw new Error("External entities are not supported");
if (e[t] === "%")
throw new Error("Parameter entities are not supported");
}
let s = "";
if ([t, s] = this.readIdentifierVal(e, t, "entity"), this.options.enabled !== !1 && this.options.maxEntitySize != null && s.length > this.options.maxEntitySize)
throw new Error(
`Entity "${i}" size (${s.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`
);
return t--, [i, s, t];
}
readNotationExp(e, t) {
t = N(e, t);
const r = t;
for (; t < e.length && !/\s/.test(e[t]); )
t++;
let i = e.substring(r, t);
!this.suppressValidationErr && O(i), t = N(e, t);
const s = e.substring(t, t + 6).toUpperCase();
if (!this.suppressValidationErr && s !== "SYSTEM" && s !== "PUBLIC")
throw new Error(`Expected SYSTEM or PUBLIC, found "${s}"`);
t += s.length, t = N(e, t);
let l = null, a = null;
if (s === "PUBLIC")
[t, l] = this.readIdentifierVal(e, t, "publicIdentifier"), t = N(e, t), (e[t] === '"' || e[t] === "'") && ([t, a] = this.readIdentifierVal(e, t, "systemIdentifier"));
else if (s === "SYSTEM" && ([t, a] = this.readIdentifierVal(e, t, "systemIdentifier"), !this.suppressValidationErr && !a))
throw new Error("Missing mandatory system identifier for SYSTEM notation");
return { notationName: i, publicIdentifier: l, systemIdentifier: a, index: --t };
}
readIdentifierVal(e, t, r) {
let i = "";
const s = e[t];
if (s !== '"' && s !== "'")
throw new Error(`Expected quoted string, found "${s}"`);
t++;
const l = t;
for (; t < e.length && e[t] !== s; )
t++;
if (i = e.substring(l, t), e[t] !== s)
throw new Error(`Unterminated ${r} value`);
return t++, [t, i];
}
readElementExp(e, t) {
t = N(e, t);
const r = t;
for (; t < e.length && !/\s/.test(e[t]); )
t++;
let i = e.substring(r, t);
if (!this.suppressValidationErr && !U(i))
throw new Error(`Invalid element name: "${i}"`);
t = N(e, t);
let s = "";
if (e[t] === "E" && v(e, "MPTY", t))
t += 4;
else if (e[t] === "A" && v(e, "NY", t))
t += 2;
else if (e[t] === "(") {
t++;
const l = t;
for (; t < e.length && e[t] !== ")"; )
t++;
if (s = e.substring(l, t), e[t] !== ")")
throw new Error("Unterminated content model");
} else if (!this.suppressValidationErr)
throw new Error(`Invalid Element Expression, found "${e[t]}"`);
return {
elementName: i,
contentModel: s.trim(),
index: t
};
}
readAttlistExp(e, t) {
t = N(e, t);
let r = t;
for (; t < e.length && !/\s/.test(e[t]); )
t++;
let i = e.substring(r, t);
for (O(i), t = N(e, t), r = t; t < e.length && !/\s/.test(e[t]); )
t++;
let s = e.substring(r, t);
if (!O(s))
throw new Error(`Invalid attribute name: "${s}"`);
t = N(e, t);
let l = "";
if (e.substring(t, t + 8).toUpperCase() === "NOTATION") {
if (l = "NOTATION", t += 8, t = N(e, t), e[t] !== "(")
throw new Error(`Expected '(', found "${e[t]}"`);
t++;
let o = [];
for (; t < e.length && e[t] !== ")"; ) {
const c = t;
for (; t < e.length && e[t] !== "|" && e[t] !== ")"; )
t++;
let u = e.substring(c, t);
if (u = u.trim(), !O(u))
throw new Error(`Invalid notation name: "${u}"`);
o.push(u), e[t] === "|" && (t++, t = N(e, t));
}
if (e[t] !== ")")
throw new Error("Unterminated list of notations");
t++, l += " (" + o.join("|") + ")";
} else {
const o = t;
for (; t < e.length && !/\s/.test(e[t]); )
t++;
l += e.substring(o, t);
const c = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
if (!this.suppressValidationErr && !c.includes(l.toUpperCase()))
throw new Error(`Invalid attribute type: "${l}"`);
}
t = N(e, t);
let a = "";
return e.substring(t, t + 8).toUpperCase() === "#REQUIRED" ? (a = "#REQUIRED", t += 8) : e.substring(t, t + 7).toUpperCase() === "#IMPLIED" ? (a = "#IMPLIED", t += 7) : [t, a] = this.readIdentifierVal(e, t, "ATTLIST"), {
elementName: i,
attributeName: s,
attributeType: l,
defaultValue: a,
index: t
};
}
}
const N = (n, e) => {
for (; e < n.length && /\s/.test(n[e]); )
e++;
return e;
};
function v(n, e, t) {
for (let r = 0; r < e.length; r++)
if (e[r] !== n[t + r + 1])
return !1;
return !0;
}
function O(n) {
if (U(n))
return n;
throw new Error(`Invalid entity name ${n}`);
}
const et = /^[-+]?0x[a-fA-F0-9]+$/, tt = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/, nt = {
hex: !0,
// oct: false,
leadingZeros: !0,
decimalPoint: ".",
eNotation: !0,
//skipLike: /regex/,
infinity: "original"
// "null", "infinity" (Infinity type), "string" ("Infinity" (the string literal))
};
function rt(n, e = {}) {
if (e = Object.assign({}, nt, e), !n || typeof n != "string")
return n;
let t = n.trim();
if (t.length === 0)
return n;
if (e.skipLike !== void 0 && e.skipLike.test(t))
return n;
if (t === "0")
return 0;
if (e.hex && et.test(t))
return at(t, 16);
if (isFinite(t)) {
if (t.includes("e") || t.includes("E"))
return it(n, t, e);
{
const r = tt.exec(t);
if (r) {
const i = r[1] || "", s = r[2];
let l = ot(r[3]);
const a = i ? (
// 0., -00., 000.
n[s.length + 1] === "."
) : n[s.length] === ".";
if (!e.leadingZeros && (s.length > 1 || s.length === 1 && !a))
return n;
{
const o = Number(t), c = String(o);
if (o === 0)
return o;
if (c.search(/[eE]/) !== -1)
return e.eNotation ? o : n;
if (t.indexOf(".") !== -1)
return c === "0" || c === l || c === `${i}${l}` ? o : n;
let u = s ? l : t;
return s ? u === c || i + u === c ? o : n : u === c || u === i + c ? o : n;
}
} else
return n;
}
} else
return lt(n, Number(t), e);
}
const st = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
function it(n, e, t) {
if (!t.eNotation)
return n;
const r = e.match(st);
if (r) {
let i = r[1] || "";
const s = r[3].indexOf("e") === -1 ? "E" : "e", l = r[2], a = i ? (
// 0E.
n[l.length + 1] === s
) : n[l.length] === s;
return l.length > 1 && a ? n : l.length === 1 && (r[3].startsWith(`.${s}`) || r[3][0] === s) ? Number(e) : l.length > 0 ? t.leadingZeros && !a ? (e = (r[1] || "") + r[3], Number(e)) : n : Number(e);
} else
return n;
}
function ot(n) {
return n && n.indexOf(".") !== -1 && (n = n.replace(/0+$/, ""), n === "." ? n = "0" : n[0] === "." ? n = "0" + n : n[n.length - 1] === "." && (n = n.substring(0, n.length - 1))), n;
}
function at(n, e) {
if (parseInt)
return parseInt(n, e);
if (Number.parseInt)
return Number.parseInt(n, e);
if (window && window.parseInt)
return window.parseInt(n, e);
throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
}
function lt(n, e, t) {
const r = e === 1 / 0;
switch (t.infinity.toLowerCase()) {
case "null":
return null;
case "infinity":
return e;
case "string":
return r ? "Infinity" : "-Infinity";
case "original":
default:
return n;
}
}
function ut(n) {
return typeof n == "function" ? n : Array.isArray(n) ? (e) => {
for (const t of n)
if (typeof t == "string" && e === t || t instanceof RegExp && t.test(e))
return !0;
} : () => !1;
}
class ne {
/**
* Create a new Expression
* @param {string} pattern - Pattern string (e.g., "root.users.user", "..user[id]")
* @param {Object} options - Configuration options
* @param {string} options.separator - Path separator (default: '.')
*/
constructor(e, t = {}) {
this.pattern = e, this.separator = t.separator || ".", this.segments = this._parse(e), this._hasDeepWildcard = this.segments.some((r) => r.type === "deep-wildcard"), this._hasAttributeCondition = this.segments.some((r) => r.attrName !== void 0), this._hasPositionSelector = this.segments.some((r) => r.position !== void 0);
}
/**
* Parse pattern string into segments
* @private
* @param {string} pattern - Pattern to parse
* @returns {Array} Array of segment objects
*/
_parse(e) {
const t = [];
let r = 0, i = "";
for (; r < e.length; )
e[r] === this.separator ? r + 1 < e.length && e[r + 1] === this.separator ? (i.trim() && (t.push(this._parseSegment(i.trim())), i = ""), t.push({ type: "deep-wildcard" }), r += 2) : (i.trim() && t.push(this._parseSegment(i.trim())), i = "", r++) : (i += e[r], r++);
return i.trim() && t.push(this._parseSegment(i.trim())), t;
}
/**
* Parse a single segment
* @private
* @param {string} part - Segment string (e.g., "user", "ns::user", "user[id]", "ns::user:first")
* @returns {Object} Segment object
*/
_parseSegment(e) {
const t = { type: "tag" };
let r = null, i = e;
const s = e.match(/^([^\[]+)(\[[^\]]*\])(.*)$/);
if (s && (i = s[1] + s[3], s[2])) {
const u = s[2].slice(1, -1);
u && (r = u);
}
let l, a = i;
if (i.includes("::")) {
const u = i.indexOf("::");
if (l = i.substring(0, u).trim(), a = i.substring(u + 2).trim(), !l)
throw new Error(`Invalid namespace in pattern: ${e}`);
}
let o, c = null;
if (a.includes(":")) {
const u = a.lastIndexOf(":"), h = a.substring(0, u).trim(), d = a.substring(u + 1).trim();
["first", "last", "odd", "even"].includes(d) || /^nth\(\d+\)$/.test(d) ? (o = h, c = d) : o = a;
} else
o = a;
if (!o)
throw new Error(`Invalid segment pattern: ${e}`);
if (t.tag = o, l && (t.namespace = l), r)
if (r.includes("=")) {
const u = r.indexOf("=");
t.attrName = r.substring(0, u).trim(), t.attrValue = r.substring(u + 1).trim();
} else
t.attrName = r.trim();
if (c) {
const u = c.match(/^nth\((\d+)\)$/);
u ? (t.position = "nth", t.positionValue = parseInt(u[1], 10)) : t.position = c;
}
return t;
}
/**
* Get the number of segments
* @returns {number}
*/
get length() {
return this.segments.length;
}
/**
* Check if expression contains deep wildcard
* @returns {boolean}
*/
hasDeepWildcard() {
return this._hasDeepWildcard;
}
/**
* Check if expression has attribute conditions
* @returns {boolean}
*/
hasAttributeCondition() {
return this._hasAttributeCondition;
}
/**
* Check if expression has position selectors
* @returns {boolean}
*/
hasPositionSelector() {
return this._hasPositionSelector;
}
/**
* Get string representation
* @returns {string}
*/
toString() {
return this.pattern;
}
}
const ct = /* @__PURE__ */ new Set(["push", "pop", "reset", "updateCurrent", "restore"]);
class ht {
/**
* Create a new Matcher
* @param {Object} options - Configuration options
* @param {string} options.separator - Default path separator (default: '.')
*/
constructor(e = {}) {
this.separator = e.separator || ".", this.path = [], this.siblingStacks = [];
}
/**
* Push a new tag onto the path
* @param {string} tagName - Name of the tag
* @param {Object} attrValues - Attribute key-value pairs for current node (optional)
* @param {string} namespace - Namespace for the tag (optional)
*/
push(e, t = null, r = null) {
if (this.path.length > 0) {
const u = this.path[this.path.length - 1];
u.values = void 0;
}
const i = this.path.length;
this.siblingStacks[i] || (this.siblingStacks[i] = /* @__PURE__ */ new Map());
const s = this.siblingStacks[i], l = r ? `${r}:${e}` : e, a = s.get(l) || 0;
let o = 0;
for (const u of s.values())
o += u;
s.set(l, a + 1);
const c = {
tag: e,
position: o,
counter: a
};
r != null && (c.namespace = r), t != null && (c.values = t), this.path.push(c);
}
/**
* Pop the last tag from the path
* @returns {Object|undefined} The popped node
*/
pop() {
if (this.path.length === 0)
return;
const e = this.path.pop();
return this.siblingStacks.length > this.path.length + 1 && (this.siblingStacks.length = this.path.length + 1), e;
}
/**
* Update current node's attribute values
* Useful when attributes are parsed after push
* @param {Object} attrValues - Attribute values
*/
updateCurrent(e) {
if (this.path.length > 0) {
const t = this.path[this.path.length - 1];
e != null && (t.values = e);
}
}
/**
* Get current tag name
* @returns {string|undefined}
*/
getCurrentTag() {
return this.path.length > 0 ? this.path[this.path.length - 1].tag : void 0;
}
/**
* Get current namespace
* @returns {string|undefined}
*/
getCurrentNamespace() {
return this.path.length > 0 ? this.path[this.path.length - 1].namespace : void 0;
}
/**
* Get current node's attribute value
* @param {string} attrName - Attribute name
* @returns {*} Attribute value or undefined
*/
getAttrValue(e) {
var r;
return this.path.length === 0 || (r = this.path[this.path.length - 1].values) == null ? void 0 : r[e];
}
/**
* Check if current node has an attribute
* @param {string} attrName - Attribute name
* @returns {boolean}
*/
hasAttr(e) {
if (this.path.length === 0)
return !1;
const t = this.path[this.path.length - 1];
return t.values !== void 0 && e in t.values;
}
/**
* Get current node's sibling position (child index in parent)
* @returns {number}
*/
getPosition() {
return this.path.length === 0 ? -1 : this.path[this.path.length - 1].position ?? 0;
}
/**
* Get current node's repeat counter (occurrence count of this tag name)
* @returns {number}
*/
getCounter() {
return this.path.length === 0 ? -1 : this.path[this.path.length - 1].counter ?? 0;
}
/**
* Get current node's sibling index (alias for getPosition for backward compatibility)
* @returns {number}
* @deprecated Use getPosition() or getCounter() instead
*/
getIndex() {
return this.getPosition();
}
/**
* Get current path depth
* @returns {number}
*/
getDepth() {
return this.path.length;
}
/**
* Get path as string
* @param {string} separator - Optional separator (uses default if not provided)
* @param {boolean} includeNamespace - Whether to include namespace in output (default: true)
* @returns {string}
*/
toString(e, t = !0) {
const r = e || this.separator;
return this.path.map((i) => t && i.namespace ? `${i.namespace}:${i.tag}` : i.tag).join(r);
}
/**
* Get path as array of tag names
* @returns {string[]}
*/
toArray() {
return this.path.map((e) => e.tag);
}
/**
* Reset the path to empty
*/
reset() {
this.path = [], this.siblingStacks = [];
}
/**
* Match current path against an Expression
* @param {Expression} expression - The expression to match against
* @returns {boolean} True if current path matches the expression
*/
matches(e) {
const t = e.segments;
return t.length === 0 ? !1 : e.hasDeepWildcard() ? this._matchWithDeepWildcard(t) : this._matchSimple(t);
}
/**
* Match simple path (no deep wildcards)
* @private
*/
_matchSimple(e) {
if (this.path.length !== e.length)
return !1;
for (let t = 0; t < e.length; t++) {
const r = e[t], i = this.path[t], s = t === this.path.length - 1;
if (!this._matchSegment(r, i, s))
return !1;
}
return !0;
}
/**
* Match path with deep wildcards
* @private
*/
_matchWithDeepWildcard(e) {
let t = this.path.length - 1, r = e.length - 1;
for (; r >= 0 && t >= 0; ) {
const i = e[r];
if (i.type === "deep-wildcard") {
if (r--, r < 0)
return !0;
const s = e[r];
let l = !1;
for (let a = t; a >= 0; a--) {
const o = a === this.path.length - 1;
if (this._matchSegment(s, this.path[a], o)) {
t = a - 1, r--, l = !0;
break;
}
}
if (!l)
return !1;
} else {
const s = t === this.path.length - 1;
if (!this._matchSegment(i, this.path[t], s))
return !1;
t--, r--;
}
}
return r < 0;
}
/**
* Match a single segment against a node
* @private
* @param {Object} segment - Segment from Expression
* @param {Object} node - Node from path
* @param {boolean} isCurrentNode - Whether this is the current (last) node
* @returns {boolean}
*/
_matchSegment(e, t, r) {
if (e.tag !== "*" && e.tag !== t.tag || e.namespace !== void 0 && e.namespace !== "*" && e.namespace !== t.namespace)
return !1;
if (e.attrName !== void 0) {
if (!r || !t.values || !(e.attrName in t.values))
return !1;
if (e.attrValue !== void 0) {
const i = t.values[e.attrName];
if (String(i) !== String(e.attrValue))
return !1;
}
}
if (e.position !== void 0) {
if (!r)
return !1;
const i = t.counter ?? 0;
if (e.position === "first" && i !== 0)
return !1;
if (e.position === "odd" && i % 2 !== 1)
return !1;
if (e.position === "even" && i % 2 !== 0)
return !1;
if (e.position === "nth" && i !== e.positionValue)
return !1;
}
return !0;
}
/**
* Create a snapshot of current state
* @returns {Object} State snapshot
*/
snapshot() {
return {
path: this.path.map((e) => ({ ...e })),
siblingStacks: this.siblingStacks.map((e) => new Map(e))
};
}
/**
* Restore state from snapshot
* @param {Object} snapshot - State snapshot
*/
restore(e) {
this.path = e.path.map((t) => ({ ...t })), this.siblingStacks = e.siblingStacks.map((t) => new Map(t));
}
/**
* Return a read-only view of this matcher.
*
* The returned object exposes all query/inspection methods but throws a
* TypeError if any state-mutating method is called (`push`, `pop`, `reset`,
* `updateCurrent`, `restore`). Property reads (e.g. `.path`, `.separator`)
* are allowed but the returned arrays/objects are frozen so callers cannot
* mutate internal state through them either.
*
* @returns {ReadOnlyMatcher} A proxy that forwards read operations and blocks writes.
*
* @example
* const matcher = new Matcher();
* matcher.push("root", {});
*
* const ro = matcher.readOnly();
* ro.matches(expr); // ✓ works
* ro.getCurrentTag(); // ✓ works
* ro.push("child", {}); // ✗ throws TypeError
* ro.reset(); // ✗ throws TypeError
*/
readOnly() {
const e = this;
return new Proxy(e, {
get(t, r, i) {
if (ct.has(r))
return () => {
throw new TypeError(
`Cannot call '${r}' on a read-only Matcher. Obtain a writable instance to mutate state.`
);
};
const s = Reflect.get(t, r, i);
return r === "path" || r === "siblingStacks" ? Object.freeze(
Array.isArray(s) ? s.map(
(l) => l instanceof Map ? Object.freeze(new Map(l)) : Object.freeze({ ...l })
// freeze a copy of each node
) : s
) : typeof s == "function" ? s.bind(t) : s;
},
// Prevent any property assignment on the read-only view
set(t, r) {
throw new TypeError(
`Cannot set property '${String(r)}' on a read-only Matcher.`
);
},
// Prevent property deletion
deleteProperty(t, r) {
throw new TypeError(
`Cannot delete property '${String(r)}' from a read-only Matcher.`
);
}
});
}
}
function ft(n, e) {
if (!n)
return {};
const t = e.attributesGroupName ? n[e.attributesGroupName] : n;
if (!t)
return {};
const r = {};
for (const i in t)
if (i.startsWith(e.attributeNamePrefix)) {
const s = i.substring(e.attributeNamePrefix.length);
r[s] = t[i];
} else
r[i] = t[i];
return r;
}
function dt(n) {
if (!n || typeof n != "string")
return;
const e = n.indexOf(":");
if (e !== -1 && e > 0) {
const t = n.substring(0, e);
if (t !== "xmlns")
return t;
}
}
class pt {
constructor(e) {
if (this.options = e, this.currentNode = null, this.tagsNodeStack = [], this.docTypeEntities = {}, this.lastEntities = {
apos: { regex: /&(apos|#39|#x27);/g, val: "'" },
gt: { regex: /&(gt|#62|#x3E);/g, val: ">" },
lt: { regex: /&(lt|#60|#x3C);/g, val: "<" },
quot: { regex: /&(quot|#34|#x22);/g, val: '"' }
}, this.ampEntity = { regex: /&(amp|#38|#x26);/g, val: "&" }, this.htmlEntities = {
space: { regex: /&(nbsp|#160);/g, val: " " },
// "lt" : { regex: /&(lt|#60);/g, val: "<" },
// "gt" : { regex: /&(gt|#62);/g, val: ">" },
// "amp" : { regex: /&(amp|#38);/g, val: "&" },
// "quot" : { regex: /&(quot|#34);/g, val: "\"" },
// "apos" : { regex: /&(apos|#39);/g, val: "'" },
cent: { regex: /&(cent|#162);/g, val: "¢" },
pound: { regex: /&(pound|#163);/g, val: "£" },
yen: { regex: /&(yen|#165);/g, val: "¥" },
euro: { regex: /&(euro|#8364);/g, val: "€" },
copyright: { regex: /&(copy|#169);/g, val: "©" },
reg: { regex: /&(reg|#174);/g, val: "®" },
inr: { regex: /&(inr|#8377);/g, val: "₹" },
num_dec: { regex: /&#([0-9]{1,7});/g, val: (t, r) => re(r, 10, "&#") },
num_hex: { regex: /&#x([0-9a-fA-F]{1,6});/g, val: (t, r) => re(r, 16, "&#x") }
}, this.addExternalEntities = gt, this.parseXml = Nt, this.parseTextData = bt, this.resolveNameSpace = Et, this.buildAttributesMap = yt, this.isItStopNode = It, this.replaceEntitiesValue = wt, this.readStopNodeData = St, this.saveTextToParentTag = Ct, this.addChild = Tt, this.ignoreAttributesFn = ut(this.options.ignoreAttributes), this.entityExpansionCount = 0, this.currentExpandedLength = 0, this.matcher = new ht(), this.isCurrentNodeStopNode = !1, this.options.stopNodes && this.options.stopNodes.length > 0) {
this.stopNodeExpressions = [];
for (let t = 0; t < this.options.stopNodes.length; t++) {
const r = this.options.stopNodes[t];
typeof r == "string" ? this.stopNodeExpressions.push(new ne(r)) : r instanceof ne && this.stopNodeExpressions.push(r);
}
}
}
}
function gt(n) {
const e = Object.keys(n);
for (let t = 0; t < e.length; t++) {
const r = e[t], i = r.replace(/[.\-+*:]/g, "\\.");
this.lastEntities[r] = {
regex: new RegExp("&" + i + ";", "g"),
val: n[r]
};
}
}
function bt(n, e, t, r, i, s, l) {
if (n !== void 0 && (this.options.trimValues && !r && (n = n.trim()), n.length > 0)) {
l || (n = this.replaceEntitiesValue(n, e, t));
const a = this.options.jPath ? t.toString() : t, o = this.options.tagValueProcessor(e, n, a, i, s);
return o == null ? n : typeof o != typeof n || o !== n ? o : this.options.trimValues ? G(n, this.options.parseTagValue, this.options.numberParseOptions) : n.trim() === n ? G(n, this.options.parseTagValue, this.options.numberParseOptions) : n;
}
}
function Et(n) {
if (this.options.removeNSPrefix) {
const e = n.split(":"), t = n.charAt(0) === "/" ? "/" : "";
if (e[0] === "xmlns")
return "";
e.length === 2 && (n = t + e[1]);
}
return n;
}
const mt = new RegExp(`([^\\s=]+)\\s*(=\\s*(['"])([\\s\\S]*?)\\3)?`, "gm");
function yt(n, e, t) {
if (this.options.ignoreAttributes !== !0 && typeof n == "string") {
const r = pe(n, mt), i = r.length, s = {}, l = {};
for (let a = 0; a < i; a++) {
const o = this.resolveNameSpace(r[a][1]), c = r[a][4];
if (o.length && c !== void 0) {
let u = c;
this.options.trimValues && (u = u.trim()), u = this.replaceEntitiesValue(u, t, e), l[o] = u;
}
}
Object.keys(l).length > 0 && typeof e == "object" && e.updateCurrent && e.updateCurrent(l);
for (let a = 0; a < i; a++) {
const o = this.resolveNameSpace(r[a][1]), c = this.options.jPath ? e.toString() : e;
if (this.ignoreAttributesFn(o, c))
continue;
let u = r[a][4], h = this.options.attributeNamePrefix + o;
if (o.length)
if (this.options.transformAttributeName && (h = this.options.transformAttributeName(h)), h = ye(h, this.options), u !== void 0) {
this.options.trimValues && (u = u.trim()), u = this.replaceEntitiesValue(u, t, e);
const d = this.options.jPath ? e.toString() : e, p = this.options.attributeValueProcessor(o, u, d);
p == null ? s[h] = u : typeof p != typeof u || p !== u ? s[h] = p : s[h] = G(
u,
this.options.parseAttributeValue,
this.options.numberParseOptions
);
} else
this.options.allowBooleanAttributes && (s[h] = !0);
}
if (!Object.keys(s).length)
return;
if (this.options.attributesGroupName) {
const a = {};
return a[this.options.attributesGroupName] = s, a;
}
return s;
}
}
const Nt = function(n) {
n = n.replace(/\r\n?/g, `
`);
const e = new C("!xml");
let t = e, r = "";
this.matcher.reset(), this.entityExpansionCount = 0, this.currentExpandedLength = 0;
const i = new De(this.options.processEntities);
for (let s = 0; s < n.length; s++)
if (n[s] === "<")
if (n[s + 1] === "/") {
const a = S(n, ">", s, "Closing Tag is not closed.");
let o = n.substring(s + 2, a).trim();
if (this.options.removeNSPrefix) {
const u = o.indexOf(":");
u !== -1 && (o = o.substr(u + 1));
}
o = z(this.options.transformTagName, o, "", this.options).tagName, t && (r = this.saveTextToParentTag(r, t, this.matcher));
const c = this.matcher.getCurrentTag();
if (o && this.options.unpairedTags.indexOf(o) !== -1)
throw new Error(`Unpaired tag can not be used as closing tag: </${o}>`);
c && this.options.unpairedTags.indexOf(c) !== -1 && (this.matcher.pop(), this.tagsNodeStack.pop()), this.matcher.pop(), this.isCurrentNodeStopNode = !1, t = this.tagsNodeStack.pop(), r = "", s = a;
} else if (n[s + 1] === "?") {
let a = W(n, s, !1, "?>");
if (!a)
throw new Error("Pi Tag is not closed.");
if (r = this.saveTextToParentTag(r, t, this.matcher), !(this.options.ignoreDeclaration && a.tagName === "?xml" || this.options.ignorePiTags)) {
const o = new C(a.tagName);
o.add(this.options.textNodeName, ""), a.tagName !== a.tagExp && a.attrExpPresent && (o[":@"] = this.buildAttributesMap(a.tagExp, this.matcher, a.tagName)), this.addChild(t, o, this.matcher, s);
}
s = a.closeIndex + 1;
} else if (n.substr(s + 1, 3) === "!--") {
const a = S(n, "-->", s + 4, "Comment is not closed.");
if (this.options.commentPropName) {
const o = n.substring(s + 4, a - 2);
r = this.saveTextToParentTag(r, t, this.matcher), t.add(this.options.commentPropName, [{ [this.options.textNodeName]: o }]);
}
s = a;
} else if (n.substr(s + 1, 2) === "!D") {
const a = i.readDocType(n, s);
this.docTypeEntities = a.entities, s = a.i;
} else if (n.substr(s + 1, 2) === "![") {
const a = S(n, "]]>", s, "CDATA is not closed.") - 2, o = n.substring(s + 9, a);
r = this.saveTextToParentTag(r, t, this.matcher);
let c = this.parseTextData(o, t.tagname, this.matcher, !0, !1, !0, !0);
c == null && (c = ""), this.options.cdataPropName ? t.add(this.options.cdataPropName, [{ [this.options.textNodeName]: o }]) : t.add(this.options.textNodeName, c), s = a + 2;
} else {
let a = W(n, s, this.options.removeNSPrefix);
if (!a) {
const y = n.substring(Math.max(0, s - 50), Math.min(n.length, s + 50));
throw new Error(`readTagExp returned undefined at position ${s}. Context: "${y}"`);
}
let o = a.tagName;
const c = a.rawTagName;
let u = a.tagExp, h = a.attrExpPresent, d = a.closeIndex;
if ({ tagName: o, tagExp: u } = z(this.options.transformTagName, o, u, this.options), this.options.strictReservedNames && (o === this.options.commentPropName || o === this.options.cdataPropName || o === this.options.textNodeName || o === this.options.attributesGroupName))
throw new Error(`Invalid tag name: ${o}`);
t && r && t.tagname !== "!xml" && (r = this.saveTextToParentTag(r, t, this.matcher, !1));
const p = t;
p && this.options.unpairedTags.indexOf(p.tagname) !== -1 && (t = this.tagsNodeStack.pop(), this.matcher.pop());
let g = !1;
u.length > 0 && u.lastIndexOf("/") === u.length - 1 && (g = !0, o[o.length - 1] === "/" ? (o = o.substr(0, o.length - 1), u = o) : u = u.substr(0, u.length - 1), h = o !== u);
let E = null, A;
A = dt(c), o !== e.tagname && this.matcher.push(o, {}, A), o !== u && h && (E = this.buildAttributesMap(u, this.matcher, o), E && ft(E, this.options)), o !== e.tagname && (this.isCurrentNodeStopNode = this.isItStopNode(this.stopNodeExpressions, this.matcher));
const M = s;
if (this.isCurrentNodeStopNode) {
let y = "";
if (g)
s = a.closeIndex;
else if (this.options.unpairedTags.indexOf(o) !== -1)
s = a.closeIndex;
else {
const X = this.readStopNodeData(n, c, d + 1);
if (!X)
throw new Error(`Unexpected end of ${c}`);
s = X.i, y = X.tagContent;
}
const B = new C(o);
E && (B[":@"] = E), B.add(this.options.textNodeName, y), this.matcher.pop(), this.isCurrentNodeStopNode = !1, this.addChild(t, B, this.matcher, M);
} else {
if (g) {
({ tagName: o, tagExp: u } = z(this.options.transformTagName, o, u, this.options));
const y = new C(o);
E && (y[":@"] = E), this.addChild(t, y, this.matcher, M), this.matcher.pop(), this.isCurrentNodeStopNode = !1;
} else if (this.options.unpairedTags.indexOf(o) !== -1) {
const y = new C(o);
E && (y[":@"] = E), this.addChild(t, y, this.matcher, M), this.matcher.pop(), this.isCurrentNodeStopNode = !1, s = a.closeIndex;
continue;
} else {
const y = new C(o);
if (this.tagsNodeStack.length > this.options.maxNestedTags)
throw new Error("Maximum nested tags exceeded");
this.tagsNodeStack.push(t), E && (y[":@"] = E), this.addChild(t, y, this.matcher, M), t = y;
}
r = "", s = d;
}
}
else
r += n[s];
return e.child;
};
function Tt(n, e, t, r) {
this.options.captureMetaData || (r = void 0);
const i = this.options.jPath ? t.toString() : t, s = this.options.updateTag(e.tagname, i, e[":@"]);
s === !1 || (typeof s == "string" && (e.tagname = s), n.addChild(e, r));
}
function wt(n, e, t) {
const r = this.options.processEntities;
if (!r || !r.enabled)
return n;
if (r.allowedTags) {
const i = this.options.jPath ? t.toString() : t;
if (!(Array.isArray(r.allowedTags) ? r.allowedTags.includes(e) : r.allowedTags(e, i)))
return n;
}
if (r.tagFilter) {
const i = this.options.jPath ? t.toString() : t;
if (!r.tagFilter(e, i))
return n;
}
for (const i of Object.keys(this.docTypeEntities)) {
const s = this.docTypeEntities[i], l = n.match(s.regx);
if (l) {
if (this.entityExpansionCount += l.length, r.maxTotalExpansions && this.entityExpansionCount > r.maxTotalExpansions)
throw new Error(
`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${r.maxTotalExpansions}`
);
const a = n.length;
if (n = n.replace(s.regx, s.val), r.maxExpandedLength && (this.currentExpandedLength += n.length - a, this.currentExpandedLength > r.maxExpandedLength))
throw new Error(
`Total expanded content size exceeded: ${this.currentExpandedLength} > ${r.maxExpandedLength}`
);
}
}
for (const i of Object.keys(this.lastEntities)) {
const s = this.lastEntities[i], l = n.match(s.regex);
if (l && (this.entityExpansionCount += l.length, r.maxTotalExpansions && this.entityExpansionCount > r.maxTotalExpansions))
throw new Error(
`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${r.maxTotalExpansions}`
);
n = n.replace(s.regex, s.val);
}
if (n.indexOf("&") === -1)
return n;
if (this.options.htmlEntities)
for (const i of Object.keys(this.htmlEntities)) {
const s = this.htmlEntities[i], l = n.match(s.regex);
if (l && (this.entityExpansionCount += l.length, r.maxTotalExpansions && this.entityExpansionCount > r.maxTotalExpansions))
thro