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
JavaScript
// 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