{"version":3,"file":"./lib/fxb.min.js","mappings":"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","sources":["webpack://fxb/webpack/universalModuleDefinition","webpack://fxb/webpack/bootstrap","webpack://fxb/webpack/runtime/define property getters","webpack://fxb/webpack/runtime/hasOwnProperty shorthand","webpack://fxb/webpack/runtime/make namespace object","webpack://fxb/./node_modules/path-expression-matcher/src/Expression.js","webpack://fxb/./node_modules/path-expression-matcher/src/Matcher.js","webpack://fxb/./src/util.js","webpack://fxb/./node_modules/xml-naming/src/index.js","webpack://fxb/./src/orderedJs2Xml.js","webpack://fxb/./src/fxb.js","webpack://fxb/./src/ignoreAttributes.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"fxb\"] = factory();\n\telse\n\t\troot[\"fxb\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}, data) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n this.data = data;\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","import ExpressionSet from \"./ExpressionSet.js\";\n\n/**\n * MatcherView - A lightweight read-only view over a Matcher's internal state.\n *\n * Created once by Matcher and reused across all callbacks. Holds a direct\n * reference to the parent Matcher so it always reflects current parser state\n * with zero copying or freezing overhead.\n *\n * Users receive this via {@link Matcher#readOnly} or directly from parser\n * callbacks. It exposes all query and matching methods but has no mutation\n * methods — misuse is caught at the TypeScript level rather than at runtime.\n *\n * @example\n * const matcher = new Matcher();\n * const view = matcher.readOnly();\n *\n * matcher.push(\"root\", {});\n * view.getCurrentTag(); // \"root\"\n * view.getDepth(); // 1\n */\nexport class MatcherView {\n /**\n * @param {Matcher} matcher - The parent Matcher instance to read from.\n */\n constructor(matcher) {\n this._matcher = matcher;\n }\n\n /**\n * Get the path separator used by the parent matcher.\n * @returns {string}\n */\n get separator() {\n return this._matcher.separator;\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return undefined;\n return path[path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return false;\n const current = path[path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get the value of a \"kept\" attribute from the nearest ancestor (or\n * current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {*}\n */\n getAnyParentAttr(attrName) {\n return this._matcher.getAnyParentAttr(attrName);\n }\n\n /**\n * Check whether any ancestor (or the current node) kept the given\n * attribute via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAnyParentAttr(attrName) {\n return this._matcher.hasAnyParentAttr(attrName);\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this._matcher.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n return this._matcher.toString(separator, includeNamespace);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this._matcher.path.map(n => n.tag);\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n return this._matcher.matches(expression);\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this._matcher);\n }\n}\n\n/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions.\n *\n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n *\n * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to\n * user callbacks — it always reflects current state with no Proxy overhead.\n *\n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n *\n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher.\n * @param {Object} [options={}]\n * @param {string} [options.separator='.'] - Default path separator\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag, values, position, counter, namespace? }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n this._pathStringCache = null;\n this._view = new MatcherView(this);\n\n // Kept-attribute stack: only populated when push() is called with options.keep.\n this._keptAttrs = [];\n }\n\n /**\n * Push a new tag onto the path.\n * @param {string} tagName\n * @param {Object|null} [attrValues=null]\n * @param {string|null} [namespace=null]\n * @param {Object|null} [options=null]\n * @param {string[]} [options.keep] - Names of attributes (from attrValues)\n */\n push(tagName, attrValues = null, namespace = null, options = null) {\n this._pathStringCache = null;\n\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n this.path[this.path.length - 1].values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n let level = this.siblingStacks[currentLevel];\n if (!level) {\n // `counts` tells same-name siblings apart (the \"counter\" — nth \n // among other s). `total` is every child seen at this level so\n // far, kept as a running number instead of re-added from `counts` on\n // every push — a parent with many differently-named children would\n // otherwise cost more per child the more distinct names it has.\n level = { counts: new Map(), total: 0 };\n this.siblingStacks[currentLevel] = level;\n }\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = level.counts.get(siblingKey) || 0;\n\n // Position = total children at this level seen before this one.\n const position = level.total;\n\n // Update sibling count for this tag, and the level's running total.\n level.counts.set(siblingKey, counter + 1);\n level.total++;\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n\n // Depth of the node we just pushed (1-based, matches this.path.length)\n const depth = this.path.length;\n\n // Copy only the requested attributes into the kept-attrs stack. This is\n // the one part of push() whose cost scales with input (O(keep.length))\n // rather than being O(1) — by design, since the caller is explicitly\n // opting in for specific attribute names. No options/keep => zero added\n // cost beyond the two property reads below.\n const keep = options !== null ? options.keep : null;\n if (keep !== null && keep !== undefined && keep.length > 0 && attrValues) {\n for (let i = 0; i < keep.length; i++) {\n const name = keep[i];\n if (attrValues[name] !== undefined) {\n this._keptAttrs.push({ depth, name, value: attrValues[name] });\n }\n }\n }\n }\n\n /**\n * Pop the last tag from the path.\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) return undefined;\n this._pathStringCache = null;\n\n const node = this.path.pop();\n\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n // Drop any kept attributes that belonged to the popped node (or deeper).\n // _keptAttrs is depth-ordered (push only ever appends increasing depths),\n // so this is a backward scan that stops at the first surviving entry —\n // typically O(1) since kept attrs are rare by design.\n const poppedDepth = this.path.length + 1;\n while (\n this._keptAttrs.length > 0 &&\n this._keptAttrs[this._keptAttrs.length - 1].depth >= poppedDepth\n ) {\n this._keptAttrs.pop();\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values.\n * Useful when attributes are parsed after push.\n * @param {Object} attrValues\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n return this.path[this.path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get the value of a \"kept\" attribute from the nearest ancestor (or\n * current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.\n * Unlike getAttrValue(), this works regardless of how deep the path has\n * gone since the attribute was pushed — but only for attribute names that\n * were explicitly marked with `keep` at push time. Cost is proportional to\n * the number of currently-kept attributes (typically 0-3), not path depth.\n * @param {string} attrName\n * @returns {*} the value, or undefined if no ancestor kept this attribute\n */\n getAnyParentAttr(attrName) {\n const kept = this._keptAttrs;\n for (let i = kept.length - 1; i >= 0; i--) {\n if (kept[i].name === attrName) return kept[i].value;\n }\n return undefined;\n }\n\n /**\n * Check whether any ancestor (or the current node) kept the given\n * attribute via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAnyParentAttr(attrName) {\n const kept = this._keptAttrs;\n for (let i = kept.length - 1; i >= 0; i--) {\n if (kept[i].name === attrName) return true;\n }\n return false;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n const isDefault = (sep === this.separator && includeNamespace === true);\n\n if (isDefault) {\n if (this._pathStringCache !== null) {\n return this._pathStringCache;\n }\n const result = this.path.map(n =>\n (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n this._pathStringCache = result;\n return result;\n }\n\n return this.path.map(n =>\n (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty.\n */\n reset() {\n this._pathStringCache = null;\n this.path = [];\n this.siblingStacks = [];\n this._keptAttrs = [];\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n return this._matchSimple(segments);\n }\n\n /**\n * @private\n */\n _matchSimple(segments) {\n if (this.path.length !== segments.length) {\n return false;\n }\n\n for (let i = 0; i < segments.length; i++) {\n if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1;\n let segIdx = segments.length - 1;\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n segIdx--;\n\n if (segIdx < 0) {\n return true;\n }\n\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n return segIdx < 0;\n }\n\n /**\n * @private\n */\n _matchSegment(segment, node, isCurrentNode) {\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n if (segment.namespace !== undefined) {\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n if (segment.attrValue !== undefined) {\n if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth' && counter !== segment.positionValue) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this);\n }\n\n /**\n * Create a snapshot of current state.\n * @returns {Object}\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(level => level ? { counts: new Map(level.counts), total: level.total } : level),\n keptAttrs: this._keptAttrs.map(entry => ({ ...entry }))\n };\n }\n\n /**\n * Restore state from snapshot.\n * @param {Object} snapshot\n */\n restore(snapshot) {\n this._pathStringCache = null;\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(level => level ? { counts: new Map(level.counts), total: level.total } : level);\n this._keptAttrs = (snapshot.keptAttrs || []).map(entry => ({ ...entry }));\n }\n\n /**\n * Return the read-only {@link MatcherView} for this matcher.\n *\n * The same instance is returned on every call — no allocation occurs.\n * It always reflects the current parser state and is safe to pass to\n * user callbacks without risk of accidental mutation.\n *\n * @returns {MatcherView}\n *\n * @example\n * const view = matcher.readOnly();\n * // pass view to callbacks — it stays in sync automatically\n * view.matches(expr); // ✓\n * view.getCurrentTag(); // ✓\n * // view.push(...) // ✗ method does not exist — caught by TypeScript\n */\n readOnly() {\n return this._view;\n }\n}\n","\n\n// String(val)/val.toString() drop the sign of -0 (e.g. String(-0) === '0'), silently\n// corrupting a round-tripped negative-zero value. XML has no separate int/float syntax,\n// so this is the single place every raw value gets turned into text.\nexport function valToStr(val) {\n return typeof val === 'number' && Object.is(val, -0) ? '-0' : String(val)\n}\n\nexport function safeComment(val) {\n return valToStr(val)\n .replace(/--/g, '- -') // -- is illegal anywhere in comment content\n .replace(/--/g, '- -') // handle the scenario when 2 consiucative dashes appears \n .replace(/-$/, '- '); // trailing - would form -- with the closing -->\n}\n\nexport function safeCdata(val) {\n return valToStr(val).replace(/\\]\\]>/g, ']]]]>')\n}\n\nexport function escapeAttribute(val) {\n return valToStr(val).replace(/\"/g, '"').replace(/'/g, ''')\n}","/**\n * xml-naming\n * Validates XML Name productions as defined in the XML 1.0 and 1.1 specifications.\n * Covers: Name, NCName, QName, NMToken, NMTokens\n *\n * XML 1.0 spec: https://www.w3.org/TR/xml/#NT-Name\n * XML 1.1 spec: https://www.w3.org/TR/xml11/#NT-NameStartChar\n * XML NS spec: https://www.w3.org/TR/xml-names/#NT-NCName\n */\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.0\n//\n// NameStartChar ::= \":\" | [A-Z] | \"_\" | [a-z]\n// | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF]\n// | [#x370-#x37D] | [#x37F-#x1FFF] <- split to exclude #x0487\n// | [#x200C-#x200D]\n// | [#x2070-#x218F] | [#x2C00-#x2FEF]\n// | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD]\n//\n// NameChar ::= NameStartChar | \"-\" | \".\" | [0-9]\n// | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]\n//\n// Note: \\u0487 (Combining Cyrillic Millions Sign) was added in Unicode 4.0,\n// after XML 1.0 was defined against Unicode 2.0. It falls inside the range\n// \\u037F-\\u1FFF but must be excluded. We split that range into\n// \\u037F-\\u0486 and \\u0488-\\u1FFF to exclude it explicitly.\n// ---------------------------------------------------------------------------\n\nconst nameStartChar10 =\n ':A-Za-z_' +\n '\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF' +\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD';\n\nconst nameChar10 =\n nameStartChar10 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.1\n//\n// Differences from XML 1.0:\n//\n// NameStartChar:\n// 1.0 has split ranges: \\u00C0-\\u00D6, \\u00D8-\\u00F6, \\u00F8-\\u02FF\n// 1.1 merges them into: \\u00C0-\\u02FF\n// (\\u00D7 x and \\u00F7 / are division symbols, excluded in both versions)\n//\n// 1.0 tops out at \\uFFFD (BMP only)\n// 1.1 adds \\u{10000}-\\u{EFFFF} (supplementary planes)\n// These require the /u flag on the RegExp — see buildRegexes below.\n//\n// NameChar:\n// 1.1 adds \\u0487 (Combining Cyrillic Millions Sign, added in Unicode 4.0)\n// ---------------------------------------------------------------------------\n\nconst nameStartChar11 =\n ':A-Za-z_' +\n '\\u00C0-\\u02FF' + // merged — 1.0 had three split ranges here\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487 (combining mark, never a NameStartChar)\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD' +\n '\\u{10000}-\\u{EFFFF}'; // supplementary planes — REQUIRES /u flag on RegExp\n\nconst nameChar11 =\n nameStartChar11 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u0487' + // Combining Cyrillic Millions Sign — valid in 1.1, not 1.0\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Regex builders\n//\n// XML 1.0 regexes: no flags — BMP only, standard JS regex behaviour.\n// XML 1.1 regexes: /u flag — required for \\u{10000}-\\u{EFFFF} to match actual\n// supplementary code points rather than lone surrogates (which are illegal XML).\n// ---------------------------------------------------------------------------\n\nconst buildRegexes = (startChar, char, flags = '') => {\n const ncStart = startChar.replace(':', '');\n const ncChar = char.replace(':', '');\n const ncNamePat = `[${ncStart}][${ncChar}]*`;\n\n return {\n name: new RegExp(`^[${startChar}][${char}]*$`, flags),\n ncName: new RegExp(`^${ncNamePat}$`, flags),\n qName: new RegExp(`^${ncNamePat}(?::${ncNamePat})?$`, flags),\n nmToken: new RegExp(`^[${char}]+$`, flags),\n nmTokens: new RegExp(`^[${char}]+(?:\\\\s+[${char}]+)*$`, flags),\n };\n};\n\nconst regexes10 = buildRegexes(nameStartChar10, nameChar10); // no /u — BMP only\nconst regexes11 = buildRegexes(nameStartChar11, nameChar11, 'u'); // /u — enables \\u{10000}-\\u{EFFFF}\n\n// ---------------------------------------------------------------------------\n// ASCII-only fast path (opt-in, off by default)\n//\n// The XML 1.0 vs 1.1 NameStartChar/NameChar productions differ *only* in\n// their non-ASCII ranges (merged vs split Latin-1 ranges, \\u0487, and\n// supplementary planes). Restricted to ASCII, both versions collapse to the\n// same character classes, so a single regex pair covers both xmlVersion\n// values — no /u flag needed.\n//\n// Rationale: unicode-aware regexes (the /u flag, required for XML 1.1's\n// supplementary-plane range) are measurably slower in V8 than plain\n// non-unicode regexes on the same input, even when the input is pure ASCII.\n// For the common case — HTML/SVG ids, XML tags — names are ASCII, so callers\n// who know this can opt in to skip the unicode-aware matching path entirely.\n// This is a real but *conditional* win: mainly for XML 1.1 input (avoids /u),\n// or at scale where the larger unicode character classes add engine\n// overhead. It also changes behaviour (rejects legitimate non-ASCII XML\n// 1.0/1.1 names), so it must never be silently enabled — hence off by\n// default.\n// ---------------------------------------------------------------------------\n\nconst nameStartCharAscii = ':A-Za-z_';\nconst nameCharAscii = nameStartCharAscii + '\\\\-\\\\.\\\\d';\n\nconst regexesAscii = buildRegexes(nameStartCharAscii, nameCharAscii); // no /u — ASCII only\n\nconst getRegexes = (xmlVersion = '1.0', asciiOnly = false) => {\n if (asciiOnly) return regexesAscii;\n return xmlVersion === '1.1' ? regexes11 : regexes10;\n};\n\n// ---------------------------------------------------------------------------\n// Boolean validators\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if the string is a valid XML Name.\n * Colons are allowed anywhere (Name production).\n * Used for: DOCTYPE entity names, notation names, DTD element declarations.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const name = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).name.test(str);\n\n/**\n * Returns true if the string is a valid NCName (Non-Colonized Name).\n * Colons are not permitted.\n * Used for: namespace prefixes, local names, SVG id attributes.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const ncName = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).ncName.test(str);\n\n/**\n * Returns true if the string is a valid QName (Qualified Name).\n * Allows exactly one colon as a prefix separator: prefix:localName.\n * Used for: element and attribute names in namespace-aware XML/SVG.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const qName = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).qName.test(str);\n\n/**\n * Returns true if the string is a valid NMToken.\n * Like Name but no restriction on the first character.\n * Used for: DTD NMTOKEN attribute values.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const nmToken = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).nmToken.test(str);\n\n/**\n * Returns true if the string is a valid NMTokens value.\n * A whitespace-separated list of NMToken values.\n * Used for: DTD NMTOKENS attribute values.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const nmTokens = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).nmTokens.test(str);\n\n// ---------------------------------------------------------------------------\n// Memoized validator factory\n//\n// Real documents reuse a small vocabulary of tag/attribute names across many\n// siblings (e.g. `id`, `class`, `href` repeated across hundreds of elements).\n// The plain boolean validators above re-run the regex on every call\n// regardless of repeats. `createValidator` returns a closure with a private\n// string -> boolean cache, so repeated names after the first become O(1)\n// lookups instead of regex tests.\n//\n// - opts (xmlVersion, asciiOnly) are fixed at creation time, so the regex is\n// resolved once, not on every call.\n// - The cache is private to the returned closure — no shared/global state,\n// no cross-caller pollution.\n// - `maxCacheSize` bounds memory: once the cache reaches this many entries,\n// it stops accepting new ones (existing entries keep serving hits; new\n// misses just fall through to the regex, uncached). This avoids unbounded\n// growth against adversarial/high-cardinality input (e.g. validating\n// attacker-supplied names with no repeats) without the cost/complexity of\n// a full LRU, and without the perf cliff of reset-and-refill thrashing.\n// - Call `.reset()` on the returned function to clear the cache manually\n// (e.g. between unrelated parse calls).\n// ---------------------------------------------------------------------------\n\nconst PRODUCTIONS = ['name', 'ncName', 'qName', 'nmToken', 'nmTokens'];\n\n/**\n * Returns a memoized boolean validator function for a single production,\n * with opts fixed at creation time.\n *\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean, maxCacheSize?: number }} [opts]\n * maxCacheSize: max number of distinct strings to cache (default 2048).\n * Once reached, new strings are validated but not cached; existing cached\n * entries keep being served.\n * @returns {((str: string) => boolean) & { reset: () => void }}\n */\nexport const createValidator = (production, { xmlVersion = '1.0', asciiOnly = false, maxCacheSize = 2048 } = {}) => {\n if (!PRODUCTIONS.includes(production)) {\n throw new TypeError(\n `Unknown production \"${production}\". Must be one of: ${PRODUCTIONS.join(', ')}`\n );\n }\n\n const regex = getRegexes(xmlVersion, asciiOnly)[production];\n let cache = new Map();\n\n const validator = (str) => {\n const cached = cache.get(str);\n if (cached !== undefined) return cached;\n\n const result = regex.test(str);\n if (cache.size < maxCacheSize) cache.set(str, result);\n return result;\n };\n\n validator.reset = () => { cache = new Map(); };\n\n return validator;\n};\n\n// ---------------------------------------------------------------------------\n// Diagnostic validator\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a string against a named production and returns a detailed result.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * @returns {{ valid: boolean, production: string, input: string, reason?: string, position?: number }}\n */\nexport const validate = (str, production, { xmlVersion = '1.0', asciiOnly = false } = {}) => {\n if (!PRODUCTIONS.includes(production)) {\n throw new TypeError(\n `Unknown production \"${production}\". Must be one of: ${PRODUCTIONS.join(', ')}`\n );\n }\n\n const validators = { name, ncName, qName, nmToken, nmTokens };\n const isValid = validators[production](str, { xmlVersion, asciiOnly });\n\n if (isValid) return { valid: true, production, input: str };\n\n let reason = 'Does not match the production rules';\n let position;\n\n // Diagnostic fallback char checks must mirror the same character set the\n // boolean validator above used, or the reported reason/position could\n // contradict the `valid: false` result (e.g. flagging a char as illegal\n // that the unicode-aware check would have accepted).\n const startCharPattern = asciiOnly ? /^[:A-Za-z_]/ : /^[:A-Za-z_\\u00C0-\\uFFFD]/;\n const namePattern = asciiOnly ? /[\\w\\-\\\\.:]/ : /[\\w\\-\\\\.:\\u00B7\\u00C0-\\uFFFD]/;\n\n if (str.length === 0) {\n reason = 'Input is empty';\n } else if (production === 'ncName' && str.includes(':')) {\n position = str.indexOf(':');\n reason = 'Colon is not allowed in NCName';\n } else if (production === 'qName' && str.startsWith(':')) {\n reason = 'QName cannot start with a colon';\n position = 0;\n } else if (production === 'qName' && str.endsWith(':')) {\n reason = 'QName cannot end with a colon';\n position = str.length - 1;\n } else if (production === 'qName' && (str.match(/:/g) || []).length > 1) {\n reason = 'QName can have at most one colon';\n position = str.lastIndexOf(':');\n } else if (\n ['name', 'ncName', 'qName'].includes(production) &&\n !startCharPattern.test(str[0])\n ) {\n reason = `First character \"${str[0]}\" is not a valid NameStartChar`;\n position = 0;\n } else {\n for (let i = 0; i < str.length; i++) {\n if (!namePattern.test(str[i])) {\n reason = `Character \"${str[i]}\" at position ${i} is not a valid NameChar`;\n position = i;\n break;\n }\n }\n }\n\n return { valid: false, production, input: str, reason, position };\n};\n\n// ---------------------------------------------------------------------------\n// Batch validator\n// ---------------------------------------------------------------------------\n\n/**\n * Validates an array of strings against a named production.\n *\n * @param {string[]} strings\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * @returns {Array<{ valid: boolean, production: string, input: string, reason?: string, position?: number }>}\n */\nexport const validateAll = (strings, production, opts = {}) =>\n strings.map(str => validate(str, production, opts));\n\n// ---------------------------------------------------------------------------\n// Sanitizer\n// ---------------------------------------------------------------------------\n\n/**\n * Transforms an invalid string into the nearest valid XML name for the given production.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ replacement?: string, asciiOnly?: boolean }} [opts]\n * asciiOnly: also replace any non-ASCII character, not just XML-illegal\n * ones (default false).\n * @returns {string}\n */\nexport const sanitize = (str, production = 'name', { replacement = '_', asciiOnly = false } = {}) => {\n if (!str) return replacement;\n\n let result = str;\n\n // Strip colons for NCName\n if (production === 'ncName') {\n result = result.replace(/:/g, '');\n }\n\n // Replace illegal characters\n const allowedCharPattern = asciiOnly ? /[^\\w\\-\\.:]/g : /[^\\w\\-\\.:\\u00B7\\u00C0-\\uFFFD]/g;\n result = result.replace(allowedCharPattern, replacement);\n\n // Fix invalid start character for Name / NCName / QName\n if (production !== 'nmToken' && production !== 'nmTokens') {\n if (/^[\\-\\.\\d]/.test(result)) {\n result = replacement + result;\n }\n }\n\n return result || replacement;\n};","import { Expression, Matcher } from 'path-expression-matcher';\nimport { safeComment, safeCdata, escapeAttribute, valToStr } from \"./util.js\";\nimport { createValidator } from 'xml-naming';\n\nconst EOL = \"\\n\";\n\n/**\n * Detect XML version from the first element of the ordered array input.\n * The first element must be a ?xml processing instruction with a version attribute.\n * Returns '1.0' if not found.\n *\n * @param {array} jArray\n * @param {object} options\n */\nfunction detectXmlVersionFromArray(jArray, options) {\n if (!Array.isArray(jArray) || jArray.length === 0) return '1.0';\n const first = jArray[0];\n const firstKey = propName(first);\n if (firstKey === '?xml') {\n const attrs = first[':@'];\n if (attrs) {\n const versionKey = options.attributeNamePrefix + 'version';\n if (attrs[versionKey]) return attrs[versionKey];\n }\n }\n return '1.0';\n}\n\n/**\n * Resolve a tag or attribute name through sanitizeName if configured.\n * Validation via xml-naming's qName is performed first; the sanitizeName\n * callback is invoked only when the name is invalid. If sanitizeName is\n * false (default), no validation occurs and the name is used as-is.\n *\n * @param {string} name - raw name from the JS object\n * @param {boolean} isAttribute - true when resolving an attribute name\n * @param {object} options\n * @param {Matcher} matcher - current matcher state (readonly from callback perspective)\n * @param {function} qNameValidator - function to validate tag names\n */\nfunction resolveTagName(name, isAttribute, options, matcher, qNameValidator) {\n if (!options.sanitizeName) return name;\n if (qNameValidator(name)) return name;\n return options.sanitizeName(name, { isAttribute, matcher: matcher.readOnly() });\n}\n\n/**\n * @param {array} jArray\n * @param {any} options\n * @returns\n */\nexport default function toXml(jArray, options) {\n let indentation = \"\";\n if (options.format) {\n indentation = EOL;\n }\n\n // Pre-compile stopNode expressions for pattern matching\n const stopNodeExpressions = [];\n if (options.stopNodes && Array.isArray(options.stopNodes)) {\n for (let i = 0; i < options.stopNodes.length; i++) {\n const node = options.stopNodes[i];\n if (typeof node === 'string') {\n stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n stopNodeExpressions.push(node);\n }\n }\n }\n\n // Detect XML version for use in name validation\n const xmlVersion = detectXmlVersionFromArray(jArray, options);\n const qNameValidator = createValidator('qName', { xmlVersion });\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n\n return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions, qNameValidator);\n}\n\nfunction arrToStr(arr, options, indentation, matcher, stopNodeExpressions, qNameValidator) {\n let xmlStr = \"\";\n let isPreviousElementTag = false;\n\n if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n\n if (!Array.isArray(arr)) {\n // Non-array values (e.g. string tag values) should be treated as text content\n if (arr !== undefined && arr !== null) {\n let text = valToStr(arr);\n text = replaceEntitiesValue(text, options);\n return text;\n }\n return \"\";\n }\n\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const rawTagName = propName(tagObj);\n if (rawTagName === undefined) continue;\n\n // Special names are exempt from sanitizeName: internal conventions and PI tags\n // are not user-supplied XML element names.\n const isSpecialName = rawTagName === options.textNodeName\n || rawTagName === options.cdataPropName\n || rawTagName === options.commentPropName\n || rawTagName[0] === '?';\n\n // Resolve tag name (may transform it; may throw for invalid names)\n const tagName = isSpecialName\n ? rawTagName\n : resolveTagName(rawTagName, false, options, matcher, qNameValidator);\n\n // Extract attributes from \":@\" property\n const attrValues = extractAttributeValues(tagObj[\":@\"], options);\n\n // Push resolved tag to matcher WITH attributes\n matcher.push(tagName, attrValues);\n\n // Check if this is a stop node using Expression matching\n const isStopNode = checkStopNode(matcher, stopNodeExpressions);\n\n if (tagName === options.textNodeName) {\n let tagText = tagObj[rawTagName];\n if (!isStopNode) {\n tagText = options.tagValueProcessor(tagName, tagText);\n tagText = replaceEntitiesValue(tagText, options);\n }\n tagText = valToStr(tagText);\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += tagText;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.cdataPropName) {\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n const val = tagObj[rawTagName][0][options.textNodeName];\n const safeVal = safeCdata(val);\n xmlStr += ``;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.commentPropName) {\n const val = tagObj[rawTagName][0][options.textNodeName];\n const safeVal = safeComment(val);\n xmlStr += indentation + ``;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n } else if (tagName[0] === \"?\") {\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode, matcher, qNameValidator);\n const tempInd = tagName === \"?xml\" ? \"\" : indentation;\n // Text node content on PI/XML declaration tags is intentionally ignored.\n // Only attributes are valid on these tags per the XML spec.\n xmlStr += tempInd + `<${tagName}${attStr}?>`;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n }\n\n let newIdentation = indentation;\n if (newIdentation !== \"\") {\n newIdentation += options.indentBy;\n }\n\n // Pass isStopNode to attr_to_str so attributes are also not processed for stopNodes\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode, matcher, qNameValidator);\n const tagStart = indentation + `<${tagName}${attStr}`;\n\n // If this is a stopNode, get raw content without processing\n let tagValue;\n if (isStopNode) {\n tagValue = getRawContent(tagObj[rawTagName], options);\n } else {\n tagValue = arrToStr(tagObj[rawTagName], options, newIdentation, matcher, stopNodeExpressions, qNameValidator);\n }\n\n if (options.unpairedTags.indexOf(tagName) !== -1) {\n if (options.suppressUnpairedNode) xmlStr += tagStart + \">\";\n else xmlStr += tagStart + \"/>\";\n } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) {\n xmlStr += tagStart + \"/>\";\n } else if (tagValue && tagValue.endsWith(\">\")) {\n xmlStr += tagStart + `>${tagValue}${indentation}`;\n } else {\n xmlStr += tagStart + \">\";\n if (tagValue && indentation !== \"\" && (tagValue.includes(\"/>\") || tagValue.includes(\"`;\n }\n isPreviousElementTag = true;\n\n // Pop tag from matcher\n matcher.pop();\n }\n\n return xmlStr;\n}\n\n/**\n * Extract attribute values from the \":@\" object and return as plain object\n * for passing to matcher.push()\n */\nfunction extractAttributeValues(attrMap, options) {\n if (!attrMap || options.ignoreAttributes) return null;\n\n const attrValues = {};\n let hasAttrs = false;\n\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // Remove the attribute prefix to get clean attribute name\n const cleanAttrName = attr.startsWith(options.attributeNamePrefix)\n ? attr.substr(options.attributeNamePrefix.length)\n : attr;\n attrValues[cleanAttrName] = escapeAttribute(attrMap[attr]);\n hasAttrs = true;\n }\n\n return hasAttrs ? attrValues : null;\n}\n\n/**\n * Extract raw content from a stopNode without any processing\n * This preserves the content exactly as-is, including special characters\n */\nfunction getRawContent(arr, options) {\n if (!Array.isArray(arr)) {\n // Non-array values return as-is\n if (arr !== undefined && arr !== null) {\n return valToStr(arr);\n }\n return \"\";\n }\n\n let content = \"\";\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n const tagName = propName(item);\n\n if (tagName === options.textNodeName) {\n // Raw text content - NO processing, NO entity replacement\n content += valToStr(item[tagName]);\n } else if (tagName === options.cdataPropName) {\n // CDATA content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName === options.commentPropName) {\n // Comment content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName && tagName[0] === \"?\") {\n // Processing instruction - skip for stopNodes\n continue;\n } else if (tagName) {\n // Nested tags within stopNode — no sanitizeName, content is raw\n const attStr = attr_to_str_raw(item[\":@\"], options);\n const nestedContent = getRawContent(item[tagName], options);\n\n if (!nestedContent || nestedContent.length === 0) {\n content += `<${tagName}${attStr}/>`;\n } else {\n content += `<${tagName}${attStr}>${nestedContent}`;\n }\n }\n }\n return content;\n}\n\n/**\n * Build attribute string for stopNodes - NO entity replacement\n */\nfunction attr_to_str_raw(attrMap, options) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // For stopNodes, use raw value without processing\n let attrVal = attrMap[attr];\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${escapeAttribute(attrVal)}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n if (key !== \":@\") return key;\n }\n}\n\n/**\n * Build attribute string, resolving attribute names through sanitizeName when configured.\n * Accepts matcher so the callback has path context.\n */\nfunction attr_to_str(attrMap, options, isStopNode, matcher, qNameValidator) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n\n // Strip prefix to get the clean XML attribute name, then optionally sanitize it\n const cleanAttrName = attr.substr(options.attributeNamePrefix.length);\n const resolvedAttrName = isStopNode\n ? cleanAttrName // stopNodes are raw — skip sanitizeName for attr names too\n : resolveTagName(cleanAttrName, true, options, matcher, qNameValidator);\n\n let attrVal;\n if (isStopNode) {\n // For stopNodes, use raw value without any processing\n attrVal = attrMap[attr];\n } else {\n // Normal processing: apply attributeValueProcessor and entity replacement\n attrVal = options.attributeValueProcessor(attr, attrMap[attr]);\n attrVal = replaceEntitiesValue(attrVal, options);\n }\n\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${resolvedAttrName}`;\n } else {\n attrStr += ` ${resolvedAttrName}=\"${escapeAttribute(attrVal)}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction checkStopNode(matcher, stopNodeExpressions) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\nfunction replaceEntitiesValue(textValue, options) {\n if (textValue && textValue.length > 0 && options.processEntities) {\n for (let i = 0; i < options.entities.length; i++) {\n const entity = options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}","'use strict';\n//parse Empty Node as self closing node\nimport buildFromOrderedJs from './orderedJs2Xml.js';\nimport getIgnoreAttributesFn from \"./ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\nimport { safeComment, safeCdata, escapeAttribute, valToStr } from './util.js';\nimport { createValidator } from 'xml-naming';\n\nconst defaultOptions = {\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n cdataPropName: false,\n format: false,\n indentBy: ' ',\n suppressEmptyNode: false,\n suppressUnpairedNode: true,\n suppressBooleanAttributes: true,\n tagValueProcessor: function (key, a) {\n return a;\n },\n attributeValueProcessor: function (attrName, a) {\n return a;\n },\n preserveOrder: false,\n commentPropName: false,\n unpairedTags: [],\n entities: [\n { regex: new RegExp(\"&\", \"g\"), val: \"&\" },//it must be on top\n { regex: new RegExp(\">\", \"g\"), val: \">\" },\n { regex: new RegExp(\"<\", \"g\"), val: \"<\" },\n { regex: new RegExp(\"\\'\", \"g\"), val: \"'\" },\n { regex: new RegExp(\"\\\"\", \"g\"), val: \""\" }\n ],\n processEntities: true,\n stopNodes: [],\n // transformTagName: false,\n // transformAttributeName: false,\n oneListGroup: false,\n maxNestedTags: 100,\n jPath: true, // When true, callbacks receive string jPath; when false, receive Matcher instance\n sanitizeName: false // false = allow all names as-is (default, backward-compatible).\n // Set to a function (name, { isAttribute, matcher }) => string to\n // validate/sanitize tag and attribute names. Throw inside the function\n // to reject an invalid name.\n};\n\nexport default function Builder(options) {\n this.options = Object.assign({}, defaultOptions, options);\n\n // Convert old-style stopNodes for backward compatibility\n // Old syntax: \"*.tag\" meant \"tag anywhere in tree\"\n // New syntax: \"..tag\" means \"tag anywhere in tree\"\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n this.options.stopNodes = this.options.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Convert old wildcard syntax to deep wildcard\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n\n // Pre-compile stopNode expressions for pattern matching\n this.stopNodeExpressions = [];\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const node = this.options.stopNodes[i];\n if (typeof node === 'string') {\n this.stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n this.stopNodeExpressions.push(node);\n }\n }\n }\n\n if (this.options.ignoreAttributes === true || this.options.attributesGroupName) {\n this.isAttribute = function (/*a*/) {\n return false;\n };\n } else {\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.attrPrefixLen = this.options.attributeNamePrefix.length;\n this.isAttribute = isAttribute;\n }\n\n this.processTextOrObjNode = processTextOrObjNode\n\n if (this.options.format) {\n this.indentate = indentate;\n this.tagEndChar = '>\\n';\n this.newLine = '\\n';\n } else {\n this.indentate = function () {\n return '';\n };\n this.tagEndChar = '>';\n this.newLine = '';\n }\n}\n\n/**\n * Detect XML version from the ?xml declaration at the root of a plain-object input.\n * Checks both attributesGroupName and flat attribute forms.\n * Returns '1.0' if no declaration is found.\n */\nfunction detectXmlVersionFromObj(jObj, options) {\n const decl = jObj['?xml'];\n if (decl && typeof decl === 'object') {\n // attributesGroupName path e.g. { '$$': { '@_version': '1.1' } }\n if (options.attributesGroupName && decl[options.attributesGroupName]) {\n const v = decl[options.attributesGroupName][options.attributeNamePrefix + 'version'];\n if (v) return v;\n }\n // flat attribute path e.g. { '@_version': '1.1' }\n const v = decl[options.attributeNamePrefix + 'version'];\n if (v) return v;\n }\n return '1.0';\n}\n\n/**\n * Resolve a tag or attribute name through sanitizeName if configured.\n * Validation via xml-naming's qName is performed first; the sanitizeName\n * callback is invoked only when the name is invalid. If sanitizeName is\n * false (default), no validation occurs and the name is used as-is.\n *\n * @param {string} name - raw name from the JS object\n * @param {boolean} isAttribute - true when resolving an attribute name\n * @param {object} options\n * @param {Matcher} matcher - current matcher state (readonly from callback perspective)\n * @param {function} qNameValidator - function to validate tag names\n */\nfunction resolveTagName(name, isAttribute, options, matcher, qNameValidator) {\n if (!options.sanitizeName) return name;\n if (qNameValidator(name)) return name;\n return options.sanitizeName(name, { isAttribute, matcher: matcher.readOnly() });\n}\n\nBuilder.prototype.build = function (jObj) {\n if (this.options.preserveOrder) {\n return buildFromOrderedJs(jObj, this.options);\n } else {\n if (Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1) {\n jObj = {\n [this.options.arrayNodeName]: jObj\n }\n }\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n const xmlVersion = detectXmlVersionFromObj(jObj, this.options);\n const qNameValidator = createValidator('qName', { xmlVersion });\n return this.j2x(jObj, 0, matcher, qNameValidator).val;\n }\n};\n\nBuilder.prototype.j2x = function (jObj, level, matcher, qNameValidator) {\n let attrStr = '';\n let val = '';\n if (this.options.maxNestedTags && matcher.getDepth() >= this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n // Get jPath based on option: string for backward compatibility, or Matcher for new features\n const jPath = this.options.jPath ? matcher.toString() : matcher;\n\n // Check if current node is a stopNode (will be used for attribute encoding)\n const isCurrentStopNode = this.checkStopNode(matcher);\n\n for (let key in jObj) {\n if (!Object.prototype.hasOwnProperty.call(jObj, key)) continue;\n\n // Resolve the key through sanitizeName before any use.\n // Special keys (textNodeName, cdataPropName, commentPropName, attributeNamePrefix,\n // attributesGroupName, \"?\" PI tags) are exempt — they are builder-internal conventions,\n // not user-supplied XML names.\n const isSpecialKey = key === this.options.textNodeName\n || key === this.options.cdataPropName\n || key === this.options.commentPropName\n || (this.options.attributesGroupName && key === this.options.attributesGroupName)\n || this.isAttribute(key)\n || key[0] === '?';\n\n const resolvedKey = isSpecialKey\n ? key\n : resolveTagName(key, false, this.options, matcher, qNameValidator);\n\n if (typeof jObj[key] === 'undefined') {\n // supress undefined node only if it is not an attribute\n if (this.isAttribute(key)) {\n val += '';\n }\n } else if (jObj[key] === null) {\n // null attribute should be ignored by the attribute list, but should not cause the tag closing\n if (this.isAttribute(key)) {\n val += '';\n } else if (resolvedKey === this.options.cdataPropName || resolvedKey === this.options.commentPropName) {\n val += '';\n } else if (resolvedKey[0] === '?') {\n val += this.indentate(level) + '<' + resolvedKey + '?' + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + resolvedKey + '/' + this.tagEndChar;\n }\n } else if (jObj[key] instanceof Date) {\n val += this.buildTextValNode(jObj[key], resolvedKey, '', level, matcher);\n } else if (typeof jObj[key] !== 'object') {\n //premitive type\n const attr = this.isAttribute(key);\n if (attr && !this.ignoreAttributesFn(attr, jPath)) {\n // Resolve the attribute name through sanitizeName\n const resolvedAttr = resolveTagName(attr, true, this.options, matcher, qNameValidator);\n attrStr += this.buildAttrPairStr(resolvedAttr, valToStr(jObj[key]), isCurrentStopNode);\n } else if (!attr) {\n //tag value\n if (key === this.options.textNodeName) {\n let newval = this.options.tagValueProcessor(key, valToStr(jObj[key]));\n val += this.replaceEntitiesValue(newval);\n } else {\n // Check if this is a stopNode before building\n matcher.push(resolvedKey);\n const isStopNode = this.checkStopNode(matcher);\n matcher.pop();\n\n if (isStopNode) {\n // Build as raw content without encoding\n const textValue = valToStr(jObj[key]);\n if (textValue === '') {\n val += this.indentate(level) + '<' + resolvedKey + this.closeTag(resolvedKey) + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + resolvedKey + '>' + textValue + '' + textValue + '${item}`;\n } else if (typeof item === 'object' && item !== null) {\n const nestedContent = this.buildRawContent(item);\n const nestedAttrs = this.buildAttributesForStopNode(item);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n }\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object\n const nestedContent = this.buildRawContent(value);\n const nestedAttrs = this.buildAttributesForStopNode(value);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n } else {\n // Primitive value\n content += `<${key}>${value}`;\n }\n }\n\n return content;\n};\n\n// Build attribute string for stopNode (no entity encoding)\nBuilder.prototype.buildAttributesForStopNode = function (obj) {\n if (!obj || typeof obj !== 'object') return '';\n\n let attrStr = '';\n\n // Check for attributesGroupName (when attributes are grouped)\n if (this.options.attributesGroupName && obj[this.options.attributesGroupName]) {\n const attrGroup = obj[this.options.attributesGroupName];\n for (let attrKey in attrGroup) {\n if (!Object.prototype.hasOwnProperty.call(attrGroup, attrKey)) continue;\n const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix)\n ? attrKey.substring(this.options.attributeNamePrefix.length)\n : attrKey;\n const val = attrGroup[attrKey];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + cleanKey;\n } else {\n // stopNode content is raw, but the quote delimiter is always escaped\n // so a quote in the value cannot break out of the attribute (see orderedJs2Xml attr_to_str)\n attrStr += ' ' + cleanKey + '=\"' + escapeAttribute(val) + '\"';\n }\n }\n } else {\n // Look for individual attributes\n for (let key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const attr = this.isAttribute(key);\n if (attr) {\n const val = obj[key];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + attr;\n } else {\n // stopNode content is raw, but the quote delimiter is always escaped\n // so a quote in the value cannot break out of the attribute (see orderedJs2Xml attr_to_str)\n attrStr += ' ' + attr + '=\"' + escapeAttribute(val) + '\"';\n }\n }\n }\n }\n\n return attrStr;\n};\n\nBuilder.prototype.buildObjectNode = function (val, key, attrStr, level) {\n if (val === \"\") {\n if (key[0] === \"?\") return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n else {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n }\n } else if (key[0] === \"?\") {\n // PI/XML-declaration tags never have body content — treat them like empty.\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n let tagEndExp = '' + val + tagEndExp);\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) {\n return this.indentate(level) + `` + this.newLine;\n } else {\n return (\n this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar +\n val +\n this.indentate(level) + tagEndExp);\n }\n }\n}\n\nBuilder.prototype.closeTag = function (key) {\n let closeTag = \"\";\n if (this.options.unpairedTags.indexOf(key) !== -1) { //unpaired\n if (!this.options.suppressUnpairedNode) closeTag = \"/\"\n } else if (this.options.suppressEmptyNode) { //empty\n closeTag = \"/\";\n } else {\n closeTag = `>` + this.newLine;\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName) {\n const safeVal = safeComment(val);\n return this.indentate(level) + `` + this.newLine;\n } else if (key[0] === \"?\") {//PI tag\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n // Normal processing: apply tagValueProcessor and entity replacement\n let textValue = this.options.tagValueProcessor(key, val);\n textValue = this.replaceEntitiesValue(textValue);\n // tagValueProcessor may return the raw value unchanged (default is identity), and\n // replaceEntitiesValue no-ops on non-strings, so a plain number can still reach here;\n // stringify it now, sign-preserving, before it's implicitly ToString'd below.\n textValue = valToStr(textValue);\n\n if (textValue === '') {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n } else {\n return this.indentate(level) + '<' + key + attrStr + '>' +\n textValue +\n ' 0 && this.options.processEntities) {\n for (let i = 0; i < this.options.entities.length; i++) {\n const entity = this.options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction indentate(level) {\n return this.options.indentBy.repeat(level);\n}\n\nfunction isAttribute(name /*, options*/) {\n if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) {\n return name.substr(this.attrPrefixLen);\n } else {\n return false;\n }\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","Expression","constructor","pattern","options","data","separator","segments","_parse","_hasDeepWildcard","some","seg","type","_hasAttributeCondition","undefined","attrName","_hasPositionSelector","position","i","currentPart","length","trim","push","_parseSegment","part","segment","bracketContent","withoutBrackets","bracketMatch","match","content","slice","namespace","tag","tagAndPosition","includes","nsIndex","indexOf","substring","Error","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","test","eqIndex","attrValue","nthMatch","positionValue","parseInt","hasDeepWildcard","hasAttributeCondition","hasPositionSelector","toString","MatcherView","matcher","_matcher","getCurrentTag","path","getCurrentNamespace","getAttrValue","values","hasAttr","current","getAnyParentAttr","hasAnyParentAttr","getPosition","getCounter","counter","getIndex","getDepth","includeNamespace","toArray","map","n","matches","expression","matchesAny","exprSet","Matcher","siblingStacks","_pathStringCache","_view","_keptAttrs","tagName","attrValues","currentLevel","level","counts","Map","total","siblingKey","set","node","depth","keep","name","pop","poppedDepth","updateCurrent","kept","sep","result","join","reset","_matchWithDeepWildcard","_matchSimple","_matchSegment","pathIdx","segIdx","nextSeg","found","isCurrentNode","String","snapshot","keptAttrs","entry","restore","readOnly","valToStr","val","is","safeComment","replace","safeCdata","escapeAttribute","nameStartChar10","nameStartChar11","nameChar11","buildRegexes","startChar","char","flags","ncNamePat","RegExp","ncName","qName","nmToken","nmTokens","regexes10","regexes11","nameStartCharAscii","regexesAscii","PRODUCTIONS","createValidator","production","xmlVersion","asciiOnly","maxCacheSize","TypeError","regex","getRegexes","cache","validator","str","cached","size","resolveTagName","isAttribute","qNameValidator","sanitizeName","toXml","jArray","indentation","format","stopNodeExpressions","stopNodes","Array","isArray","first","propName","attrs","versionKey","attributeNamePrefix","detectXmlVersionFromArray","arrToStr","arr","xmlStr","isPreviousElementTag","maxNestedTags","text","replaceEntitiesValue","tagObj","rawTagName","textNodeName","cdataPropName","commentPropName","extractAttributeValues","isStopNode","checkStopNode","newIdentation","indentBy","tagStart","attr_to_str","tagValue","getRawContent","unpairedTags","suppressUnpairedNode","suppressEmptyNode","endsWith","tagText","tagValueProcessor","attrMap","ignoreAttributes","hasAttrs","attr","startsWith","substr","item","attStr","attr_to_str_raw","nestedContent","attrStr","attrVal","suppressBooleanAttributes","keys","cleanAttrName","resolvedAttrName","attributeValueProcessor","textValue","processEntities","entities","entity","_createForOfIteratorHelperLoose","r","e","t","iterator","next","bind","a","_arrayLikeToArray","from","_unsupportedIterableToArray","done","defaultOptions","attributesGroupName","preserveOrder","oneListGroup","jPath","Builder","assign","ignoreAttributesFn","_step","_iterator","attrPrefixLen","processTextOrObjNode","indentate","tagEndChar","newLine","object","extractAttributes","rawContent","buildRawContent","buildAttributesForStopNode","buildObjectNode","j2x","buildTextValNode","repeat","build","jObj","buildFromOrderedJs","_jObj","arrayNodeName","decl","v","detectXmlVersionFromObj","isCurrentStopNode","resolvedKey","Date","resolvedAttr","buildAttrPairStr","newval","closeTag","arrLen","listTagVal","listTagAttr","j","Ks","L","attrGroup","attrKey","nestedAttrs","cleanKey","tagEndExp","piClosingChar","safeVal"],"sourceRoot":""}