UNPKG

ngx-html-bridge

Version:

An Angular Template Parser to convert Angular templates into an array of standard, static HTML strings.

1,743 lines (1,735 loc) 959 kB
// src/main.ts import * as fs from "node:fs"; // src/core/dom/index.ts import { JSDOM } from "jsdom"; var jsdom = new JSDOM(); var document = jsdom.window.document; // src/core/transformer/element.ts import { parse } from "@typescript-eslint/typescript-estree"; // src/core/html-spec/attributes.ts var VALID_HTML_ATTRIBUTES = /* @__PURE__ */ new Set([ "accesskey", "autocapitalize", "autocorrect", "autofocus", "contenteditable", "dir", "draggable", "enterkeyhint", "hidden", "inert", "inputmode", "is", "itemid", "itemprop", "itemref", "itemscope", "itemtype", "lang", "nonce", "popover", "spellcheck", "style", "tabindex", "title", "translate", "writingsuggestions", "class", "id", "slot", "xmlns", "xml:lang", "xml:space", "elementtiming", "onabort", "onauxclick", "onbeforeinput", "onbeforematch", "onbeforetoggle", "onblur", "oncancel", "oncanplay", "oncanplaythrough", "onchange", "onclick", "onclose", "oncommand", "oncontextlost", "oncompositionstart", "oncompositionupdate", "oncompositionend", "oncontextmenu", "oncontextrestored", "oncopy", "oncuechange", "oncut", "ondblclick", "ondrag", "ondragend", "ondragenter", "ondragleave", "ondragover", "ondragstart", "ondrop", "ondurationchange", "onemptied", "onended", "onerror", "onfocus", "onformdata", "onfocusin", "onfocusout", "oninput", "oninvalid", "onkeydown", "onkeypress", "onkeyup", "onload", "onloadeddata", "onloadedmetadata", "onloadstart", "onmousedown", "onmouseenter", "onmouseleave", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onpaste", "onpause", "onplay", "onplaying", "onprogress", "onratechange", "onreset", "onresize", "onscroll", "onscrollend", "onsecuritypolicyviolation", "onseeked", "onseeking", "onselect", "onslotchange", "onstalled", "onsubmit", "onsuspend", "ontimeupdate", "ontoggle", "onvolumechange", "onwaiting", "onunload", "onwheel", "onanimationstart", "onanimationiteration", "onanimationend", "onanimationcancel", "ontransitionrun", "ontransitionstart", "ontransitionend", "ontransitioncancel", "onwebkitanimationend", "onwebkitanimationiteration", "onwebkitanimationstart", "onwebkittransitionend", "href", "target", "download", "ping", "rel", "hreflang", "type", "referrerpolicy", "loading", "integrity", "media", "crossorigin", "fetchpriority", "src", "preload", "autoplay", "loop", "muted", "controls", "height", "srcset", "sizes", "width", "autocomplete", "dirname", "disabled", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "name", "maxlength", "minlength", "readonly", "required", "colspan", "rowspan", "headers", "role", "additive", "accumulate", "attributeName", "attributeType", "onbegin", "onend", "onrepeat", "xlink:href", "begin", "dur", "end", "min", "max", "restart", "repeatCount", "repeatDur", "fill", "calcMode", "values", "keyTimes", "keySplines", "from", "to", "by", "accelerate", "decelerate", "autoReverse", "speed", "requiredExtensions", "systemLanguage", "requiredFeatures", "xml:base", "x", "y", "result", "in", "cx", "cy", "r", "rx", "ry", "d", "transform", "transform-origin", "patternTransform", "gradientTransform", "alignment-baseline", "baseline-shift", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "cursor", "direction", "display", "dominant-baseline", "fill-opacity", "fill-rule", "filter", "flood-color", "flood-opacity", "font", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "glyph-orientation-horizontal", "glyph-orientation-vertical", "image-rendering", "isolation", "letter-spacing", "lighting-color", "marker", "marker-end", "marker-mid", "marker-start", "mask", "mask-type", "opacity", "overflow", "paint-order", "pointer-events", "shape-rendering", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-anchor", "text-decoration", "text-overflow", "text-rendering", "unicode-bidi", "vector-effect", "visibility", "white-space", "word-spacing", "writing-mode", "clip", "color-profile", "color-rendering", "enable-background", "kerning", "tableValues", "slope", "intercept", "amplitude", "exponent", "offset", "xlink:title", "xlink:type", "xlink:role", "xlink:arcrole", "xlink:show", "xlink:actuate", "aria-activedescendant", "aria-atomic", "aria-autocomplete", "aria-braillelabel", "aria-brailleroledescription", "aria-busy", "aria-checked", "aria-colcount", "aria-colindex", "aria-colindextext", "aria-colspan", "aria-controls", "aria-current", "aria-describedby", "aria-description", "aria-details", "aria-disabled", "aria-dropeffect", "aria-errormessage", "aria-expanded", "aria-flowto", "aria-grabbed", "aria-haspopup", "aria-hidden", "aria-invalid", "aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-level", "aria-live", "aria-modal", "aria-multiline", "aria-multiselectable", "aria-orientation", "aria-owns", "aria-placeholder", "aria-posinset", "aria-pressed", "aria-readonly", "aria-relevant", "aria-required", "aria-roledescription", "aria-rowcount", "aria-rowindex", "aria-rowindextext", "aria-rowspan", "aria-selected", "aria-setsize", "aria-sort", "aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-valuetext", "attributionsrc", "charset", "coords", "rev", "shape", "alt", "controlslist", "disableremoteplayback", "cite", "alink", "background", "bgcolor", "bottommargin", "leftmargin", "link", "onafterprint", "onbeforeprint", "onbeforeunload", "onhashchange", "onlanguagechange", "onmessage", "onmessageerror", "onoffline", "ononline", "onpagehide", "onpagereveal", "onpageshow", "onpageswap", "onpopstate", "onrejectionhandled", "onstorage", "onunhandledrejection", "rightmargin", "text", "topmargin", "vlink", "clear", "command", "commandfor", "popovertarget", "popovertargetaction", "value", "moz-opaque", "align", "char", "charoff", "span", "valign", "datetime", "open", "closedby", "compact", "face", "size", "accept", "accept-charset", "action", "enctype", "method", "novalidate", "frameborder", "marginheight", "marginwidth", "noresize", "scrolling", "cols", "rows", "profile", "noshade", "version", "allow", "allowfullscreen", "allowpaymentrequest", "browsingtopics", "credentialless", "csp", "longdesc", "sandbox", "srcdoc", "border", "decoding", "hspace", "ismap", "usemap", "vspace", "alpha", "capture", "checked", "colorspace", "incremental", "list", "multiple", "orient", "pattern", "placeholder", "results", "step", "webkitdirectory", "for", "as", "blocking", "imagesizes", "imagesrcset", "behavior", "scrollamount", "scrolldelay", "truespeed", "content", "http-equiv", "high", "low", "optimum", "archive", "classid", "codebase", "codetype", "data", "declare", "standby", "reversed", "start", "label", "selected", "valuetype", "wrap", "async", "defer", "language", "nomodule", "cellpadding", "cellspacing", "frame", "rules", "summary", "abbr", "axis", "scope", "shadowrootclonable", "shadowrootdelegatesfocus", "shadowrootmode", "shadowrootserializable", "default", "kind", "srclang", "disablepictureinpicture", "playsinline", "poster", "keyPoints", "origin", "path", "rotate", "pathLength", "clipPathUnits", "externalResourcesRequired", "in2", "mode", "k1", "k2", "k3", "k4", "operator", "bias", "divisor", "edgeMode", "kernelMatrix", "kernelUnitLength", "order", "preserveAlpha", "targetX", "targetY", "diffuseConstant", "surfaceScale", "scale", "xChannelSelector", "yChannelSelector", "azimuth", "elevation", "dx", "dy", "stdDeviation", "preserveAspectRatio", "radius", "z", "specularConstant", "specularExponent", "limitingConeAngle", "pointsAtX", "pointsAtY", "pointsAtZ", "baseFrequency", "numOctaves", "seed", "stitchTiles", "filterRes", "filterUnits", "primitiveUnits", "x1", "x2", "y1", "y2", "gradientUnits", "spreadMethod", "markerHeight", "markerUnits", "markerWidth", "refX", "refY", "viewBox", "maskContentUnits", "maskUnits", "patternContentUnits", "patternUnits", "points", "fr", "fx", "fy", "baseProfile", "contentScriptType", "contentStyleType", "lengthAdjust", "textLength", "side", "spacing", "startOffset", "viewTarget", "zoomAndPan" ]); // src/core/properties/utils.ts import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/typescript-estree"; var castNode = (node) => node; var castAST = (ast) => ast; var isTSESTreeCallExpression = (node) => node?.type === TSESTree.AST_NODE_TYPES.CallExpression; var isTSESTreeBinaryExpression = (node) => node?.type === TSESTree.AST_NODE_TYPES.BinaryExpression; var isTSESTreeArrayExpression = (node) => node?.type === TSESTree.AST_NODE_TYPES.ArrayExpression; var isTSESTreeSpreadElement = (node) => node?.type === TSESTree.AST_NODE_TYPES.SpreadElement; var isTSESTreeIdentifier = (node) => node?.type === TSESTree.AST_NODE_TYPES.Identifier; var isTSESTreeLiteral = (node) => node?.type === TSESTree.AST_NODE_TYPES.Literal; var isTSESTreeConditionalExpression = (node) => node?.type === TSESTree.AST_NODE_TYPES.ConditionalExpression; var isTSESExportNamedDeclaration = (statement) => statement?.type === AST_NODE_TYPES.ExportNamedDeclaration; var isTSESClassDeclaration = (declaration) => declaration?.declaration?.type === AST_NODE_TYPES.ClassDeclaration; var isTSEStreePropertyDefinition = (classElement) => classElement?.type === AST_NODE_TYPES.PropertyDefinition; var isComponentClass = (declaration) => { if (!declaration.declaration) { return false; } const decoratorNames = castNode( declaration.declaration ).decorators.map((decorator) => { const expression = decorator.expression; const callee = castNode(expression).callee; const identifier = castNode(callee); return identifier.name; }); return decoratorNames.includes("Component"); }; // src/core/transformer/combination-generator.ts var generateCombinations = (arrays) => { const result = []; function backtrack(index, current) { if (index === arrays.length) { result.push([...current]); return; } for (const subArray of arrays[index]) { for (const value of subArray) { current.push(value); } backtrack(index + 1, current); for (let i = 0; i < subArray.length; i++) { current.pop(); } } } backtrack(0, []); return result; }; var generateAttrCombinations = (ternaryAttrs) => { const result = []; function backtrack(index, currentCombination) { if (index === ternaryAttrs.length) { result.push([...currentCombination]); return; } const currentAttributeValues = ternaryAttrs[index]; for (const attr of currentAttributeValues) { currentCombination.push(attr); backtrack(index + 1, currentCombination); currentCombination.pop(); } } backtrack(0, []); return result; }; // src/core/transformer/element.ts var attributeNames = []; var transformTmplAstElement = async (element2, tmplAstTemplates, metadata, transformTmplAstNodes2, option) => { if (element2.name === "ng-container") { return [ ...await transformTmplAstNodes2( element2.children, tmplAstTemplates, metadata, option ) ]; } const parsedElementNodes = []; const { properties } = metadata; const properties2DArray = pairwisePropertyNameAndValue( element2.inputs, properties, option ); const attribute2DArray = pairwiseAttributeNameAndValue( element2.attributes, option ); const children2DArray = await transformTmplAstNodes2( element2.children, tmplAstTemplates, metadata, option ); for (const props of properties2DArray) { for (const attributes of attribute2DArray) { for (const children of children2DArray) { const elementNode = document.createElement(element2.name); elementNode.setAttribute( "data-ngx-html-bridge-line", element2.sourceSpan.start.line.toString() ); elementNode.setAttribute( "data-ngx-html-bridge-col", element2.sourceSpan.start.col.toString() ); elementNode.setAttribute( "data-ngx-html-bridge-start-offset", element2.sourceSpan.start.offset.toString() ); elementNode.setAttribute( "data-ngx-html-bridge-end-offset", element2.sourceSpan.end.offset.toString() ); for (const child of children) { elementNode.appendChild(child.cloneNode(true)); } for (const attribute2 of attributes) { const value = attribute2.value; if (!(value === null || value === void 0)) { attributeNames.push(attribute2.name); elementNode.setAttribute( `data-ngx-html-bridge-${attribute2.name}-start-offset`, attribute2.sourceSpan.start.offset.toString() ); elementNode.setAttribute( `data-ngx-html-bridge-${attribute2.name}-end-offset`, attribute2.sourceSpan.end.offset.toString() ); elementNode.setAttribute(attribute2.name, value); } } for (const prop of props) { const value = prop.value; if (!(value === null || value === void 0)) { attributeNames.push(prop.name); elementNode.setAttribute( `data-ngx-html-bridge-${prop.name}-start-offset`, prop.sourceSpan.start.offset.toString() ); elementNode.setAttribute( `data-ngx-html-bridge-${prop.name}-end-offset`, prop.sourceSpan.end.offset.toString() ); elementNode.setAttribute(prop.name, value); } } parsedElementNodes.push([elementNode]); } } } return parsedElementNodes; }; var pairwiseAttributeNameAndValue = (tmplAstTextAttributes, option) => { const attributesOrInputs = tmplAstTextAttributes.map((attr) => ({ name: attr.name, value: attr.value, sourceSpan: attr.sourceSpan })); const attributes = attributesOrInputs.filter( (attributeOrInput) => VALID_HTML_ATTRIBUTES.has(attributeOrInput.name) || option.includedAttributes?.map((attr) => new RegExp(attr)).find((regex) => regex.test(attributeOrInput.name)) ); return [[...attributes]]; }; var pairwisePropertyNameAndValue = (tmplAstBoundAttributes, properties, option) => { const listOfPossibleAttributeValues = tmplAstBoundAttributes.filter( (attributeOrInput) => VALID_HTML_ATTRIBUTES.has(attributeOrInput.name) || option.includedAttributes?.includes(attributeOrInput.name) ).filter((attribute2) => { const details = attribute2.keySpan.details; if (!details) { return true; } return !(details.includes("class.") || details.includes("style.")); }).map((attr) => { try { const rawSource = castAST(attr.value).source || ""; const source = rawSource.replace(/\}\}(.*)\{\{/g, "}} + '$1' + {{").replace(/^(.*?)\{\{/, "'$1' + {{").replace(/\{\{(.*?)\}\}/g, "$1"); const body = parse(source.replace(/(.*)\{\{(.*)\}\}/, "'$1' + $2")).body[0]; const expression = castNode(body).expression; const values = parseExpressionIntoLiterals(expression, properties); return values.map((value) => ({ name: attr.name, value, sourceSpan: attr.sourceSpan })); } catch { return [ { name: attr.name, value: "some-random-value", sourceSpan: attr.sourceSpan } ]; } }).filter((attr) => !!attr); return generateAttrCombinations(listOfPossibleAttributeValues); }; var parseExpressionIntoLiterals = (expression, properties) => { if (isTSESTreeConditionalExpression(expression)) { const { consequent, alternate } = castNode(expression); return [ ...parseExpressionIntoLiterals(consequent, properties), ...parseExpressionIntoLiterals(alternate, properties) ]; } if (isTSESTreeLiteral(expression)) { const literal2 = castNode(expression); if (literal2.raw === "null") { return [null]; } const literalValue = literal2.value?.toString(); return [literalValue || ""]; } if (isTSESTreeIdentifier(expression)) { const name = castNode(expression).name || ""; if (name === "undefined") { return [void 0]; } return [properties.get(name) || "some-random-value"]; } if (isTSESTreeCallExpression(expression)) { const callee = castNode(expression).callee; return parseExpressionIntoLiterals(callee, properties); } if (isTSESTreeBinaryExpression(expression)) { const binaryExpression = castNode(expression); if (binaryExpression.operator === "+") { const left = parseExpressionIntoLiterals( binaryExpression.left, properties ).filter((operand) => !!operand); const right = parseExpressionIntoLiterals( binaryExpression.right, properties ).filter((operand) => !!operand); const result = []; for (const leftOperand of left) { for (const rightOperand of right) { result.push(leftOperand.toString() + rightOperand.toString()); } } return result; } } return ["some-random-value"]; }; // src/core/generator/index.ts var generateHTMLs = (node2DArray) => { return node2DArray.map((nodeArray) => generateHTML(nodeArray)); }; var generateHTML = (nodes) => { const annotatedContainer = document.createElement("div"); for (const node of nodes) { annotatedContainer.appendChild(node); } const annotated = annotatedContainer.innerHTML; const plainContainer = document.createElement("div"); for (const node of nodes) { plainContainer.appendChild(node.cloneNode(true)); } for (const el of plainContainer.querySelectorAll( "[data-ngx-html-bridge-line]" )) { el.removeAttribute("data-ngx-html-bridge-line"); el.removeAttribute("data-ngx-html-bridge-col"); el.removeAttribute("data-ngx-html-bridge-start-offset"); el.removeAttribute("data-ngx-html-bridge-end-offset"); } for (const attribute2 of new Set(attributeNames)) { for (const el of plainContainer.querySelectorAll( `[data-ngx-html-bridge-${attribute2}-start-offset]` )) { el.removeAttribute(`data-ngx-html-bridge-${attribute2}-start-offset`); el.removeAttribute(`data-ngx-html-bridge-${attribute2}-end-offset`); } } const plain = plainContainer.innerHTML; return { annotated, plain }; }; // node_modules/@angular/compiler/fesm2022/compiler.mjs var _SELECTOR_REGEXP = new RegExp( `(\\:not\\()|(([\\.\\#]?)[-\\w]+)|(?:\\[([-.\\w*\\\\$]+)(?:=(["']?)([^\\]"']*)\\5)?\\])|(\\))|(\\s*,\\s*)`, // 8: "," "g" ); var CssSelector = class _CssSelector { element = null; classNames = []; /** * The selectors are encoded in pairs where: * - even locations are attribute names * - odd locations are attribute values. * * Example: * Selector: `[key1=value1][key2]` would parse to: * ``` * ['key1', 'value1', 'key2', ''] * ``` */ attrs = []; notSelectors = []; static parse(selector) { const results = []; const _addResult = (res, cssSel) => { if (cssSel.notSelectors.length > 0 && !cssSel.element && cssSel.classNames.length == 0 && cssSel.attrs.length == 0) { cssSel.element = "*"; } res.push(cssSel); }; let cssSelector = new _CssSelector(); let match; let current = cssSelector; let inNot = false; _SELECTOR_REGEXP.lastIndex = 0; while (match = _SELECTOR_REGEXP.exec(selector)) { if (match[ 1 /* SelectorRegexp.NOT */ ]) { if (inNot) { throw new Error("Nesting :not in a selector is not allowed"); } inNot = true; current = new _CssSelector(); cssSelector.notSelectors.push(current); } const tag = match[ 2 /* SelectorRegexp.TAG */ ]; if (tag) { const prefix = match[ 3 /* SelectorRegexp.PREFIX */ ]; if (prefix === "#") { current.addAttribute("id", tag.slice(1)); } else if (prefix === ".") { current.addClassName(tag.slice(1)); } else { current.setElement(tag); } } const attribute2 = match[ 4 /* SelectorRegexp.ATTRIBUTE */ ]; if (attribute2) { current.addAttribute(current.unescapeAttribute(attribute2), match[ 6 /* SelectorRegexp.ATTRIBUTE_VALUE */ ]); } if (match[ 7 /* SelectorRegexp.NOT_END */ ]) { inNot = false; current = cssSelector; } if (match[ 8 /* SelectorRegexp.SEPARATOR */ ]) { if (inNot) { throw new Error("Multiple selectors in :not are not supported"); } _addResult(results, cssSelector); cssSelector = current = new _CssSelector(); } } _addResult(results, cssSelector); return results; } /** * Unescape `\$` sequences from the CSS attribute selector. * * This is needed because `$` can have a special meaning in CSS selectors, * but we might want to match an attribute that contains `$`. * [MDN web link for more * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors). * @param attr the attribute to unescape. * @returns the unescaped string. */ unescapeAttribute(attr) { let result = ""; let escaping = false; for (let i = 0; i < attr.length; i++) { const char = attr.charAt(i); if (char === "\\") { escaping = true; continue; } if (char === "$" && !escaping) { throw new Error(`Error in attribute selector "${attr}". Unescaped "$" is not supported. Please escape with "\\$".`); } escaping = false; result += char; } return result; } /** * Escape `$` sequences from the CSS attribute selector. * * This is needed because `$` can have a special meaning in CSS selectors, * with this method we are escaping `$` with `\$'. * [MDN web link for more * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors). * @param attr the attribute to escape. * @returns the escaped string. */ escapeAttribute(attr) { return attr.replace(/\\/g, "\\\\").replace(/\$/g, "\\$"); } isElementSelector() { return this.hasElementSelector() && this.classNames.length == 0 && this.attrs.length == 0 && this.notSelectors.length === 0; } hasElementSelector() { return !!this.element; } setElement(element2 = null) { this.element = element2; } getAttrs() { const result = []; if (this.classNames.length > 0) { result.push("class", this.classNames.join(" ")); } return result.concat(this.attrs); } addAttribute(name, value = "") { this.attrs.push(name, value && value.toLowerCase() || ""); } addClassName(name) { this.classNames.push(name.toLowerCase()); } toString() { let res = this.element || ""; if (this.classNames) { this.classNames.forEach((klass) => res += `.${klass}`); } if (this.attrs) { for (let i = 0; i < this.attrs.length; i += 2) { const name = this.escapeAttribute(this.attrs[i]); const value = this.attrs[i + 1]; res += `[${name}${value ? "=" + value : ""}]`; } } this.notSelectors.forEach((notSelector) => res += `:not(${notSelector})`); return res; } }; var SelectorMatcher = class _SelectorMatcher { static createNotMatcher(notSelectors) { const notMatcher = new _SelectorMatcher(); notMatcher.addSelectables(notSelectors, null); return notMatcher; } _elementMap = /* @__PURE__ */ new Map(); _elementPartialMap = /* @__PURE__ */ new Map(); _classMap = /* @__PURE__ */ new Map(); _classPartialMap = /* @__PURE__ */ new Map(); _attrValueMap = /* @__PURE__ */ new Map(); _attrValuePartialMap = /* @__PURE__ */ new Map(); _listContexts = []; addSelectables(cssSelectors, callbackCtxt) { let listContext = null; if (cssSelectors.length > 1) { listContext = new SelectorListContext(cssSelectors); this._listContexts.push(listContext); } for (let i = 0; i < cssSelectors.length; i++) { this._addSelectable(cssSelectors[i], callbackCtxt, listContext); } } /** * Add an object that can be found later on by calling `match`. * @param cssSelector A css selector * @param callbackCtxt An opaque object that will be given to the callback of the `match` function */ _addSelectable(cssSelector, callbackCtxt, listContext) { let matcher = this; const element2 = cssSelector.element; const classNames = cssSelector.classNames; const attrs = cssSelector.attrs; const selectable = new SelectorContext(cssSelector, callbackCtxt, listContext); if (element2) { const isTerminal = attrs.length === 0 && classNames.length === 0; if (isTerminal) { this._addTerminal(matcher._elementMap, element2, selectable); } else { matcher = this._addPartial(matcher._elementPartialMap, element2); } } if (classNames) { for (let i = 0; i < classNames.length; i++) { const isTerminal = attrs.length === 0 && i === classNames.length - 1; const className = classNames[i]; if (isTerminal) { this._addTerminal(matcher._classMap, className, selectable); } else { matcher = this._addPartial(matcher._classPartialMap, className); } } } if (attrs) { for (let i = 0; i < attrs.length; i += 2) { const isTerminal = i === attrs.length - 2; const name = attrs[i]; const value = attrs[i + 1]; if (isTerminal) { const terminalMap = matcher._attrValueMap; let terminalValuesMap = terminalMap.get(name); if (!terminalValuesMap) { terminalValuesMap = /* @__PURE__ */ new Map(); terminalMap.set(name, terminalValuesMap); } this._addTerminal(terminalValuesMap, value, selectable); } else { const partialMap = matcher._attrValuePartialMap; let partialValuesMap = partialMap.get(name); if (!partialValuesMap) { partialValuesMap = /* @__PURE__ */ new Map(); partialMap.set(name, partialValuesMap); } matcher = this._addPartial(partialValuesMap, value); } } } } _addTerminal(map, name, selectable) { let terminalList = map.get(name); if (!terminalList) { terminalList = []; map.set(name, terminalList); } terminalList.push(selectable); } _addPartial(map, name) { let matcher = map.get(name); if (!matcher) { matcher = new _SelectorMatcher(); map.set(name, matcher); } return matcher; } /** * Find the objects that have been added via `addSelectable` * whose css selector is contained in the given css selector. * @param cssSelector A css selector * @param matchedCallback This callback will be called with the object handed into `addSelectable` * @return boolean true if a match was found */ match(cssSelector, matchedCallback) { let result = false; const element2 = cssSelector.element; const classNames = cssSelector.classNames; const attrs = cssSelector.attrs; for (let i = 0; i < this._listContexts.length; i++) { this._listContexts[i].alreadyMatched = false; } result = this._matchTerminal(this._elementMap, element2, cssSelector, matchedCallback) || result; result = this._matchPartial(this._elementPartialMap, element2, cssSelector, matchedCallback) || result; if (classNames) { for (let i = 0; i < classNames.length; i++) { const className = classNames[i]; result = this._matchTerminal(this._classMap, className, cssSelector, matchedCallback) || result; result = this._matchPartial(this._classPartialMap, className, cssSelector, matchedCallback) || result; } } if (attrs) { for (let i = 0; i < attrs.length; i += 2) { const name = attrs[i]; const value = attrs[i + 1]; const terminalValuesMap = this._attrValueMap.get(name); if (value) { result = this._matchTerminal(terminalValuesMap, "", cssSelector, matchedCallback) || result; } result = this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result; const partialValuesMap = this._attrValuePartialMap.get(name); if (value) { result = this._matchPartial(partialValuesMap, "", cssSelector, matchedCallback) || result; } result = this._matchPartial(partialValuesMap, value, cssSelector, matchedCallback) || result; } } return result; } /** @internal */ _matchTerminal(map, name, cssSelector, matchedCallback) { if (!map || typeof name !== "string") { return false; } let selectables = map.get(name) || []; const starSelectables = map.get("*"); if (starSelectables) { selectables = selectables.concat(starSelectables); } if (selectables.length === 0) { return false; } let selectable; let result = false; for (let i = 0; i < selectables.length; i++) { selectable = selectables[i]; result = selectable.finalize(cssSelector, matchedCallback) || result; } return result; } /** @internal */ _matchPartial(map, name, cssSelector, matchedCallback) { if (!map || typeof name !== "string") { return false; } const nestedSelector = map.get(name); if (!nestedSelector) { return false; } return nestedSelector.match(cssSelector, matchedCallback); } }; var SelectorListContext = class { selectors; alreadyMatched = false; constructor(selectors) { this.selectors = selectors; } }; var SelectorContext = class { selector; cbContext; listContext; notSelectors; constructor(selector, cbContext, listContext) { this.selector = selector; this.cbContext = cbContext; this.listContext = listContext; this.notSelectors = selector.notSelectors; } finalize(cssSelector, callback) { let result = true; if (this.notSelectors.length > 0 && (!this.listContext || !this.listContext.alreadyMatched)) { const notMatcher = SelectorMatcher.createNotMatcher(this.notSelectors); result = !notMatcher.match(cssSelector, null); } if (result && callback && (!this.listContext || !this.listContext.alreadyMatched)) { if (this.listContext) { this.listContext.alreadyMatched = true; } callback(this.selector, this.cbContext); } return result; } }; var SelectorlessMatcher = class { registry; constructor(registry) { this.registry = registry; } match(name) { return this.registry.has(name) ? this.registry.get(name) : []; } }; var ViewEncapsulation$1; (function(ViewEncapsulation2) { ViewEncapsulation2[ViewEncapsulation2["Emulated"] = 0] = "Emulated"; ViewEncapsulation2[ViewEncapsulation2["None"] = 2] = "None"; ViewEncapsulation2[ViewEncapsulation2["ShadowDom"] = 3] = "ShadowDom"; })(ViewEncapsulation$1 || (ViewEncapsulation$1 = {})); var ChangeDetectionStrategy; (function(ChangeDetectionStrategy2) { ChangeDetectionStrategy2[ChangeDetectionStrategy2["OnPush"] = 0] = "OnPush"; ChangeDetectionStrategy2[ChangeDetectionStrategy2["Default"] = 1] = "Default"; })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {})); var InputFlags; (function(InputFlags2) { InputFlags2[InputFlags2["None"] = 0] = "None"; InputFlags2[InputFlags2["SignalBased"] = 1] = "SignalBased"; InputFlags2[InputFlags2["HasDecoratorInputTransform"] = 2] = "HasDecoratorInputTransform"; })(InputFlags || (InputFlags = {})); var CUSTOM_ELEMENTS_SCHEMA = { name: "custom-elements" }; var NO_ERRORS_SCHEMA = { name: "no-errors-schema" }; var SecurityContext; (function(SecurityContext2) { SecurityContext2[SecurityContext2["NONE"] = 0] = "NONE"; SecurityContext2[SecurityContext2["HTML"] = 1] = "HTML"; SecurityContext2[SecurityContext2["STYLE"] = 2] = "STYLE"; SecurityContext2[SecurityContext2["SCRIPT"] = 3] = "SCRIPT"; SecurityContext2[SecurityContext2["URL"] = 4] = "URL"; SecurityContext2[SecurityContext2["RESOURCE_URL"] = 5] = "RESOURCE_URL"; })(SecurityContext || (SecurityContext = {})); var MissingTranslationStrategy; (function(MissingTranslationStrategy2) { MissingTranslationStrategy2[MissingTranslationStrategy2["Error"] = 0] = "Error"; MissingTranslationStrategy2[MissingTranslationStrategy2["Warning"] = 1] = "Warning"; MissingTranslationStrategy2[MissingTranslationStrategy2["Ignore"] = 2] = "Ignore"; })(MissingTranslationStrategy || (MissingTranslationStrategy = {})); function parserSelectorToSimpleSelector(selector) { const classes = selector.classNames && selector.classNames.length ? [8, ...selector.classNames] : []; const elementName = selector.element && selector.element !== "*" ? selector.element : ""; return [elementName, ...selector.attrs, ...classes]; } function parserSelectorToNegativeSelector(selector) { const classes = selector.classNames && selector.classNames.length ? [8, ...selector.classNames] : []; if (selector.element) { return [ 1 | 4, selector.element, ...selector.attrs, ...classes ]; } else if (selector.attrs.length) { return [1 | 2, ...selector.attrs, ...classes]; } else { return selector.classNames && selector.classNames.length ? [1 | 8, ...selector.classNames] : []; } } function parserSelectorToR3Selector(selector) { const positive = parserSelectorToSimpleSelector(selector); const negative = selector.notSelectors && selector.notSelectors.length ? selector.notSelectors.map((notSelector) => parserSelectorToNegativeSelector(notSelector)) : []; return positive.concat(...negative); } function parseSelectorToR3Selector(selector) { return selector ? CssSelector.parse(selector).map(parserSelectorToR3Selector) : []; } var FactoryTarget; (function(FactoryTarget2) { FactoryTarget2[FactoryTarget2["Directive"] = 0] = "Directive"; FactoryTarget2[FactoryTarget2["Component"] = 1] = "Component"; FactoryTarget2[FactoryTarget2["Injectable"] = 2] = "Injectable"; FactoryTarget2[FactoryTarget2["Pipe"] = 3] = "Pipe"; FactoryTarget2[FactoryTarget2["NgModule"] = 4] = "NgModule"; })(FactoryTarget || (FactoryTarget = {})); var R3TemplateDependencyKind$1; (function(R3TemplateDependencyKind2) { R3TemplateDependencyKind2[R3TemplateDependencyKind2["Directive"] = 0] = "Directive"; R3TemplateDependencyKind2[R3TemplateDependencyKind2["Pipe"] = 1] = "Pipe"; R3TemplateDependencyKind2[R3TemplateDependencyKind2["NgModule"] = 2] = "NgModule"; })(R3TemplateDependencyKind$1 || (R3TemplateDependencyKind$1 = {})); var ViewEncapsulation; (function(ViewEncapsulation2) { ViewEncapsulation2[ViewEncapsulation2["Emulated"] = 0] = "Emulated"; ViewEncapsulation2[ViewEncapsulation2["None"] = 2] = "None"; ViewEncapsulation2[ViewEncapsulation2["ShadowDom"] = 3] = "ShadowDom"; })(ViewEncapsulation || (ViewEncapsulation = {})); var textEncoder; function computeDigest(message) { return sha1(serializeNodes(message.nodes).join("") + `[${message.meaning}]`); } function decimalDigest(message) { return message.id || computeDecimalDigest(message); } function computeDecimalDigest(message) { const visitor = new _SerializerIgnoreIcuExpVisitor(); const parts = message.nodes.map((a) => a.visit(visitor, null)); return computeMsgId(parts.join(""), message.meaning); } var _SerializerVisitor = class { visitText(text2, context) { return text2.value; } visitContainer(container, context) { return `[${container.children.map((child) => child.visit(this)).join(", ")}]`; } visitIcu(icu, context) { const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`); return `{${icu.expression}, ${icu.type}, ${strCases.join(", ")}}`; } visitTagPlaceholder(ph, context) { return ph.isVoid ? `<ph tag name="${ph.startName}"/>` : `<ph tag name="${ph.startName}">${ph.children.map((child) => child.visit(this)).join(", ")}</ph name="${ph.closeName}">`; } visitPlaceholder(ph, context) { return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`; } visitIcuPlaceholder(ph, context) { return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`; } visitBlockPlaceholder(ph, context) { return `<ph block name="${ph.startName}">${ph.children.map((child) => child.visit(this)).join(", ")}</ph name="${ph.closeName}">`; } }; var serializerVisitor$1 = new _SerializerVisitor(); function serializeNodes(nodes) { return nodes.map((a) => a.visit(serializerVisitor$1, null)); } var _SerializerIgnoreIcuExpVisitor = class extends _SerializerVisitor { visitIcu(icu) { let strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`); return `{${icu.type}, ${strCases.join(", ")}}`; } }; function sha1(str) { textEncoder ??= new TextEncoder(); const utf8 = [...textEncoder.encode(str)]; const words32 = bytesToWords32(utf8, Endian.Big); const len = utf8.length * 8; const w = new Uint32Array(80); let a = 1732584193, b = 4023233417, c = 2562383102, d = 271733878, e = 3285377520; words32[len >> 5] |= 128 << 24 - len % 32; words32[(len + 64 >> 9 << 4) + 15] = len; for (let i = 0; i < words32.length; i += 16) { const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e; for (let j = 0; j < 80; j++) { if (j < 16) { w[j] = words32[i + j]; } else { w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); } const fkVal = fk(j, b, c, d); const f = fkVal[0]; const k = fkVal[1]; const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32); e = d; d = c; c = rol32(b, 30); b = a; a = temp; } a = add32(a, h0); b = add32(b, h1); c = add32(c, h2); d = add32(d, h3); e = add32(e, h4); } return toHexU32(a) + toHexU32(b) + toHexU32(c) + toHexU32(d) + toHexU32(e); } function toHexU32(value) { return (value >>> 0).toString(16).padStart(8, "0"); } function fk(index, b, c, d) { if (index < 20) { return [b & c | ~b & d, 1518500249]; } if (index < 40) { return [b ^ c ^ d, 1859775393]; } if (index < 60) { return [b & c | b & d | c & d, 2400959708]; } return [b ^ c ^ d, 3395469782]; } function fingerprint(str) { textEncoder ??= new TextEncoder(); const utf8 = textEncoder.encode(str); const view = new DataView(utf8.buffer, utf8.byteOffset, utf8.byteLength); let hi = hash32(view, utf8.length, 0); let lo = hash32(view, utf8.length, 102072); if (hi == 0 && (lo == 0 || lo == 1)) { hi = hi ^ 319790063; lo = lo ^ -1801410264; } return BigInt.asUintN(32, BigInt(hi)) << BigInt(32) | BigInt.asUintN(32, BigInt(lo)); } function computeMsgId(msg, meaning = "") { let msgFingerprint = fingerprint(msg); if (meaning) { msgFingerprint = BigInt.asUintN(64, msgFingerprint << BigInt(1)) | msgFingerprint >> BigInt(63) & BigInt(1); msgFingerprint += fingerprint(meaning); } return BigInt.asUintN(63, msgFingerprint).toString(); } function hash32(view, length, c) { let a = 2654435769, b = 2654435769; let index = 0; const end = length - 12; for (; index <= end; index += 12) { a += view.getUint32(index, true); b += view.getUint32(index + 4, true); c += view.getUint32(index + 8, true); const res = mix(a, b, c); a = res[0], b = res[1], c = res[2]; } const remainder = length - index; c += length; if (remainder >= 4) { a += view.getUint32(index, true); index += 4; if (remainder >= 8) { b += view.getUint32(index, true); index += 4; if (remainder >= 9) { c += view.getUint8(index++) << 8; } if (remainder >= 10) { c += view.getUint8(index++) << 16; } if (remainder === 11) { c += view.getUint8(index++) << 24; } } else { if (remainder >= 5) { b += view.getUint8(index++); } if (remainder >= 6) { b += view.getUint8(index++) << 8; } if (remainder === 7) { b += view.getUint8(index++) << 16; } } } else { if (remainder >= 1) { a += view.getUint8(index++); } if (remainder >= 2) { a += view.getUint8(index++) << 8; } if (remainder === 3) { a += view.getUint8(index++) << 16; } } return mix(a, b, c)[2]; } function mix(a, b, c) { a -= b; a -= c; a ^= c >>> 13; b -= c; b -= a; b ^= a << 8; c -= a; c -= b; c ^= b >>> 13; a -= b; a -= c; a ^= c >>> 12; b -= c; b -= a; b ^= a << 16; c -= a; c -= b; c ^= b >>> 5; a -= b; a -= c; a ^= c >>> 3; b -= c; b -= a; b ^= a << 10; c -= a; c -= b; c ^= b >>> 15; return [a, b, c]; } var Endian; (function(Endian2) { Endian2[Endian2["Little"] = 0] = "Little"; Endian2[Endian2["Big"] = 1] = "Big"; })(Endian || (Endian = {})); function add32(a, b) { return add32to64(a, b)[1]; } function add32to64(a, b) { const low = (a & 65535) + (b & 65535); const high = (a >>> 16) + (b >>> 16) + (low >>> 16); return [high >>> 16, high << 16 | low & 65535]; } function rol32(a, count) { return a << count | a >>> 32 - count; } function bytesToWords32(bytes, endian) { const size = bytes.length + 3 >>> 2; const words32 = []; for (let i = 0; i < size; i++) { words32[i] = wordAt(bytes, i * 4, endian); } return words32; } function byteAt(bytes, index) { return index >= bytes.length ? 0 : bytes[index]; } function wordAt(bytes, index, endian) { let word = 0; if (endian === Endian.Big) { for (let i = 0; i < 4; i++) { word += byteAt(bytes, index + i) << 24 - 8 * i; } } else { for (let i = 0; i < 4; i++) { word += byteAt(bytes, index + i) << 8 * i; } } return word; } var TypeModifier; (function(TypeModifier2) { TypeModifier2[TypeModifier2["None"] = 0] = "None"; TypeModifier2[TypeModifier2["Const"] = 1] = "Const"; })(TypeModifier || (TypeModifier = {})); var Type = class { modifiers; constructor(modifiers = TypeModifier.None) { this.modifiers = modifiers; } hasModifier(modifier) { return (this.modifiers & modifier) !== 0; } }; var BuiltinTypeName; (function(BuiltinTypeName2) { BuiltinTypeName2[BuiltinTypeName2["Dynamic"] = 0] = "Dynamic"; BuiltinTypeName2[BuiltinTypeName2["Bool"] = 1] = "Bool"; BuiltinTypeName2[BuiltinTypeName2["String"] = 2] = "String"; BuiltinTypeName2[BuiltinTypeName2["Int"] = 3] = "Int"; BuiltinTypeName2[BuiltinTypeName2["Number"] = 4] = "Number"; BuiltinTypeName2[BuiltinTypeName2["Function"] = 5] = "Function"; BuiltinTypeName2[BuiltinTypeName2["Inferred"] = 6] = "Inferred"; BuiltinTypeName2[BuiltinTypeName2["None"] = 7] = "None"; })(BuiltinTypeName || (BuiltinTypeName = {})); var BuiltinType = class extends Type { name; constructor(name, modifiers) { super(modifiers); this.name = name; } visitType(visitor, context) { return visitor.visitBuiltinType(this, context); } }; var ExpressionType = class extends Type { value; typeParams; constructor(value, modifiers, typeParams = null) { super(modifiers); this.value = value; this.typeParams = typeParams; } visitType(visitor, context) { return visitor.visitExpressionType(this, context); } }; var DYNAMIC_TYPE = new BuiltinType(BuiltinTypeName.Dynamic); var INFERRED_TYPE = new BuiltinType(BuiltinTypeName.Inferred); var BOOL_TYPE = new BuiltinType(BuiltinTypeName.Bool); var INT_TYPE = new BuiltinType(BuiltinTypeName.Int); var NUMBER_TYPE = new BuiltinType(BuiltinTypeName.Number); var STRING_TYPE = new BuiltinType(BuiltinTypeName.String); var FUNCTION_TYPE = new BuiltinType(BuiltinTypeName.Function); var NONE_TYPE = new BuiltinType(BuiltinTypeName.None); var UnaryOperator; (function(UnaryOperator2) { UnaryOperator2[UnaryOperator2["Minus"] = 0] = "Minus"; UnaryOperator2[UnaryOperator2["Plus"] = 1] = "Plus"; })(UnaryOperator || (UnaryOperator = {})); var BinaryOperator; (function(BinaryOperator2) { BinaryOperator2[BinaryOperator2["Equals"] = 0] = "Equals"; BinaryOperator2[BinaryOperator2["NotEquals"] = 1] = "NotEquals"; BinaryOperator2[BinaryOperator2["Assign"] = 2] = "Assign"; BinaryOperator2[BinaryOperator2["Identical"] = 3] = "Identical"; BinaryOperator2[BinaryOperator2["NotIdentical"] = 4] = "NotIdentical"; BinaryOperator2[BinaryOperator2["Minus"] = 5] = "Minus"; BinaryOperator2[BinaryOperator2["Plus"] = 6] = "Plus"; BinaryOperator2[BinaryOperator2["Divide"] = 7] = "Divide"; BinaryOperator2[BinaryOperator2["Multiply"] = 8] = "Multiply"; BinaryOperator2[BinaryOperator2["Modulo"] = 9] = "Modulo"; BinaryOperator2[BinaryOperator2["And"] = 10] = "And"; BinaryOperator2[BinaryOperator2["Or"] = 11] = "Or"; BinaryOperator2[BinaryOperator2["BitwiseOr"] = 12] = "BitwiseOr"; BinaryOperator2[BinaryOperator2["BitwiseAnd"] = 13] = "BitwiseAnd"; BinaryOperator2[BinaryOperator2["Lower"] = 14] = "Lower"; BinaryOperator2[BinaryOperator2["LowerEquals"] = 15] = "LowerEquals"; BinaryOperator2[BinaryOperator2["Bigger"] = 16] = "Bigger"; BinaryOperator2[BinaryOperator2["BiggerEquals"] = 17] = "BiggerEquals"; BinaryOperator2[BinaryOperator2["NullishCoalesce"] = 18] = "NullishCoalesce"; BinaryOperator2[BinaryOperator2["Exponentiation"] = 19] = "Exponentiation"; BinaryOperator2[BinaryOperator2["In"] = 20] = "In"; BinaryOperator2[BinaryOperator2["AdditionAssignment"] = 21] = "AdditionAssignment"; BinaryOperator2[BinaryOperator2["SubtractionAssignment"] = 22] = "SubtractionAssignment"; BinaryOperator2[BinaryOperator2["MultiplicationAssignment"] = 23] = "MultiplicationAssignment"; BinaryOperator2[BinaryOperator2["DivisionAssignment"] = 24] = "DivisionAssignment"; BinaryOperator2[BinaryOperator2["RemainderAssignment"] = 25] = "RemainderAssignment"; BinaryOperator2[BinaryOperator2["ExponentiationAssignment"] = 26] = "ExponentiationAssignment"; BinaryOperator2[BinaryOperator2["AndAssignment"] = 27] = "AndAssignment"; BinaryOperator2[BinaryOperator2["OrAssignment"] = 28] = "OrAssignment"; BinaryOperator2[BinaryOperator2["NullishCoalesceAssignment"] = 29] = "NullishCoalesceAssignment"; })(BinaryOperator || (BinaryOperator = {})); function nullSafeIsEquivalent(base, other) { if (base == null || other == null) { return base == other; } return base.isEquivalent(other); } function areAllEquivalentPredicate(base, other, equivalentPredicate) { const len = base.length; if (len !== other.length) { return false; } for (let i = 0; i < len; i++) { if (!equivalentPredicate(base[i], other[i])) { return false; } } return true; } function areAllEquivalent(base, other) { return areAllEquivalentPredicate(base, other, (baseElement, otherElement) => baseElement.isEquivalent(otherElement)); } var Expression = class { type; sourceSpan; constructor(type, sourceSpan) { this.type = type || null; this.sourceSpan = sourceSpan || null; } prop(name, sourceSpan) { return new ReadPropExpr(this, name, null, sourceSpan); } key(index, type, sourceSpan) { return new ReadKeyExpr(this, index, type, sourceSpan); } callFn(params, sourceSpan, pure) { return new InvokeFunctionExpr(this, params, null, sourceSpan, pure); } instantiate(params, type, sourceSpan) { return new InstantiateExpr(this, params, type, sourceSpan); } conditional(trueCase, falseCase = null, sourceSpan) { return new ConditionalExpr(this, trueCase, falseCase, null, sourceSpan); } equals(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.Equals, this, rhs, null, sourceSpan); } notEquals(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.NotEquals, this, rhs, null, sourceSpan); } identical(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.Identical, this, rhs, null, sourceSpan); } notIdentical(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.NotIdentical, this, rhs, null, sourceSpan); } minus(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.Minus, this, rhs, null, sourceSpan); } plus(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.Plus, this, rhs, null, sourceSpan); } divide(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.Divide, this, rhs, null, sourceSpan); } multiply(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.Multiply, this, rhs, null, sourceSpan); } modulo(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOperator.Modulo, this, rhs, null, sourceSpan); } power(rhs, sourceSpan) { return new BinaryOperatorExpr(BinaryOpe