/** * @web-browser/core bundled for browser injection. * Auto-generated - do not edit directly. * * This bundle exposes window.__browserMcpCore with all core exports. */ export const coreBundleSource = "(() => {\n var __defProp = Object.defineProperty;\n var __getOwnPropNames = Object.getOwnPropertyNames;\n var __getOwnPropDesc = Object.getOwnPropertyDescriptor;\n var __hasOwnProp = Object.prototype.hasOwnProperty;\n var __moduleCache = /* @__PURE__ */ new WeakMap;\n var __toCommonJS = (from) => {\n var entry = __moduleCache.get(from), desc;\n if (entry)\n return entry;\n entry = __defProp({}, \"__esModule\", { value: true });\n if (from && typeof from === \"object\" || typeof from === \"function\")\n __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {\n get: () => from[key],\n enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable\n }));\n __moduleCache.set(from, entry);\n return entry;\n };\n var __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, {\n get: all[name],\n enumerable: true,\n configurable: true,\n set: (newValue) => all[name] = () => newValue\n });\n };\n\n // .bundle-entry.ts\n var exports__bundle_entry = {};\n __export(exports__bundle_entry, {\n default: () => __bundle_entry_default\n });\n\n // src/index.ts\n var exports_src = {};\n __export(exports_src, {\n xpathEngine: () => xpathEngine,\n withSelectorCacheAsync: () => withSelectorCacheAsync,\n withSelectorCache: () => withSelectorCache,\n withCacheAsync: () => withCacheAsync,\n withCache: () => withCache,\n withAriaCacheAsync: () => withAriaCacheAsync,\n withAriaCache: () => withAriaCache,\n waitForElementState: () => waitForElementState,\n waitForElementStable: () => waitForElementStable,\n typeText: () => typeText,\n textEngine: () => textEngine,\n setupHitTargetInterceptor: () => setupHitTargetInterceptor,\n selectorEngines: () => selectorEngines,\n selectorCache: () => selectorCache,\n selectAll: () => selectAll,\n scrollIntoViewIfNeeded: () => scrollIntoViewIfNeeded,\n roleEngine: () => roleEngine,\n retarget: () => retarget,\n resolveSmartModifier: () => resolveSmartModifier,\n resolveElementRefs: () => resolveElementRefs,\n registerLayoutEngines: () => registerLayoutEngines,\n registerInternalEngines: () => registerInternalEngines,\n receivesPointerEvents: () => receivesPointerEvents,\n querySelectorAll: () => querySelectorAll,\n querySelector: () => querySelector,\n parseTextSelectorBody: () => parseTextSelectorBody,\n parseSelector: () => parseSelector,\n parseKeyCombinationSmart: () => parseKeyCombinationSmart,\n parseKeyCombination: () => parseKeyCombination,\n parseCompoundSelectorBody: () => parseCompoundSelectorBody,\n layoutSelectorScore: () => layoutSelectorScore,\n layoutEngines: () => layoutEngines,\n kLayoutSelectorNames: () => kLayoutSelectorNames,\n isVisibleTextNode: () => isVisibleTextNode,\n isValidRef: () => isValidRef,\n isTouchEvent: () => isTouchEvent,\n isSelectorCachingActive: () => isSelectorCachingActive,\n isNotSlotted: () => isNotSlotted,\n isLabelElement: () => isLabelElement,\n isInteractiveElement: () => isInteractiveElement,\n isInputLike: () => isInputLike,\n isInertSubtree: () => isInertSubtree,\n isInViewport: () => isInViewport,\n isIgnoredForAria: () => isIgnoredForAria,\n isHiddenByCSS: () => isHiddenByCSS,\n isFormControl: () => isFormControl2,\n isFocusable: () => isFocusable2,\n isElementVisuallyVisible: () => isElementVisuallyVisible,\n isElementVisible: () => isElementVisible,\n isElementStyleVisible: () => isElementStyleVisible,\n isElementStableSync: () => isElementStableSync,\n isElementInteractable: () => isElementInteractable,\n isElementHiddenForAria: () => isElementHiddenForAria,\n isElementActionable: () => isElementActionable,\n isEditable: () => isEditable,\n isDisplayContentsWithNoVisibleChildren: () => isDisplayContentsWithNoVisibleChildren,\n isCachingActive: () => isCachingActive,\n isAriaHidden: () => isAriaHidden,\n isActionTarget: () => isActionTarget,\n internalEngines: () => internalEngines,\n insertTextAtCursor: () => insertTextAtCursor,\n hasPresentationConflict: () => hasPresentationConflict,\n hasAriaHidden: () => hasAriaHidden,\n getViewportRatio: () => getViewportRatio,\n getShadowRoots: () => getShadowRoots,\n getSelectorCacheStats: () => getSelectorCacheStats,\n getRefCount: () => getRefCount,\n getOwnerWindow: () => getOwnerWindow,\n getOwnerDocument: () => getOwnerDocument,\n getNormalizedText: () => getNormalizedText,\n getLabelTarget: () => getLabelTarget,\n getKeyDefinitionWithShift: () => getKeyDefinitionWithShift,\n getKeyDefinitionFromChar: () => getKeyDefinitionFromChar,\n getKeyDefinition: () => getKeyDefinition,\n getInteractiveAncestorWithCheckbox: () => getInteractiveAncestorWithCheckbox,\n getInteractiveAncestor: () => getInteractiveAncestor,\n getInputType: () => getInputType,\n getHeadingLevel: () => getHeadingLevel,\n getElementRef: () => getElementRef,\n getElementCenter: () => getElementCenter,\n getElementByRef: () => getElementByRef,\n getComposedPath: () => getComposedPath,\n getClickablePoint: () => getClickablePoint,\n getCachedStyle: () => getCachedStyle,\n getCachedPseudoContent: () => getCachedPseudoContent,\n getCacheStats: () => getCacheStats,\n getAriaRole: () => getAriaRole,\n getAccessibleName: () => getAccessibleName,\n generateAriaTree: () => generateAriaTree,\n generateA11yTree: () => generateA11yTree,\n formatAriaTree: () => formatAriaTree,\n formatA11yTree: () => formatA11yTree,\n focusElement: () => focusElement,\n fillElement: () => fillElement,\n expectHitTarget: () => expectHitTarget,\n endSelectorCaches: () => endSelectorCaches,\n endDOMCaches: () => endDOMCaches,\n endAriaCaches: () => endAriaCaches,\n dispatchTouchEvent: () => dispatchTouchEvent,\n dispatchTapAt: () => dispatchTapAt,\n dispatchTap: () => dispatchTap,\n dispatchSwipeAt: () => dispatchSwipeAt,\n dispatchScroll: () => dispatchScroll,\n dispatchRightClickAt: () => dispatchRightClickAt,\n dispatchPinchAt: () => dispatchPinchAt,\n dispatchMouseMove: () => dispatchMouseMove,\n dispatchKeyPress: () => dispatchKeyPress,\n dispatchKeyCombination: () => dispatchKeyCombination,\n dispatchHoverAt: () => dispatchHoverAt,\n dispatchDrag: () => dispatchDrag,\n dispatchDoubleClickAt: () => dispatchDoubleClickAt,\n dispatchClickByRef: () => dispatchClickByRef,\n dispatchClickAt: () => dispatchClickAt,\n detectPlatform: () => detectPlatform,\n describeElement: () => describeElement,\n deepQueryAll: () => deepQueryAll,\n deepQuery: () => deepQuery,\n deepElementFromPoint: () => deepElementFromPoint,\n cssEngine: () => cssEngine,\n createWheelEvent: () => createWheelEvent,\n createVisibleEngine: () => createVisibleEngine,\n createTouchObject: () => createTouchObject,\n createTouchEvent: () => createTouchEvent,\n createTextMatcher: () => createTextMatcher,\n createOrEngine: () => createOrEngine,\n createMouseEvent: () => createMouseEvent,\n createLayoutEngine: () => createLayoutEngine,\n createLabelEngine: () => createLabelEngine,\n createKeyboardEvent: () => createKeyboardEvent,\n createHasTextEngine: () => createHasTextEngine,\n createHasNotTextEngine: () => createHasNotTextEngine,\n createHasNotEngine: () => createHasNotEngine,\n createHasEngine: () => createHasEngine,\n createElementRefs: () => createElementRefs,\n createCacheKey: () => createCacheKey,\n createAndEngine: () => createAndEngine,\n computeElementBox: () => computeElementBox,\n computeAccessibleName: () => computeAccessibleName,\n computeAccessibleDescription: () => computeAccessibleDescription,\n clearSelectorCaches: () => clearSelectorCaches,\n clearElementRefs: () => clearElementRefs,\n clearElement: () => clearElement,\n clearAllCaches: () => clearAllCaches,\n cleanupStaleRefs: () => cleanupStaleRefs,\n checkElementVisibility: () => checkElementVisibility,\n checkElementStatesSync: () => checkElementStatesSync,\n checkElementStates: () => checkElementStates,\n checkElementState: () => checkElementState,\n checkElementStability: () => checkElementStability,\n boxRightOf: () => boxRightOf,\n boxNear: () => boxNear,\n boxLeftOf: () => boxLeftOf,\n boxBelow: () => boxBelow,\n boxAbove: () => boxAbove,\n blurElement: () => blurElement,\n beginSelectorCaches: () => beginSelectorCaches,\n beginDOMCaches: () => beginDOMCaches,\n beginAriaCaches: () => beginAriaCaches,\n ariaCache: () => ariaCache,\n XPathSelectorEngine: () => XPathSelectorEngine,\n TouchState: () => TouchState,\n TextSelectorEngine: () => TextSelectorEngine,\n SelectorEngineRegistry: () => SelectorEngineRegistry,\n SelectorCacheManager: () => SelectorCacheManager,\n RoleSelectorEngine: () => RoleSelectorEngine,\n MouseState: () => MouseState,\n Modifiers: () => Modifiers,\n Keys: () => Keys,\n KeyboardState: () => KeyboardState,\n CssSelectorEngine: () => CssSelectorEngine\n });\n\n // src/selectors/engine.ts\n class SelectorEngineRegistry {\n engines = new Map;\n register(engine) {\n this.engines.set(engine.name, engine);\n }\n get(name) {\n return this.engines.get(name);\n }\n has(name) {\n return this.engines.has(name);\n }\n names() {\n return [...this.engines.keys()];\n }\n }\n function parseSelector(selector) {\n const match = selector.match(/^([a-zA-Z_][a-zA-Z0-9_:-]*)=(.+)$/s);\n if (match) {\n return { engine: match[1].toLowerCase(), body: match[2] };\n }\n return { engine: \"css\", body: selector };\n }\n var selectorEngines = new SelectorEngineRegistry;\n // src/selectors/css.ts\n class CssSelectorEngine {\n name = \"css\";\n query(root, selector) {\n try {\n return root.querySelector(selector);\n } catch {\n return null;\n }\n }\n queryAll(root, selector) {\n try {\n return [...root.querySelectorAll(selector)];\n } catch {\n return [];\n }\n }\n }\n var cssEngine = new CssSelectorEngine;\n // src/selectors/xpath.ts\n function getOwnerDoc(root) {\n if (root instanceof Document)\n return root;\n if (root instanceof ShadowRoot)\n return root.ownerDocument;\n return root.ownerDocument;\n }\n\n class XPathSelectorEngine {\n name = \"xpath\";\n query(root, selector) {\n const doc = getOwnerDoc(root);\n if (!doc)\n return null;\n try {\n const result = doc.evaluate(selector, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n const node = result.singleNodeValue;\n return node instanceof Element ? node : null;\n } catch {\n return null;\n }\n }\n queryAll(root, selector) {\n const doc = getOwnerDoc(root);\n if (!doc)\n return [];\n try {\n const result = doc.evaluate(selector, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\n const elements = [];\n for (let i = 0;i < result.snapshotLength; i++) {\n const node = result.snapshotItem(i);\n if (node instanceof Element) {\n elements.push(node);\n }\n }\n return elements;\n } catch {\n return [];\n }\n }\n }\n var xpathEngine = new XPathSelectorEngine;\n // src/dom/visibility.ts\n function isInsideClosedDetails(element) {\n const detailsOrSummary = element.closest(\"details,summary\");\n if (detailsOrSummary !== element && detailsOrSummary?.nodeName === \"DETAILS\" && !detailsOrSummary.open) {\n return true;\n }\n return false;\n }\n function isVisibleTextNode(node) {\n const range = node.ownerDocument.createRange();\n range.selectNode(node);\n const rect = range.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n }\n function isElementStyleVisible(element, style) {\n style = style ?? getComputedStyle(element);\n const checkVisibility = element.checkVisibility;\n if (typeof checkVisibility === \"function\") {\n if (!checkVisibility.call(element, { checkVisibilityCSS: true, checkOpacity: false })) {\n return false;\n }\n } else {\n if (isInsideClosedDetails(element)) {\n return false;\n }\n const contentVisibility = style.getPropertyValue(\"content-visibility\");\n if (contentVisibility === \"hidden\") {\n return false;\n }\n }\n const visibility = style.visibility;\n if (visibility !== \"visible\" && visibility !== \"\" && visibility !== \"inherit\") {\n return false;\n }\n return true;\n }\n function isElementVisible(element) {\n if (!element.isConnected)\n return false;\n const style = getComputedStyle(element);\n if (style.display === \"none\") {\n return false;\n }\n if (style.display === \"contents\") {\n for (let child = element.firstChild;child; child = child.nextSibling) {\n if (child.nodeType === Node.ELEMENT_NODE && isElementVisible(child)) {\n return true;\n }\n if (child.nodeType === Node.TEXT_NODE && isVisibleTextNode(child)) {\n return true;\n }\n }\n return false;\n }\n if (!isElementStyleVisible(element, style)) {\n return false;\n }\n if (parseFloat(style.opacity) === 0) {\n return false;\n }\n const rect = element.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n return false;\n }\n return true;\n }\n function isInViewport(element, threshold = 0) {\n const rect = element.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n return false;\n }\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const visibleLeft = Math.max(0, rect.left);\n const visibleTop = Math.max(0, rect.top);\n const visibleRight = Math.min(viewportWidth, rect.right);\n const visibleBottom = Math.min(viewportHeight, rect.bottom);\n const visibleWidth = Math.max(0, visibleRight - visibleLeft);\n const visibleHeight = Math.max(0, visibleBottom - visibleTop);\n const visibleArea = visibleWidth * visibleHeight;\n const totalArea = rect.width * rect.height;\n const ratio = visibleArea / totalArea;\n return ratio > threshold;\n }\n async function getViewportRatio(element) {\n return new Promise((resolve) => {\n if (!element.isConnected) {\n resolve(0);\n return;\n }\n if (typeof IntersectionObserver === \"undefined\") {\n const rect = element.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n resolve(0);\n return;\n }\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const visibleLeft = Math.max(0, rect.left);\n const visibleTop = Math.max(0, rect.top);\n const visibleRight = Math.min(viewportWidth, rect.right);\n const visibleBottom = Math.min(viewportHeight, rect.bottom);\n const visibleWidth = Math.max(0, visibleRight - visibleLeft);\n const visibleHeight = Math.max(0, visibleBottom - visibleTop);\n const ratio = visibleWidth * visibleHeight / (rect.width * rect.height);\n resolve(ratio);\n return;\n }\n const observer = new IntersectionObserver((entries) => {\n observer.disconnect();\n resolve(entries[0]?.intersectionRatio ?? 0);\n });\n observer.observe(element);\n });\n }\n function isElementInteractable(element) {\n if (!isElementVisible(element))\n return false;\n const style = getComputedStyle(element);\n if (style.pointerEvents === \"none\") {\n return false;\n }\n return true;\n }\n function isElementActionable(element) {\n if (!isElementInteractable(element))\n return false;\n if (element instanceof HTMLInputElement || element instanceof HTMLButtonElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement) {\n if (element.disabled)\n return false;\n }\n if (element.getAttribute(\"aria-disabled\") === \"true\") {\n return false;\n }\n return true;\n }\n function getElementCenter(element) {\n const rect = element.getBoundingClientRect();\n return {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2\n };\n }\n function getClickablePoint(element) {\n if (!isElementVisible(element))\n return null;\n const rect = element.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const elementAtCenter = document.elementFromPoint(centerX, centerY);\n if (elementAtCenter && (elementAtCenter === element || element.contains(elementAtCenter))) {\n return { x: centerX, y: centerY };\n }\n const points = [\n { x: rect.left + rect.width * 0.25, y: rect.top + rect.height * 0.25 },\n { x: rect.left + rect.width * 0.75, y: rect.top + rect.height * 0.25 },\n { x: rect.left + rect.width * 0.25, y: rect.top + rect.height * 0.75 },\n { x: rect.left + rect.width * 0.75, y: rect.top + rect.height * 0.75 },\n { x: rect.left + 1, y: rect.top + rect.height / 2 },\n { x: rect.right - 1, y: rect.top + rect.height / 2 }\n ];\n for (const point of points) {\n const elementAtPoint = document.elementFromPoint(point.x, point.y);\n if (elementAtPoint && (elementAtPoint === element || element.contains(elementAtPoint))) {\n return point;\n }\n }\n return { x: centerX, y: centerY };\n }\n function computeElementBox(element) {\n if (!element.isConnected) {\n return null;\n }\n const style = getComputedStyle(element);\n const cursor = style.cursor;\n if (style.display === \"contents\") {\n for (let child = element.firstChild;child; child = child.nextSibling) {\n if (child.nodeType === Node.ELEMENT_NODE && isElementVisible(child)) {\n return { visible: true, inline: false, cursor };\n }\n if (child.nodeType === Node.TEXT_NODE && isVisibleTextNode(child)) {\n return { visible: true, inline: true, cursor };\n }\n }\n return { visible: false, inline: false, cursor };\n }\n if (!isElementStyleVisible(element, style)) {\n return { visible: false, inline: false, cursor };\n }\n const rect = element.getBoundingClientRect();\n const visible = rect.width > 0 && rect.height > 0;\n const inline = style.display === \"inline\";\n return { visible, inline, cursor };\n }\n function receivesPointerEvents(element) {\n if (!element.isConnected) {\n return false;\n }\n if (!isElementVisible(element)) {\n return false;\n }\n const style = getComputedStyle(element);\n if (style.pointerEvents === \"none\") {\n return false;\n }\n return true;\n }\n\n // src/selectors/text.ts\n function createTextMatcher(text, options = {}) {\n if (options.regex) {\n const regex = new RegExp(text);\n return (content) => regex.test(content);\n }\n if (options.exact) {\n return (content) => content.trim() === text;\n }\n const lower = text.toLowerCase();\n return (content) => content.toLowerCase().includes(lower);\n }\n\n class TextSelectorEngine {\n name = \"text\";\n query(root, selector) {\n const { text, exact, regex } = parseTextSelector(selector);\n const matcher = createTextMatcher(text, { exact, regex });\n return this.findTextElement(root, matcher, true);\n }\n queryAll(root, selector) {\n const { text, exact, regex } = parseTextSelector(selector);\n const matcher = createTextMatcher(text, { exact, regex });\n const results = [];\n this.findTextElements(root, matcher, results);\n return results;\n }\n findTextElement(root, matcher, first) {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node2) => {\n if (!(node2 instanceof Element))\n return NodeFilter.FILTER_REJECT;\n if (!isElementVisible(node2))\n return NodeFilter.FILTER_SKIP;\n return NodeFilter.FILTER_ACCEPT;\n }\n });\n let node;\n while (node = walker.nextNode()) {\n const directText = this.getDirectTextContent(node);\n if (matcher(directText)) {\n return node;\n }\n }\n return null;\n }\n findTextElements(root, matcher, results) {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node2) => {\n if (!(node2 instanceof Element))\n return NodeFilter.FILTER_REJECT;\n if (!isElementVisible(node2))\n return NodeFilter.FILTER_SKIP;\n return NodeFilter.FILTER_ACCEPT;\n }\n });\n let node;\n while (node = walker.nextNode()) {\n const directText = this.getDirectTextContent(node);\n if (matcher(directText)) {\n results.push(node);\n }\n }\n }\n getDirectTextContent(element) {\n let text = \"\";\n for (const child of element.childNodes) {\n if (child.nodeType === Node.TEXT_NODE) {\n text += child.textContent || \"\";\n }\n }\n return text;\n }\n }\n function parseTextSelector(selector) {\n if (selector.startsWith(\"/\") && selector.endsWith(\"/\")) {\n return {\n text: selector.slice(1, -1),\n exact: false,\n regex: true\n };\n }\n if (selector.startsWith('\"') && selector.endsWith('\"') || selector.startsWith(\"'\") && selector.endsWith(\"'\")) {\n return {\n text: selector.slice(1, -1),\n exact: true,\n regex: false\n };\n }\n return { text: selector, exact: false, regex: false };\n }\n var textEngine = new TextSelectorEngine;\n // src/a11y/roles.ts\n var GLOBAL_ARIA_ATTRIBUTES = [\n [\"aria-atomic\", undefined],\n [\"aria-busy\", undefined],\n [\"aria-controls\", undefined],\n [\"aria-current\", undefined],\n [\"aria-describedby\", undefined],\n [\"aria-details\", undefined],\n [\"aria-dropeffect\", undefined],\n [\"aria-flowto\", undefined],\n [\"aria-grabbed\", undefined],\n [\"aria-hidden\", undefined],\n [\"aria-keyshortcuts\", undefined],\n [\"aria-label\", [\"caption\", \"code\", \"deletion\", \"emphasis\", \"generic\", \"insertion\", \"paragraph\", \"presentation\", \"strong\", \"subscript\", \"superscript\"]],\n [\"aria-labelledby\", [\"caption\", \"code\", \"deletion\", \"emphasis\", \"generic\", \"insertion\", \"paragraph\", \"presentation\", \"strong\", \"subscript\", \"superscript\"]],\n [\"aria-live\", undefined],\n [\"aria-owns\", undefined],\n [\"aria-relevant\", undefined],\n [\"aria-roledescription\", [\"generic\"]]\n ];\n var LANDMARK_ANCESTORS = [\"article\", \"aside\", \"main\", \"nav\", \"section\"];\n var VALID_ROLES = new Set([\n \"alert\",\n \"alertdialog\",\n \"application\",\n \"article\",\n \"banner\",\n \"blockquote\",\n \"button\",\n \"caption\",\n \"cell\",\n \"checkbox\",\n \"code\",\n \"columnheader\",\n \"combobox\",\n \"complementary\",\n \"contentinfo\",\n \"definition\",\n \"deletion\",\n \"dialog\",\n \"directory\",\n \"document\",\n \"emphasis\",\n \"feed\",\n \"figure\",\n \"form\",\n \"generic\",\n \"grid\",\n \"gridcell\",\n \"group\",\n \"heading\",\n \"img\",\n \"insertion\",\n \"link\",\n \"list\",\n \"listbox\",\n \"listitem\",\n \"log\",\n \"main\",\n \"mark\",\n \"marquee\",\n \"math\",\n \"meter\",\n \"menu\",\n \"menubar\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"navigation\",\n \"none\",\n \"note\",\n \"option\",\n \"paragraph\",\n \"presentation\",\n \"progressbar\",\n \"radio\",\n \"radiogroup\",\n \"region\",\n \"row\",\n \"rowgroup\",\n \"rowheader\",\n \"scrollbar\",\n \"search\",\n \"searchbox\",\n \"separator\",\n \"slider\",\n \"spinbutton\",\n \"status\",\n \"strong\",\n \"subscript\",\n \"superscript\",\n \"switch\",\n \"tab\",\n \"table\",\n \"tablist\",\n \"tabpanel\",\n \"term\",\n \"textbox\",\n \"time\",\n \"timer\",\n \"toolbar\",\n \"tooltip\",\n \"tree\",\n \"treegrid\",\n \"treeitem\"\n ]);\n var IMPLICIT_ROLES = {\n a: (el) => el.hasAttribute(\"href\") ? \"link\" : null,\n area: (el) => el.hasAttribute(\"href\") ? \"link\" : null,\n article: \"article\",\n aside: \"complementary\",\n footer: (el) => isWithinLandmark(el) ? null : \"contentinfo\",\n header: (el) => isWithinLandmark(el) ? null : \"banner\",\n main: \"main\",\n nav: \"navigation\",\n section: (el) => hasExplicitAccessibleName(el) ? \"region\" : null,\n search: \"search\",\n button: \"button\",\n datalist: \"listbox\",\n fieldset: \"group\",\n form: (el) => hasExplicitAccessibleName(el) ? \"form\" : null,\n input: getInputRole,\n meter: \"meter\",\n optgroup: \"group\",\n option: \"option\",\n output: \"status\",\n progress: \"progressbar\",\n select: getSelectRole,\n textarea: \"textbox\",\n dd: \"definition\",\n dl: \"list\",\n dt: \"term\",\n li: \"listitem\",\n menu: \"list\",\n ol: \"list\",\n ul: \"list\",\n caption: \"caption\",\n table: \"table\",\n tbody: \"rowgroup\",\n td: getCellRole,\n tfoot: \"rowgroup\",\n th: getHeaderCellRole,\n thead: \"rowgroup\",\n tr: \"row\",\n figure: \"figure\",\n img: getImageRole,\n svg: \"img\",\n details: \"group\",\n dialog: \"dialog\",\n summary: \"button\",\n blockquote: \"blockquote\",\n code: \"code\",\n del: \"deletion\",\n dfn: \"term\",\n em: \"emphasis\",\n hr: \"separator\",\n ins: \"insertion\",\n mark: \"mark\",\n p: \"paragraph\",\n strong: \"strong\",\n sub: \"subscript\",\n sup: \"superscript\",\n time: \"time\",\n address: \"group\",\n hgroup: \"group\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\",\n html: \"document\",\n math: \"math\"\n };\n var INPUT_TYPE_TO_ROLE = {\n button: \"button\",\n checkbox: \"checkbox\",\n image: \"button\",\n number: \"spinbutton\",\n radio: \"radio\",\n range: \"slider\",\n reset: \"button\",\n submit: \"button\"\n };\n function isWithinLandmark(element) {\n let parent = element.parentElement;\n while (parent) {\n const tag = parent.tagName.toLowerCase();\n if (LANDMARK_ANCESTORS.includes(tag)) {\n return true;\n }\n const role = parent.getAttribute(\"role\");\n if (role && [\"article\", \"complementary\", \"main\", \"navigation\", \"region\"].includes(role)) {\n return true;\n }\n parent = parent.parentElement;\n }\n return false;\n }\n function hasExplicitAccessibleName(element) {\n return element.hasAttribute(\"aria-label\") || element.hasAttribute(\"aria-labelledby\");\n }\n function hasGlobalAriaAttribute(element, forRole) {\n return GLOBAL_ARIA_ATTRIBUTES.some(([attr, prohibited]) => {\n if (prohibited?.includes(forRole || \"\")) {\n return false;\n }\n return element.hasAttribute(attr);\n });\n }\n function hasTabIndex(element) {\n return !Number.isNaN(Number(String(element.getAttribute(\"tabindex\"))));\n }\n function isFocusable(element) {\n return !isNativelyDisabled(element) && (isNativelyFocusable(element) || hasTabIndex(element));\n }\n function isNativelyFocusable(element) {\n const tagName = element.tagName.toUpperCase();\n if ([\"BUTTON\", \"DETAILS\", \"SELECT\", \"TEXTAREA\"].includes(tagName)) {\n return true;\n }\n if (tagName === \"A\" || tagName === \"AREA\") {\n return element.hasAttribute(\"href\");\n }\n if (tagName === \"INPUT\") {\n return element.type !== \"hidden\";\n }\n return false;\n }\n function isNativelyDisabled(element) {\n const tagName = element.tagName.toUpperCase();\n if ([\"BUTTON\", \"INPUT\", \"SELECT\", \"TEXTAREA\", \"OPTION\", \"OPTGROUP\"].includes(tagName)) {\n return element.hasAttribute(\"disabled\");\n }\n return false;\n }\n function getInputRole(element) {\n const input = element;\n const type = (input.type || \"text\").toLowerCase();\n if (type === \"search\") {\n return input.hasAttribute(\"list\") ? \"combobox\" : \"searchbox\";\n }\n if ([\"email\", \"tel\", \"text\", \"url\", \"\"].includes(type)) {\n const listId = input.getAttribute(\"list\");\n if (listId) {\n const datalist = input.ownerDocument.getElementById(listId);\n if (datalist && datalist.tagName.toLowerCase() === \"datalist\") {\n return \"combobox\";\n }\n }\n return \"textbox\";\n }\n if (type === \"password\") {\n return \"textbox\";\n }\n if (type === \"hidden\") {\n return null;\n }\n if (type === \"file\") {\n return \"button\";\n }\n return INPUT_TYPE_TO_ROLE[type] || \"textbox\";\n }\n function getSelectRole(element) {\n const select = element;\n if (select.hasAttribute(\"multiple\")) {\n return \"listbox\";\n }\n const sizeAttr = select.getAttribute(\"size\");\n if (sizeAttr) {\n const size = parseInt(sizeAttr, 10);\n if (!isNaN(size) && size > 1) {\n return \"listbox\";\n }\n }\n return \"combobox\";\n }\n function getCellRole(element) {\n const table = element.closest(\"table\");\n if (table) {\n const role = table.getAttribute(\"role\");\n if (role === \"grid\" || role === \"treegrid\") {\n return \"gridcell\";\n }\n }\n return \"cell\";\n }\n function getHeaderCellRole(element) {\n const scope = element.getAttribute(\"scope\");\n if (scope === \"col\" || scope === \"colgroup\") {\n return \"columnheader\";\n }\n if (scope === \"row\" || scope === \"rowgroup\") {\n return \"rowheader\";\n }\n const nextSibling = element.nextElementSibling;\n const prevSibling = element.previousElementSibling;\n const row = element.parentElement?.tagName?.toUpperCase() === \"TR\" ? element.parentElement : undefined;\n if (!nextSibling && !prevSibling) {\n if (row) {\n const table = row.closest(\"table\");\n if (table && table.rows.length <= 1) {\n return null;\n }\n }\n return \"columnheader\";\n }\n const isHeaderCell = (el) => !!el && el.tagName.toUpperCase() === \"TH\";\n const isNonEmptyDataCell = (el) => !!el && el.tagName.toUpperCase() === \"TD\" && !!(el.textContent?.trim() || el.children.length > 0);\n if (isHeaderCell(nextSibling) && isHeaderCell(prevSibling)) {\n return \"columnheader\";\n }\n if (isNonEmptyDataCell(nextSibling) || isNonEmptyDataCell(prevSibling)) {\n return \"rowheader\";\n }\n return \"columnheader\";\n }\n function getImageRole(element) {\n const alt = element.getAttribute(\"alt\");\n const title = element.getAttribute(\"title\");\n if (alt === \"\" && !title && !hasGlobalAriaAttribute(element, null) && !hasTabIndex(element)) {\n return \"presentation\";\n }\n return \"img\";\n }\n function hasPresentationConflict(element, implicitRole) {\n return hasGlobalAriaAttribute(element, implicitRole || null) || isFocusable(element);\n }\n function getExplicitAriaRole(element) {\n const roleAttr = element.getAttribute(\"role\");\n if (!roleAttr) {\n return null;\n }\n const roles = roleAttr.split(/\\s+/).map((r) => r.toLowerCase().trim());\n for (const role of roles) {\n if (VALID_ROLES.has(role)) {\n return role;\n }\n }\n return null;\n }\n function getImplicitRole(element) {\n const tagName = element.tagName.toLowerCase();\n const roleOrFn = IMPLICIT_ROLES[tagName];\n if (typeof roleOrFn === \"function\") {\n return roleOrFn(element);\n }\n return roleOrFn ?? null;\n }\n var PRESENTATION_INHERITANCE_PARENTS = {\n DD: [\"DL\", \"DIV\"],\n DIV: [\"DL\"],\n DT: [\"DL\", \"DIV\"],\n LI: [\"OL\", \"UL\"],\n TBODY: [\"TABLE\"],\n TD: [\"TR\"],\n TFOOT: [\"TABLE\"],\n TH: [\"TR\"],\n THEAD: [\"TABLE\"],\n TR: [\"THEAD\", \"TBODY\", \"TFOOT\", \"TABLE\"]\n };\n function shouldInheritPresentationRole(element) {\n let current = element;\n while (current) {\n const parent = current.parentElement;\n const validParents = PRESENTATION_INHERITANCE_PARENTS[current.tagName.toUpperCase()];\n if (!validParents || !parent || !validParents.includes(parent.tagName.toUpperCase())) {\n break;\n }\n const parentExplicitRole = getExplicitAriaRole(parent);\n if (parentExplicitRole === \"none\" || parentExplicitRole === \"presentation\") {\n if (!hasPresentationConflict(parent)) {\n return true;\n }\n }\n current = parent;\n }\n return false;\n }\n function getAriaRole(element) {\n const explicitRole = getExplicitAriaRole(element);\n if (!explicitRole) {\n if (shouldInheritPresentationRole(element)) {\n return null;\n }\n return getImplicitRole(element);\n }\n if (explicitRole === \"none\" || explicitRole === \"presentation\") {\n const implicitRole = getImplicitRole(element);\n if (hasPresentationConflict(element, implicitRole)) {\n return implicitRole;\n }\n return null;\n }\n return explicitRole;\n }\n function getAccessibleName(element) {\n const labelledBy = element.getAttribute(\"aria-labelledby\");\n if (labelledBy) {\n const names = [];\n for (const id of labelledBy.split(/\\s+/)) {\n const labelElement = document.getElementById(id);\n if (labelElement) {\n names.push(getTextContent(labelElement));\n }\n }\n if (names.length > 0) {\n return names.join(\" \");\n }\n }\n const ariaLabel = element.getAttribute(\"aria-label\");\n if (ariaLabel && ariaLabel.trim()) {\n return ariaLabel.trim();\n }\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {\n const labels = element.labels;\n if (labels && labels.length > 0) {\n return getTextContent(labels[0]);\n }\n }\n const title = element.getAttribute(\"title\");\n if (title && title.trim()) {\n return title.trim();\n }\n if (element instanceof HTMLImageElement) {\n const alt = element.alt;\n if (alt && alt.trim()) {\n return alt.trim();\n }\n }\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n const placeholder = element.placeholder;\n if (placeholder && placeholder.trim()) {\n return placeholder.trim();\n }\n }\n const role = getAriaRole(element);\n if (role && [\"button\", \"link\", \"menuitem\", \"option\", \"tab\"].includes(role)) {\n return getTextContent(element);\n }\n return \"\";\n }\n function getTextContent(element) {\n return (element.textContent || \"\").replace(/\\s+/g, \" \").trim();\n }\n function isAriaHidden(element) {\n if (element.getAttribute(\"aria-hidden\") === \"true\") {\n return true;\n }\n let parent = element.parentElement;\n while (parent) {\n if (parent.getAttribute(\"aria-hidden\") === \"true\") {\n return true;\n }\n parent = parent.parentElement;\n }\n const style = getComputedStyle(element);\n if (style.display === \"none\" || style.visibility === \"hidden\") {\n return true;\n }\n return false;\n }\n function getHeadingLevel(element) {\n const ariaLevel = element.getAttribute(\"aria-level\");\n if (ariaLevel) {\n const level = parseInt(ariaLevel, 10);\n if (!isNaN(level) && level >= 1) {\n return level;\n }\n }\n const match = element.tagName.match(/^H([1-6])$/i);\n if (match) {\n return parseInt(match[1], 10);\n }\n return null;\n }\n\n // src/selectors/role.ts\n class RoleSelectorEngine {\n name = \"role\";\n query(root, selector) {\n const { role, options } = parseRoleSelector(selector);\n return this.findRoleElement(root, role, options);\n }\n queryAll(root, selector) {\n const { role, options } = parseRoleSelector(selector);\n const results = [];\n this.findRoleElements(root, role, options, results);\n return results;\n }\n findRoleElement(root, role, options) {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node2) => {\n if (!(node2 instanceof Element))\n return NodeFilter.FILTER_REJECT;\n if (!isElementVisible(node2))\n return NodeFilter.FILTER_SKIP;\n return NodeFilter.FILTER_ACCEPT;\n }\n });\n let node;\n while (node = walker.nextNode()) {\n if (this.matchesRole(node, role, options)) {\n return node;\n }\n }\n return null;\n }\n findRoleElements(root, role, options, results) {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node2) => {\n if (!(node2 instanceof Element))\n return NodeFilter.FILTER_REJECT;\n if (!isElementVisible(node2))\n return NodeFilter.FILTER_SKIP;\n return NodeFilter.FILTER_ACCEPT;\n }\n });\n let node;\n while (node = walker.nextNode()) {\n if (this.matchesRole(node, role, options)) {\n results.push(node);\n }\n }\n }\n matchesRole(element, role, options) {\n const elementRole = getAriaRole(element);\n if (elementRole !== role)\n return false;\n if (options.name !== undefined) {\n const accessibleName = getAccessibleName(element);\n if (options.exact) {\n return accessibleName === options.name;\n }\n return accessibleName.toLowerCase().includes(options.name.toLowerCase());\n }\n return true;\n }\n }\n function parseRoleSelector(selector) {\n const bracketMatch = selector.match(/^([a-z]+)\\[(.+)\\]$/i);\n if (bracketMatch) {\n const role = bracketMatch[1].toLowerCase();\n const attrsStr = bracketMatch[2];\n const options = {};\n const nameMatch = attrsStr.match(/name\\s*=\\s*[\"'](.+?)[\"']/i);\n if (nameMatch) {\n options.name = nameMatch[1];\n }\n const exactMatch = attrsStr.match(/exact\\s*=\\s*(true|false)/i);\n if (exactMatch) {\n options.exact = exactMatch[1].toLowerCase() === \"true\";\n }\n return { role, options };\n }\n return { role: selector.toLowerCase(), options: {} };\n }\n var roleEngine = new RoleSelectorEngine;\n // src/selectors/layout.ts\n var kLayoutSelectorNames = [\n \"left-of\",\n \"right-of\",\n \"above\",\n \"below\",\n \"near\"\n ];\n function boxRightOf(box1, box2, maxDistance) {\n const distance = box1.left - box2.right;\n if (distance < 0 || maxDistance !== undefined && distance > maxDistance) {\n return;\n }\n return distance + Math.max(box2.bottom - box1.bottom, 0) + Math.max(box1.top - box2.top, 0);\n }\n function boxLeftOf(box1, box2, maxDistance) {\n const distance = box2.left - box1.right;\n if (distance < 0 || maxDistance !== undefined && distance > maxDistance) {\n return;\n }\n return distance + Math.max(box2.bottom - box1.bottom, 0) + Math.max(box1.top - box2.top, 0);\n }\n function boxAbove(box1, box2, maxDistance) {\n const distance = box2.top - box1.bottom;\n if (distance < 0 || maxDistance !== undefined && distance > maxDistance) {\n return;\n }\n return distance + Math.max(box1.left - box2.left, 0) + Math.max(box2.right - box1.right, 0);\n }\n function boxBelow(box1, box2, maxDistance) {\n const distance = box1.top - box2.bottom;\n if (distance < 0 || maxDistance !== undefined && distance > maxDistance) {\n return;\n }\n return distance + Math.max(box1.left - box2.left, 0) + Math.max(box2.right - box1.right, 0);\n }\n function boxNear(box1, box2, maxDistance) {\n const threshold = maxDistance === undefined ? 50 : maxDistance;\n let score = 0;\n if (box1.left - box2.right >= 0) {\n score += box1.left - box2.right;\n }\n if (box2.left - box1.right >= 0) {\n score += box2.left - box1.right;\n }\n if (box2.top - box1.bottom >= 0) {\n score += box2.top - box1.bottom;\n }\n if (box1.top - box2.bottom >= 0) {\n score += box1.top - box2.bottom;\n }\n return score > threshold ? undefined : score;\n }\n var layoutScorers = {\n \"left-of\": boxLeftOf,\n \"right-of\": boxRightOf,\n above: boxAbove,\n below: boxBelow,\n near: boxNear\n };\n function layoutSelectorScore(name, element, innerElements, maxDistance) {\n const box = element.getBoundingClientRect();\n const scorer = layoutScorers[name];\n let bestScore;\n for (const innerElement of innerElements) {\n if (innerElement === element) {\n continue;\n }\n const score = scorer(box, innerElement.getBoundingClientRect(), maxDistance);\n if (score === undefined) {\n continue;\n }\n if (bestScore === undefined || score < bestScore) {\n bestScore = score;\n }\n }\n return bestScore;\n }\n function parseLayoutSelectorBody(body) {\n let depth = 0;\n let lastCommaIndex = -1;\n for (let i = 0;i < body.length; i++) {\n const char = body[i];\n if (char === \"(\" || char === \"[\") {\n depth++;\n } else if (char === \")\" || char === \"]\") {\n depth--;\n } else if (char === \",\" && depth === 0) {\n lastCommaIndex = i;\n }\n }\n if (lastCommaIndex !== -1) {\n const potentialDistance = body.slice(lastCommaIndex + 1).trim();\n const distanceNum = parseInt(potentialDistance, 10);\n if (!isNaN(distanceNum) && String(distanceNum) === potentialDistance) {\n return {\n innerSelector: body.slice(0, lastCommaIndex).trim(),\n maxDistance: distanceNum\n };\n }\n }\n return {\n innerSelector: body.trim(),\n maxDistance: undefined\n };\n }\n function queryWithSelector(root, selectorString) {\n const { engine: engineName, body } = parseSelector(selectorString.trim());\n const engine = selectorEngines.get(engineName);\n if (!engine) {\n console.warn(`Unknown selector engine: ${engineName}`);\n return [];\n }\n return engine.queryAll(root, body);\n }\n function createLayoutEngine(name) {\n return {\n name: `internal:${name}`,\n query(root, body) {\n const results = this.queryAll(root, body);\n return results[0] || null;\n },\n queryAll(root, body) {\n const { innerSelector, maxDistance } = parseLayoutSelectorBody(body);\n const innerElements = queryWithSelector(root, innerSelector);\n if (innerElements.length === 0) {\n return [];\n }\n const allElements = root instanceof Element ? Array.from(root.querySelectorAll(\"*\")) : Array.from(root.querySelectorAll(\"*\"));\n const scored = [];\n for (const element of allElements) {\n const score = layoutSelectorScore(name, element, innerElements, maxDistance);\n if (score !== undefined) {\n scored.push({ element, score });\n }\n }\n scored.sort((a, b) => a.score - b.score);\n return scored.map((s) => s.element);\n }\n };\n }\n var layoutEngines = {\n \"internal:left-of\": createLayoutEngine(\"left-of\"),\n \"internal:right-of\": createLayoutEngine(\"right-of\"),\n \"internal:above\": createLayoutEngine(\"above\"),\n \"internal:below\": createLayoutEngine(\"below\"),\n \"internal:near\": createLayoutEngine(\"near\")\n };\n function registerLayoutEngines() {\n for (const engine of Object.values(layoutEngines)) {\n selectorEngines.register(engine);\n }\n }\n\n // src/selectors/internal.ts\n function parseTextSelectorBody(body) {\n const regexMatch = body.match(/^\\/(.+)\\/([gimsuy]*)$/);\n if (regexMatch) {\n try {\n return {\n text: regexMatch[1],\n exact: false,\n regex: new RegExp(regexMatch[1], regexMatch[2])\n };\n } catch {}\n }\n if (body.startsWith('\"') && body.endsWith('\"') || body.startsWith(\"'\") && body.endsWith(\"'\")) {\n return {\n text: body.slice(1, -1),\n exact: true,\n regex: null\n };\n }\n return {\n text: body,\n exact: false,\n regex: null\n };\n }\n function parseCompoundSelectorBody(body) {\n const selectors = [];\n let current = \"\";\n let depth = 0;\n let inQuote = false;\n let quoteChar = \"\";\n for (let i = 0;i < body.length; i++) {\n const char = body[i];\n if (!inQuote && (char === '\"' || char === \"'\")) {\n inQuote = true;\n quoteChar = char;\n current += char;\n } else if (inQuote && char === quoteChar) {\n inQuote = false;\n quoteChar = \"\";\n current += char;\n } else if (!inQuote) {\n if (char === \"(\" || char === \"[\") {\n depth++;\n current += char;\n } else if (char === \")\" || char === \"]\") {\n depth--;\n current += char;\n } else if (depth === 0 && body.slice(i, i + 2) === \"&&\") {\n if (current.trim()) {\n selectors.push(current.trim());\n }\n current = \"\";\n i++;\n } else {\n current += char;\n }\n } else {\n current += char;\n }\n }\n if (current.trim()) {\n selectors.push(current.trim());\n }\n return selectors;\n }\n function getElementTextContent(element) {\n return (element.textContent || \"\").replace(/\\s+/g, \" \").trim();\n }\n function textMatches(content, selector) {\n if (selector.regex) {\n return selector.regex.test(content);\n }\n if (selector.exact) {\n return content.trim() === selector.text;\n }\n return content.toLowerCase().includes(selector.text.toLowerCase());\n }\n function sortInDOMOrder(elements) {\n return elements.slice().sort((a, b) => {\n const position = a.compareDocumentPosition(b);\n if (position & Node.DOCUMENT_POSITION_FOLLOWING) {\n return -1;\n }\n if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n return 1;\n }\n return 0;\n });\n }\n function deduplicateElements(elements) {\n const seen = new Set;\n return elements.filter((el) => {\n if (seen.has(el))\n return false;\n seen.add(el);\n return true;\n });\n }\n function queryWithSelector2(root, selectorString) {\n const { engine: engineName, body } = parseSelector(selectorString.trim());\n const engine = selectorEngines.get(engineName);\n if (!engine) {\n console.warn(`Unknown selector engine: ${engineName}`);\n return [];\n }\n return engine.queryAll(root, body);\n }\n function createHasEngine() {\n return {\n name: \"internal:has\",\n query(root, body) {\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const matches = queryWithSelector2(element, body);\n if (matches.length > 0) {\n return element;\n }\n }\n return null;\n },\n queryAll(root, body) {\n const results = [];\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const matches = queryWithSelector2(element, body);\n if (matches.length > 0) {\n results.push(element);\n }\n }\n return results;\n }\n };\n }\n function createHasNotEngine() {\n return {\n name: \"internal:has-not\",\n query(root, body) {\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const matches = queryWithSelector2(element, body);\n if (matches.length === 0) {\n return element;\n }\n }\n return null;\n },\n queryAll(root, body) {\n const results = [];\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const matches = queryWithSelector2(element, body);\n if (matches.length === 0) {\n results.push(element);\n }\n }\n return results;\n }\n };\n }\n function createHasTextEngine() {\n return {\n name: \"internal:has-text\",\n query(root, body) {\n const selector = parseTextSelectorBody(body);\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const content = getElementTextContent(element);\n if (textMatches(content, selector)) {\n return element;\n }\n }\n return null;\n },\n queryAll(root, body) {\n const selector = parseTextSelectorBody(body);\n const results = [];\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const content = getElementTextContent(element);\n if (textMatches(content, selector)) {\n results.push(element);\n }\n }\n return results;\n }\n };\n }\n function createHasNotTextEngine() {\n return {\n name: \"internal:has-not-text\",\n query(root, body) {\n const selector = parseTextSelectorBody(body);\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const content = getElementTextContent(element);\n if (!textMatches(content, selector)) {\n return element;\n }\n }\n return null;\n },\n queryAll(root, body) {\n const selector = parseTextSelectorBody(body);\n const results = [];\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n const content = getElementTextContent(element);\n if (!textMatches(content, selector)) {\n results.push(element);\n }\n }\n return results;\n }\n };\n }\n function createAndEngine() {\n return {\n name: \"internal:and\",\n query(root, body) {\n const selectors = parseCompoundSelectorBody(body);\n if (selectors.length === 0)\n return null;\n const initial = queryWithSelector2(root, selectors[0]);\n if (initial.length === 0)\n return null;\n for (const element of initial) {\n let matchesAll = true;\n for (let i = 1;i < selectors.length; i++) {\n const matches = queryWithSelector2(root, selectors[i]);\n if (!matches.includes(element)) {\n matchesAll = false;\n break;\n }\n }\n if (matchesAll) {\n return element;\n }\n }\n return null;\n },\n queryAll(root, body) {\n const selectors = parseCompoundSelectorBody(body);\n if (selectors.length === 0)\n return [];\n const allResults = selectors.map((sel) => queryWithSelector2(root, sel));\n if (allResults.length === 0 || allResults[0].length === 0)\n return [];\n const intersection = allResults[0].filter((element) => allResults.every((results) => results.includes(element)));\n return intersection;\n }\n };\n }\n function createOrEngine() {\n return {\n name: \"internal:or\",\n query(root, body) {\n const selectors = parseCompoundSelectorBody(body);\n const allMatches = [];\n for (const selectorString of selectors) {\n const matches = queryWithSelector2(root, selectorString);\n allMatches.push(...matches);\n }\n if (allMatches.length === 0)\n return null;\n const unique = deduplicateElements(allMatches);\n const sorted = sortInDOMOrder(unique);\n return sorted[0] || null;\n },\n queryAll(root, body) {\n const selectors = parseCompoundSelectorBody(body);\n const allMatches = [];\n for (const selectorString of selectors) {\n const matches = queryWithSelector2(root, selectorString);\n allMatches.push(...matches);\n }\n const unique = deduplicateElements(allMatches);\n return sortInDOMOrder(unique);\n }\n };\n }\n function getControlsForLabelText(root, text, exact) {\n const results = [];\n const normalizedText = text.toLowerCase();\n const labels = root.querySelectorAll(\"label\");\n for (const label of labels) {\n const labelText = getElementTextContent(label);\n const matches = exact ? labelText === text : labelText.toLowerCase().includes(normalizedText);\n if (!matches)\n continue;\n const forAttr = label.getAttribute(\"for\");\n if (forAttr) {\n const doc = root instanceof Document ? root : root.ownerDocument || document;\n const control = doc.getElementById(forAttr);\n if (control && isFormControl(control)) {\n results.push(control);\n continue;\n }\n }\n const nestedControl = label.querySelector(\"input, select, textarea, button\");\n if (nestedControl) {\n results.push(nestedControl);\n }\n }\n const allElements = root.querySelectorAll(\"[aria-labelledby]\");\n for (const element of allElements) {\n const labelIds = element.getAttribute(\"aria-labelledby\")?.split(/\\s+/) || [];\n for (const id of labelIds) {\n const doc = root instanceof Document ? root : root.ownerDocument || document;\n const labelElement = doc.getElementById(id);\n if (labelElement) {\n const labelText = getElementTextContent(labelElement);\n const matches = exact ? labelText === text : labelText.toLowerCase().includes(normalizedText);\n if (matches && !results.includes(element)) {\n results.push(element);\n }\n }\n }\n }\n return results;\n }\n function isFormControl(element) {\n const tagName = element.tagName.toLowerCase();\n return [\"input\", \"select\", \"textarea\", \"button\"].includes(tagName);\n }\n function createLabelEngine() {\n return {\n name: \"internal:label\",\n query(root, body) {\n const selector = parseTextSelectorBody(body);\n const controls = getControlsForLabelText(root, selector.text, selector.exact);\n return controls[0] || null;\n },\n queryAll(root, body) {\n const selector = parseTextSelectorBody(body);\n return getControlsForLabelText(root, selector.text, selector.exact);\n }\n };\n }\n function createVisibleEngine() {\n return {\n name: \"internal:visible\",\n query(root, _body) {\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n for (const element of elements) {\n if (isElementVisible(element)) {\n return element;\n }\n }\n return null;\n },\n queryAll(root, _body) {\n const elements = root instanceof Element ? [root, ...Array.from(root.querySelectorAll(\"*\"))] : Array.from(root.querySelectorAll(\"*\"));\n return elements.filter(isElementVisible);\n }\n };\n }\n var internalEngines = {\n \"internal:has\": createHasEngine(),\n \"internal:has-not\": createHasNotEngine(),\n \"internal:has-text\": createHasTextEngine(),\n \"internal:has-not-text\": createHasNotTextEngine(),\n \"internal:and\": createAndEngine(),\n \"internal:or\": createOrEngine(),\n \"internal:label\": createLabelEngine(),\n \"internal:visible\": createVisibleEngine(),\n ...layoutEngines\n };\n function registerInternalEngines() {\n for (const engine of Object.values(internalEngines)) {\n selectorEngines.register(engine);\n }\n }\n // src/selectors/cache.ts\n var cacheIdCounter = 0;\n var CACHE_ID_SYMBOL = Symbol(\"selectorCacheId\");\n function isDocument(node) {\n return node.nodeType === 9;\n }\n function isShadowRoot(node) {\n return node.nodeType === 11 && \"host\" in node;\n }\n function createCacheKey(selector, root) {\n let rootId;\n if (isDocument(root)) {\n rootId = \"document\";\n } else if (isShadowRoot(root)) {\n const host = root.host;\n rootId = `shadow:${getCacheId(host)}`;\n } else {\n rootId = getCacheId(root);\n }\n return `${rootId}:${selector}`;\n }\n function getCacheId(element) {\n const cached = element[CACHE_ID_SYMBOL];\n if (cached !== undefined) {\n return cached;\n }\n const id = ++cacheIdCounter;\n element[CACHE_ID_SYMBOL] = id;\n return id;\n }\n\n class SelectorCacheManager {\n cacheCounter = 0;\n queryCache;\n queryAllCache;\n matchesCache;\n textCache;\n _queryHits = 0;\n _queryMisses = 0;\n _queryAllHits = 0;\n _queryAllMisses = 0;\n _matchesHits = 0;\n _matchesMisses = 0;\n _textHits = 0;\n _textMisses = 0;\n begin() {\n if (++this.cacheCounter === 1) {\n this.queryCache = new Map;\n this.queryAllCache = new Map;\n this.matchesCache = new Map;\n this.textCache = new Map;\n this._queryHits = 0;\n this._queryMisses = 0;\n this._queryAllHits = 0;\n this._queryAllMisses = 0;\n this._matchesHits = 0;\n this._matchesMisses = 0;\n this._textHits = 0;\n this._textMisses = 0;\n }\n }\n end() {\n if (this.cacheCounter <= 0) {\n this.cacheCounter = 0;\n return;\n }\n if (--this.cacheCounter === 0) {\n this.queryCache = undefined;\n this.queryAllCache = undefined;\n this.matchesCache = undefined;\n this.textCache = undefined;\n }\n }\n isActive() {\n return this.cacheCounter > 0;\n }\n cachedQuery(key, executor) {\n if (!this.queryCache) {\n return executor();\n }\n if (this.queryCache.has(key)) {\n this._queryHits++;\n return this.queryCache.get(key) ?? null;\n }\n this._queryMisses++;\n const result = executor();\n this.queryCache.set(key, result);\n return result;\n }\n cachedQueryAll(key, executor) {\n if (!this.queryAllCache) {\n return executor();\n }\n const cached = this.queryAllCache.get(key);\n if (cached !== undefined) {\n this._queryAllHits++;\n return cached;\n }\n this._queryAllMisses++;\n const result = executor();\n this.queryAllCache.set(key, result);\n return result;\n }\n cachedMatches(key, executor) {\n if (!this.matchesCache) {\n return executor();\n }\n const cached = this.matchesCache.get(key);\n if (cached !== undefined) {\n this._matchesHits++;\n return cached;\n }\n this._matchesMisses++;\n const result = executor();\n this.matchesCache.set(key, result);\n return result;\n }\n cachedText(element, executor) {\n if (!this.textCache) {\n return executor();\n }\n const cached = this.textCache.get(element);\n if (cached !== undefined) {\n this._textHits++;\n return cached;\n }\n this._textMisses++;\n const result = executor();\n this.textCache.set(element, result);\n return result;\n }\n getStats() {\n return {\n active: this.cacheCounter > 0,\n depth: this.cacheCounter,\n queryHits: this._queryHits,\n queryMisses: this._queryMisses,\n queryAllHits: this._queryAllHits,\n queryAllMisses: this._queryAllMisses,\n matchesHits: this._matchesHits,\n matchesMisses: this._matchesMisses,\n textHits: this._textHits,\n textMisses: this._textMisses,\n queryEntries: this.queryCache?.size ?? 0,\n queryAllEntries: this.queryAllCache?.size ?? 0,\n matchesEntries: this.matchesCache?.size ?? 0,\n textEntries: this.textCache?.size ?? 0\n };\n }\n clearAll() {\n this.cacheCounter = 0;\n this.queryCache = undefined;\n this.queryAllCache = undefined;\n this.matchesCache = undefined;\n this.textCache = undefined;\n this._queryHits = 0;\n this._queryMisses = 0;\n this._queryAllHits = 0;\n this._queryAllMisses = 0;\n this._matchesHits = 0;\n this._matchesMisses = 0;\n this._textHits = 0;\n this._textMisses = 0;\n }\n }\n var selectorCache = new SelectorCacheManager;\n function beginSelectorCaches() {\n selectorCache.begin();\n }\n function endSelectorCaches() {\n selectorCache.end();\n }\n function isSelectorCachingActive() {\n return selectorCache.isActive();\n }\n function getSelectorCacheStats() {\n return selectorCache.getStats();\n }\n function withSelectorCache(fn) {\n beginSelectorCaches();\n try {\n return fn();\n } finally {\n endSelectorCaches();\n }\n }\n async function withSelectorCacheAsync(fn) {\n beginSelectorCaches();\n try {\n return await fn();\n } finally {\n endSelectorCaches();\n }\n }\n function clearSelectorCaches() {\n selectorCache.clearAll();\n }\n\n // src/selectors/evaluator.ts\n selectorEngines.register(cssEngine);\n selectorEngines.register(xpathEngine);\n selectorEngines.register(textEngine);\n selectorEngines.register(roleEngine);\n registerInternalEngines();\n function querySelector(root, selector, options = {}) {\n if (options.visibleOnly) {\n const results = querySelectorAll(root, selector, options);\n return results[0] || null;\n }\n const cacheKey = createCacheKey(`${selector}:${options.piercesShadowDom ? \"shadow\" : \"light\"}`, root);\n return selectorCache.cachedQuery(cacheKey, () => {\n return executeQuery(root, selector, options);\n });\n }\n function executeQuery(root, selector, options) {\n const parts = splitSelector(selector);\n let current = root;\n for (const part of parts) {\n const { engine: engineName, body } = parseSelector(part.trim());\n const engine = selectorEngines.get(engineName);\n if (!engine) {\n console.warn(`Unknown selector engine: ${engineName}`);\n return null;\n }\n const element = options.piercesShadowDom ? queryShadowDom(current, body, engine) : engine.query(current, body);\n if (!element)\n return null;\n current = element;\n }\n return current instanceof Element ? current : null;\n }\n function querySelectorAll(root, selector, options = {}) {\n const cacheKey = createCacheKey(`all:${selector}:${options.piercesShadowDom ? \"shadow\" : \"light\"}`, root);\n let results = selectorCache.cachedQueryAll(cacheKey, () => {\n return executeQueryAll(root, selector, options);\n });\n if (options.visibleOnly) {\n results = results.filter(isElementVisible);\n }\n return results;\n }\n function executeQueryAll(root, selector, options) {\n const parts = splitSelector(selector);\n let results;\n if (parts.length === 1) {\n const { engine: engineName, body } = parseSelector(parts[0].trim());\n const engine = selectorEngines.get(engineName);\n if (!engine) {\n console.warn(`Unknown selector engine: ${engineName}`);\n return [];\n }\n results = options.piercesShadowDom ? queryShadowDomAll(root, body, engine) : engine.queryAll(root, body);\n } else {\n results = [];\n querySelectorChain(root, parts, 0, options, results);\n }\n return results;\n }\n function splitSelector(selector) {\n const parts = [];\n let current = \"\";\n let inQuote = false;\n let quoteChar = \"\";\n for (let i = 0;i < selector.length; i++) {\n const char = selector[i];\n if (!inQuote && (char === '\"' || char === \"'\")) {\n inQuote = true;\n quoteChar = char;\n current += char;\n } else if (inQuote && char === quoteChar) {\n inQuote = false;\n quoteChar = \"\";\n current += char;\n } else if (!inQuote && selector.slice(i, i + 2) === \">>\") {\n if (current.trim()) {\n parts.push(current.trim());\n }\n current = \"\";\n i++;\n } else {\n current += char;\n }\n }\n if (current.trim()) {\n parts.push(current.trim());\n }\n return parts;\n }\n function queryShadowDom(root, selector, engine) {\n const lightResult = engine.query(root, selector);\n if (lightResult)\n return lightResult;\n const shadows = collectShadowRoots(root);\n for (const shadow of shadows) {\n const result = engine.query(shadow, selector);\n if (result)\n return result;\n }\n return null;\n }\n function queryShadowDomAll(root, selector, engine) {\n const results = [];\n results.push(...engine.queryAll(root, selector));\n const shadows = collectShadowRoots(root);\n for (const shadow of shadows) {\n results.push(...engine.queryAll(shadow, selector));\n }\n return results;\n }\n function collectShadowRoots(root) {\n const shadows = [];\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);\n let node;\n while (node = walker.nextNode()) {\n if (node.shadowRoot) {\n shadows.push(node.shadowRoot);\n shadows.push(...collectShadowRoots(node.shadowRoot));\n }\n }\n return shadows;\n }\n function querySelectorChain(root, parts, index, options, results) {\n if (index >= parts.length)\n return;\n const { engine: engineName, body } = parseSelector(parts[index].trim());\n const engine = selectorEngines.get(engineName);\n if (!engine)\n return;\n const elements = options.piercesShadowDom ? queryShadowDomAll(root, body, engine) : engine.queryAll(root, body);\n if (index === parts.length - 1) {\n results.push(...elements);\n } else {\n for (const element of elements) {\n querySelectorChain(element, parts, index + 1, options, results);\n }\n }\n }\n // src/dom/cache.ts\n var cacheCounter = 0;\n var styleCache;\n var styleBeforeCache;\n var styleAfterCache;\n var pseudoContentCache;\n function beginDOMCaches() {\n if (++cacheCounter === 1) {\n styleCache = new Map;\n styleBeforeCache = new Map;\n styleAfterCache = new Map;\n pseudoContentCache = new Map;\n }\n }\n function endDOMCaches() {\n if (cacheCounter <= 0) {\n cacheCounter = 0;\n return;\n }\n if (--cacheCounter === 0) {\n styleCache = undefined;\n styleBeforeCache = undefined;\n styleAfterCache = undefined;\n pseudoContentCache = undefined;\n }\n }\n function getStyleCache(pseudo) {\n if (pseudo === \"::before\")\n return styleBeforeCache;\n if (pseudo === \"::after\")\n return styleAfterCache;\n return styleCache;\n }\n function getCachedStyle(element, pseudo) {\n const cache2 = getStyleCache(pseudo);\n if (cache2) {\n let style = cache2.get(element);\n if (!style) {\n const win = element.ownerDocument?.defaultView;\n if (win) {\n style = win.getComputedStyle(element, pseudo);\n cache2.set(element, style);\n } else {\n return getComputedStyle(element, pseudo);\n }\n }\n return style;\n }\n return getComputedStyle(element, pseudo);\n }\n function getCachedPseudoContent(element, pseudo) {\n if (pseudoContentCache) {\n let elementCache = pseudoContentCache.get(element);\n if (!elementCache) {\n elementCache = new Map;\n pseudoContentCache.set(element, elementCache);\n }\n let content = elementCache.get(pseudo);\n if (content === undefined) {\n const style2 = getCachedStyle(element, pseudo);\n content = style2.content || \"none\";\n elementCache.set(pseudo, content);\n }\n return content;\n }\n const style = getComputedStyle(element, pseudo);\n return style.content || \"none\";\n }\n function isCachingActive() {\n return cacheCounter > 0;\n }\n function getCacheStats() {\n const styleEntries = (styleCache?.size ?? 0) + (styleBeforeCache?.size ?? 0) + (styleAfterCache?.size ?? 0);\n let pseudoEntries = 0;\n if (pseudoContentCache) {\n for (const elementMap of pseudoContentCache.values()) {\n pseudoEntries += elementMap.size;\n }\n }\n return {\n active: cacheCounter > 0,\n depth: cacheCounter,\n styleEntries,\n pseudoEntries\n };\n }\n function withCache(fn) {\n beginDOMCaches();\n try {\n return fn();\n } finally {\n endDOMCaches();\n }\n }\n async function withCacheAsync(fn) {\n beginDOMCaches();\n try {\n return await fn();\n } finally {\n endDOMCaches();\n }\n }\n function clearAllCaches() {\n cacheCounter = 0;\n styleCache = undefined;\n styleBeforeCache = undefined;\n styleAfterCache = undefined;\n pseudoContentCache = undefined;\n }\n // src/dom/shadow.ts\n function getShadowRoots(root) {\n const shadows = [];\n collectShadowRoots2(root, shadows);\n return shadows;\n }\n function collectShadowRoots2(root, shadows) {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);\n let node;\n while (node = walker.nextNode()) {\n if (node.shadowRoot) {\n shadows.push(node.shadowRoot);\n collectShadowRoots2(node.shadowRoot, shadows);\n }\n }\n }\n function deepQuery(root, selector) {\n const lightResult = root.querySelector(selector);\n if (lightResult)\n return lightResult;\n const shadows = getShadowRoots(root);\n for (const shadow of shadows) {\n const result = shadow.querySelector(selector);\n if (result)\n return result;\n }\n return null;\n }\n function deepQueryAll(root, selector) {\n const results = [];\n results.push(...root.querySelectorAll(selector));\n const shadows = getShadowRoots(root);\n for (const shadow of shadows) {\n results.push(...shadow.querySelectorAll(selector));\n }\n return results;\n }\n function getComposedPath(element) {\n const path = [];\n let current = element;\n while (current) {\n if (current instanceof Element || current instanceof ShadowRoot || current instanceof Document) {\n path.push(current);\n }\n if (current instanceof ShadowRoot) {\n current = current.host;\n } else {\n current = current.parentNode;\n }\n }\n return path;\n }\n function deepElementFromPoint(x, y) {\n let element = document.elementFromPoint(x, y);\n if (!element)\n return null;\n while (element.shadowRoot) {\n const inner = element.shadowRoot.elementFromPoint(x, y);\n if (!inner || inner === element)\n break;\n element = inner;\n }\n return element;\n }\n // src/dom/utils.ts\n function getOwnerDocument(node) {\n return node instanceof Document ? node : node.ownerDocument;\n }\n function getOwnerWindow(node) {\n return getOwnerDocument(node).defaultView;\n }\n function isFormControl2(element) {\n return element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement || element instanceof HTMLButtonElement;\n }\n function isEditable(element) {\n if (element instanceof HTMLInputElement) {\n const type = element.type.toLowerCase();\n const editableTypes = [\n \"text\",\n \"password\",\n \"email\",\n \"number\",\n \"search\",\n \"tel\",\n \"url\",\n \"date\",\n \"datetime-local\",\n \"month\",\n \"time\",\n \"week\",\n \"color\"\n ];\n return editableTypes.includes(type) && !element.readOnly && !element.disabled;\n }\n if (element instanceof HTMLTextAreaElement) {\n return !element.readOnly && !element.disabled;\n }\n if (element.getAttribute(\"contenteditable\") === \"true\") {\n return true;\n }\n return false;\n }\n function isFocusable2(element) {\n const tabIndex = element.getAttribute(\"tabindex\");\n if (tabIndex !== null && parseInt(tabIndex, 10) >= 0) {\n return true;\n }\n if (element instanceof HTMLAnchorElement && element.href)\n return true;\n if (element instanceof HTMLButtonElement && !element.disabled)\n return true;\n if (element instanceof HTMLInputElement && !element.disabled)\n return true;\n if (element instanceof HTMLTextAreaElement && !element.disabled)\n return true;\n if (element instanceof HTMLSelectElement && !element.disabled)\n return true;\n if (element.getAttribute(\"contenteditable\") === \"true\")\n return true;\n return false;\n }\n function getInputType(element) {\n if (element instanceof HTMLInputElement) {\n return element.type.toLowerCase();\n }\n if (element instanceof HTMLTextAreaElement) {\n return \"textarea\";\n }\n if (element instanceof HTMLSelectElement) {\n return \"select\";\n }\n return null;\n }\n function scrollIntoViewIfNeeded(element, options) {\n const rect = element.getBoundingClientRect();\n const isInViewport2 = rect.top >= 0 && rect.left >= 0 && rect.bottom <= window.innerHeight && rect.right <= window.innerWidth;\n if (!isInViewport2) {\n element.scrollIntoView(options ?? { block: \"center\", inline: \"center\", behavior: \"instant\" });\n }\n }\n function getNormalizedText(element) {\n return (element.textContent || \"\").replace(/\\s+/g, \" \").trim();\n }\n // src/dom/hitTarget.ts\n function parentElementOrShadowHost(element) {\n if (element.parentElement) {\n return element.parentElement;\n }\n if (!element.parentNode) {\n return;\n }\n if (element.parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE && element.parentNode.host) {\n return element.parentNode.host;\n }\n return;\n }\n function enclosingShadowRootOrDocument(element) {\n let node = element;\n while (node.parentNode) {\n node = node.parentNode;\n }\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.DOCUMENT_NODE) {\n return node;\n }\n return;\n }\n function truncateWithEllipsis(str, maxLength) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.slice(0, maxLength - 1) + \"…\";\n }\n function toSingleLine(str) {\n return str.replace(/\\s+/g, \" \").trim();\n }\n var SELF_CLOSING_TAGS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\"\n ]);\n var BOOLEAN_ATTRIBUTES = new Set([\n \"async\",\n \"autofocus\",\n \"autoplay\",\n \"checked\",\n \"controls\",\n \"default\",\n \"defer\",\n \"disabled\",\n \"formnovalidate\",\n \"hidden\",\n \"inert\",\n \"ismap\",\n \"itemscope\",\n \"loop\",\n \"multiple\",\n \"muted\",\n \"nomodule\",\n \"novalidate\",\n \"open\",\n \"playsinline\",\n \"readonly\",\n \"required\",\n \"reversed\",\n \"selected\"\n ]);\n function describeElement(element) {\n if (!element) {\n return \"\";\n }\n const tagName = element.tagName.toLowerCase();\n const attrs = [];\n for (let i = 0;i < element.attributes.length; i++) {\n const { name, value } = element.attributes[i];\n if (name === \"style\") {\n continue;\n }\n if (!value && BOOLEAN_ATTRIBUTES.has(name)) {\n attrs.push(` ${name}`);\n } else {\n attrs.push(` ${name}=\"${value}\"`);\n }\n }\n attrs.sort((a, b) => a.length - b.length);\n const attrText = truncateWithEllipsis(attrs.join(\"\"), 500);\n if (SELF_CLOSING_TAGS.has(tagName)) {\n return toSingleLine(`<${tagName}${attrText}/>`);\n }\n const children = element.childNodes;\n let onlyText = false;\n if (children.length <= 5) {\n onlyText = true;\n for (let i = 0;i < children.length; i++) {\n onlyText = onlyText && children[i].nodeType === Node.TEXT_NODE;\n }\n }\n const text2 = onlyText ? element.textContent || \"\" : children.length ? \"…\" : \"\";\n return toSingleLine(`<${tagName}${attrText}>${truncateWithEllipsis(text2, 50)}`);\n }\n function expectHitTarget(hitPoint, targetElement) {\n if (!targetElement.isConnected) {\n return {\n success: false,\n blocked: true,\n hitTargetDescription: \"Element is not connected to the DOM\"\n };\n }\n const roots = [];\n let parentElement = targetElement;\n while (parentElement) {\n const root = enclosingShadowRootOrDocument(parentElement);\n if (!root) {\n break;\n }\n roots.push(root);\n if (root.nodeType === Node.DOCUMENT_NODE) {\n break;\n }\n parentElement = root.host;\n }\n let hitElement;\n for (let index = roots.length - 1;index >= 0; index--) {\n const root = roots[index];\n const ownerWindow = root.ownerDocument?.defaultView || window;\n const elements = root.elementsFromPoint(hitPoint.x, hitPoint.y);\n const singleElement = root.elementFromPoint(hitPoint.x, hitPoint.y);\n if (singleElement && elements[0] && parentElementOrShadowHost(singleElement) === elements[0]) {\n const style = ownerWindow.getComputedStyle(singleElement);\n if (style?.display === \"contents\") {\n elements.unshift(singleElement);\n }\n }\n if (elements[0] && elements[0].shadowRoot === root && elements[1] === singleElement) {\n elements.shift();\n }\n const innerElement = elements[0];\n if (!innerElement) {\n break;\n }\n hitElement = innerElement;\n if (index && innerElement !== roots[index - 1].host) {\n break;\n }\n }\n const hitParents = [];\n while (hitElement && hitElement !== targetElement) {\n hitParents.push(hitElement);\n hitElement = hitElement.assignedSlot ?? parentElementOrShadowHost(hitElement);\n }\n if (hitElement === targetElement) {\n return { success: true };\n }\n const hitTargetDescription = describeElement(hitParents[0] || document.documentElement);\n let rootHitTargetDescription;\n let element = targetElement;\n while (element) {\n const index = hitParents.indexOf(element);\n if (index !== -1) {\n if (index > 1) {\n rootHitTargetDescription = describeElement(hitParents[index - 1]);\n }\n break;\n }\n element = parentElementOrShadowHost(element);\n }\n if (rootHitTargetDescription) {\n return {\n success: false,\n blocked: true,\n hitTargetDescription: `${hitTargetDescription} from ${rootHitTargetDescription} subtree`\n };\n }\n return {\n success: false,\n blocked: true,\n hitTargetDescription\n };\n }\n var HOVER_EVENTS = new Set([\"mousemove\"]);\n var CLICK_EVENTS = new Set([\n \"mousedown\",\n \"mouseup\",\n \"pointerdown\",\n \"pointerup\",\n \"click\",\n \"auxclick\",\n \"dblclick\",\n \"contextmenu\"\n ]);\n var DRAG_EVENTS = new Set;\n var TAP_EVENTS = new Set([\n \"pointerdown\",\n \"pointerup\",\n \"touchstart\",\n \"touchend\",\n \"touchcancel\"\n ]);\n function isTouchEvent(event) {\n if (typeof TouchEvent !== \"undefined\") {\n return event instanceof TouchEvent;\n }\n return event.type.startsWith(\"touch\");\n }\n function createTouchObject(target, identifier, x, y) {\n if (typeof Touch === \"function\") {\n try {\n return new Touch({\n identifier,\n target,\n clientX: x,\n clientY: y,\n screenX: x,\n screenY: y,\n pageX: x,\n pageY: y\n });\n } catch {}\n }\n const doc = target instanceof Node ? target.ownerDocument || document : document;\n if (\"createTouch\" in doc) {\n return doc.createTouch(doc.defaultView, target, identifier, x, y, x, y, x, y);\n }\n return {\n identifier,\n target,\n clientX: x,\n clientY: y,\n screenX: x,\n screenY: y,\n pageX: x,\n pageY: y,\n radiusX: 1,\n radiusY: 1,\n rotationAngle: 0,\n force: 1\n };\n }\n function setupHitTargetInterceptor(element, hitPoint, action, options) {\n const blockAllEvents = options?.blockAllEvents ?? false;\n if (!element.isConnected) {\n return {\n verify: () => ({\n success: false,\n blocked: true,\n hitTargetDescription: \"Element is not connected to the DOM\"\n }),\n stop: () => {}\n };\n }\n const preliminaryResult = expectHitTarget(hitPoint, element);\n if (!preliminaryResult.success) {\n return {\n verify: () => preliminaryResult,\n stop: () => {}\n };\n }\n if (action === \"drag\") {\n return {\n verify: () => ({ success: true }),\n stop: () => {}\n };\n }\n const events = action === \"tap\" ? TAP_EVENTS : action === \"hover\" ? HOVER_EVENTS : CLICK_EVENTS;\n let result;\n let stopped = false;\n const listener = (event) => {\n if (!events.has(event.type)) {\n return;\n }\n if (!event.isTrusted) {\n return;\n }\n let point;\n if (isTouchEvent(event)) {\n const touchEvent = event;\n const touch = touchEvent.touches[0] || touchEvent.changedTouches[0];\n if (touch) {\n point = { clientX: touch.clientX, clientY: touch.clientY };\n }\n } else {\n point = event;\n }\n if (result === undefined && point) {\n result = expectHitTarget({ x: point.clientX, y: point.clientY }, element);\n }\n if (blockAllEvents || result && !result.success) {\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n }\n };\n const ownerWindow = element.ownerDocument?.defaultView || window;\n for (const eventType of events) {\n ownerWindow.addEventListener(eventType, listener, {\n capture: true,\n passive: false\n });\n }\n return {\n verify: () => {\n return result ?? { success: true };\n },\n stop: () => {\n if (stopped) {\n return;\n }\n stopped = true;\n for (const eventType of events) {\n ownerWindow.removeEventListener(eventType, listener, {\n capture: true\n });\n }\n }\n };\n }\n // src/dom/stability.ts\n function rectsEqual(a, b) {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n }\n function getRect(element) {\n const rect = element.getBoundingClientRect();\n return {\n x: rect.top,\n y: rect.left,\n width: rect.width,\n height: rect.height\n };\n }\n async function checkElementStability(element, options) {\n const frameCount = options?.frameCount ?? 2;\n const timeout = options?.timeout ?? 5000;\n if (!element.isConnected) {\n return { stable: false, reason: \"disconnected\" };\n }\n const startTime = performance.now();\n const continuePolling = Symbol(\"continuePolling\");\n let lastRect;\n let stableFrameCount = 0;\n let lastTime = 0;\n const check = () => {\n if (!element.isConnected) {\n return { stable: false, reason: \"disconnected\" };\n }\n if (performance.now() - startTime > timeout) {\n return { stable: false, reason: \"timeout\" };\n }\n const time = performance.now();\n if (frameCount > 1 && time - lastTime < 15) {\n return continuePolling;\n }\n lastTime = time;\n const currentRect = getRect(element);\n if (lastRect) {\n if (!rectsEqual(currentRect, lastRect)) {\n if (currentRect.width !== lastRect.width || currentRect.height !== lastRect.height) {\n lastRect = currentRect;\n stableFrameCount = 0;\n return continuePolling;\n }\n if (currentRect.x !== lastRect.x || currentRect.y !== lastRect.y) {\n lastRect = currentRect;\n stableFrameCount = 0;\n return continuePolling;\n }\n }\n stableFrameCount++;\n if (stableFrameCount >= frameCount) {\n return { stable: true };\n }\n }\n lastRect = currentRect;\n return continuePolling;\n };\n return new Promise((resolve, reject) => {\n const raf = () => {\n try {\n const result = check();\n if (result !== continuePolling) {\n resolve(result);\n } else {\n requestAnimationFrame(raf);\n }\n } catch (e) {\n reject(e);\n }\n };\n requestAnimationFrame(raf);\n });\n }\n async function waitForElementStable(element, options) {\n return checkElementStability(element, options);\n }\n function isElementStableSync(element) {\n if (!element.isConnected) {\n return false;\n }\n const rect = element.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n }\n\n // src/dom/states.ts\n var kAriaDisabledRoles = [\n \"application\",\n \"button\",\n \"composite\",\n \"gridcell\",\n \"group\",\n \"input\",\n \"link\",\n \"menuitem\",\n \"scrollbar\",\n \"separator\",\n \"tab\",\n \"checkbox\",\n \"columnheader\",\n \"combobox\",\n \"grid\",\n \"listbox\",\n \"menu\",\n \"menubar\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"radio\",\n \"radiogroup\",\n \"row\",\n \"rowheader\",\n \"searchbox\",\n \"select\",\n \"slider\",\n \"spinbutton\",\n \"switch\",\n \"tablist\",\n \"textbox\",\n \"toolbar\",\n \"tree\",\n \"treegrid\",\n \"treeitem\"\n ];\n var kAriaCheckedRoles = [\n \"checkbox\",\n \"menuitemcheckbox\",\n \"option\",\n \"radio\",\n \"switch\",\n \"menuitemradio\",\n \"treeitem\"\n ];\n var kAriaReadonlyRoles = [\n \"checkbox\",\n \"combobox\",\n \"grid\",\n \"gridcell\",\n \"listbox\",\n \"radiogroup\",\n \"slider\",\n \"spinbutton\",\n \"textbox\",\n \"columnheader\",\n \"rowheader\",\n \"searchbox\",\n \"switch\",\n \"treegrid\"\n ];\n function getTagName(element) {\n return element.tagName?.toUpperCase() ?? \"\";\n }\n function getRole(element) {\n const explicitRole = element.getAttribute(\"role\");\n if (explicitRole) {\n return explicitRole.split(/\\s+/)[0].toLowerCase();\n }\n const tagName = getTagName(element);\n switch (tagName) {\n case \"BUTTON\":\n return \"button\";\n case \"INPUT\": {\n const type = element.type.toLowerCase();\n if (type === \"checkbox\")\n return \"checkbox\";\n if (type === \"radio\")\n return \"radio\";\n if ([\"text\", \"email\", \"tel\", \"url\", \"password\", \"search\"].includes(type))\n return \"textbox\";\n if (type === \"number\")\n return \"spinbutton\";\n if (type === \"range\")\n return \"slider\";\n return null;\n }\n case \"TEXTAREA\":\n return \"textbox\";\n case \"SELECT\":\n return \"combobox\";\n default:\n return null;\n }\n }\n function hasAncestorAriaDisabled(element) {\n let current = element.parentElement;\n while (current) {\n const ariaDisabled = current.getAttribute(\"aria-disabled\");\n if (ariaDisabled?.toLowerCase() === \"true\") {\n return true;\n }\n if (ariaDisabled?.toLowerCase() === \"false\") {\n return false;\n }\n current = current.parentElement;\n }\n return false;\n }\n function isInDisabledFieldset(element) {\n const fieldset = element.closest(\"fieldset[disabled]\");\n if (!fieldset)\n return false;\n const legend = fieldset.querySelector(\":scope > legend\");\n if (legend && legend.contains(element)) {\n return false;\n }\n return true;\n }\n function isInDisabledOptgroup(element) {\n return getTagName(element) === \"OPTION\" && !!element.closest(\"optgroup[disabled]\");\n }\n function isElementDisabled(element) {\n const tagName = getTagName(element);\n const isNativeFormControl = [\"BUTTON\", \"INPUT\", \"SELECT\", \"TEXTAREA\", \"OPTION\", \"OPTGROUP\"].includes(tagName);\n if (isNativeFormControl) {\n if (element.hasAttribute(\"disabled\")) {\n return true;\n }\n if (isInDisabledFieldset(element)) {\n return true;\n }\n if (isInDisabledOptgroup(element)) {\n return true;\n }\n }\n const role2 = getRole(element);\n if (role2 && kAriaDisabledRoles.includes(role2)) {\n const ariaDisabled = element.getAttribute(\"aria-disabled\");\n if (ariaDisabled?.toLowerCase() === \"true\") {\n return true;\n }\n if (ariaDisabled?.toLowerCase() === \"false\") {\n return false;\n }\n }\n return hasAncestorAriaDisabled(element);\n }\n function isElementReadonly(element) {\n const tagName = getTagName(element);\n if ([\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(tagName)) {\n return element.hasAttribute(\"readonly\");\n }\n const role2 = getRole(element);\n if (role2 && kAriaReadonlyRoles.includes(role2)) {\n return element.getAttribute(\"aria-readonly\") === \"true\";\n }\n if (element.isContentEditable) {\n return false;\n }\n return \"error\";\n }\n function getCheckedState(element, allowMixed) {\n const tagName = getTagName(element);\n if (tagName === \"INPUT\") {\n const input = element;\n const type = input.type.toLowerCase();\n if ([\"checkbox\", \"radio\"].includes(type)) {\n if (allowMixed && input.indeterminate) {\n return \"mixed\";\n }\n return input.checked;\n }\n }\n const role2 = getRole(element);\n if (role2 && kAriaCheckedRoles.includes(role2)) {\n const ariaChecked = element.getAttribute(\"aria-checked\");\n if (ariaChecked === \"true\") {\n return true;\n }\n if (allowMixed && ariaChecked === \"mixed\") {\n return \"mixed\";\n }\n return false;\n }\n return \"error\";\n }\n function checkElementState(element, state) {\n if (state === \"stable\") {\n if (!element.isConnected) {\n return { matches: false, received: \"disconnected\" };\n }\n const rect = element.getBoundingClientRect();\n const hasSize = rect.width > 0 && rect.height > 0;\n return { matches: hasSize, received: hasSize ? \"stable\" : \"no-size\" };\n }\n if (!element.isConnected) {\n if (state === \"hidden\") {\n return { matches: true, received: \"hidden\" };\n }\n return { matches: false, received: \"error:notconnected\" };\n }\n if (state === \"visible\" || state === \"hidden\") {\n const visible = isElementVisible(element);\n return {\n matches: state === \"visible\" ? visible : !visible,\n received: visible ? \"visible\" : \"hidden\"\n };\n }\n if (state === \"enabled\" || state === \"disabled\") {\n const disabled = isElementDisabled(element);\n return {\n matches: state === \"disabled\" ? disabled : !disabled,\n received: disabled ? \"disabled\" : \"enabled\"\n };\n }\n if (state === \"editable\") {\n const disabled = isElementDisabled(element);\n const readonly = isElementReadonly(element);\n if (readonly === \"error\") {\n throw new Error(\"Element is not an ,