/* * Vendored subset of Playwright injected ariaSnapshot (Apache-2.0). * Source: github.com/microsoft/playwright @ aa3c7b5 (packages/injected/src/{ariaSnapshot,roleUtils,domUtils}.ts + packages/isomorphic/*). * Built via esbuild from esm-entry.ts. Do not edit by hand; regenerate to update. * See dootask/docs/ai-page-operation-unified-executor.md. */ // packages/isomorphic/ariaSnapshot.ts function ariaNodesEqual(a, b) { if (a.role !== b.role || a.name !== b.name) return false; if (!ariaPropsEqual(a, b) || hasPointerCursor(a) !== hasPointerCursor(b)) return false; const aKeys = Object.keys(a.props); const bKeys = Object.keys(b.props); return aKeys.length === bKeys.length && aKeys.every((k) => a.props[k] === b.props[k]); } function hasPointerCursor(ariaNode) { return ariaNode.box.cursor === "pointer"; } function ariaPropsEqual(a, b) { return a.active === b.active && a.checked === b.checked && a.disabled === b.disabled && a.expanded === b.expanded && a.invalid === b.invalid && a.selected === b.selected && a.level === b.level && a.pressed === b.pressed; } // packages/isomorphic/stringUtils.ts var normalizedWhitespaceCache; function normalizeWhiteSpace(text) { let result = normalizedWhitespaceCache?.get(text); if (result === void 0) { result = text.replace(/[\u200b\u00ad]/g, "").trim().replace(/\s+/g, " "); normalizedWhitespaceCache?.set(text, result); } return result; } function escapeRegExp(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function longestCommonSubstring(s1, s2) { const n = s1.length; const m = s2.length; let maxLen = 0; let endingIndex = 0; const dp = Array(n + 1).fill(null).map(() => Array(m + 1).fill(0)); for (let i = 1; i <= n; i++) { for (let j = 1; j <= m; j++) { if (s1[i - 1] === s2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; if (dp[i][j] > maxLen) { maxLen = dp[i][j]; endingIndex = i; } } } } return s1.slice(endingIndex - maxLen, endingIndex); } var ansiRegex = new RegExp("([\\u001B\\u009B][[\\]()#?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)|(?:(?:\\d{0,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~])))", "g"); // packages/isomorphic/yaml.ts function yamlEscapeKeyIfNeeded(str) { if (!yamlStringNeedsQuotes(str)) return str; return `'` + str.replace(/'/g, `''`) + `'`; } function yamlEscapeValueIfNeeded(str) { if (!yamlStringNeedsQuotes(str)) return str; return '"' + str.replace(/[\\"\x00-\x1f\x7f-\x9f]/g, (c) => { switch (c) { case "\\": return "\\\\"; case '"': return '\\"'; case "\b": return "\\b"; case "\f": return "\\f"; case "\n": return "\\n"; case "\r": return "\\r"; case " ": return "\\t"; default: const code = c.charCodeAt(0); return "\\x" + code.toString(16).padStart(2, "0"); } }) + '"'; } function yamlStringNeedsQuotes(str) { if (str.length === 0) return true; if (/^\s|\s$/.test(str)) return true; if (/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/.test(str)) return true; if (/^-/.test(str)) return true; if (/[\n:](\s|$)/.test(str)) return true; if (/\s#/.test(str)) return true; if (/[\n\r]/.test(str)) return true; if (/^[&*\],?!>|@"'#%]/.test(str)) return true; if (/[{}`]/.test(str)) return true; if (/^\[/.test(str)) return true; if (!isNaN(Number(str)) || ["y", "n", "yes", "no", "true", "false", "on", "off", "null"].includes(str.toLowerCase())) return true; return false; } // packages/injected/src/domUtils.ts var globalOptions = {}; function parentElementOrShadowHost(element) { if (element.parentElement) return element.parentElement; if (!element.parentNode) return; if (element.parentNode.nodeType === 11 && element.parentNode.host) return element.parentNode.host; } function enclosingShadowRootOrDocument(element) { let node = element; while (node.parentNode) node = node.parentNode; if (node.nodeType === 11 || node.nodeType === 9) return node; } function enclosingShadowHost(element) { while (element.parentElement) element = element.parentElement; return parentElementOrShadowHost(element); } function closestCrossShadow(element, css, scope) { while (element) { const closest = element.closest(css); if (scope && closest !== scope && closest?.contains(scope)) return; if (closest) return closest; element = enclosingShadowHost(element); } } function getElementComputedStyle(element, pseudo) { const cache = pseudo === "::before" ? cacheStyleBefore : pseudo === "::after" ? cacheStyleAfter : cacheStyle; if (cache && cache.has(element)) return cache.get(element); const style = element.ownerDocument && element.ownerDocument.defaultView ? element.ownerDocument.defaultView.getComputedStyle(element, pseudo) : void 0; cache?.set(element, style); return style; } function isElementStyleVisibilityVisible(element, style) { style = style ?? getElementComputedStyle(element); if (!style) return true; if (Element.prototype.checkVisibility && globalOptions.browserNameForWorkarounds !== "webkit") { if (!element.checkVisibility()) return false; } else { const detailsOrSummary = element.closest("details,summary"); if (detailsOrSummary !== element && detailsOrSummary?.nodeName === "DETAILS" && !detailsOrSummary.open) return false; } if (style.visibility !== "visible") return false; return true; } function computeBox(element) { const style = getElementComputedStyle(element); if (!style) return { visible: true, inline: false }; const cursor = style.cursor; if (style.display === "contents") { for (let child = element.firstChild; child; child = child.nextSibling) { if (child.nodeType === 1 && isElementVisible(child)) return { visible: true, inline: false, cursor }; if (child.nodeType === 3 && isVisibleTextNode(child)) return { visible: true, inline: true, cursor }; } return { visible: false, inline: false, cursor }; } if (!isElementStyleVisibilityVisible(element, style)) return { cursor, visible: false, inline: false }; const rect = element.getBoundingClientRect(); return { cursor, visible: rect.width > 0 && rect.height > 0, inline: style.display === "inline" }; } function isElementVisible(element) { return computeBox(element).visible; } function isVisibleTextNode(node) { const range = node.ownerDocument.createRange(); range.selectNode(node); const rect = range.getBoundingClientRect(); return rect.width > 0 && rect.height > 0; } function elementSafeTagName(element) { const tagName = element.tagName; if (typeof tagName === "string") return tagName.toUpperCase(); if (element instanceof HTMLFormElement) return "FORM"; return element.tagName.toUpperCase(); } var cacheStyle; var cacheStyleBefore; var cacheStyleAfter; var cachesCounter = 0; function beginDOMCaches() { ++cachesCounter; cacheStyle ??= /* @__PURE__ */ new Map(); cacheStyleBefore ??= /* @__PURE__ */ new Map(); cacheStyleAfter ??= /* @__PURE__ */ new Map(); } function endDOMCaches() { if (!--cachesCounter) { cacheStyle = void 0; cacheStyleBefore = void 0; cacheStyleAfter = void 0; } } // packages/isomorphic/cssTokenizer.ts var between = function(num, first, last) { return num >= first && num <= last; }; function digit(code) { return between(code, 48, 57); } function hexdigit(code) { return digit(code) || between(code, 65, 70) || between(code, 97, 102); } function uppercaseletter(code) { return between(code, 65, 90); } function lowercaseletter(code) { return between(code, 97, 122); } function letter(code) { return uppercaseletter(code) || lowercaseletter(code); } function nonascii(code) { return code >= 128; } function namestartchar(code) { return letter(code) || nonascii(code) || code === 95; } function namechar(code) { return namestartchar(code) || digit(code) || code === 45; } function nonprintable(code) { return between(code, 0, 8) || code === 11 || between(code, 14, 31) || code === 127; } function newline(code) { return code === 10; } function whitespace(code) { return newline(code) || code === 9 || code === 32; } var maximumallowedcodepoint = 1114111; var InvalidCharacterError = class extends Error { constructor(message) { super(message); this.name = "InvalidCharacterError"; } }; function preprocess(str) { const codepoints = []; for (let i = 0; i < str.length; i++) { let code = str.charCodeAt(i); if (code === 13 && str.charCodeAt(i + 1) === 10) { code = 10; i++; } if (code === 13 || code === 12) code = 10; if (code === 0) code = 65533; if (between(code, 55296, 56319) && between(str.charCodeAt(i + 1), 56320, 57343)) { const lead = code - 55296; const trail = str.charCodeAt(i + 1) - 56320; code = Math.pow(2, 16) + lead * Math.pow(2, 10) + trail; i++; } codepoints.push(code); } return codepoints; } function stringFromCode(code) { if (code <= 65535) return String.fromCharCode(code); code -= Math.pow(2, 16); const lead = Math.floor(code / Math.pow(2, 10)) + 55296; const trail = code % Math.pow(2, 10) + 56320; return String.fromCharCode(lead) + String.fromCharCode(trail); } function tokenize(str1) { const str = preprocess(str1); let i = -1; const tokens = []; let code; let line = 0; let column = 0; let lastLineLength = 0; const incrLineno = function() { line += 1; lastLineLength = column; column = 0; }; const locStart = { line, column }; const codepoint = function(i2) { if (i2 >= str.length) return -1; return str[i2]; }; const next = function(num) { if (num === void 0) num = 1; if (num > 3) throw "Spec Error: no more than three codepoints of lookahead."; return codepoint(i + num); }; const consume = function(num) { if (num === void 0) num = 1; i += num; code = codepoint(i); if (newline(code)) incrLineno(); else column += num; return true; }; const reconsume = function() { i -= 1; if (newline(code)) { line -= 1; column = lastLineLength; } else { column -= 1; } locStart.line = line; locStart.column = column; return true; }; const eof = function(codepoint2) { if (codepoint2 === void 0) codepoint2 = code; return codepoint2 === -1; }; const donothing = function() { }; const parseerror = function() { }; const consumeAToken = function() { consumeComments(); consume(); if (whitespace(code)) { while (whitespace(next())) consume(); return new WhitespaceToken(); } else if (code === 34) { return consumeAStringToken(); } else if (code === 35) { if (namechar(next()) || areAValidEscape(next(1), next(2))) { const token = new HashToken(""); if (wouldStartAnIdentifier(next(1), next(2), next(3))) token.type = "id"; token.value = consumeAName(); return token; } else { return new DelimToken(code); } } else if (code === 36) { if (next() === 61) { consume(); return new SuffixMatchToken(); } else { return new DelimToken(code); } } else if (code === 39) { return consumeAStringToken(); } else if (code === 40) { return new OpenParenToken(); } else if (code === 41) { return new CloseParenToken(); } else if (code === 42) { if (next() === 61) { consume(); return new SubstringMatchToken(); } else { return new DelimToken(code); } } else if (code === 43) { if (startsWithANumber()) { reconsume(); return consumeANumericToken(); } else { return new DelimToken(code); } } else if (code === 44) { return new CommaToken(); } else if (code === 45) { if (startsWithANumber()) { reconsume(); return consumeANumericToken(); } else if (next(1) === 45 && next(2) === 62) { consume(2); return new CDCToken(); } else if (startsWithAnIdentifier()) { reconsume(); return consumeAnIdentlikeToken(); } else { return new DelimToken(code); } } else if (code === 46) { if (startsWithANumber()) { reconsume(); return consumeANumericToken(); } else { return new DelimToken(code); } } else if (code === 58) { return new ColonToken(); } else if (code === 59) { return new SemicolonToken(); } else if (code === 60) { if (next(1) === 33 && next(2) === 45 && next(3) === 45) { consume(3); return new CDOToken(); } else { return new DelimToken(code); } } else if (code === 64) { if (wouldStartAnIdentifier(next(1), next(2), next(3))) return new AtKeywordToken(consumeAName()); else return new DelimToken(code); } else if (code === 91) { return new OpenSquareToken(); } else if (code === 92) { if (startsWithAValidEscape()) { reconsume(); return consumeAnIdentlikeToken(); } else { parseerror(); return new DelimToken(code); } } else if (code === 93) { return new CloseSquareToken(); } else if (code === 94) { if (next() === 61) { consume(); return new PrefixMatchToken(); } else { return new DelimToken(code); } } else if (code === 123) { return new OpenCurlyToken(); } else if (code === 124) { if (next() === 61) { consume(); return new DashMatchToken(); } else if (next() === 124) { consume(); return new ColumnToken(); } else { return new DelimToken(code); } } else if (code === 125) { return new CloseCurlyToken(); } else if (code === 126) { if (next() === 61) { consume(); return new IncludeMatchToken(); } else { return new DelimToken(code); } } else if (digit(code)) { reconsume(); return consumeANumericToken(); } else if (namestartchar(code)) { reconsume(); return consumeAnIdentlikeToken(); } else if (eof()) { return new EOFToken(); } else { return new DelimToken(code); } }; const consumeComments = function() { while (next(1) === 47 && next(2) === 42) { consume(2); while (true) { consume(); if (code === 42 && next() === 47) { consume(); break; } else if (eof()) { parseerror(); return; } } } }; const consumeANumericToken = function() { const num = consumeANumber(); if (wouldStartAnIdentifier(next(1), next(2), next(3))) { const token = new DimensionToken(); token.value = num.value; token.repr = num.repr; token.type = num.type; token.unit = consumeAName(); return token; } else if (next() === 37) { consume(); const token = new PercentageToken(); token.value = num.value; token.repr = num.repr; return token; } else { const token = new NumberToken(); token.value = num.value; token.repr = num.repr; token.type = num.type; return token; } }; const consumeAnIdentlikeToken = function() { const str2 = consumeAName(); if (str2.toLowerCase() === "url" && next() === 40) { consume(); while (whitespace(next(1)) && whitespace(next(2))) consume(); if (next() === 34 || next() === 39) return new FunctionToken(str2); else if (whitespace(next()) && (next(2) === 34 || next(2) === 39)) return new FunctionToken(str2); else return consumeAURLToken(); } else if (next() === 40) { consume(); return new FunctionToken(str2); } else { return new IdentToken(str2); } }; const consumeAStringToken = function(endingCodePoint) { if (endingCodePoint === void 0) endingCodePoint = code; let string = ""; while (consume()) { if (code === endingCodePoint || eof()) { return new StringToken(string); } else if (newline(code)) { parseerror(); reconsume(); return new BadStringToken(); } else if (code === 92) { if (eof(next())) donothing(); else if (newline(next())) consume(); else string += stringFromCode(consumeEscape()); } else { string += stringFromCode(code); } } throw new Error("Internal error"); }; const consumeAURLToken = function() { const token = new URLToken(""); while (whitespace(next())) consume(); if (eof(next())) return token; while (consume()) { if (code === 41 || eof()) { return token; } else if (whitespace(code)) { while (whitespace(next())) consume(); if (next() === 41 || eof(next())) { consume(); return token; } else { consumeTheRemnantsOfABadURL(); return new BadURLToken(); } } else if (code === 34 || code === 39 || code === 40 || nonprintable(code)) { parseerror(); consumeTheRemnantsOfABadURL(); return new BadURLToken(); } else if (code === 92) { if (startsWithAValidEscape()) { token.value += stringFromCode(consumeEscape()); } else { parseerror(); consumeTheRemnantsOfABadURL(); return new BadURLToken(); } } else { token.value += stringFromCode(code); } } throw new Error("Internal error"); }; const consumeEscape = function() { consume(); if (hexdigit(code)) { const digits = [code]; for (let total = 0; total < 5; total++) { if (hexdigit(next())) { consume(); digits.push(code); } else { break; } } if (whitespace(next())) consume(); let value = parseInt(digits.map(function(x) { return String.fromCharCode(x); }).join(""), 16); if (value > maximumallowedcodepoint) value = 65533; return value; } else if (eof()) { return 65533; } else { return code; } }; const areAValidEscape = function(c1, c2) { if (c1 !== 92) return false; if (newline(c2)) return false; return true; }; const startsWithAValidEscape = function() { return areAValidEscape(code, next()); }; const wouldStartAnIdentifier = function(c1, c2, c3) { if (c1 === 45) return namestartchar(c2) || c2 === 45 || areAValidEscape(c2, c3); else if (namestartchar(c1)) return true; else if (c1 === 92) return areAValidEscape(c1, c2); else return false; }; const startsWithAnIdentifier = function() { return wouldStartAnIdentifier(code, next(1), next(2)); }; const wouldStartANumber = function(c1, c2, c3) { if (c1 === 43 || c1 === 45) { if (digit(c2)) return true; if (c2 === 46 && digit(c3)) return true; return false; } else if (c1 === 46) { if (digit(c2)) return true; return false; } else if (digit(c1)) { return true; } else { return false; } }; const startsWithANumber = function() { return wouldStartANumber(code, next(1), next(2)); }; const consumeAName = function() { let result = ""; while (consume()) { if (namechar(code)) { result += stringFromCode(code); } else if (startsWithAValidEscape()) { result += stringFromCode(consumeEscape()); } else { reconsume(); return result; } } throw new Error("Internal parse error"); }; const consumeANumber = function() { let repr = ""; let type = "integer"; if (next() === 43 || next() === 45) { consume(); repr += stringFromCode(code); } while (digit(next())) { consume(); repr += stringFromCode(code); } if (next(1) === 46 && digit(next(2))) { consume(); repr += stringFromCode(code); consume(); repr += stringFromCode(code); type = "number"; while (digit(next())) { consume(); repr += stringFromCode(code); } } const c1 = next(1); const c2 = next(2); const c3 = next(3); if ((c1 === 69 || c1 === 101) && digit(c2)) { consume(); repr += stringFromCode(code); consume(); repr += stringFromCode(code); type = "number"; while (digit(next())) { consume(); repr += stringFromCode(code); } } else if ((c1 === 69 || c1 === 101) && (c2 === 43 || c2 === 45) && digit(c3)) { consume(); repr += stringFromCode(code); consume(); repr += stringFromCode(code); consume(); repr += stringFromCode(code); type = "number"; while (digit(next())) { consume(); repr += stringFromCode(code); } } const value = convertAStringToANumber(repr); return { type, value, repr }; }; const convertAStringToANumber = function(string) { return +string; }; const consumeTheRemnantsOfABadURL = function() { while (consume()) { if (code === 41 || eof()) { return; } else if (startsWithAValidEscape()) { consumeEscape(); donothing(); } else { donothing(); } } }; let iterationCount = 0; while (!eof(next())) { tokens.push(consumeAToken()); iterationCount++; if (iterationCount > str.length * 2) throw new Error("I'm infinite-looping!"); } return tokens; } var CSSParserToken = class { tokenType = ""; value; toJSON() { return { token: this.tokenType }; } toString() { return this.tokenType; } toSource() { return "" + this; } }; var BadStringToken = class extends CSSParserToken { tokenType = "BADSTRING"; }; var BadURLToken = class extends CSSParserToken { tokenType = "BADURL"; }; var WhitespaceToken = class extends CSSParserToken { tokenType = "WHITESPACE"; toString() { return "WS"; } toSource() { return " "; } }; var CDOToken = class extends CSSParserToken { tokenType = "CDO"; toSource() { return ""; } }; var ColonToken = class extends CSSParserToken { tokenType = ":"; }; var SemicolonToken = class extends CSSParserToken { tokenType = ";"; }; var CommaToken = class extends CSSParserToken { tokenType = ","; }; var GroupingToken = class extends CSSParserToken { value = ""; mirror = ""; }; var OpenCurlyToken = class extends GroupingToken { tokenType = "{"; constructor() { super(); this.value = "{"; this.mirror = "}"; } }; var CloseCurlyToken = class extends GroupingToken { tokenType = "}"; constructor() { super(); this.value = "}"; this.mirror = "{"; } }; var OpenSquareToken = class extends GroupingToken { tokenType = "["; constructor() { super(); this.value = "["; this.mirror = "]"; } }; var CloseSquareToken = class extends GroupingToken { tokenType = "]"; constructor() { super(); this.value = "]"; this.mirror = "["; } }; var OpenParenToken = class extends GroupingToken { tokenType = "("; constructor() { super(); this.value = "("; this.mirror = ")"; } }; var CloseParenToken = class extends GroupingToken { tokenType = ")"; constructor() { super(); this.value = ")"; this.mirror = "("; } }; var IncludeMatchToken = class extends CSSParserToken { tokenType = "~="; }; var DashMatchToken = class extends CSSParserToken { tokenType = "|="; }; var PrefixMatchToken = class extends CSSParserToken { tokenType = "^="; }; var SuffixMatchToken = class extends CSSParserToken { tokenType = "$="; }; var SubstringMatchToken = class extends CSSParserToken { tokenType = "*="; }; var ColumnToken = class extends CSSParserToken { tokenType = "||"; }; var EOFToken = class extends CSSParserToken { tokenType = "EOF"; toSource() { return ""; } }; var DelimToken = class extends CSSParserToken { tokenType = "DELIM"; value = ""; constructor(code) { super(); this.value = stringFromCode(code); } toString() { return "DELIM(" + this.value + ")"; } toJSON() { const json = this.constructor.prototype.constructor.prototype.toJSON.call(this); json.value = this.value; return json; } toSource() { if (this.value === "\\") return "\\\n"; else return this.value; } }; var StringValuedToken = class extends CSSParserToken { value = ""; ASCIIMatch(str) { return this.value.toLowerCase() === str.toLowerCase(); } toJSON() { const json = this.constructor.prototype.constructor.prototype.toJSON.call(this); json.value = this.value; return json; } }; var IdentToken = class extends StringValuedToken { constructor(val) { super(); this.value = val; } tokenType = "IDENT"; toString() { return "IDENT(" + this.value + ")"; } toSource() { return escapeIdent(this.value); } }; var FunctionToken = class extends StringValuedToken { tokenType = "FUNCTION"; mirror; constructor(val) { super(); this.value = val; this.mirror = ")"; } toString() { return "FUNCTION(" + this.value + ")"; } toSource() { return escapeIdent(this.value) + "("; } }; var AtKeywordToken = class extends StringValuedToken { tokenType = "AT-KEYWORD"; constructor(val) { super(); this.value = val; } toString() { return "AT(" + this.value + ")"; } toSource() { return "@" + escapeIdent(this.value); } }; var HashToken = class extends StringValuedToken { tokenType = "HASH"; type; constructor(val) { super(); this.value = val; this.type = "unrestricted"; } toString() { return "HASH(" + this.value + ")"; } toJSON() { const json = this.constructor.prototype.constructor.prototype.toJSON.call(this); json.value = this.value; json.type = this.type; return json; } toSource() { if (this.type === "id") return "#" + escapeIdent(this.value); else return "#" + escapeHash(this.value); } }; var StringToken = class extends StringValuedToken { tokenType = "STRING"; constructor(val) { super(); this.value = val; } toString() { return '"' + escapeString(this.value) + '"'; } }; var URLToken = class extends StringValuedToken { tokenType = "URL"; constructor(val) { super(); this.value = val; } toString() { return "URL(" + this.value + ")"; } toSource() { return 'url("' + escapeString(this.value) + '")'; } }; var NumberToken = class extends CSSParserToken { tokenType = "NUMBER"; type; repr; constructor() { super(); this.type = "integer"; this.repr = ""; } toString() { if (this.type === "integer") return "INT(" + this.value + ")"; return "NUMBER(" + this.value + ")"; } toJSON() { const json = super.toJSON(); json.value = this.value; json.type = this.type; json.repr = this.repr; return json; } toSource() { return this.repr; } }; var PercentageToken = class extends CSSParserToken { tokenType = "PERCENTAGE"; repr; constructor() { super(); this.repr = ""; } toString() { return "PERCENTAGE(" + this.value + ")"; } toJSON() { const json = this.constructor.prototype.constructor.prototype.toJSON.call(this); json.value = this.value; json.repr = this.repr; return json; } toSource() { return this.repr + "%"; } }; var DimensionToken = class extends CSSParserToken { tokenType = "DIMENSION"; type; repr; unit; constructor() { super(); this.type = "integer"; this.repr = ""; this.unit = ""; } toString() { return "DIM(" + this.value + "," + this.unit + ")"; } toJSON() { const json = this.constructor.prototype.constructor.prototype.toJSON.call(this); json.value = this.value; json.type = this.type; json.repr = this.repr; json.unit = this.unit; return json; } toSource() { const source = this.repr; let unit = escapeIdent(this.unit); if (unit[0].toLowerCase() === "e" && (unit[1] === "-" || between(unit.charCodeAt(1), 48, 57))) { unit = "\\65 " + unit.slice(1, unit.length); } return source + unit; } }; function escapeIdent(string) { string = "" + string; let result = ""; const firstcode = string.charCodeAt(0); for (let i = 0; i < string.length; i++) { const code = string.charCodeAt(i); if (code === 0) throw new InvalidCharacterError("Invalid character: the input contains U+0000."); if (between(code, 1, 31) || code === 127 || i === 0 && between(code, 48, 57) || i === 1 && between(code, 48, 57) && firstcode === 45) result += "\\" + code.toString(16) + " "; else if (code >= 128 || code === 45 || code === 95 || between(code, 48, 57) || between(code, 65, 90) || between(code, 97, 122)) result += string[i]; else result += "\\" + string[i]; } return result; } function escapeHash(string) { string = "" + string; let result = ""; for (let i = 0; i < string.length; i++) { const code = string.charCodeAt(i); if (code === 0) throw new InvalidCharacterError("Invalid character: the input contains U+0000."); if (code >= 128 || code === 45 || code === 95 || between(code, 48, 57) || between(code, 65, 90) || between(code, 97, 122)) result += string[i]; else result += "\\" + code.toString(16) + " "; } return result; } function escapeString(string) { string = "" + string; let result = ""; for (let i = 0; i < string.length; i++) { const code = string.charCodeAt(i); if (code === 0) throw new InvalidCharacterError("Invalid character: the input contains U+0000."); if (between(code, 1, 31) || code === 127) result += "\\" + code.toString(16) + " "; else if (code === 34 || code === 92) result += "\\" + string[i]; else result += string[i]; } return result; } // packages/injected/src/roleUtils.ts function hasExplicitAccessibleName(e) { return e.hasAttribute("aria-label") || e.hasAttribute("aria-labelledby"); } var kAncestorPreventingLandmark = "article:not([role]), aside:not([role]), main:not([role]), nav:not([role]), section:not([role]), [role=article], [role=complementary], [role=main], [role=navigation], [role=region]"; var kGlobalAriaAttributes = [ ["aria-atomic", void 0], ["aria-busy", void 0], ["aria-controls", void 0], ["aria-current", void 0], ["aria-describedby", void 0], ["aria-details", void 0], // Global use deprecated in ARIA 1.2 // ['aria-disabled', undefined], ["aria-dropeffect", void 0], // Global use deprecated in ARIA 1.2 // ['aria-errormessage', undefined], ["aria-flowto", void 0], ["aria-grabbed", void 0], // Global use deprecated in ARIA 1.2 // ['aria-haspopup', undefined], ["aria-hidden", void 0], // Global use deprecated in ARIA 1.2 // ['aria-invalid', undefined], ["aria-keyshortcuts", void 0], ["aria-label", ["caption", "code", "deletion", "emphasis", "generic", "insertion", "paragraph", "presentation", "strong", "subscript", "superscript"]], ["aria-labelledby", ["caption", "code", "deletion", "emphasis", "generic", "insertion", "paragraph", "presentation", "strong", "subscript", "superscript"]], ["aria-live", void 0], ["aria-owns", void 0], ["aria-relevant", void 0], ["aria-roledescription", ["generic"]] ]; function hasGlobalAriaAttribute(element, forRole) { return kGlobalAriaAttributes.some(([attr, prohibited]) => { return !prohibited?.includes(forRole || "") && element.hasAttribute(attr); }); } function hasTabIndex(element) { return !Number.isNaN(Number(String(element.getAttribute("tabindex")))); } function isFocusable(element) { return !isNativelyDisabled(element) && (isNativelyFocusable(element) || hasTabIndex(element)); } function isNativelyFocusable(element) { const tagName = elementSafeTagName(element); if (["BUTTON", "DETAILS", "SELECT", "TEXTAREA"].includes(tagName)) return true; if (tagName === "A" || tagName === "AREA") return element.hasAttribute("href"); if (tagName === "INPUT") return !element.hidden; return false; } var kImplicitRoleByTagName = { "A": (e) => { return e.hasAttribute("href") ? "link" : null; }, "AREA": (e) => { return e.hasAttribute("href") ? "link" : null; }, "ARTICLE": () => "article", "ASIDE": () => "complementary", "BLOCKQUOTE": () => "blockquote", "BUTTON": () => "button", "CAPTION": () => "caption", "CODE": () => "code", "DATALIST": () => "listbox", "DD": () => "definition", "DEL": () => "deletion", "DETAILS": () => "group", "DFN": () => "term", "DIALOG": () => "dialog", "DT": () => "term", "EM": () => "emphasis", "FIELDSET": () => "group", "FIGURE": () => "figure", "FOOTER": (e) => closestCrossShadow(e, kAncestorPreventingLandmark) ? null : "contentinfo", "FORM": (e) => hasExplicitAccessibleName(e) ? "form" : null, "H1": () => "heading", "H2": () => "heading", "H3": () => "heading", "H4": () => "heading", "H5": () => "heading", "H6": () => "heading", "HEADER": (e) => closestCrossShadow(e, kAncestorPreventingLandmark) ? null : "banner", "HR": () => "separator", "HTML": () => "document", "IMG": (e) => e.getAttribute("alt") === "" && !e.getAttribute("title") && !hasGlobalAriaAttribute(e) && !hasTabIndex(e) ? "presentation" : "img", "INPUT": (e) => { const type = e.type.toLowerCase(); if (type === "search") return e.hasAttribute("list") ? "combobox" : "searchbox"; if (["email", "tel", "text", "url", ""].includes(type)) { const list = getIdRefs(e, e.getAttribute("list"))[0]; return list && elementSafeTagName(list) === "DATALIST" ? "combobox" : "textbox"; } if (type === "hidden") return null; if (type === "file") return "button"; return inputTypeToRole[type] || "textbox"; }, "INS": () => "insertion", "LI": () => "listitem", "MAIN": () => "main", "MARK": () => "mark", "MATH": () => "math", "MENU": () => "list", "METER": () => "meter", "NAV": () => "navigation", "OL": () => "list", "OPTGROUP": () => "group", "OPTION": () => "option", "OUTPUT": () => "status", "P": () => "paragraph", "PROGRESS": () => "progressbar", "SEARCH": () => "search", "SECTION": (e) => hasExplicitAccessibleName(e) ? "region" : null, "SELECT": (e) => e.hasAttribute("multiple") || e.size > 1 ? "listbox" : "combobox", "STRONG": () => "strong", "SUB": () => "subscript", "SUP": () => "superscript", // For we default to Chrome behavior: // - Chrome reports 'img'. // - Firefox reports 'diagram' that is not in official ARIA spec yet. // - Safari reports 'no role', but still computes accessible name. "SVG": () => "img", "TABLE": () => "table", "TBODY": () => "rowgroup", "TD": (e) => { const table = closestCrossShadow(e, "table"); const role = table ? getExplicitAriaRole(table) : ""; return role === "grid" || role === "treegrid" ? "gridcell" : "cell"; }, "TEXTAREA": () => "textbox", "TFOOT": () => "rowgroup", "TH": (e) => { const scope = e.getAttribute("scope"); if (scope === "col" || scope === "colgroup") return "columnheader"; if (scope === "row" || scope === "rowgroup") return "rowheader"; const nextSibling = e.nextElementSibling; const prevSibling = e.previousElementSibling; const row = !!e.parentElement && elementSafeTagName(e.parentElement) === "TR" ? e.parentElement : void 0; if (!nextSibling && !prevSibling) { if (row) { const table = closestCrossShadow(row, "table"); if (table && table.rows.length <= 1) return null; } return "columnheader"; } if (isHeaderCell(nextSibling) && isHeaderCell(prevSibling)) return "columnheader"; if (isNonEmptyDataCell(nextSibling) || isNonEmptyDataCell(prevSibling)) return "rowheader"; return "columnheader"; }, "THEAD": () => "rowgroup", "TIME": () => "time", "TR": () => "row", "UL": () => "list" }; function isHeaderCell(element) { return !!element && elementSafeTagName(element) === "TH"; } function isNonEmptyDataCell(element) { if (!element || elementSafeTagName(element) !== "TD") return false; return !!(element.textContent?.trim() || element.children.length > 0); } var kPresentationInheritanceParents = { "DD": ["DL", "DIV"], "DIV": ["DL"], "DT": ["DL", "DIV"], "LI": ["OL", "UL"], "TBODY": ["TABLE"], "TD": ["TR"], "TFOOT": ["TABLE"], "TH": ["TR"], "THEAD": ["TABLE"], "TR": ["THEAD", "TBODY", "TFOOT", "TABLE"] }; function getImplicitAriaRole(element) { const implicitRole = kImplicitRoleByTagName[elementSafeTagName(element)]?.(element) || ""; if (!implicitRole) return null; let ancestor = element; while (ancestor) { const parent = parentElementOrShadowHost(ancestor); const parents = kPresentationInheritanceParents[elementSafeTagName(ancestor)]; if (!parents || !parent || !parents.includes(elementSafeTagName(parent))) break; const parentExplicitRole = getExplicitAriaRole(parent); if ((parentExplicitRole === "none" || parentExplicitRole === "presentation") && !hasPresentationConflictResolution(parent, parentExplicitRole)) return parentExplicitRole; ancestor = parent; } return implicitRole; } var validRoles = [ "alert", "alertdialog", "application", "article", "banner", "blockquote", "button", "caption", "cell", "checkbox", "code", "columnheader", "combobox", "complementary", "contentinfo", "definition", "deletion", "dialog", "directory", "document", "emphasis", "feed", "figure", "form", "generic", "grid", "gridcell", "group", "heading", "img", "insertion", "link", "list", "listbox", "listitem", "log", "main", "mark", "marquee", "math", "meter", "menu", "menubar", "menuitem", "menuitemcheckbox", "menuitemradio", "navigation", "none", "note", "option", "paragraph", "presentation", "progressbar", "radio", "radiogroup", "region", "row", "rowgroup", "rowheader", "scrollbar", "search", "searchbox", "separator", "slider", "spinbutton", "status", "strong", "subscript", "superscript", "switch", "tab", "table", "tablist", "tabpanel", "term", "textbox", "time", "timer", "toolbar", "tooltip", "tree", "treegrid", "treeitem" ]; function getExplicitAriaRole(element) { const roles = (element.getAttribute("role") || "").split(" ").map((role) => role.trim()); return roles.find((role) => validRoles.includes(role)) || null; } function hasPresentationConflictResolution(element, role) { return hasGlobalAriaAttribute(element, role) || isFocusable(element); } function getAriaRole(element) { const explicitRole = getExplicitAriaRole(element); if (!explicitRole) return getImplicitAriaRole(element); if (explicitRole === "none" || explicitRole === "presentation") { const implicitRole = getImplicitAriaRole(element); if (hasPresentationConflictResolution(element, implicitRole)) return implicitRole; } return explicitRole; } function getAriaBoolean(attr) { return attr === null ? void 0 : attr.toLowerCase() === "true"; } function isElementIgnoredForAria(element) { return ["STYLE", "SCRIPT", "NOSCRIPT", "TEMPLATE"].includes(elementSafeTagName(element)); } function isElementHiddenForAria(element) { if (isElementIgnoredForAria(element)) return true; const style = getElementComputedStyle(element); const isSlot = element.nodeName === "SLOT"; if (style?.display === "contents" && !isSlot) { for (let child = element.firstChild; child; child = child.nextSibling) { if (child.nodeType === 1 && !isElementHiddenForAria(child)) return false; if (child.nodeType === 3 && isVisibleTextNode(child)) return false; } return true; } const isOptionInsideSelect = element.nodeName === "OPTION" && !!element.closest("select"); if (!isOptionInsideSelect && !isSlot && !isElementStyleVisibilityVisible(element, style)) return true; return belongsToDisplayNoneOrAriaHiddenOrNonSlotted(element); } function belongsToDisplayNoneOrAriaHiddenOrNonSlotted(element) { let hidden = cacheIsHidden?.get(element); if (hidden === void 0) { hidden = false; if (element.parentElement && element.parentElement.shadowRoot && !element.assignedSlot) hidden = true; if (!hidden) { const style = getElementComputedStyle(element); hidden = !style || style.display === "none" || getAriaBoolean(element.getAttribute("aria-hidden")) === true; } if (!hidden) { const parent = parentElementOrShadowHost(element); if (parent) hidden = belongsToDisplayNoneOrAriaHiddenOrNonSlotted(parent); } cacheIsHidden?.set(element, hidden); } return hidden; } function getIdRefs(element, ref) { if (!ref) return []; const root = enclosingShadowRootOrDocument(element); if (!root) return []; try { const ids = ref.split(" ").filter((id) => !!id); const result = []; for (const id of ids) { const firstElement = root.querySelector("#" + CSS.escape(id)); if (firstElement && !result.includes(firstElement)) result.push(firstElement); } return result; } catch (e) { return []; } } function trimFlatString(s) { return s.trim(); } function asFlatString(s) { return s.split("\xA0").map((chunk) => chunk.replace(/\r\n/g, "\n").replace(/[\u200b\u00ad]/g, "").replace(/\s\s*/g, " ")).join("\xA0").trim(); } function queryInAriaOwned(element, selector) { const result = [...element.querySelectorAll(selector)]; for (const owned of getIdRefs(element, element.getAttribute("aria-owns"))) { if (owned.matches(selector)) result.push(owned); result.push(...owned.querySelectorAll(selector)); } return result; } function getCSSContent(element, pseudo) { const cache = pseudo === "::before" ? cachePseudoContentBefore : pseudo === "::after" ? cachePseudoContentAfter : cachePseudoContent; if (cache?.has(element)) return cache?.get(element); const style = getElementComputedStyle(element, pseudo); let content; if (style) { const contentValue = style.content; if (contentValue && contentValue !== "none" && contentValue !== "normal") { if (style.display !== "none" && style.visibility !== "hidden") { content = parseCSSContentPropertyAsString(element, contentValue, !!pseudo); } } } if (pseudo && content !== void 0) { const display = style?.display || "inline"; if (display !== "inline") content = " " + content + " "; } if (cache) cache.set(element, content); return content; } function parseCSSContentPropertyAsString(element, content, isPseudo) { if (!content || content === "none" || content === "normal") { return; } try { let tokens = tokenize(content).filter((token) => !(token instanceof WhitespaceToken)); const delimIndex = tokens.findIndex((token) => token instanceof DelimToken && token.value === "/"); if (delimIndex !== -1) { tokens = tokens.slice(delimIndex + 1); } else if (!isPseudo) { return; } const accumulated = []; let index = 0; while (index < tokens.length) { if (tokens[index] instanceof StringToken) { accumulated.push(tokens[index].value); index++; } else if (index + 2 < tokens.length && tokens[index] instanceof FunctionToken && tokens[index].value === "attr" && tokens[index + 1] instanceof IdentToken && tokens[index + 2] instanceof CloseParenToken) { const attrName = tokens[index + 1].value; accumulated.push(element.getAttribute(attrName) || ""); index += 3; } else { return; } } return accumulated.join(""); } catch { } } function getAriaLabelledByElements(element) { const ref = element.getAttribute("aria-labelledby"); if (ref === null) return null; const refs = getIdRefs(element, ref); return refs.length ? refs : null; } function allowsNameFromContent(role, targetDescendant) { const alwaysAllowsNameFromContent = ["button", "cell", "checkbox", "columnheader", "gridcell", "heading", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "row", "rowheader", "switch", "tab", "tooltip", "treeitem"].includes(role); const descendantAllowsNameFromContent = targetDescendant && ["", "caption", "code", "contentinfo", "definition", "deletion", "emphasis", "insertion", "list", "listitem", "mark", "none", "paragraph", "presentation", "region", "row", "rowgroup", "section", "strong", "subscript", "superscript", "table", "term", "time"].includes(role); return alwaysAllowsNameFromContent || descendantAllowsNameFromContent; } function getElementAccessibleName(element, includeHidden) { const cache = includeHidden ? cacheAccessibleNameHidden : cacheAccessibleName; let accessibleName = cache?.get(element); if (accessibleName === void 0) { accessibleName = ""; const elementProhibitsNaming = ["caption", "code", "definition", "deletion", "emphasis", "generic", "insertion", "mark", "paragraph", "presentation", "strong", "subscript", "suggestion", "superscript", "term", "time"].includes(getAriaRole(element) || ""); if (!elementProhibitsNaming) { accessibleName = asFlatString(getTextAlternativeInternal(element, { includeHidden, visitedElements: /* @__PURE__ */ new Set(), embeddedInTargetElement: "self" })); } cache?.set(element, accessibleName); } return accessibleName; } var kAriaInvalidRoles = [ "application", "checkbox", "columnheader", "combobox", "gridcell", "listbox", "radiogroup", "rowheader", "searchbox", "slider", "spinbutton", "switch", "textbox", "tree" ]; function getAriaInvalid(element) { const ariaInvalid = element.getAttribute("aria-invalid"); if (!ariaInvalid || ariaInvalid.trim() === "" || ariaInvalid.toLocaleLowerCase() === "false") return "false"; if (ariaInvalid === "true" || ariaInvalid === "grammar" || ariaInvalid === "spelling") return ariaInvalid; return "true"; } function getTextAlternativeInternal(element, options) { if (options.visitedElements.has(element)) return ""; const childOptions = { ...options, embeddedInTargetElement: options.embeddedInTargetElement === "self" ? "descendant" : options.embeddedInTargetElement }; if (!options.includeHidden) { const isEmbeddedInHiddenReferenceTraversal = !!options.embeddedInLabelledBy?.hidden || !!options.embeddedInDescribedBy?.hidden || !!options.embeddedInNativeTextAlternative?.hidden || !!options.embeddedInLabel?.hidden; if (isElementIgnoredForAria(element) || !isEmbeddedInHiddenReferenceTraversal && isElementHiddenForAria(element)) { options.visitedElements.add(element); return ""; } } const labelledBy = getAriaLabelledByElements(element); if (!options.embeddedInLabelledBy) { const accessibleName = (labelledBy || []).map((ref) => getTextAlternativeInternal(ref, { ...options, embeddedInLabelledBy: { element: ref, hidden: isElementHiddenForAria(ref) }, embeddedInDescribedBy: void 0, embeddedInTargetElement: void 0, embeddedInLabel: void 0, embeddedInNativeTextAlternative: void 0 })).join(" "); if (accessibleName) return accessibleName; } const role = getAriaRole(element) || ""; const tagName = elementSafeTagName(element); if (!!options.embeddedInLabel || !!options.embeddedInLabelledBy || options.embeddedInTargetElement === "descendant") { const isOwnLabel = [...element.labels || []].includes(element); const isOwnLabelledBy = (labelledBy || []).includes(element); if (!isOwnLabel && !isOwnLabelledBy) { if (role === "textbox") { options.visitedElements.add(element); if (tagName === "INPUT" || tagName === "TEXTAREA") return element.value; return element.textContent || ""; } if (["combobox", "listbox"].includes(role)) { options.visitedElements.add(element); let selectedOptions; if (tagName === "SELECT") { selectedOptions = [...element.selectedOptions]; if (!selectedOptions.length && element.options.length) selectedOptions.push(element.options[0]); } else { const listbox = role === "combobox" ? queryInAriaOwned(element, "*").find((e) => getAriaRole(e) === "listbox") : element; selectedOptions = listbox ? queryInAriaOwned(listbox, '[aria-selected="true"]').filter((e) => getAriaRole(e) === "option") : []; } if (!selectedOptions.length && tagName === "INPUT") { return element.value; } return selectedOptions.map((option) => getTextAlternativeInternal(option, childOptions)).join(" "); } if (["progressbar", "scrollbar", "slider", "spinbutton", "meter"].includes(role)) { options.visitedElements.add(element); if (element.hasAttribute("aria-valuetext")) return element.getAttribute("aria-valuetext") || ""; if (element.hasAttribute("aria-valuenow")) return element.getAttribute("aria-valuenow") || ""; return element.getAttribute("value") || ""; } if (["menu"].includes(role)) { options.visitedElements.add(element); return ""; } } } const ariaLabel = element.getAttribute("aria-label") || ""; if (trimFlatString(ariaLabel)) { options.visitedElements.add(element); return ariaLabel; } if (!["presentation", "none"].includes(role)) { if (tagName === "INPUT" && ["button", "submit", "reset"].includes(element.type)) { options.visitedElements.add(element); const value = element.value || ""; if (trimFlatString(value)) return value; if (element.type === "submit") return "Submit"; if (element.type === "reset") return "Reset"; const title = element.getAttribute("title") || ""; return title; } if (tagName === "INPUT" && element.type === "file") { options.visitedElements.add(element); const labels = element.labels || []; if (labels.length && !options.embeddedInLabelledBy) return getAccessibleNameFromAssociatedLabels(labels, options); return "Choose File"; } if (tagName === "INPUT" && element.type === "image") { options.visitedElements.add(element); const labels = element.labels || []; if (labels.length && !options.embeddedInLabelledBy) return getAccessibleNameFromAssociatedLabels(labels, options); const alt = element.getAttribute("alt") || ""; if (trimFlatString(alt)) return alt; const title = element.getAttribute("title") || ""; if (trimFlatString(title)) return title; return "Submit"; } if (!labelledBy && tagName === "BUTTON") { options.visitedElements.add(element); const labels = element.labels || []; if (labels.length) return getAccessibleNameFromAssociatedLabels(labels, options); } if (!labelledBy && tagName === "OUTPUT") { options.visitedElements.add(element); const labels = element.labels || []; if (labels.length) return getAccessibleNameFromAssociatedLabels(labels, options); return element.getAttribute("title") || ""; } if (!labelledBy && (tagName === "TEXTAREA" || tagName === "SELECT" || tagName === "INPUT")) { options.visitedElements.add(element); const labels = element.labels || []; if (labels.length) return getAccessibleNameFromAssociatedLabels(labels, options); const usePlaceholder = tagName === "INPUT" && ["text", "password", "search", "tel", "email", "url"].includes(element.type) || tagName === "TEXTAREA"; const placeholder = element.getAttribute("placeholder") || ""; const title = element.getAttribute("title") || ""; if (!usePlaceholder || title) return title; return placeholder; } if (!labelledBy && tagName === "FIELDSET") { options.visitedElements.add(element); for (let child = element.firstElementChild; child; child = child.nextElementSibling) { if (elementSafeTagName(child) === "LEGEND") { return getTextAlternativeInternal(child, { ...childOptions, embeddedInNativeTextAlternative: { element: child, hidden: isElementHiddenForAria(child) } }); } } const title = element.getAttribute("title") || ""; return title; } if (!labelledBy && tagName === "FIGURE") { options.visitedElements.add(element); for (let child = element.firstElementChild; child; child = child.nextElementSibling) { if (elementSafeTagName(child) === "FIGCAPTION") { return getTextAlternativeInternal(child, { ...childOptions, embeddedInNativeTextAlternative: { element: child, hidden: isElementHiddenForAria(child) } }); } } const title = element.getAttribute("title") || ""; return title; } if (tagName === "IMG") { options.visitedElements.add(element); const alt = element.getAttribute("alt") || ""; if (trimFlatString(alt)) return alt; const title = element.getAttribute("title") || ""; return title; } if (tagName === "TABLE") { options.visitedElements.add(element); for (let child = element.firstElementChild; child; child = child.nextElementSibling) { if (elementSafeTagName(child) === "CAPTION") { return getTextAlternativeInternal(child, { ...childOptions, embeddedInNativeTextAlternative: { element: child, hidden: isElementHiddenForAria(child) } }); } } const summary = element.getAttribute("summary") || ""; if (summary) return summary; } if (tagName === "AREA") { options.visitedElements.add(element); const alt = element.getAttribute("alt") || ""; if (trimFlatString(alt)) return alt; const title = element.getAttribute("title") || ""; return title; } if (tagName === "SVG" || element.ownerSVGElement) { options.visitedElements.add(element); for (let child = element.firstElementChild; child; child = child.nextElementSibling) { if (elementSafeTagName(child) === "TITLE" && child.ownerSVGElement) { return getTextAlternativeInternal(child, { ...childOptions, embeddedInLabelledBy: { element: child, hidden: isElementHiddenForAria(child) } }); } } } if (element.ownerSVGElement && tagName === "A") { const title = element.getAttribute("xlink:title") || ""; if (trimFlatString(title)) { options.visitedElements.add(element); return title; } } } const shouldNameFromContentForSummary = tagName === "SUMMARY" && !["presentation", "none"].includes(role); if (allowsNameFromContent(role, options.embeddedInTargetElement === "descendant") || shouldNameFromContentForSummary || !!options.embeddedInLabelledBy || !!options.embeddedInDescribedBy || !!options.embeddedInLabel || !!options.embeddedInNativeTextAlternative) { options.visitedElements.add(element); const accessibleName = innerAccumulatedElementText(element, childOptions); const maybeTrimmedAccessibleName = options.embeddedInTargetElement === "self" ? trimFlatString(accessibleName) : accessibleName; if (maybeTrimmedAccessibleName) return accessibleName; } if (!["presentation", "none"].includes(role) || tagName === "IFRAME") { options.visitedElements.add(element); const title = element.getAttribute("title") || ""; if (trimFlatString(title)) return title; } options.visitedElements.add(element); return ""; } function innerAccumulatedElementText(element, options) { const tokens = []; const visit = (node, skipSlotted) => { if (skipSlotted && node.assignedSlot) return; if (node.nodeType === 1) { const display = getElementComputedStyle(node)?.display || "inline"; let token = getTextAlternativeInternal(node, options); if (display !== "inline" || node.nodeName === "BR") token = " " + token + " "; tokens.push(token); } else if (node.nodeType === 3) { tokens.push(node.textContent || ""); } }; tokens.push(getCSSContent(element, "::before") || ""); const content = getCSSContent(element); if (content !== void 0) { tokens.push(content); } else { const assignedNodes = element.nodeName === "SLOT" ? element.assignedNodes() : []; if (assignedNodes.length) { for (const child of assignedNodes) visit(child, false); } else { for (let child = element.firstChild; child; child = child.nextSibling) visit(child, true); if (element.shadowRoot) { for (let child = element.shadowRoot.firstChild; child; child = child.nextSibling) visit(child, true); } for (const owned of getIdRefs(element, element.getAttribute("aria-owns"))) visit(owned, true); } } tokens.push(getCSSContent(element, "::after") || ""); return tokens.join(""); } var kAriaSelectedRoles = ["gridcell", "option", "row", "tab", "rowheader", "columnheader", "treeitem"]; function getAriaSelected(element) { if (elementSafeTagName(element) === "OPTION") return element.selected; if (kAriaSelectedRoles.includes(getAriaRole(element) || "")) return getAriaBoolean(element.getAttribute("aria-selected")) === true; return false; } var kAriaCheckedRoles = ["checkbox", "menuitemcheckbox", "option", "radio", "switch", "menuitemradio", "treeitem"]; function getAriaChecked(element) { const result = getChecked(element, true); return result === "error" ? false : result; } function getChecked(element, allowMixed) { const tagName = elementSafeTagName(element); if (allowMixed && tagName === "INPUT" && element.indeterminate) return "mixed"; if (tagName === "INPUT" && ["checkbox", "radio"].includes(element.type)) return element.checked; if (kAriaCheckedRoles.includes(getAriaRole(element) || "")) { const checked = element.getAttribute("aria-checked"); if (checked === "true") return true; if (allowMixed && checked === "mixed") return "mixed"; return false; } return "error"; } var kAriaPressedRoles = ["button"]; function getAriaPressed(element) { if (kAriaPressedRoles.includes(getAriaRole(element) || "")) { const pressed = element.getAttribute("aria-pressed"); if (pressed === "true") return true; if (pressed === "mixed") return "mixed"; } return false; } var kAriaExpandedRoles = ["application", "button", "checkbox", "combobox", "gridcell", "link", "listbox", "menuitem", "row", "rowheader", "tab", "treeitem", "columnheader", "menuitemcheckbox", "menuitemradio", "rowheader", "switch"]; function getAriaExpanded(element) { if (elementSafeTagName(element) === "DETAILS") return element.open; if (kAriaExpandedRoles.includes(getAriaRole(element) || "")) { const expanded = element.getAttribute("aria-expanded"); if (expanded === null) return void 0; if (expanded === "true") return true; return false; } return void 0; } var kAriaLevelRoles = ["heading", "listitem", "row", "treeitem"]; function getAriaLevel(element) { const native = { "H1": 1, "H2": 2, "H3": 3, "H4": 4, "H5": 5, "H6": 6 }[elementSafeTagName(element)]; if (native) return native; if (kAriaLevelRoles.includes(getAriaRole(element) || "")) { const attr = element.getAttribute("aria-level"); const value = attr === null ? Number.NaN : Number(attr); if (Number.isInteger(value) && value >= 1) return value; } return 0; } var kAriaDisabledRoles = ["application", "button", "composite", "gridcell", "group", "input", "link", "menuitem", "scrollbar", "separator", "tab", "checkbox", "columnheader", "combobox", "grid", "listbox", "menu", "menubar", "menuitemcheckbox", "menuitemradio", "option", "radio", "radiogroup", "row", "rowheader", "searchbox", "select", "slider", "spinbutton", "switch", "tablist", "textbox", "toolbar", "tree", "treegrid", "treeitem"]; function getAriaDisabled(element) { return isNativelyDisabled(element) || hasExplicitAriaDisabled(element); } function isNativelyDisabled(element) { const isNativeFormControl = ["BUTTON", "INPUT", "SELECT", "TEXTAREA", "OPTION", "OPTGROUP"].includes(elementSafeTagName(element)); return isNativeFormControl && (element.hasAttribute("disabled") || belongsToDisabledOptGroup(element) || belongsToDisabledFieldSet(element)); } function belongsToDisabledOptGroup(element) { return elementSafeTagName(element) === "OPTION" && !!element.closest("OPTGROUP[DISABLED]"); } function belongsToDisabledFieldSet(element) { const fieldSetElement = element?.closest("FIELDSET[DISABLED]"); if (!fieldSetElement) return false; const legendElement = fieldSetElement.querySelector(":scope > LEGEND"); return !legendElement || !legendElement.contains(element); } function hasExplicitAriaDisabled(element, isAncestor = false) { if (!element) return false; if (isAncestor || kAriaDisabledRoles.includes(getAriaRole(element) || "")) { const attribute = (element.getAttribute("aria-disabled") || "").toLowerCase(); if (attribute === "true") return true; if (attribute === "false") return false; return hasExplicitAriaDisabled(parentElementOrShadowHost(element), true); } return false; } function getAccessibleNameFromAssociatedLabels(labels, options) { return [...labels].map((label) => getTextAlternativeInternal(label, { ...options, embeddedInLabel: { element: label, hidden: isElementHiddenForAria(label) }, embeddedInNativeTextAlternative: void 0, embeddedInLabelledBy: void 0, embeddedInDescribedBy: void 0, embeddedInTargetElement: void 0 })).filter((accessibleName) => !!accessibleName).join(" "); } function receivesPointerEvents(element) { const cache = cachePointerEvents; let e = element; let result; const parents = []; for (; e; e = parentElementOrShadowHost(e)) { const cached = cache.get(e); if (cached !== void 0) { result = cached; break; } parents.push(e); const style = getElementComputedStyle(e); if (!style) { result = true; break; } const value = style.pointerEvents; if (value) { result = value !== "none"; break; } } if (result === void 0) result = true; for (const parent of parents) cache.set(parent, result); return result; } var cacheAccessibleName; var cacheAccessibleNameHidden; var cacheAccessibleDescription; var cacheAccessibleDescriptionHidden; var cacheAccessibleErrorMessage; var cacheIsHidden; var cachePseudoContent; var cachePseudoContentBefore; var cachePseudoContentAfter; var cachePointerEvents; var cachesCounter2 = 0; function beginAriaCaches() { beginDOMCaches(); ++cachesCounter2; cacheAccessibleName ??= /* @__PURE__ */ new Map(); cacheAccessibleNameHidden ??= /* @__PURE__ */ new Map(); cacheAccessibleDescription ??= /* @__PURE__ */ new Map(); cacheAccessibleDescriptionHidden ??= /* @__PURE__ */ new Map(); cacheAccessibleErrorMessage ??= /* @__PURE__ */ new Map(); cacheIsHidden ??= /* @__PURE__ */ new Map(); cachePseudoContent ??= /* @__PURE__ */ new Map(); cachePseudoContentBefore ??= /* @__PURE__ */ new Map(); cachePseudoContentAfter ??= /* @__PURE__ */ new Map(); cachePointerEvents ??= /* @__PURE__ */ new Map(); } function endAriaCaches() { if (!--cachesCounter2) { cacheAccessibleName = void 0; cacheAccessibleNameHidden = void 0; cacheAccessibleDescription = void 0; cacheAccessibleDescriptionHidden = void 0; cacheAccessibleErrorMessage = void 0; cacheIsHidden = void 0; cachePseudoContent = void 0; cachePseudoContentBefore = void 0; cachePseudoContentAfter = void 0; cachePointerEvents = void 0; } endDOMCaches(); } var inputTypeToRole = { "button": "button", "checkbox": "checkbox", "image": "button", "number": "spinbutton", "radio": "radio", "range": "slider", "reset": "button", "submit": "button" }; // packages/injected/src/ariaSnapshot.ts var lastRef = 0; function toInternalOptions(options) { const renderBoxes = options.boxes; if (options.mode === "ai") { return { visibility: "ariaOrVisible", refs: "interactable", refPrefix: options.refPrefix, includeGenericRole: true, renderActive: !options.doNotRenderActive, renderCursorPointer: true, renderBoxes }; } if (options.mode === "autoexpect") { return { visibility: "ariaAndVisible", refs: "none", renderBoxes }; } if (options.mode === "codegen") { return { visibility: "aria", refs: "none", renderStringsAsRegex: true, renderBoxes }; } return { visibility: "aria", refs: "none", renderBoxes }; } function generateAriaTree(rootElement, publicOptions) { const options = toInternalOptions(publicOptions); const visited = /* @__PURE__ */ new Set(); const snapshot = { root: { role: "fragment", name: "", children: [], props: {}, box: computeBox(rootElement), receivesPointerEvents: true }, elements: /* @__PURE__ */ new Map(), refs: /* @__PURE__ */ new Map(), iframeRefs: [] }; setAriaNodeElement(snapshot.root, rootElement); const visit = (ariaNode, node, parentElementVisible) => { if (visited.has(node)) return; visited.add(node); if (node.nodeType === Node.TEXT_NODE && node.nodeValue) { if (!parentElementVisible) return; const text = node.nodeValue; if (ariaNode.role !== "textbox" && text) ariaNode.children.push(node.nodeValue || ""); return; } if (node.nodeType !== Node.ELEMENT_NODE) return; const element = node; const isElementVisibleForAria = !isElementHiddenForAria(element); let visible = isElementVisibleForAria; if (options.visibility === "ariaOrVisible") visible = isElementVisibleForAria || isElementVisible(element); if (options.visibility === "ariaAndVisible") visible = isElementVisibleForAria && isElementVisible(element); if (options.visibility === "aria" && !visible) return; const ariaChildren = []; if (element.hasAttribute("aria-owns")) { const ids = element.getAttribute("aria-owns").split(/\s+/); for (const id of ids) { const ownedElement = rootElement.ownerDocument.getElementById(id); if (ownedElement) ariaChildren.push(ownedElement); } } const childAriaNode = visible ? toAriaNode(element, options) : null; if (childAriaNode) { if (childAriaNode.ref) { snapshot.elements.set(childAriaNode.ref, element); snapshot.refs.set(element, childAriaNode.ref); if (childAriaNode.role === "iframe") snapshot.iframeRefs.push(childAriaNode.ref); } ariaNode.children.push(childAriaNode); } processElement(childAriaNode || ariaNode, element, ariaChildren, visible); }; function processElement(ariaNode, element, ariaChildren, parentElementVisible) { const display = getElementComputedStyle(element)?.display || "inline"; const treatAsBlock = display !== "inline" || element.nodeName === "BR" ? " " : ""; if (treatAsBlock) ariaNode.children.push(treatAsBlock); ariaNode.children.push(getCSSContent(element, "::before") || ""); const assignedNodes = element.nodeName === "SLOT" ? element.assignedNodes() : []; if (assignedNodes.length) { for (const child of assignedNodes) visit(ariaNode, child, parentElementVisible); } else { for (let child = element.firstChild; child; child = child.nextSibling) { if (!child.assignedSlot) visit(ariaNode, child, parentElementVisible); } if (element.shadowRoot) { for (let child = element.shadowRoot.firstChild; child; child = child.nextSibling) visit(ariaNode, child, parentElementVisible); } } for (const child of ariaChildren) visit(ariaNode, child, parentElementVisible); ariaNode.children.push(getCSSContent(element, "::after") || ""); if (treatAsBlock) ariaNode.children.push(treatAsBlock); if (ariaNode.children.length === 1 && ariaNode.name === ariaNode.children[0]) ariaNode.children = []; if (ariaNode.role === "link" && element.hasAttribute("href")) { const href = element.getAttribute("href"); ariaNode.props["url"] = href; } if (ariaNode.role === "textbox" && element.hasAttribute("placeholder") && element.getAttribute("placeholder") !== ariaNode.name) { const placeholder = element.getAttribute("placeholder"); ariaNode.props["placeholder"] = placeholder; } } beginAriaCaches(); try { visit(snapshot.root, rootElement, true); } finally { endAriaCaches(); } normalizeStringChildren(snapshot.root); normalizeGenericRoles(snapshot.root); return snapshot; } function computeAriaRef(ariaNode, options) { if (options.refs === "none") return; if (options.refs === "interactable" && (!ariaNode.box.visible || !ariaNode.receivesPointerEvents)) return; const element = ariaNodeElement(ariaNode); let ariaRef = element._ariaRef; if (!ariaRef || ariaRef.role !== ariaNode.role || ariaRef.name !== ariaNode.name) { ariaRef = { role: ariaNode.role, name: ariaNode.name, ref: (options.refPrefix ?? "") + "e" + ++lastRef }; element._ariaRef = ariaRef; } ariaNode.ref = ariaRef.ref; } function toAriaNode(element, options) { const active = element.ownerDocument.activeElement === element; if (element.nodeName === "IFRAME") { const ariaNode = { role: "iframe", name: "", children: [], props: {}, box: computeBox(element), receivesPointerEvents: true, active }; setAriaNodeElement(ariaNode, element); computeAriaRef(ariaNode, options); return ariaNode; } const defaultRole = options.includeGenericRole ? "generic" : null; const role = getAriaRole(element) ?? defaultRole; if (!role || role === "presentation" || role === "none") return null; const name = normalizeWhiteSpace(getElementAccessibleName(element, false) || ""); const receivesPointerEvents2 = receivesPointerEvents(element); const box = computeBox(element); if (role === "generic" && box.inline && element.childNodes.length === 1 && element.childNodes[0].nodeType === Node.TEXT_NODE) return null; const result = { role, name, children: [], props: {}, box, receivesPointerEvents: receivesPointerEvents2, active }; setAriaNodeElement(result, element); computeAriaRef(result, options); if (kAriaCheckedRoles.includes(role)) result.checked = getAriaChecked(element); if (kAriaDisabledRoles.includes(role)) result.disabled = getAriaDisabled(element); if (kAriaExpandedRoles.includes(role)) result.expanded = getAriaExpanded(element); if (kAriaInvalidRoles.includes(role)) { const invalid = getAriaInvalid(element); result.invalid = invalid === "false" ? false : invalid === "true" ? true : invalid; } if (kAriaLevelRoles.includes(role)) result.level = getAriaLevel(element); if (kAriaPressedRoles.includes(role)) result.pressed = getAriaPressed(element); if (kAriaSelectedRoles.includes(role)) result.selected = getAriaSelected(element); if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) { if (element.type !== "checkbox" && element.type !== "radio" && element.type !== "file") result.children = [element.value]; } return result; } function normalizeGenericRoles(node) { const normalizeChildren = (node2) => { const result = []; for (const child of node2.children || []) { if (typeof child === "string") { result.push(child); continue; } const normalized = normalizeChildren(child); result.push(...normalized); } const removeSelf = node2.role === "generic" && !node2.name && result.length <= 1 && result.every((c) => typeof c !== "string" && !!c.ref); if (removeSelf) return result; node2.children = result; return [node2]; }; normalizeChildren(node); } function normalizeStringChildren(rootA11yNode) { const flushChildren = (buffer, normalizedChildren) => { if (!buffer.length) return; const text = normalizeWhiteSpace(buffer.join("")); if (text) normalizedChildren.push(text); buffer.length = 0; }; const visit = (ariaNode) => { const normalizedChildren = []; const buffer = []; for (const child of ariaNode.children || []) { if (typeof child === "string") { buffer.push(child); } else { flushChildren(buffer, normalizedChildren); visit(child); normalizedChildren.push(child); } } flushChildren(buffer, normalizedChildren); ariaNode.children = normalizedChildren.length ? normalizedChildren : []; if (ariaNode.children.length === 1 && ariaNode.children[0] === ariaNode.name) ariaNode.children = []; }; visit(rootA11yNode); } function buildByRefMap(root, map = /* @__PURE__ */ new Map()) { if (root?.ref) map.set(root.ref, root); for (const child of root?.children || []) { if (typeof child !== "string") buildByRefMap(child, map); } return map; } function compareSnapshots(ariaSnapshot, previousSnapshot) { const previousByRef = buildByRefMap(previousSnapshot?.root); const result = /* @__PURE__ */ new Map(); const visit = (ariaNode, previousNode) => { let same = ariaNode.children.length === previousNode?.children.length && ariaNodesEqual(ariaNode, previousNode); let canBeSkipped = same; for (let childIndex = 0; childIndex < ariaNode.children.length; childIndex++) { const child = ariaNode.children[childIndex]; const previousChild = previousNode?.children[childIndex]; if (typeof child === "string") { same &&= child === previousChild; canBeSkipped &&= child === previousChild; } else { let previous = typeof previousChild !== "string" ? previousChild : void 0; if (child.ref) previous = previousByRef.get(child.ref); const sameChild = visit(child, previous); if (!previous || !sameChild && !child.ref || previous !== previousChild) canBeSkipped = false; same &&= sameChild && previous === previousChild; } } result.set(ariaNode, same ? "same" : canBeSkipped ? "skip" : "changed"); return same; }; visit(ariaSnapshot.root, previousByRef.get(previousSnapshot?.root?.ref)); return result; } function filterSnapshotDiff(nodes, statusMap) { const result = []; const visit = (ariaNode) => { const status = statusMap.get(ariaNode); if (status === "same") { } else if (status === "skip") { for (const child of ariaNode.children) { if (typeof child !== "string") visit(child); } } else { result.push(ariaNode); } }; for (const node of nodes) { if (typeof node === "string") result.push(node); else visit(node); } return result; } function indent(depth) { return " ".repeat(depth); } function renderAriaTree(ariaSnapshot, publicOptions, previousSnapshot) { const options = toInternalOptions(publicOptions); const lines = []; const iframeDepths = {}; const includeText = options.renderStringsAsRegex ? textContributesInfo : () => true; const renderString = options.renderStringsAsRegex ? convertToBestGuessRegex : (str) => str; let nodesToRender = ariaSnapshot.root.role === "fragment" ? ariaSnapshot.root.children : [ariaSnapshot.root]; const statusMap = compareSnapshots(ariaSnapshot, previousSnapshot); if (previousSnapshot) nodesToRender = filterSnapshotDiff(nodesToRender, statusMap); const visitText = (text, depth) => { if (publicOptions.depth && depth > publicOptions.depth) return; const escaped = yamlEscapeValueIfNeeded(renderString(text)); if (escaped) lines.push(indent(depth) + "- text: " + escaped); }; const createKey = (ariaNode, renderCursorPointer) => { let key = ariaNode.role; if (ariaNode.name && ariaNode.name.length <= 900) { const name = renderString(ariaNode.name); if (name) { const stringifiedName = name.startsWith("/") && name.endsWith("/") ? name : JSON.stringify(name); key += " " + stringifiedName; } } if (ariaNode.checked === "mixed") key += ` [checked=mixed]`; if (ariaNode.checked === true) key += ` [checked]`; if (ariaNode.disabled) key += ` [disabled]`; if (ariaNode.expanded) key += ` [expanded]`; if (ariaNode.active && options.renderActive) key += ` [active]`; if (ariaNode.invalid === "grammar" || ariaNode.invalid === "spelling") key += ` [invalid=${ariaNode.invalid}]`; if (ariaNode.invalid === true) key += ` [invalid]`; if (ariaNode.level) key += ` [level=${ariaNode.level}]`; if (ariaNode.pressed === "mixed") key += ` [pressed=mixed]`; if (ariaNode.pressed === true) key += ` [pressed]`; if (ariaNode.selected === true) key += ` [selected]`; if (ariaNode.ref) { key += ` [ref=${ariaNode.ref}]`; if (renderCursorPointer && hasPointerCursor(ariaNode)) key += " [cursor=pointer]"; } if (options.renderBoxes) { const element = ariaNodeElement(ariaNode); if (element) { const r = element.getBoundingClientRect(); key += ` [box=${Math.round(r.x)},${Math.round(r.y)},${Math.round(r.width)},${Math.round(r.height)}]`; } } return key; }; const getSingleInlinedTextChild = (ariaNode) => { return ariaNode?.children.length === 1 && typeof ariaNode.children[0] === "string" && !Object.keys(ariaNode.props).length ? ariaNode.children[0] : void 0; }; const visit = (ariaNode, depth, renderCursorPointer) => { if (publicOptions.depth && depth > publicOptions.depth) return; if (ariaNode.role === "iframe" && ariaNode.ref) iframeDepths[ariaNode.ref] = depth; if (statusMap.get(ariaNode) === "same" && ariaNode.ref) { lines.push(indent(depth) + `- ref=${ariaNode.ref} [unchanged]`); return; } const isDiffRoot = !!previousSnapshot && !depth; const escapedKey = indent(depth) + "- " + (isDiffRoot ? " " : "") + yamlEscapeKeyIfNeeded(createKey(ariaNode, renderCursorPointer)); const singleInlinedTextChild = getSingleInlinedTextChild(ariaNode); const isAtDepthLimit = !!publicOptions.depth && depth === publicOptions.depth; const hasNoChildren = !singleInlinedTextChild && (!ariaNode.children.length || isAtDepthLimit); if (hasNoChildren && !Object.keys(ariaNode.props).length) { lines.push(escapedKey); } else if (singleInlinedTextChild !== void 0) { const shouldInclude = includeText(ariaNode, singleInlinedTextChild); if (shouldInclude) lines.push(escapedKey + ": " + yamlEscapeValueIfNeeded(renderString(singleInlinedTextChild))); else lines.push(escapedKey); } else { lines.push(escapedKey + ":"); for (const [name, value] of Object.entries(ariaNode.props)) lines.push(indent(depth + 1) + "- /" + name + ": " + yamlEscapeValueIfNeeded(value)); const inCursorPointer = !!ariaNode.ref && renderCursorPointer && hasPointerCursor(ariaNode); for (const child of ariaNode.children) { if (typeof child === "string") visitText(includeText(ariaNode, child) ? child : "", depth + 1); else visit(child, depth + 1, renderCursorPointer && !inCursorPointer); } } }; for (const nodeToRender of nodesToRender) { if (typeof nodeToRender === "string") visitText(nodeToRender, 0); else visit(nodeToRender, 0, !!options.renderCursorPointer); } return { text: lines.join("\n"), iframeDepths }; } function convertToBestGuessRegex(text) { const dynamicContent = [ // 550e8400-e29b-41d4-a716-446655440000 { regex: /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/, replacement: "[0-9a-fA-F-]+" }, // 2mb { regex: /\b[\d,.]+[bkmBKM]+\b/, replacement: "[\\d,.]+[bkmBKM]+" }, // 2ms, 20s { regex: /\b\d+[hmsp]+\b/, replacement: "\\d+[hmsp]+" }, { regex: /\b[\d,.]+[hmsp]+\b/, replacement: "[\\d,.]+[hmsp]+" }, // Do not replace single digits with regex by default. // 2+ digits: [Issue 22, 22.3, 2.33, 2,333] { regex: /\b\d+,\d+\b/, replacement: "\\d+,\\d+" }, { regex: /\b\d+\.\d{2,}\b/, replacement: "\\d+\\.\\d+" }, { regex: /\b\d{2,}\.\d+\b/, replacement: "\\d+\\.\\d+" }, { regex: /\b\d{2,}\b/, replacement: "\\d+" } ]; let pattern = ""; let lastIndex = 0; const combinedRegex = new RegExp(dynamicContent.map((r) => "(" + r.regex.source + ")").join("|"), "g"); text.replace(combinedRegex, (match, ...args) => { const offset = args[args.length - 2]; const groups = args.slice(0, -2); pattern += escapeRegExp(text.slice(lastIndex, offset)); for (let i = 0; i < groups.length; i++) { if (groups[i]) { const { replacement } = dynamicContent[i]; pattern += replacement; break; } } lastIndex = offset + match.length; return match; }); if (!pattern) return text; pattern += escapeRegExp(text.slice(lastIndex)); return String(new RegExp(pattern)); } function textContributesInfo(node, text) { if (!text.length) return false; if (!node.name) return true; const substr = text.length <= 200 && node.name.length <= 200 ? longestCommonSubstring(text, node.name) : ""; let filtered = text; while (substr && filtered.includes(substr)) filtered = filtered.replace(substr, ""); return filtered.trim().length / text.length > 0.1; } var elementSymbol = /* @__PURE__ */ Symbol("element"); function ariaNodeElement(ariaNode) { return ariaNode[elementSymbol]; } function setAriaNodeElement(ariaNode, element) { ariaNode[elementSymbol] = element; } // esm-entry.ts function buildSnapshot(root, options) { const o = Object.assign({ mode: "ai" }, options || {}); const tree = generateAriaTree(root || document.body, o); const rendered = renderAriaTree(tree, o); return { text: rendered.text, elements: tree.elements, // Map refs: tree.refs // Map }; } export { buildSnapshot, generateAriaTree, renderAriaTree };