surf-cli 2.19.0 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -3
- package/dist/content/index.js +4 -4
- package/dist/content/index.js.map +1 -1
- package/dist/options/options.html +1 -18
- package/dist/service-worker/index.js +44 -15
- package/dist/service-worker/index.js.map +1 -1
- package/native/cli.cjs +109 -6
- package/native/do-executor.cjs +35 -8
- package/native/doctor.cjs +200 -40
- package/native/host-helpers.cjs +95 -10
- package/native/host.cjs +24 -2
- package/native/native-host-launch-probe.cjs +69 -0
- package/native/private-state.cjs +25 -1
- package/native/semantic-cli.cjs +764 -0
- package/native/semantic-core.cjs +369 -0
- package/native/semantic-credentials.cjs +207 -0
- package/native/semantic-provider.cjs +61 -0
- package/native/semantic-workflow-executor.cjs +65 -0
- package/native/semantic-workflow-state.cjs +271 -0
- package/native/semantic-workflow.cjs +398 -0
- package/native/tool-scope.cjs +1 -0
- package/native/workflow-definition.cjs +125 -1
- package/native/workflow-runtime.cjs +71 -5
- package/package.json +8 -4
- package/scripts/install-native-host.cjs +103 -60
- package/scripts/uninstall-native-host.cjs +40 -38
- package/scripts/windows-interop.cjs +89 -0
- package/skills/surf/SKILL.md +78 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/content/visual-indicator.ts","../../src/content/accessibility-tree.ts"],"sourcesContent":["export type VisualIndicatorMessageType =\n | \"SHOW_AGENT_INDICATORS\"\n | \"HIDE_AGENT_INDICATORS\"\n | \"HIDE_FOR_TOOL_USE\"\n | \"SHOW_AFTER_TOOL_USE\"\n | \"SHOW_STATIC_INDICATOR\"\n | \"HIDE_STATIC_INDICATOR\";\n\ndeclare global {\n interface Window {\n __piVisualIndicatorMessageHandler?: (type: VisualIndicatorMessageType) => void;\n }\n}\n\nconst PI_COLOR = \"59, 178, 191\";\nconst DEFAULT_HEARTBEAT_INTERVAL = 10000;\n\nlet glowBorder: HTMLDivElement | null = null;\nlet stopButton: HTMLDivElement | null = null;\nlet staticIndicator: HTMLDivElement | null = null;\nlet isActive = false;\nlet isStaticActive = false;\nlet wasActiveBeforeToolUse = false;\nlet wasStaticActiveBeforeToolUse = false;\nlet heartbeatIntervalId: number | null = null;\nlet heartbeatIntervalMs = DEFAULT_HEARTBEAT_INTERVAL;\nlet showIndicatorsWhenReady = false;\nlet showStaticIndicatorWhenReady = false;\nconst isTopFrame = window === window.top;\n\nif (isTopFrame) {\n chrome.storage.local.get(\"heartbeatInterval\").then(({ heartbeatInterval }) => {\n if (heartbeatInterval && typeof heartbeatInterval === \"number\") {\n heartbeatIntervalMs = heartbeatInterval * 1000;\n }\n });\n\n chrome.storage.onChanged.addListener((changes, areaName) => {\n if (areaName === \"local\" && changes.heartbeatInterval) {\n const newValue = changes.heartbeatInterval.newValue;\n if (newValue && typeof newValue === \"number\") {\n heartbeatIntervalMs = newValue * 1000;\n if (isStaticActive && heartbeatIntervalId) {\n clearInterval(heartbeatIntervalId);\n startHeartbeat();\n }\n }\n }\n });\n}\n\nfunction startHeartbeat() {\n heartbeatIntervalId = window.setInterval(async () => {\n try {\n const response = await chrome.runtime.sendMessage({ type: \"STATIC_INDICATOR_HEARTBEAT\" });\n if (!response?.success) hideStaticIndicator();\n } catch {\n hideStaticIndicator();\n }\n }, heartbeatIntervalMs);\n}\n\nfunction injectStyles() {\n if (document.getElementById(\"pi-agent-styles\")) return;\n\n const style = document.createElement(\"style\");\n style.id = \"pi-agent-styles\";\n style.textContent = `\n @keyframes pi-pulse {\n 0% {\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n }\n 50% {\n box-shadow: \n inset 0 0 15px rgba(${PI_COLOR}, 0.7),\n inset 0 0 25px rgba(${PI_COLOR}, 0.5),\n inset 0 0 35px rgba(${PI_COLOR}, 0.2);\n }\n 100% {\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n }\n }\n `;\n document.head.appendChild(style);\n}\n\nfunction createGlowBorder(): HTMLDivElement {\n const el = document.createElement(\"div\");\n el.id = \"pi-agent-glow\";\n el.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n z-index: 2147483646;\n opacity: 0;\n transition: opacity 0.3s ease-in-out;\n animation: pi-pulse 2s ease-in-out infinite;\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n `;\n return el;\n}\n\nfunction createStopButton(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.id = \"pi-agent-stop-container\";\n container.style.cssText = `\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n z-index: 2147483647;\n `;\n\n const button = document.createElement(\"button\");\n button.id = \"pi-agent-stop-button\";\n button.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 256 256\" fill=\"currentColor\" style=\"margin-right: 12px; vertical-align: middle;\">\n <path d=\"M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm40-112v56a12,12,0,0,1-12,12H100a12,12,0,0,1-12-12V100a12,12,0,0,1,12-12h56A12,12,0,0,1,168,100Z\"></path>\n </svg>\n <span style=\"vertical-align: middle;\">Stop Surf</span>\n `;\n button.style.cssText = `\n position: relative;\n transform: translateY(100px);\n padding: 12px 16px;\n background: #FAF9F5;\n color: #141413;\n border: 0.5px solid rgba(31, 30, 29, 0.4);\n border-radius: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-shadow: \n 0 40px 80px rgba(${PI_COLOR}, 0.24),\n 0 4px 14px rgba(${PI_COLOR}, 0.24);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n opacity: 0;\n user-select: none;\n pointer-events: auto;\n white-space: nowrap;\n margin: 0 auto;\n `;\n\n button.addEventListener(\"mouseenter\", () => {\n if (isActive) button.style.background = \"#F5F4F0\";\n });\n\n button.addEventListener(\"mouseleave\", () => {\n if (isActive) button.style.background = \"#FAF9F5\";\n });\n\n button.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"STOP_AGENT\", fromTabId: \"CURRENT_TAB\" });\n });\n\n container.appendChild(button);\n return container;\n}\n\nfunction createStaticIndicator(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.id = \"pi-agent-static-indicator\";\n container.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style=\"width: 16px; height: 16px; margin-right: 8px; flex-shrink: 0;\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"rgb(${PI_COLOR})\"/>\n <text x=\"8\" y=\"11\" font-size=\"9\" fill=\"white\" text-anchor=\"middle\" font-weight=\"bold\">π</text>\n </svg>\n <span style=\"color: #141413; font-size: 14px;\">Surf is active in this tab group</span>\n <div style=\"width: 0.5px; height: 32px; background: rgba(31, 30, 29, 0.15); margin: 0 8px;\"></div>\n <button id=\"pi-static-chat-button\" style=\"display: inline-flex; align-items: center; justify-content: center; padding: 6px; background: transparent; border: none; cursor: pointer; width: 32px; height: 32px; border-radius: 8px; transition: background 0.2s;\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"#141413\">\n <path d=\"M10 2.5C14.1421 2.5 17.5 5.85786 17.5 10C17.5 14.1421 14.1421 17.5 10 17.5H3C2.79779 17.5 2.61549 17.3782 2.53809 17.1914C2.4607 17.0046 2.50349 16.7895 2.64648 16.6465L4.35547 14.9365C3.20124 13.6175 2.5 11.8906 2.5 10C2.5 5.85786 5.85786 2.5 10 2.5Z\"/>\n </svg>\n </button>\n <button id=\"pi-static-close-button\" style=\"display: inline-flex; align-items: center; justify-content: center; padding: 6px; background: transparent; border: none; cursor: pointer; width: 32px; height: 32px; margin-left: 4px; border-radius: 8px; transition: background 0.2s;\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M15.1464 4.14642C15.3417 3.95121 15.6582 3.95118 15.8534 4.14642C16.0486 4.34168 16.0486 4.65822 15.8534 4.85346L10.7069 9.99997L15.8534 15.1465C16.0486 15.3417 16.0486 15.6583 15.8534 15.8535C15.6826 16.0244 15.4186 16.0461 15.2245 15.918L15.1464 15.8535L9.99989 10.707L4.85338 15.8535C4.65813 16.0486 4.34155 16.0486 4.14634 15.8535C3.95115 15.6583 3.95129 15.3418 4.14634 15.1465L9.29286 9.99997L4.14634 4.85346C3.95129 4.65818 3.95115 4.34162 4.14634 4.14642C4.34154 3.95128 4.65812 3.95138 4.85338 4.14642L9.99989 9.29294L15.1464 4.14642Z\" fill=\"#141413\"/>\n </svg>\n </button>\n `;\n container.style.cssText = `\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: inline-flex;\n align-items: center;\n padding: 6px 6px 6px 16px;\n background: #FAF9F5;\n border: 0.5px solid rgba(31, 30, 29, 0.30);\n border-radius: 14px;\n box-shadow: 0 40px 80px 0 rgba(0, 0, 0, 0.15);\n z-index: 2147483647;\n pointer-events: none;\n white-space: nowrap;\n user-select: none;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n `;\n\n const chatButton = container.querySelector(\"#pi-static-chat-button\") as HTMLButtonElement;\n const closeButton = container.querySelector(\"#pi-static-close-button\") as HTMLButtonElement;\n\n if (chatButton) {\n chatButton.style.pointerEvents = \"auto\";\n chatButton.addEventListener(\"mouseenter\", () => chatButton.style.background = \"#F0EEE6\");\n chatButton.addEventListener(\"mouseleave\", () => chatButton.style.background = \"transparent\");\n chatButton.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"OPEN_SIDEPANEL\" });\n });\n }\n\n if (closeButton) {\n closeButton.style.pointerEvents = \"auto\";\n closeButton.addEventListener(\"mouseenter\", () => closeButton.style.background = \"#F0EEE6\");\n closeButton.addEventListener(\"mouseleave\", () => closeButton.style.background = \"transparent\");\n closeButton.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"DISMISS_STATIC_INDICATOR\" });\n hideStaticIndicator();\n });\n }\n\n return container;\n}\n\nfunction showIndicators() {\n if (!document.body) {\n if (!showIndicatorsWhenReady) {\n showIndicatorsWhenReady = true;\n window.addEventListener(\n \"DOMContentLoaded\",\n () => {\n if (!showIndicatorsWhenReady) return;\n showIndicatorsWhenReady = false;\n showIndicators();\n },\n { once: true },\n );\n }\n return;\n }\n showIndicatorsWhenReady = false;\n if (isActive) return;\n isActive = true;\n\n injectStyles();\n\n if (!glowBorder) {\n glowBorder = createGlowBorder();\n document.body.appendChild(glowBorder);\n } else {\n glowBorder.style.display = \"\";\n }\n\n if (!stopButton) {\n stopButton = createStopButton();\n document.body.appendChild(stopButton);\n } else {\n stopButton.style.display = \"\";\n }\n\n requestAnimationFrame(() => {\n if (glowBorder) glowBorder.style.opacity = \"1\";\n if (stopButton) {\n const btn = stopButton.querySelector(\"#pi-agent-stop-button\") as HTMLElement;\n if (btn) {\n btn.style.transform = \"translateY(0)\";\n btn.style.opacity = \"1\";\n }\n }\n });\n}\n\nfunction hideIndicators() {\n showIndicatorsWhenReady = false;\n if (!isActive) return;\n isActive = false;\n\n if (glowBorder) glowBorder.style.opacity = \"0\";\n if (stopButton) {\n const btn = stopButton.querySelector(\"#pi-agent-stop-button\") as HTMLElement;\n if (btn) {\n btn.style.transform = \"translateY(100px)\";\n btn.style.opacity = \"0\";\n }\n }\n\n setTimeout(() => {\n if (!isActive) {\n if (glowBorder?.parentNode) {\n glowBorder.parentNode.removeChild(glowBorder);\n glowBorder = null;\n }\n if (stopButton?.parentNode) {\n stopButton.parentNode.removeChild(stopButton);\n stopButton = null;\n }\n }\n }, 300);\n}\n\nfunction showStaticIndicator() {\n if (!document.body) {\n if (!showStaticIndicatorWhenReady) {\n showStaticIndicatorWhenReady = true;\n window.addEventListener(\n \"DOMContentLoaded\",\n () => {\n if (!showStaticIndicatorWhenReady) return;\n showStaticIndicatorWhenReady = false;\n showStaticIndicator();\n },\n { once: true },\n );\n }\n return;\n }\n showStaticIndicatorWhenReady = false;\n if (isStaticActive) return;\n isStaticActive = true;\n\n if (!staticIndicator) {\n staticIndicator = createStaticIndicator();\n document.body.appendChild(staticIndicator);\n } else {\n staticIndicator.style.display = \"\";\n }\n\n if (heartbeatIntervalId) clearInterval(heartbeatIntervalId);\n startHeartbeat();\n}\n\nfunction hideStaticIndicator() {\n showStaticIndicatorWhenReady = false;\n if (!isStaticActive) return;\n isStaticActive = false;\n\n if (heartbeatIntervalId) {\n clearInterval(heartbeatIntervalId);\n heartbeatIntervalId = null;\n }\n\n if (staticIndicator?.parentNode) {\n staticIndicator.parentNode.removeChild(staticIndicator);\n staticIndicator = null;\n }\n}\n\nif (isTopFrame) {\n window.__piVisualIndicatorMessageHandler = (type) => {\n switch (type) {\n case \"SHOW_AGENT_INDICATORS\":\n showIndicators();\n break;\n case \"HIDE_AGENT_INDICATORS\":\n hideIndicators();\n break;\n case \"HIDE_FOR_TOOL_USE\":\n wasActiveBeforeToolUse = isActive || showIndicatorsWhenReady;\n wasStaticActiveBeforeToolUse = isStaticActive || showStaticIndicatorWhenReady;\n showIndicatorsWhenReady = false;\n showStaticIndicatorWhenReady = false;\n if (glowBorder) glowBorder.style.display = \"none\";\n if (stopButton) stopButton.style.display = \"none\";\n if (staticIndicator && isStaticActive) staticIndicator.style.display = \"none\";\n break;\n case \"SHOW_AFTER_TOOL_USE\":\n if (wasActiveBeforeToolUse) {\n if (isActive) {\n if (glowBorder) glowBorder.style.display = \"\";\n if (stopButton) stopButton.style.display = \"\";\n } else {\n showIndicators();\n }\n }\n if (wasStaticActiveBeforeToolUse) {\n if (isStaticActive && staticIndicator) {\n staticIndicator.style.display = \"\";\n } else {\n showStaticIndicator();\n }\n }\n wasActiveBeforeToolUse = false;\n wasStaticActiveBeforeToolUse = false;\n break;\n case \"SHOW_STATIC_INDICATOR\":\n showStaticIndicator();\n break;\n case \"HIDE_STATIC_INDICATOR\":\n hideStaticIndicator();\n break;\n }\n };\n\n window.addEventListener(\"beforeunload\", () => {\n hideIndicators();\n hideStaticIndicator();\n });\n}\n","import type { VisualIndicatorMessageType } from \"./visual-indicator.ts\";\n\nexport {};\n\ndeclare global {\n interface Window {\n __piElementMap?: Record<string, { element: WeakRef<Element>; role: string; name: string }>;\n __piLastSnapshot?: { content: string; timestamp: number };\n __piHelpers?: typeof piHelpersImpl;\n piHelpers?: typeof piHelpersImpl;\n __piRefs?: Record<string, Element>;\n }\n}\n\ninterface ModalState {\n type: 'dialog' | 'alertdialog';\n description: string;\n clearedBy: string;\n}\n\nconst VALID_ARIA_ROLES = new Set([\n \"alert\", \"alertdialog\", \"application\", \"article\", \"banner\", \"blockquote\",\n \"button\", \"caption\", \"cell\", \"checkbox\", \"code\", \"columnheader\", \"combobox\",\n \"complementary\", \"contentinfo\", \"definition\", \"deletion\", \"dialog\", \"directory\",\n \"document\", \"emphasis\", \"feed\", \"figure\", \"form\", \"generic\", \"grid\", \"gridcell\",\n \"group\", \"heading\", \"img\", \"insertion\", \"link\", \"list\", \"listbox\", \"listitem\",\n \"log\", \"main\", \"mark\", \"marquee\", \"math\", \"menu\", \"menubar\", \"menuitem\",\n \"menuitemcheckbox\", \"menuitemradio\", \"meter\", \"navigation\", \"none\", \"note\",\n \"option\", \"paragraph\", \"presentation\", \"progressbar\", \"radio\", \"radiogroup\",\n \"region\", \"row\", \"rowgroup\", \"rowheader\", \"scrollbar\", \"search\", \"searchbox\",\n \"separator\", \"slider\", \"spinbutton\", \"status\", \"strong\", \"subscript\",\n \"superscript\", \"switch\", \"tab\", \"table\", \"tablist\", \"tabpanel\", \"term\",\n \"textbox\", \"time\", \"timer\", \"toolbar\", \"tooltip\", \"tree\", \"treegrid\", \"treeitem\"\n]);\n\nfunction isFocusable(element: Element): boolean {\n const tagName = element.tagName.toLowerCase();\n if ([\"button\", \"input\", \"select\", \"textarea\"].includes(tagName)) {\n return !(element as HTMLButtonElement).disabled;\n }\n if (tagName === \"a\" && element.hasAttribute(\"href\")) return true;\n if (element.hasAttribute(\"tabindex\")) {\n const tabindex = parseInt(element.getAttribute(\"tabindex\") || \"\", 10);\n return !isNaN(tabindex) && tabindex >= 0;\n }\n if (element.getAttribute(\"contenteditable\") === \"true\") return true;\n return false;\n}\n\nfunction getExplicitRole(element: Element): string | null {\n const roleAttr = element.getAttribute(\"role\");\n if (!roleAttr) return null;\n const roles = roleAttr.split(/\\s+/).filter(r => r);\n for (const role of roles) {\n if (VALID_ARIA_ROLES.has(role)) {\n return role;\n }\n }\n return null;\n}\n\nfunction getImplicitRole(element: Element): string {\n const tag = element.tagName.toLowerCase();\n const type = element.getAttribute(\"type\");\n\n const tagRoles: Record<string, string | ((el: Element) => string)> = {\n a: (el) => el.hasAttribute(\"href\") ? \"link\" : \"generic\",\n article: \"article\",\n aside: \"complementary\",\n button: \"button\",\n datalist: \"listbox\",\n dd: \"definition\",\n details: \"group\",\n dialog: \"dialog\",\n dt: \"term\",\n fieldset: \"group\",\n figure: \"figure\",\n footer: (el) => el.closest(\"article, aside, main, nav, section\") ? \"generic\" : \"contentinfo\",\n form: (el) => el.hasAttribute(\"aria-label\") || el.hasAttribute(\"aria-labelledby\") ? \"form\" : \"generic\",\n h1: \"heading\", h2: \"heading\", h3: \"heading\", h4: \"heading\", h5: \"heading\", h6: \"heading\",\n header: (el) => el.closest(\"article, aside, main, nav, section\") ? \"generic\" : \"banner\",\n hr: \"separator\",\n img: (el) => el.getAttribute(\"alt\") === \"\" ? \"presentation\" : \"img\",\n li: \"listitem\",\n main: \"main\",\n math: \"math\",\n menu: \"list\",\n meter: \"meter\",\n nav: \"navigation\",\n ol: \"list\",\n optgroup: \"group\",\n option: \"option\",\n output: \"status\",\n p: \"paragraph\",\n progress: \"progressbar\",\n search: \"search\",\n section: (el) => el.hasAttribute(\"aria-label\") || el.hasAttribute(\"aria-labelledby\") ? \"region\" : \"generic\",\n select: (el) => {\n const s = el as HTMLSelectElement;\n return s.hasAttribute(\"multiple\") || (s.size && s.size > 1) ? \"listbox\" : \"combobox\";\n },\n table: \"table\",\n tbody: \"rowgroup\",\n td: \"cell\",\n textarea: \"textbox\",\n tfoot: \"rowgroup\",\n th: \"columnheader\",\n thead: \"rowgroup\",\n time: \"time\",\n tr: \"row\",\n ul: \"list\",\n };\n\n if (tag === \"input\") {\n const inputRoles: Record<string, string> = {\n button: \"button\",\n checkbox: \"checkbox\",\n email: \"textbox\",\n file: \"button\",\n image: \"button\",\n number: \"spinbutton\",\n radio: \"radio\",\n range: \"slider\",\n reset: \"button\",\n search: \"searchbox\",\n submit: \"button\",\n tel: \"textbox\",\n text: \"textbox\",\n url: \"textbox\",\n };\n return inputRoles[type || \"\"] || \"textbox\";\n }\n\n const roleOrFn = tagRoles[tag];\n if (typeof roleOrFn === \"function\") {\n return roleOrFn(element);\n }\n return roleOrFn || \"generic\";\n}\n\nfunction getResolvedRole(element: Element): string {\n const explicitRole = getExplicitRole(element);\n \n if (!explicitRole) {\n return getImplicitRole(element);\n }\n \n if ((explicitRole === \"none\" || explicitRole === \"presentation\") && isFocusable(element)) {\n return getImplicitRole(element);\n }\n \n return explicitRole;\n}\n\nif (!window.__piElementMap) window.__piElementMap = {};\n\ninterface ElementRef {\n role: string;\n name: string;\n ref: string;\n}\n\nconst elementRefs = new WeakMap<Element, ElementRef>();\nlet globalRefCounter = 0;\n\nfunction getOrAssignRef(element: Element, role: string, name: string): string {\n const existing = elementRefs.get(element);\n if (existing && existing.role === role && existing.name === name) {\n return existing.ref;\n }\n \n const ref = `e${++globalRefCounter}`;\n elementRefs.set(element, { role, name, ref });\n return ref;\n}\n\nfunction detectModalStates(): ModalState[] {\n const modals: ModalState[] = [];\n \n const dialogs = document.querySelectorAll('[role=\"dialog\"], [role=\"alertdialog\"], dialog[open]');\n dialogs.forEach(dialog => {\n const style = window.getComputedStyle(dialog);\n const isVisible = style.display !== 'none' && \n style.visibility !== 'hidden' && \n style.opacity !== '0' &&\n (dialog as HTMLElement).offsetWidth > 0 &&\n (dialog as HTMLElement).offsetHeight > 0;\n if (!isVisible) return;\n \n const role = dialog.getAttribute('role') || 'dialog';\n let title = dialog.getAttribute('aria-label') || \n dialog.querySelector('[role=\"heading\"], h1, h2, h3')?.textContent?.trim() ||\n 'Dialog';\n if (title.length > 100) title = title.substring(0, 100) + '...';\n modals.push({\n type: role as 'dialog' | 'alertdialog',\n description: `${role}: ${title}`,\n clearedBy: 'computer(action=key, text=Escape)',\n });\n });\n \n return modals;\n}\n\nconst piHelpersImpl = {\n wait(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n\n async waitForSelector(\n selector: string,\n options: { state?: 'visible' | 'hidden' | 'attached' | 'detached'; timeout?: number } = {}\n ): Promise<Element | null> {\n const { state = 'visible', timeout = 20000 } = options;\n\n const isElementVisible = (el: Element | null): boolean => {\n if (!el) return false;\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && \n style.visibility !== 'hidden' && \n style.opacity !== '0' &&\n (el as HTMLElement).offsetWidth > 0 &&\n (el as HTMLElement).offsetHeight > 0;\n };\n\n const checkElement = (): Element | null => {\n const el = document.querySelector(selector);\n switch (state) {\n case 'attached':\n return el;\n case 'detached':\n return el ? null : document.body;\n case 'hidden':\n if (!el) return document.body;\n return isElementVisible(el) ? null : el;\n case 'visible':\n default:\n return isElementVisible(el) ? el : null;\n }\n };\n\n return new Promise((resolve, reject) => {\n const result = checkElement();\n if (result) {\n resolve(state === 'detached' || state === 'hidden' ? null : result);\n return;\n }\n\n const observer = new MutationObserver(() => {\n const result = checkElement();\n if (result) {\n observer.disconnect();\n clearTimeout(timeoutId);\n resolve(state === 'detached' || state === 'hidden' ? null : result);\n }\n });\n\n const timeoutId = setTimeout(() => {\n observer.disconnect();\n reject(new Error(`Timeout waiting for \"${selector}\" to be ${state}`));\n }, timeout);\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'class', 'hidden']\n });\n });\n },\n\n async waitForText(\n text: string,\n options: { selector?: string; timeout?: number } = {}\n ): Promise<Element | null> {\n const { selector, timeout = 20000 } = options;\n\n const checkText = (): Element | null => {\n const root = selector ? document.querySelector(selector) : document.body;\n if (!root) return null;\n \n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n while (walker.nextNode()) {\n if (walker.currentNode.textContent?.includes(text)) {\n return walker.currentNode.parentElement;\n }\n }\n return null;\n };\n\n return new Promise((resolve, reject) => {\n const result = checkText();\n if (result) {\n resolve(result);\n return;\n }\n\n const observer = new MutationObserver(() => {\n const result = checkText();\n if (result) {\n observer.disconnect();\n clearTimeout(timeoutId);\n resolve(result);\n }\n });\n\n const timeoutId = setTimeout(() => {\n observer.disconnect();\n reject(new Error(`Timeout waiting for text \"${text}\"`));\n }, timeout);\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n characterData: true\n });\n });\n },\n\n async waitForHidden(selector: string, timeout = 20000): Promise<void> {\n await piHelpersImpl.waitForSelector(selector, { state: 'hidden', timeout });\n },\n\n getByRole(role: string, options: { name?: string } = {}): Element | null {\n const { name } = options;\n \n const implicitRoles: Record<string, string[]> = {\n button: ['button', 'input[type=\"button\"]', 'input[type=\"submit\"]', 'input[type=\"reset\"]'],\n link: ['a[href]'],\n textbox: ['input:not([type])', 'input[type=\"text\"]', 'input[type=\"email\"]', 'input[type=\"password\"]', 'input[type=\"search\"]', 'input[type=\"tel\"]', 'input[type=\"url\"]', 'textarea'],\n checkbox: ['input[type=\"checkbox\"]'],\n radio: ['input[type=\"radio\"]'],\n combobox: ['select'],\n heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n list: ['ul', 'ol'],\n listitem: ['li'],\n navigation: ['nav'],\n main: ['main'],\n banner: ['header'],\n contentinfo: ['footer'],\n form: ['form'],\n img: ['img'],\n table: ['table'],\n };\n\n const candidates: Element[] = [];\n candidates.push(...document.querySelectorAll(`[role=\"${role}\"]`));\n \n const implicitSelectors = implicitRoles[role];\n if (implicitSelectors) {\n for (const sel of implicitSelectors) {\n candidates.push(...document.querySelectorAll(`${sel}:not([role])`));\n }\n }\n\n if (!name) return candidates[0] || null;\n\n const normalizedName = name.toLowerCase().trim();\n for (const el of candidates) {\n const ariaLabel = el.getAttribute('aria-label')?.toLowerCase().trim();\n const textContent = el.textContent?.toLowerCase().trim();\n const title = el.getAttribute('title')?.toLowerCase().trim();\n const placeholder = el.getAttribute('placeholder')?.toLowerCase().trim();\n\n if (ariaLabel === normalizedName || textContent === normalizedName || \n title === normalizedName || placeholder === normalizedName) {\n return el;\n }\n if (ariaLabel?.includes(normalizedName) || textContent?.includes(normalizedName)) {\n return el;\n }\n }\n\n return null;\n }\n};\n\nif (!window.__piHelpers) {\n window.__piHelpers = piHelpersImpl;\n window.piHelpers = piHelpersImpl;\n}\n\nfunction getElementMap() {\n return window.__piElementMap!;\n}\n\nfunction generateAccessibilityTree(\n filter: \"all\" | \"interactive\" = \"interactive\",\n maxDepth = 15,\n refId?: string,\n forceFullSnapshot = false,\n compact = false\n): { \n pageContent: string;\n diff?: string;\n viewport: { width: number; height: number }; \n error?: string;\n modalStates?: ModalState[];\n modalLimitations?: string;\n isIncremental?: boolean;\n} {\n try {\n window.__piRefs = {};\n\n function getRole(element: Element): string {\n return getResolvedRole(element);\n }\n\n function getName(element: Element): string {\n const tag = element.tagName.toLowerCase();\n\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const names = labelledBy.split(/\\s+/).map(id => {\n const el = document.getElementById(id);\n return el?.textContent?.trim() || '';\n }).filter(Boolean);\n if (names.length) {\n const joined = names.join(' ');\n return joined.length > 100 ? joined.substring(0, 100) + '...' : joined;\n }\n }\n\n if (tag === \"select\") {\n const select = element as HTMLSelectElement;\n const selected = select.querySelector(\"option[selected]\") || \n (select.selectedIndex >= 0 ? select.options[select.selectedIndex] : null);\n if (selected?.textContent?.trim()) return selected.textContent.trim();\n }\n\n const ariaLabel = element.getAttribute(\"aria-label\");\n if (ariaLabel?.trim()) return ariaLabel.trim();\n\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder?.trim()) return placeholder.trim();\n\n const title = element.getAttribute(\"title\");\n if (title?.trim()) return title.trim();\n\n const alt = element.getAttribute(\"alt\");\n if (alt?.trim()) return alt.trim();\n\n if (element.id) {\n const label = document.querySelector(`label[for=\"${element.id}\"]`);\n if (label?.textContent?.trim()) return label.textContent.trim();\n }\n\n if (tag === \"input\") {\n const input = element as HTMLInputElement;\n const type = element.getAttribute(\"type\") || \"\";\n const value = element.getAttribute(\"value\");\n if (type === \"submit\" && value?.trim()) return value.trim();\n if (input.value && input.value.length < 50 && input.value.trim()) return input.value.trim();\n }\n\n if ([\"button\", \"a\", \"summary\"].includes(tag)) {\n const textContent = element.textContent || \"\";\n if (textContent.trim()) return textContent.trim();\n }\n\n if (/^h[1-6]$/.test(tag)) {\n const text = element.textContent;\n if (text?.trim()) {\n const t = text.trim();\n return t.length > 100 ? t.substring(0, 100) + \"...\" : t;\n }\n }\n\n if (tag === \"img\") return \"\";\n\n let directText = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n directText += node.textContent;\n }\n }\n if (directText?.trim() && directText.trim().length >= 3) {\n const text = directText.trim();\n return text.length > 100 ? text.substring(0, 100) + \"...\" : text;\n }\n\n return \"\";\n }\n\n interface AriaProps {\n checked?: boolean | 'mixed';\n disabled?: boolean;\n expanded?: boolean;\n level?: number;\n pressed?: boolean | 'mixed';\n selected?: boolean;\n active?: boolean;\n }\n\n function getAriaProps(element: Element): AriaProps {\n const props: AriaProps = {};\n \n const checkedAttr = element.getAttribute('aria-checked');\n if (checkedAttr === 'true') props.checked = true;\n else if (checkedAttr === 'false') props.checked = false;\n else if (checkedAttr === 'mixed') props.checked = 'mixed';\n else if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {\n if (element.type === 'checkbox' && element.indeterminate) {\n props.checked = 'mixed';\n } else {\n props.checked = element.checked;\n }\n }\n \n const isDisableable = element instanceof HTMLButtonElement || \n element instanceof HTMLInputElement || \n element instanceof HTMLSelectElement || \n element instanceof HTMLTextAreaElement;\n if (element.getAttribute('aria-disabled') === 'true' || \n (isDisableable && (element as HTMLButtonElement).disabled) ||\n element.closest('fieldset:disabled')) {\n props.disabled = true;\n }\n \n const expandedAttr = element.getAttribute('aria-expanded');\n if (expandedAttr === 'true') props.expanded = true;\n else if (expandedAttr === 'false') props.expanded = false;\n \n const pressedAttr = element.getAttribute('aria-pressed');\n if (pressedAttr === 'true') props.pressed = true;\n else if (pressedAttr === 'false') props.pressed = false;\n else if (pressedAttr === 'mixed') props.pressed = 'mixed';\n \n const selectedAttr = element.getAttribute('aria-selected');\n if (selectedAttr === 'true') props.selected = true;\n else if (selectedAttr === 'false') props.selected = false;\n \n const activeAttr = element.getAttribute('aria-current');\n if (activeAttr && activeAttr !== 'false') {\n props.active = true;\n }\n \n const tag = element.tagName.toLowerCase();\n if (/^h[1-6]$/.test(tag)) {\n props.level = parseInt(tag[1], 10);\n } else {\n const levelAttr = element.getAttribute('aria-level');\n if (levelAttr) props.level = parseInt(levelAttr, 10);\n }\n \n return props;\n }\n\n function formatAriaProps(props: AriaProps): string {\n const parts: string[] = [];\n \n if (props.checked !== undefined) {\n parts.push(props.checked === 'mixed' ? '[checked=mixed]' : props.checked ? '[checked]' : '[unchecked]');\n }\n if (props.disabled) parts.push('[disabled]');\n if (props.expanded !== undefined) {\n parts.push(props.expanded ? '[expanded]' : '[collapsed]');\n }\n if (props.pressed !== undefined) {\n parts.push(props.pressed === 'mixed' ? '[pressed=mixed]' : props.pressed ? '[pressed]' : '[not-pressed]');\n }\n if (props.selected !== undefined) {\n parts.push(props.selected ? '[selected]' : '[not-selected]');\n }\n if (props.active) parts.push('[active]');\n if (props.level !== undefined) {\n parts.push(`[level=${props.level}]`);\n }\n \n return parts.join(' ');\n }\n\n function isVisible(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return (\n style.display !== \"none\" &&\n style.visibility !== \"hidden\" &&\n style.opacity !== \"0\" &&\n (element as HTMLElement).offsetWidth > 0 &&\n (element as HTMLElement).offsetHeight > 0\n );\n }\n\n function isInteractive(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"a\", \"button\", \"input\", \"select\", \"textarea\", \"details\", \"summary\"].includes(tag) ||\n element.hasAttribute(\"onclick\") ||\n element.hasAttribute(\"tabindex\") ||\n element.getAttribute(\"role\") === \"button\" ||\n element.getAttribute(\"role\") === \"link\" ||\n element.getAttribute(\"contenteditable\") === \"true\"\n );\n }\n\n function isLandmark(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"nav\", \"main\", \"header\", \"footer\", \"section\", \"article\", \"aside\"].includes(tag) ||\n element.hasAttribute(\"role\")\n );\n }\n\n function hasCursorPointer(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return style.cursor === \"pointer\";\n }\n\n function shouldInclude(element: Element, options: { filter: string; refId: string | null; compact: boolean }): boolean {\n const tag = element.tagName.toLowerCase();\n if ([\"script\", \"style\", \"meta\", \"link\", \"title\", \"noscript\"].includes(tag)) return false;\n if (options.filter !== \"all\" && element.getAttribute(\"aria-hidden\") === \"true\") return false;\n if (options.filter !== \"all\" && !isVisible(element)) return false;\n\n if (options.filter !== \"all\" && !options.refId) {\n const rect = element.getBoundingClientRect();\n if (!(rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0)) {\n return false;\n }\n }\n\n if (options.filter === \"interactive\") return isInteractive(element);\n if (isInteractive(element)) return true;\n if (isLandmark(element)) return true;\n if (getName(element).length > 0) return true;\n\n const role = getRole(element);\n \n // In compact mode, skip empty structural elements\n if (options.compact) {\n const emptyStructuralRoles = new Set([\"generic\", \"group\", \"region\", \"article\", \"section\", \"complementary\"]);\n if (emptyStructuralRoles.has(role) && getName(element).length === 0) {\n return false;\n }\n }\n \n return role !== \"generic\" && role !== \"img\";\n }\n\n function traverse(element: Element, depth: number): string[] {\n const lines: string[] = [];\n const options = { filter, refId: refId || null, compact };\n const elementMap = getElementMap();\n\n const include = shouldInclude(element, options) || (refId && depth === 0);\n\n if (include) {\n const role = getRole(element);\n const name = getName(element);\n const ariaProps = getAriaProps(element);\n\n const elemRefId = getOrAssignRef(element, role, name);\n window.__piRefs![elemRefId] = element;\n elementMap[elemRefId] = {\n element: new WeakRef(element),\n role,\n name,\n };\n\n const indent = \" \".repeat(depth);\n let line = `${indent}${role}`;\n if (name) {\n const escapedName = name.replace(/\\s+/g, \" \").replace(/\"/g, '\\\\\"');\n line += ` \"${escapedName}\"`;\n }\n line += ` [${elemRefId}]`;\n\n const propsStr = formatAriaProps(ariaProps);\n if (propsStr) line += ` ${propsStr}`;\n\n if (hasCursorPointer(element)) {\n line += \" [cursor=pointer]\";\n }\n\n const href = element.getAttribute(\"href\");\n if (href) line += ` href=\"${href}\"`;\n\n const type = element.getAttribute(\"type\");\n if (type) line += ` type=\"${type}\"`;\n\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder) line += ` placeholder=\"${placeholder}\"`;\n\n lines.push(line);\n }\n\n if (depth < maxDepth) {\n for (const child of element.children) {\n lines.push(...traverse(child, include ? depth + 1 : depth));\n }\n }\n\n return lines;\n }\n\n function normalizeLineForDiff(line: string): string {\n return line.replace(/\\[e\\d+\\]/g, '[REF]');\n }\n\n function countOccurrences(lines: string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const line of lines) {\n if (!line.trim()) continue;\n const norm = normalizeLineForDiff(line);\n counts.set(norm, (counts.get(norm) || 0) + 1);\n }\n return counts;\n }\n\n function computeSimpleDiff(oldContent: string, newContent: string): { diff: string; hasChanges: boolean } {\n const oldLines = oldContent.split('\\n');\n const newLines = newContent.split('\\n');\n \n const oldCounts = countOccurrences(oldLines);\n const newCounts = countOccurrences(newLines);\n \n const added: string[] = [];\n const removed: string[] = [];\n \n for (const line of newLines) {\n if (!line.trim()) continue;\n const norm = normalizeLineForDiff(line);\n const oldCount = oldCounts.get(norm) || 0;\n const newCount = newCounts.get(norm) || 0;\n if (newCount > oldCount) {\n added.push(line);\n oldCounts.set(norm, oldCount + 1);\n }\n }\n \n const oldCountsReset = countOccurrences(oldLines);\n for (const line of oldLines) {\n if (!line.trim()) continue;\n const norm = normalizeLineForDiff(line);\n const oldCount = oldCountsReset.get(norm) || 0;\n const newCount = newCounts.get(norm) || 0;\n if (oldCount > newCount) {\n removed.push(line);\n oldCountsReset.set(norm, oldCount - 1);\n }\n }\n \n if (added.length === 0 && removed.length === 0) {\n return { diff: '[NO CHANGES]', hasChanges: false };\n }\n \n const diffLines: string[] = [];\n if (removed.length > 0) {\n diffLines.push(...removed.map(l => `- ${l}`));\n }\n if (added.length > 0) {\n diffLines.push(...added.map(l => `+ ${l}`));\n }\n \n return { diff: diffLines.join('\\n'), hasChanges: true };\n }\n\n const elementMap = getElementMap();\n let startElement: Element | null = null;\n\n if (refId) {\n const elemRef = elementMap[refId];\n if (!elemRef) {\n return {\n error: `Element with ref_id '${refId}' not found. Use read_page without ref_id to get current elements.`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n const element = elemRef.element.deref();\n if (!element) {\n delete elementMap[refId];\n return {\n error: `Element with ref_id '${refId}' no longer exists. Use read_page without ref_id to get current elements.`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n startElement = element;\n } else {\n startElement = document.body;\n }\n\n const lines = startElement ? traverse(startElement, 0) : [];\n\n for (const id of Object.keys(elementMap)) {\n if (!elementMap[id].element.deref()) {\n delete elementMap[id];\n }\n }\n\n const content = lines.join(\"\\n\");\n\n if (content.length > 50000) {\n return {\n error: `Output exceeds 50000 character limit (${content.length} characters). Try using filter=\"interactive\" or specify a ref_id.`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n\n const modalStates = detectModalStates();\n\n let diff: string | undefined;\n let isIncremental = false;\n const lastSnapshot = window.__piLastSnapshot;\n\n if (!forceFullSnapshot && !refId && lastSnapshot && \n Date.now() - lastSnapshot.timestamp < 5000) {\n const diffResult = computeSimpleDiff(lastSnapshot.content, content);\n diff = diffResult.diff;\n isIncremental = true;\n }\n\n window.__piLastSnapshot = { content, timestamp: Date.now() };\n\n return {\n pageContent: content + `\\n\\n[Viewport: ${window.innerWidth}x${window.innerHeight}]`,\n diff: isIncremental ? diff : undefined,\n viewport: { width: window.innerWidth, height: window.innerHeight },\n modalStates: modalStates.length > 0 ? modalStates : undefined,\n modalLimitations: 'Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts.',\n isIncremental,\n };\n } catch (err) {\n return {\n error: `Error generating accessibility tree: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n}\n\nfunction yamlEscapeValue(str: string): string {\n if (!str.length) return '\"\"';\n if (/[\\n\\r]/.test(str) || /^[\\s]/.test(str) || /[\\s]$/.test(str) || /[:\"{}[\\]]/.test(str)) {\n return '\"' + str.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r') + '\"';\n }\n return str;\n}\n\nfunction generateYamlTree(\n filter: \"all\" | \"interactive\" = \"interactive\",\n maxDepth = 15\n): { yaml: string; viewport: { width: number; height: number }; error?: string } {\n try {\n window.__piRefs = {};\n \n const lines: string[] = [];\n\n function getRole(element: Element): string {\n return getResolvedRole(element);\n }\n\n function getName(element: Element): string {\n const tag = element.tagName.toLowerCase();\n\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const names = labelledBy.split(/\\s+/).map(id => {\n const el = document.getElementById(id);\n return el?.textContent?.trim() || '';\n }).filter(Boolean);\n if (names.length) {\n const joined = names.join(' ');\n return joined.length > 100 ? joined.substring(0, 100) + '...' : joined;\n }\n }\n\n if (tag === \"select\") {\n const select = element as HTMLSelectElement;\n const selected = select.querySelector(\"option[selected]\") || \n (select.selectedIndex >= 0 ? select.options[select.selectedIndex] : null);\n if (selected?.textContent?.trim()) return selected.textContent.trim();\n }\n\n const ariaLabel = element.getAttribute(\"aria-label\");\n if (ariaLabel?.trim()) return ariaLabel.trim();\n\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder?.trim()) return placeholder.trim();\n\n const title = element.getAttribute(\"title\");\n if (title?.trim()) return title.trim();\n\n const alt = element.getAttribute(\"alt\");\n if (alt?.trim()) return alt.trim();\n\n if (element.id) {\n const label = document.querySelector(`label[for=\"${element.id}\"]`);\n if (label?.textContent?.trim()) return label.textContent.trim();\n }\n\n if (tag === \"input\") {\n const input = element as HTMLInputElement;\n const type = element.getAttribute(\"type\") || \"\";\n const value = element.getAttribute(\"value\");\n if (type === \"submit\" && value?.trim()) return value.trim();\n if (input.value && input.value.length < 50 && input.value.trim()) return input.value.trim();\n }\n\n if ([\"button\", \"a\", \"summary\"].includes(tag)) {\n const textContent = element.textContent || \"\";\n if (textContent.trim()) return textContent.trim();\n }\n\n if (/^h[1-6]$/.test(tag)) {\n const text = element.textContent;\n if (text?.trim()) {\n const t = text.trim();\n return t.length > 100 ? t.substring(0, 100) + \"...\" : t;\n }\n }\n\n if (tag === \"img\") return \"\";\n\n let directText = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n directText += node.textContent;\n }\n }\n if (directText?.trim() && directText.trim().length >= 3) {\n const text = directText.trim();\n return text.length > 100 ? text.substring(0, 100) + \"...\" : text;\n }\n\n return \"\";\n }\n\n interface AriaProps {\n checked?: boolean | 'mixed';\n disabled?: boolean;\n expanded?: boolean;\n level?: number;\n pressed?: boolean | 'mixed';\n selected?: boolean;\n active?: boolean;\n }\n\n function getAriaProps(element: Element): AriaProps {\n const props: AriaProps = {};\n \n const checkedAttr = element.getAttribute('aria-checked');\n if (checkedAttr === 'true') props.checked = true;\n else if (checkedAttr === 'false') props.checked = false;\n else if (checkedAttr === 'mixed') props.checked = 'mixed';\n else if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {\n if (element.type === 'checkbox' && element.indeterminate) {\n props.checked = 'mixed';\n } else {\n props.checked = element.checked;\n }\n }\n \n const isDisableable = element instanceof HTMLButtonElement || \n element instanceof HTMLInputElement || \n element instanceof HTMLSelectElement || \n element instanceof HTMLTextAreaElement;\n if (element.getAttribute('aria-disabled') === 'true' || \n (isDisableable && (element as HTMLButtonElement).disabled) ||\n element.closest('fieldset:disabled')) {\n props.disabled = true;\n }\n \n const expandedAttr = element.getAttribute('aria-expanded');\n if (expandedAttr === 'true') props.expanded = true;\n else if (expandedAttr === 'false') props.expanded = false;\n \n const pressedAttr = element.getAttribute('aria-pressed');\n if (pressedAttr === 'true') props.pressed = true;\n else if (pressedAttr === 'false') props.pressed = false;\n else if (pressedAttr === 'mixed') props.pressed = 'mixed';\n \n const selectedAttr = element.getAttribute('aria-selected');\n if (selectedAttr === 'true') props.selected = true;\n else if (selectedAttr === 'false') props.selected = false;\n \n const activeAttr = element.getAttribute('aria-current');\n if (activeAttr && activeAttr !== 'false') {\n props.active = true;\n }\n \n const tag = element.tagName.toLowerCase();\n if (/^h[1-6]$/.test(tag)) {\n props.level = parseInt(tag[1], 10);\n } else {\n const levelAttr = element.getAttribute('aria-level');\n if (levelAttr) props.level = parseInt(levelAttr, 10);\n }\n \n return props;\n }\n\n function formatAriaProps(props: AriaProps): string {\n const parts: string[] = [];\n \n if (props.checked !== undefined) {\n parts.push(props.checked === 'mixed' ? '[checked=mixed]' : props.checked ? '[checked]' : '[unchecked]');\n }\n if (props.disabled) parts.push('[disabled]');\n if (props.expanded !== undefined) {\n parts.push(props.expanded ? '[expanded]' : '[collapsed]');\n }\n if (props.pressed !== undefined) {\n parts.push(props.pressed === 'mixed' ? '[pressed=mixed]' : props.pressed ? '[pressed]' : '[not-pressed]');\n }\n if (props.selected !== undefined) {\n parts.push(props.selected ? '[selected]' : '[not-selected]');\n }\n if (props.active) parts.push('[active]');\n if (props.level !== undefined) {\n parts.push(`[level=${props.level}]`);\n }\n \n return parts.join(' ');\n }\n\n function isVisible(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return (\n style.display !== \"none\" &&\n style.visibility !== \"hidden\" &&\n style.opacity !== \"0\" &&\n (element as HTMLElement).offsetWidth > 0 &&\n (element as HTMLElement).offsetHeight > 0\n );\n }\n\n function isInteractive(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"a\", \"button\", \"input\", \"select\", \"textarea\", \"details\", \"summary\"].includes(tag) ||\n element.hasAttribute(\"onclick\") ||\n element.hasAttribute(\"tabindex\") ||\n element.getAttribute(\"role\") === \"button\" ||\n element.getAttribute(\"role\") === \"link\" ||\n element.getAttribute(\"contenteditable\") === \"true\"\n );\n }\n\n function isLandmark(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"nav\", \"main\", \"header\", \"footer\", \"section\", \"article\", \"aside\"].includes(tag) ||\n element.hasAttribute(\"role\")\n );\n }\n\n function hasCursorPointer(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return style.cursor === \"pointer\";\n }\n\n function buildKey(role: string, name: string, element: Element, ariaProps: AriaProps): string {\n let key = role;\n if (name) {\n key += ' ' + yamlEscapeValue(name);\n }\n \n const ref = getOrAssignRef(element, role, name);\n window.__piRefs![ref] = element;\n key += ` [ref=${ref}]`;\n \n const propsStr = formatAriaProps(ariaProps);\n if (propsStr) key += ` ${propsStr}`;\n \n if (hasCursorPointer(element)) {\n key += ' [cursor=pointer]';\n }\n \n return key;\n }\n\n function getElementProps(element: Element): Record<string, string> {\n const props: Record<string, string> = {};\n const href = element.getAttribute(\"href\");\n if (href) props.url = href;\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder) props.placeholder = placeholder;\n return props;\n }\n\n function traverse(element: Element, depth: number, parentIncluded: boolean): void {\n if (depth > maxDepth) return;\n \n const tag = element.tagName.toLowerCase();\n if ([\"script\", \"style\", \"meta\", \"link\", \"title\", \"noscript\"].includes(tag)) return;\n if (filter !== \"all\" && element.getAttribute(\"aria-hidden\") === \"true\") return;\n if (filter !== \"all\" && !isVisible(element)) return;\n \n if (filter !== \"all\") {\n const rect = element.getBoundingClientRect();\n if (!(rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0)) {\n return;\n }\n }\n \n const role = getRole(element);\n const name = getName(element);\n const ariaProps = getAriaProps(element);\n \n const isInteractiveEl = isInteractive(element);\n const isLandmarkEl = isLandmark(element);\n const hasName = name.length > 0;\n \n let include: boolean;\n if (filter === \"interactive\") {\n include = isInteractiveEl;\n } else if (filter === \"all\") {\n include = true;\n } else {\n include = isInteractiveEl || isLandmarkEl || hasName || (role !== \"generic\" && role !== \"img\");\n }\n \n if (include) {\n const indent = \" \".repeat(depth);\n const key = buildKey(role, name, element, ariaProps);\n const props = getElementProps(element);\n \n const children: Element[] = [];\n for (const child of element.children) {\n children.push(child);\n }\n \n const hasChildren = children.length > 0;\n const hasProps = Object.keys(props).length > 0;\n \n if (!hasChildren && !hasProps) {\n lines.push(`${indent}- ${key}`);\n } else {\n lines.push(`${indent}- ${key}:`);\n for (const [propName, propValue] of Object.entries(props)) {\n lines.push(`${indent} - /${propName}: ${yamlEscapeValue(propValue)}`);\n }\n for (const child of children) {\n traverse(child, depth + 1, true);\n }\n }\n } else {\n for (const child of element.children) {\n traverse(child, depth, parentIncluded);\n }\n }\n }\n\n traverse(document.body, 0, false);\n\n const yaml = lines.join('\\n');\n \n if (yaml.length > 50000) {\n return {\n error: `Output exceeds 50000 character limit (${yaml.length} characters). Try using filter=\"interactive\".`,\n yaml: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n\n return {\n yaml: yaml + `\\n\\n[Viewport: ${window.innerWidth}x${window.innerHeight}]`,\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n } catch (err) {\n return {\n error: `Error generating YAML tree: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n yaml: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n}\n\nfunction getElementCoordinates(ref: string): { x: number; y: number; error?: string } {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n let element: Element | undefined;\n \n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) {\n delete elementMap[ref];\n }\n }\n \n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n return { x: 0, y: 0, error: `Element ${ref} not found. Use read_page to get current elements.` };\n }\n\n const rect = element.getBoundingClientRect();\n const x = Math.round(rect.left + rect.width / 2);\n const y = Math.round(rect.top + rect.height / 2);\n\n return { x, y };\n}\n\nfunction setFormValue(ref: string, value: string | boolean | number): { success: boolean; error?: string } {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n let element: Element | undefined;\n \n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) {\n delete elementMap[ref];\n }\n }\n \n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n return { success: false, error: `Element ${ref} not found. Use read_page to get current elements.` };\n }\n\n const tagName = element.tagName.toLowerCase();\n\n try {\n if (tagName === \"input\") {\n const input = element as HTMLInputElement;\n const type = input.type.toLowerCase();\n\n if (type === \"checkbox\" || type === \"radio\") {\n input.checked = Boolean(value);\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else {\n input.value = String(value);\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n } else if (tagName === \"textarea\") {\n const textarea = element as HTMLTextAreaElement;\n textarea.value = String(value);\n textarea.dispatchEvent(new Event(\"input\", { bubbles: true }));\n textarea.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else if (tagName === \"select\") {\n const select = element as HTMLSelectElement;\n const strValue = String(value);\n\n let found = false;\n for (const option of select.options) {\n if (option.value === strValue || option.textContent?.trim() === strValue) {\n select.value = option.value;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return { success: false, error: `Option \"${value}\" not found in select element ${ref}` };\n }\n\n select.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else if (element.getAttribute(\"contenteditable\") === \"true\") {\n element.textContent = String(value);\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n } else {\n return { success: false, error: `Element ${ref} (${tagName}) is not a form field` };\n }\n\n return { success: true };\n } catch (err) {\n return { success: false, error: `Failed to set value: ${err instanceof Error ? err.message : \"Unknown error\"}` };\n }\n}\n\nfunction smartType(selector: string, text: string, clear = true, submit = false): { success: boolean; contentEditable?: boolean; error?: string } {\n try {\n const element = document.querySelector(selector) as HTMLElement | null;\n if (!element) return { success: false, error: `Element not found: ${selector}` };\n\n const contentEditableChild = element.querySelector<HTMLElement>('[contenteditable=\"true\"]');\n const target = contentEditableChild || element;\n const contentEditable = element.isContentEditable || !!contentEditableChild;\n target.focus();\n\n if (clear) {\n if (contentEditable) target.textContent = \"\";\n else (target as HTMLInputElement | HTMLTextAreaElement).value = \"\";\n }\n\n if (contentEditable) target.textContent = text;\n else (target as HTMLInputElement | HTMLTextAreaElement).value = text;\n\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\n if (submit) {\n const form = element.closest(\"form\");\n const submitButton = form?.querySelector<HTMLElement>('button[type=\"submit\"], input[type=\"submit\"]')\n || document.querySelector<HTMLElement>('button[type=\"submit\"], button[data-testid*=\"send\"], button[aria-label*=\"Send\"]');\n if (submitButton) submitButton.click();\n else if (form) form.dispatchEvent(new Event(\"submit\", { bubbles: true }));\n else target.dispatchEvent(new KeyboardEvent(\"keydown\", { key: \"Enter\", code: \"Enter\", keyCode: 13, bubbles: true }));\n }\n\n return { success: true, contentEditable };\n } catch (err) {\n return { success: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction truncateToUtf8Bytes(input: string, maxBytes: number): string {\n const encoder = new TextEncoder();\n const encoded = encoder.encode(input);\n if (encoded.length <= maxBytes) return input;\n let end = maxBytes;\n while (end > 0 && (encoded[end] & 0xc0) === 0x80) end--;\n return new TextDecoder(\"utf-8\", { fatal: false }).decode(encoded.subarray(0, end));\n}\n\nfunction getPageText(options: { maxBytes?: number } = {}): { text: string; title: string; url: string; error?: string } {\n try {\n const article = document.querySelector(\"article\");\n const main = document.querySelector(\"main\");\n const content = article || main || document.body;\n\n const normalized = content.textContent\n ?.replace(/\\s+/g, \" \")\n .trim() || \"\";\n const text = Number.isFinite(options.maxBytes) && options.maxBytes! > 0\n ? truncateToUtf8Bytes(normalized, options.maxBytes!)\n : normalized.substring(0, 50000);\n\n return {\n text,\n title: document.title,\n url: window.location.href,\n };\n } catch (err) {\n return {\n text: \"\",\n title: \"\",\n url: \"\",\n error: `Failed to extract text: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n };\n }\n}\n\nfunction scrollToElement(ref: string): { success: boolean; error?: string } {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n let element: Element | undefined;\n \n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) {\n delete elementMap[ref];\n }\n }\n \n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n return { success: false, error: `Element ${ref} not found. Run read_page to get current element refs.` };\n }\n\n element.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n return { success: true };\n}\n\nfunction uploadImage(\n base64: string,\n ref?: string,\n coordinate?: [number, number],\n filename: string = \"screenshot.png\"\n): { success: boolean; error?: string } {\n try {\n const byteString = atob(base64);\n const ab = new ArrayBuffer(byteString.length);\n const ia = new Uint8Array(ab);\n for (let i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n const blob = new Blob([ab], { type: \"image/png\" });\n const file = new File([blob], filename, { type: \"image/png\" });\n\n let targetElement: HTMLElement | null = null;\n\n if (ref) {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n \n if (elemRef) {\n targetElement = elemRef.element.deref() as HTMLElement | null;\n if (!targetElement) {\n delete elementMap[ref];\n }\n }\n \n if (!targetElement && window.__piRefs) {\n targetElement = window.__piRefs[ref] as HTMLElement | null;\n }\n \n if (!targetElement) {\n return { success: false, error: `Element ${ref} not found. Run read_page to get current element refs.` };\n }\n } else if (coordinate) {\n targetElement = document.elementFromPoint(coordinate[0], coordinate[1]) as HTMLElement | null;\n if (!targetElement) {\n return { success: false, error: `No element at (${coordinate[0]}, ${coordinate[1]})` };\n }\n }\n\n if (!targetElement) {\n return { success: false, error: \"No target element\" };\n }\n\n if (targetElement.tagName === \"INPUT\" && (targetElement as HTMLInputElement).type === \"file\") {\n const input = targetElement as HTMLInputElement;\n const dt = new DataTransfer();\n dt.items.add(file);\n input.files = dt.files;\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { success: true };\n }\n\n const dt = new DataTransfer();\n dt.items.add(file);\n\n const dropEvent = new DragEvent(\"drop\", {\n bubbles: true,\n cancelable: true,\n dataTransfer: dt,\n });\n\n targetElement.dispatchEvent(dropEvent);\n return { success: true };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : \"Upload failed\",\n };\n }\n}\n\nlet playbookWatch: { includeInputValues: boolean } | null = null;\n\nfunction watchSelector(element: Element): string {\n if (element.id) return `#${CSS.escape(element.id)}`;\n for (const name of [\"data-testid\", \"data-test-id\", \"name\", \"aria-label\"]) {\n const value = element.getAttribute(name);\n if (value) return `${element.tagName.toLowerCase()}[${name}=${JSON.stringify(value)}]`;\n }\n return element.tagName.toLowerCase();\n}\n\nfunction postWatchEvent(event: string, element?: Element, value?: string): void {\n if (!playbookWatch) return;\n chrome.runtime.sendMessage({\n type: \"PLAYBOOK_WATCH_EVENT\",\n event,\n selector: element ? watchSelector(element) : undefined,\n value,\n url: location.href,\n timestamp: new Date().toISOString(),\n }).catch(() => {});\n}\n\nif (typeof document.addEventListener === \"function\") {\n document.addEventListener(\"click\", (event) => {\n if (event.isTrusted && event.target instanceof Element) postWatchEvent(\"click\", event.target);\n }, true);\n document.addEventListener(\"change\", (event) => {\n if (!event.isTrusted || !(event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement || event.target instanceof HTMLSelectElement)) return;\n const target = event.target;\n const secret = target instanceof HTMLInputElement && target.type === \"password\";\n const value = playbookWatch?.includeInputValues && !secret ? target.value : \"<input>\";\n postWatchEvent(\"input\", target, value);\n }, true);\n}\nif (typeof window.addEventListener === \"function\") {\n window.addEventListener(\"popstate\", () => postWatchEvent(\"navigation\"));\n window.addEventListener(\"hashchange\", () => postWatchEvent(\"navigation\"));\n}\n\nchrome.runtime.onMessage.addListener((message, sender, sendResponse) => {\n switch (message.type) {\n case \"PLAYBOOK_WATCH_START\":\n playbookWatch = { includeInputValues: message.includeInputValues === true };\n sendResponse({ success: true });\n break;\n case \"PLAYBOOK_WATCH_STOP\":\n playbookWatch = null;\n sendResponse({ success: true });\n break;\n case \"SHOW_AGENT_INDICATORS\":\n case \"HIDE_AGENT_INDICATORS\":\n case \"HIDE_FOR_TOOL_USE\":\n case \"SHOW_AFTER_TOOL_USE\":\n case \"SHOW_STATIC_INDICATOR\":\n case \"HIDE_STATIC_INDICATOR\": {\n if (!window.__piVisualIndicatorMessageHandler) {\n sendResponse({ error: \"Visual indicator content script not loaded.\" });\n break;\n }\n window.__piVisualIndicatorMessageHandler(message.type as VisualIndicatorMessageType);\n sendResponse({ success: true });\n break;\n }\n case \"GENERATE_ACCESSIBILITY_TREE\": {\n const options = message.options || {};\n \n if (options.format === \"yaml\") {\n const result = generateYamlTree(\n options.filter || \"interactive\",\n options.depth ?? 15\n );\n const modalStates = detectModalStates();\n if (result.error) {\n sendResponse({ error: result.error, pageContent: \"\", viewport: result.viewport });\n } else {\n sendResponse({ \n pageContent: result.yaml, \n viewport: result.viewport,\n modalStates: modalStates.length > 0 ? modalStates : undefined,\n modalLimitations: 'Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts.',\n });\n }\n } else {\n const result = generateAccessibilityTree(\n options.filter || \"interactive\",\n options.depth ?? 15,\n options.refId,\n options.forceFullSnapshot ?? false,\n options.compact ?? false\n );\n sendResponse(result);\n }\n break;\n }\n case \"GET_ELEMENT_COORDINATES\": {\n const result = getElementCoordinates(message.ref);\n sendResponse(result);\n break;\n }\n case \"CLICK_ELEMENT\": {\n const elementMap = getElementMap();\n const elemRef = elementMap[message.ref];\n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[message.ref];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[message.ref];\n }\n if (!element) {\n sendResponse({ error: `Element ${message.ref} not found. Use read_page to get current elements.` });\n break;\n }\n if (message.button === \"triple\") {\n const tripleClick = new MouseEvent(\"click\", { bubbles: true, cancelable: true, view: window, detail: 3 });\n element.dispatchEvent(tripleClick);\n } else if (message.button === \"double\") {\n element.dispatchEvent(new MouseEvent(\"dblclick\", { bubbles: true, cancelable: true, view: window }));\n } else if (message.button === \"right\") {\n element.dispatchEvent(new MouseEvent(\"contextmenu\", { bubbles: true, cancelable: true, view: window }));\n } else {\n (element as HTMLElement).click();\n }\n sendResponse({ success: true });\n break;\n }\n case \"FORM_INPUT\": {\n const result = setFormValue(message.ref, message.value);\n sendResponse(result);\n break;\n }\n case \"EVAL_IN_PAGE\": {\n try {\n const script = document.createElement('script');\n script.textContent = `(function() { ${message.code} })();`;\n document.documentElement.appendChild(script);\n script.remove();\n sendResponse({ success: true });\n } catch (err) {\n sendResponse({ success: false, error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_PAGE_TEXT\": {\n const result = getPageText(message.options || {});\n sendResponse(result);\n break;\n }\n case \"SMART_TYPE\": {\n sendResponse(smartType(message.selector, message.text, message.clear, message.submit));\n break;\n }\n case \"GET_FRAME_BY_SELECTOR\": {\n try {\n const iframe = document.querySelector(message.selector) as HTMLIFrameElement;\n if (!iframe || iframe.tagName.toLowerCase() !== 'iframe') {\n sendResponse({ error: `No iframe found with selector \"${message.selector}\"` });\n break;\n }\n // Return what info we can - the service worker will match by URL or name\n sendResponse({ \n url: iframe.src,\n name: iframe.name || undefined,\n });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_FRAME_NAME\": {\n // Return this frame's name (for frame matching by name)\n try {\n sendResponse({ name: window.name || null });\n } catch (err) {\n sendResponse({ name: null });\n }\n break;\n }\n case \"LOCATE_ROLE\": {\n try {\n const { role, name, all } = message;\n const elementMap = getElementMap();\n \n // Mapping of role to possible selectors\n const implicitRoles: Record<string, string[]> = {\n button: ['button', 'input[type=\"button\"]', 'input[type=\"submit\"]', 'input[type=\"reset\"]', '[role=\"button\"]'],\n link: ['a[href]', '[role=\"link\"]'],\n textbox: ['input:not([type])', 'input[type=\"text\"]', 'input[type=\"email\"]', 'input[type=\"password\"]', 'input[type=\"search\"]', 'input[type=\"tel\"]', 'input[type=\"url\"]', 'textarea', '[role=\"textbox\"]'],\n checkbox: ['input[type=\"checkbox\"]', '[role=\"checkbox\"]'],\n radio: ['input[type=\"radio\"]', '[role=\"radio\"]'],\n combobox: ['select', '[role=\"combobox\"]'],\n listbox: ['[role=\"listbox\"]', 'select[multiple]'],\n option: ['option', '[role=\"option\"]'],\n heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', '[role=\"heading\"]'],\n navigation: ['nav', '[role=\"navigation\"]'],\n main: ['main', '[role=\"main\"]'],\n img: ['img[alt]', '[role=\"img\"]'],\n dialog: ['dialog', '[role=\"dialog\"]', '[role=\"alertdialog\"]'],\n tab: ['[role=\"tab\"]'],\n tabpanel: ['[role=\"tabpanel\"]'],\n menu: ['[role=\"menu\"]'],\n menuitem: ['[role=\"menuitem\"]'],\n };\n \n // Build selectors for the role\n const selectors = implicitRoles[role] || [`[role=\"${role}\"]`];\n const candidates: Element[] = [];\n \n for (const sel of selectors) {\n try {\n candidates.push(...document.querySelectorAll(sel));\n } catch {}\n }\n \n // Filter by visibility\n const visible = candidates.filter(el => {\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && \n style.visibility !== 'hidden' && \n (el as HTMLElement).offsetWidth > 0 &&\n (el as HTMLElement).offsetHeight > 0;\n });\n \n // Filter by name if provided\n let matches = visible;\n if (name) {\n const lowerName = name.toLowerCase();\n matches = visible.filter(el => {\n const ariaLabel = el.getAttribute('aria-label')?.toLowerCase();\n const text = el.textContent?.trim().toLowerCase();\n const title = el.getAttribute('title')?.toLowerCase();\n const placeholder = (el as HTMLInputElement).placeholder?.toLowerCase();\n const value = (el as HTMLInputElement).value?.toLowerCase();\n \n return ariaLabel?.includes(lowerName) || \n text?.includes(lowerName) || \n title?.includes(lowerName) ||\n placeholder?.includes(lowerName) ||\n value?.includes(lowerName);\n });\n }\n \n if (matches.length === 0) {\n sendResponse({ error: `No element found with role \"${role}\"${name ? ` and name \"${name}\"` : ''}` });\n break;\n }\n \n // Generate refs for matches\n const results = matches.map(el => {\n const ref = getOrAssignRef(el, role, name || '');\n window.__piRefs = window.__piRefs || {};\n window.__piRefs[ref] = el;\n elementMap[ref] = { element: new WeakRef(el), role, name: name || '' };\n return { ref, text: el.textContent?.trim().slice(0, 50) };\n });\n \n if (all) {\n sendResponse({ matches: results });\n } else {\n sendResponse({ ref: results[0].ref, text: results[0].text });\n }\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"LOCATE_TEXT\": {\n try {\n const { text, exact } = message;\n const elementMap = getElementMap();\n \n // Find elements containing the text\n const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);\n const matches: Element[] = [];\n \n while (walker.nextNode()) {\n const nodeText = walker.currentNode.textContent || '';\n const hasMatch = exact \n ? nodeText.trim() === text \n : nodeText.toLowerCase().includes(text.toLowerCase());\n \n if (hasMatch) {\n const parent = walker.currentNode.parentElement;\n if (parent && !matches.includes(parent)) {\n // Check visibility\n const style = window.getComputedStyle(parent);\n if (style.display !== 'none' && style.visibility !== 'hidden') {\n matches.push(parent);\n }\n }\n }\n }\n \n if (matches.length === 0) {\n sendResponse({ error: `No element found with text \"${text}\"` });\n break;\n }\n \n // Pick the most specific (smallest) element\n const el = matches.sort((a, b) => \n (a.textContent?.length || 0) - (b.textContent?.length || 0)\n )[0];\n \n const role = getResolvedRole(el);\n const ref = getOrAssignRef(el, role, text);\n window.__piRefs = window.__piRefs || {};\n window.__piRefs[ref] = el;\n elementMap[ref] = { element: new WeakRef(el), role, name: text };\n \n sendResponse({ ref, text: el.textContent?.trim().slice(0, 50) });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"LOCATE_LABEL\": {\n try {\n const { label } = message;\n const elementMap = getElementMap();\n \n // Find label element\n const labels = document.querySelectorAll('label');\n let input: Element | null = null;\n \n for (const lbl of labels) {\n const lblText = lbl.textContent?.trim().toLowerCase();\n if (lblText?.includes(label.toLowerCase())) {\n // Check for 'for' attribute\n const forId = lbl.getAttribute('for');\n if (forId) {\n input = document.getElementById(forId);\n }\n // Check for nested input\n if (!input) {\n input = lbl.querySelector('input, select, textarea');\n }\n if (input) break;\n }\n }\n \n // Also check aria-label and placeholder\n if (!input) {\n const lowerLabel = label.toLowerCase();\n input = document.querySelector(\n `input[aria-label*=\"${label}\" i], input[placeholder*=\"${label}\" i], ` +\n `textarea[aria-label*=\"${label}\" i], textarea[placeholder*=\"${label}\" i], ` +\n `select[aria-label*=\"${label}\" i]`\n );\n }\n \n if (!input) {\n sendResponse({ error: `No form field found with label \"${label}\"` });\n break;\n }\n \n const role = getResolvedRole(input);\n const ref = getOrAssignRef(input, role, label);\n window.__piRefs = window.__piRefs || {};\n window.__piRefs[ref] = input;\n elementMap[ref] = { element: new WeakRef(input), role, name: label };\n \n sendResponse({ ref, label });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_ELEMENT_STYLES\": {\n try {\n const { selector } = message;\n const elementMap = getElementMap();\n \n // Helper to extract styles from an element\n const extractStyles = (el: Element) => {\n const s = getComputedStyle(el);\n const r = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n text: (el as HTMLElement).innerText?.trim().slice(0, 80) || null,\n box: {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n },\n styles: {\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n fontFamily: s.fontFamily.split(',')[0].trim().replace(/\"/g, ''),\n color: s.color,\n backgroundColor: s.backgroundColor,\n borderRadius: s.borderRadius,\n border: s.border !== 'none' && s.borderWidth !== '0px' ? s.border : null,\n boxShadow: s.boxShadow !== 'none' ? s.boxShadow : null,\n padding: s.padding,\n },\n };\n };\n \n // Check if selector is a ref (e.g., \"e5\")\n if (/^e\\d+$/.test(selector)) {\n const elemRef = elementMap[selector];\n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[selector];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[selector];\n }\n \n if (!element) {\n sendResponse({ error: `Element ${selector} not found` });\n break;\n }\n \n sendResponse({ styles: [extractStyles(element)] });\n } else {\n // CSS selector - can match multiple elements\n const elements = document.querySelectorAll(selector);\n if (elements.length === 0) {\n sendResponse({ error: `No elements found matching \"${selector}\"` });\n break;\n }\n \n const styles = Array.from(elements).map(extractStyles);\n sendResponse({ styles });\n }\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"SELECT_OPTION\": {\n try {\n const { selector, values, by } = message;\n const elementMap = getElementMap();\n \n // Find the select element\n let selectEl: HTMLSelectElement | null = null;\n \n if (/^e\\d+$/.test(selector)) {\n const elemRef = elementMap[selector];\n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[selector];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[selector];\n }\n \n if (!element) {\n sendResponse({ error: `Element ${selector} not found` });\n break;\n }\n if (element.tagName !== 'SELECT') {\n sendResponse({ error: `Element ${selector} is not a <select>` });\n break;\n }\n selectEl = element as HTMLSelectElement;\n } else {\n selectEl = document.querySelector(selector) as HTMLSelectElement;\n if (!selectEl) {\n sendResponse({ error: `No element found matching \"${selector}\"` });\n break;\n }\n if (selectEl.tagName !== 'SELECT') {\n sendResponse({ error: `Element \"${selector}\" is not a <select>` });\n break;\n }\n }\n \n // Clear current selection for multi-select\n if (selectEl.multiple) {\n for (const opt of selectEl.options) {\n opt.selected = false;\n }\n }\n \n const selected: string[] = [];\n const notFound: string[] = [];\n \n // For single-select, only use the first value\n const valuesToSelect = selectEl.multiple ? values : [values[0]];\n \n for (const val of valuesToSelect) {\n let found = false;\n \n for (const opt of selectEl.options) {\n let matches = false;\n \n if (by === 'index') {\n matches = opt.index === parseInt(val, 10);\n } else if (by === 'label') {\n matches = opt.text.toLowerCase().includes(val.toLowerCase());\n } else {\n // Default: match by value\n matches = opt.value === val;\n }\n \n if (matches) {\n opt.selected = true;\n selected.push(opt.value);\n found = true;\n break; // Found match for this value, move to next\n }\n }\n \n if (!found) notFound.push(val);\n }\n \n // Dispatch change event\n selectEl.dispatchEvent(new Event('change', { bubbles: true }));\n \n if (notFound.length > 0) {\n sendResponse({ \n selected, \n warning: `Values not found: ${notFound.join(', ')}` \n });\n } else {\n sendResponse({ selected });\n }\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_ELEMENT_TEXT\": {\n try {\n const { ref } = message;\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n \n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[ref];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n sendResponse({ error: `Element ${ref} not found` });\n break;\n }\n \n sendResponse({ text: element.textContent?.trim() || '' });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"SCROLL_TO_ELEMENT\": {\n const result = scrollToElement(message.ref);\n sendResponse(result);\n break;\n }\n case \"UPLOAD_IMAGE\": {\n const result = uploadImage(message.base64, message.ref, message.coordinate, message.filename);\n sendResponse(result);\n break;\n }\n case \"WAIT_FOR_ELEMENT\": {\n const { selector, state = 'visible', timeout = 20000 } = message;\n const maxTimeout = Math.min(timeout, 60000);\n\n const isElementVisible = (el: Element | null): boolean => {\n if (!el) return false;\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && \n style.visibility !== 'hidden' && \n style.opacity !== '0' &&\n (el as HTMLElement).offsetWidth > 0 &&\n (el as HTMLElement).offsetHeight > 0;\n };\n\n const checkElement = (): boolean => {\n const el = document.querySelector(selector);\n switch (state) {\n case 'attached': return !!el;\n case 'detached': return !el;\n case 'hidden': return !el || !isElementVisible(el);\n case 'visible':\n default: return isElementVisible(el);\n }\n };\n\n const startTime = Date.now();\n \n const waitForCondition = (): Promise<{ success: boolean; waited: number; error?: string }> => {\n return new Promise((resolve) => {\n if (checkElement()) {\n resolve({ success: true, waited: Date.now() - startTime });\n return;\n }\n\n const observer = new MutationObserver(() => {\n if (checkElement()) {\n observer.disconnect();\n clearTimeout(timeoutId);\n resolve({ success: true, waited: Date.now() - startTime });\n }\n });\n\n const timeoutId = setTimeout(() => {\n observer.disconnect();\n resolve({ \n success: false, \n waited: Date.now() - startTime,\n error: `Timeout waiting for \"${selector}\" to be ${state}` \n });\n }, maxTimeout);\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'class', 'hidden', 'disabled']\n });\n });\n };\n\n waitForCondition().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({ \n error: waitResult.error, \n waited: waitResult.waited,\n pageContent: \"\", \n viewport: { width: window.innerWidth, height: window.innerHeight } \n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"WAIT_FOR_URL\": {\n const { pattern, timeout = 20000 } = message;\n const maxTimeout = Math.min(timeout, 60000);\n\n const matchesPattern = (url: string): boolean => {\n if (pattern.includes('*')) {\n const regexPattern = pattern\n .replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<<GLOBSTAR>>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<<GLOBSTAR>>>/g, '.*');\n return new RegExp(`^${regexPattern}$`).test(url);\n }\n return url.includes(pattern);\n };\n\n const startTime = Date.now();\n\n const waitForUrl = (): Promise<{ success: boolean; waited: number; error?: string }> => {\n return new Promise((resolve) => {\n if (matchesPattern(window.location.href)) {\n resolve({ success: true, waited: Date.now() - startTime });\n return;\n }\n\n let resolved = false;\n const checkUrl = () => {\n if (resolved) return;\n if (matchesPattern(window.location.href)) {\n resolved = true;\n clearInterval(intervalId);\n clearTimeout(timeoutId);\n window.removeEventListener('popstate', checkUrl);\n window.removeEventListener('hashchange', checkUrl);\n resolve({ success: true, waited: Date.now() - startTime });\n }\n };\n\n const intervalId = setInterval(checkUrl, 100);\n const timeoutId = setTimeout(() => {\n if (resolved) return;\n resolved = true;\n clearInterval(intervalId);\n window.removeEventListener('popstate', checkUrl);\n window.removeEventListener('hashchange', checkUrl);\n resolve({ \n success: false, \n waited: Date.now() - startTime,\n error: `Timeout waiting for URL to match \"${pattern}\". Current: ${window.location.href}` \n });\n }, maxTimeout);\n\n window.addEventListener('popstate', checkUrl);\n window.addEventListener('hashchange', checkUrl);\n });\n };\n\n waitForUrl().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({ \n error: waitResult.error, \n waited: waitResult.waited,\n pageContent: \"\", \n viewport: { width: window.innerWidth, height: window.innerHeight } \n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"WAIT_FOR_DOM_STABLE\": {\n const { stable = 100, timeout = 5000 } = message;\n const maxTimeout = Math.min(timeout, 30000);\n const startTime = Date.now();\n\n const waitForStability = (): Promise<{ success: boolean; waited: number; error?: string }> => {\n return new Promise((resolve) => {\n let lastMutationTime = Date.now();\n let resolved = false;\n\n const checkStability = () => {\n if (resolved) return;\n const timeSinceLastMutation = Date.now() - lastMutationTime;\n if (timeSinceLastMutation >= stable) {\n resolved = true;\n observer.disconnect();\n clearTimeout(timeoutId);\n clearInterval(checkInterval);\n resolve({ success: true, waited: Date.now() - startTime });\n }\n };\n\n const observer = new MutationObserver(() => {\n lastMutationTime = Date.now();\n });\n\n const timeoutId = setTimeout(() => {\n if (resolved) return;\n resolved = true;\n observer.disconnect();\n clearInterval(checkInterval);\n resolve({\n success: false,\n waited: Date.now() - startTime,\n error: `Timeout: DOM did not stabilize within ${maxTimeout}ms`\n });\n }, maxTimeout);\n\n const checkInterval = setInterval(checkStability, Math.max(10, Math.min(50, stable / 2)));\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n checkStability();\n });\n };\n\n waitForStability().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({\n error: waitResult.error,\n waited: waitResult.waited,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight }\n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"FORM_FILL\": {\n const { data } = message;\n if (!Array.isArray(data)) {\n sendResponse({ error: \"data must be an array of {ref, value} pairs\" });\n return true;\n }\n const elementMap = getElementMap();\n const results: { ref: string; success: boolean; error?: string }[] = [];\n for (const item of data) {\n const { ref, value } = item;\n if (!ref) {\n results.push({ ref: ref || \"unknown\", success: false, error: \"Missing ref\" });\n continue;\n }\n const elemRef = elementMap[ref];\n if (!elemRef) {\n results.push({ ref, success: false, error: \"Element not found (run page.read first)\" });\n continue;\n }\n const el = elemRef.element.deref() as HTMLElement | null;\n if (!el) {\n delete elementMap[ref];\n results.push({ ref, success: false, error: \"Element no longer exists\" });\n continue;\n }\n try {\n if (el instanceof HTMLInputElement) {\n const inputType = el.type.toLowerCase();\n if (inputType === \"checkbox\" || inputType === \"radio\") {\n const shouldCheck = value === true || value === \"true\" || value === \"1\" || value === \"checked\";\n el.checked = shouldCheck;\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else {\n el.focus();\n el.value = String(value);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n results.push({ ref, success: true });\n } else if (el instanceof HTMLTextAreaElement) {\n el.focus();\n el.value = String(value);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n results.push({ ref, success: true });\n } else if (el instanceof HTMLSelectElement) {\n el.value = String(value);\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n results.push({ ref, success: true });\n } else if (el.isContentEditable) {\n el.focus();\n el.textContent = String(value);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n results.push({ ref, success: true });\n } else {\n results.push({ ref, success: false, error: \"Element is not fillable\" });\n }\n } catch (e) {\n results.push({ ref, success: false, error: e instanceof Error ? e.message : String(e) });\n }\n }\n const failed = results.filter(r => !r.success);\n sendResponse({\n success: failed.length === 0,\n filled: results.filter(r => r.success).length,\n failed: failed.length,\n results,\n });\n return true;\n }\n case \"GET_FILE_INPUT_SELECTOR\": {\n const { ref } = message;\n if (!ref) {\n sendResponse({ error: \"No ref provided\" });\n return true;\n }\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n if (!elemRef) {\n sendResponse({ error: \"Element not found (run page.read first)\" });\n return true;\n }\n const el = elemRef.element.deref() as HTMLElement | null;\n if (!el) {\n delete elementMap[ref];\n sendResponse({ error: \"Element no longer exists\" });\n return true;\n }\n if (!(el instanceof HTMLInputElement) || el.type !== \"file\") {\n sendResponse({ error: \"Element is not a file input\" });\n return true;\n }\n const uniqueId = `__pi_file_${Date.now()}`;\n el.setAttribute(\"data-pi-file-id\", uniqueId);\n sendResponse({ selector: `[data-pi-file-id=\"${uniqueId}\"]` });\n return true;\n }\n case \"WAIT_FOR_NETWORK_IDLE\": {\n const { timeout = 10000 } = message;\n const maxTimeout = Math.min(timeout, 60000);\n\n const adPatterns = [\n \"doubleclick.net\", \"googlesyndication.com\", \"googletagmanager.com\",\n \"google-analytics.com\", \"facebook.net\", \"connect.facebook.net\",\n \"analytics\", \"ads\", \"tracking\", \"pixel\", \"hotjar.com\", \"clarity.ms\",\n \"mixpanel.com\", \"segment.com\", \"newrelic.com\", \"nr-data.net\",\n \"/tracker/\", \"/collector/\", \"/beacon/\", \"/telemetry/\", \"/log/\",\n \"/events/\", \"/track.\", \"/metrics/\"\n ];\n\n const nonCriticalTypes = [\"img\", \"image\", \"font\", \"icon\"];\n\n const isAdOrTracking = (url: string): boolean => {\n return adPatterns.some(pattern => url.includes(pattern));\n };\n\n const isNonCritical = (entry: PerformanceResourceTiming): boolean => {\n const type = entry.initiatorType || \"unknown\";\n if (nonCriticalTypes.includes(type)) return true;\n if (/\\.(jpg|jpeg|png|gif|webp|svg|ico|woff|woff2|ttf|eot)(\\?|$)/i.test(entry.name)) return true;\n return false;\n };\n\n const getPendingRequests = (): PerformanceResourceTiming[] => {\n const now = performance.now();\n const resources = performance.getEntriesByType(\"resource\") as PerformanceResourceTiming[];\n return resources.filter(entry => {\n if (entry.responseEnd !== 0) return false;\n if (entry.name.startsWith(\"data:\")) return false;\n if (entry.name.length > 500) return false;\n if (isAdOrTracking(entry.name)) return false;\n const loadingDuration = now - entry.startTime;\n if (loadingDuration > 10000) return false;\n if (isNonCritical(entry) && loadingDuration > 3000) return false;\n return true;\n });\n };\n\n const startTime = Date.now();\n\n const waitForIdle = (): Promise<{ success: boolean; waited: number; pendingCount?: number }> => {\n return new Promise((resolve) => {\n const check = () => {\n const pending = getPendingRequests();\n const elapsed = Date.now() - startTime;\n \n if (pending.length === 0) {\n resolve({ success: true, waited: elapsed });\n return;\n }\n \n if (elapsed >= maxTimeout) {\n resolve({ success: false, waited: elapsed, pendingCount: pending.length });\n return;\n }\n \n setTimeout(check, 100);\n };\n check();\n });\n };\n\n waitForIdle().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({ \n error: `Network not idle after ${waitResult.waited}ms (${waitResult.pendingCount} requests pending)`,\n waited: waitResult.waited,\n pageContent: \"\", \n viewport: { width: window.innerWidth, height: window.innerHeight } \n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"SEARCH_PAGE\": {\n const { term, caseSensitive, limit } = message;\n const matches = searchPageText(term, caseSensitive || false, limit || 10);\n sendResponse({ query: term, count: matches.length, matches });\n break;\n }\n case \"GET_ELEMENT_BOUNDS_FOR_ANNOTATION\": {\n const elementMap = getElementMap();\n const elements: Array<{ ref: string; tag: string; bounds: { x: number; y: number; width: number; height: number } }> = [];\n \n for (const [ref, entry] of Object.entries(elementMap)) {\n const el = entry.element.deref();\n if (!el) continue;\n \n const rect = el.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) continue;\n if (rect.bottom < 0 || rect.top > window.innerHeight) continue;\n if (rect.right < 0 || rect.left > window.innerWidth) continue;\n \n elements.push({\n ref,\n tag: el.tagName.toLowerCase(),\n bounds: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n },\n });\n }\n \n sendResponse({ elements });\n break;\n }\n default:\n return false;\n }\n return false;\n});\n\nfunction searchPageText(term: string, caseSensitive: boolean, limit: number) {\n const matches: Array<{\n ref: string;\n text: string;\n context: string;\n bounds: { x: number; y: number; width: number; height: number };\n elementRef: string | null;\n }> = [];\n \n const searchTerm = caseSensitive ? term : term.toLowerCase();\n const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);\n const elementMap = getElementMap();\n let matchIndex = 0;\n \n while (walker.nextNode() && matches.length < limit) {\n const node = walker.currentNode;\n const textContent = node.textContent || \"\";\n const searchIn = caseSensitive ? textContent : textContent.toLowerCase();\n \n let pos = 0;\n while ((pos = searchIn.indexOf(searchTerm, pos)) !== -1 && matches.length < limit) {\n const parent = node.parentElement;\n if (!parent) { pos++; continue; }\n \n const range = document.createRange();\n range.setStart(node, pos);\n range.setEnd(node, Math.min(pos + term.length, textContent.length));\n const rect = range.getBoundingClientRect();\n \n if (rect.width === 0 || rect.height === 0) { pos++; continue; }\n \n const fullText = node.textContent || \"\";\n const contextStart = Math.max(0, pos - 30);\n const contextEnd = Math.min(fullText.length, pos + term.length + 30);\n const context = fullText.slice(contextStart, contextEnd).trim();\n \n let elementRef: string | null = null;\n for (const [ref, entry] of Object.entries(elementMap)) {\n const el = entry.element.deref();\n if (el && (el === parent || el.contains(parent))) {\n elementRef = ref;\n break;\n }\n }\n \n matches.push({\n ref: `m${++matchIndex}`,\n text: fullText.slice(pos, pos + term.length),\n context,\n bounds: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n },\n elementRef,\n });\n \n pos++;\n }\n }\n \n return matches;\n}\n"],"mappings":"AAcA,IAAM,EAAW,eACX,EAA6B,IAE/B,EAAoC,KACpC,EAAoC,KACpC,EAAyC,KACzC,EAAW,GACX,EAAiB,GACjB,EAAyB,GACzB,EAA+B,GAC/B,EAAqC,KACrC,EAAsB,EACtB,EAA0B,GAC1B,EAA+B,GAC7B,EAAa,SAAW,OAAO,IAEjC,IACF,OAAO,QAAQ,MAAM,IAAI,mBAAmB,CAAC,CAAC,MAAM,CAAE,uBAAwB,CACxE,GAAqB,OAAO,GAAsB,WACpD,EAAsB,EAAoB,IAE9C,CAAC,EAED,OAAO,QAAQ,UAAU,aAAa,EAAS,IAAa,CAC1D,GAAI,IAAa,SAAW,EAAQ,kBAAmB,CACrD,IAAM,EAAW,EAAQ,kBAAkB,SACvC,GAAY,OAAO,GAAa,WAClC,EAAsB,EAAW,IAC7B,GAAkB,IACpB,cAAc,CAAmB,EACjC,EAAe,GAGrB,CACF,CAAC,GAGH,SAAS,GAAiB,CACxB,EAAsB,OAAO,YAAY,SAAY,CACnD,GAAI,EAEG,MADkB,OAAO,QAAQ,YAAY,CAAE,KAAM,4BAA6B,CAAC,EAAA,EACzE,SAAS,EAAoB,CAC9C,MAAQ,CACN,EAAoB,CACtB,CACF,EAAG,CAAmB,CACxB,CAEA,SAAS,GAAe,CACtB,GAAI,SAAS,eAAe,iBAAiB,EAAG,OAEhD,IAAM,EAAQ,SAAS,cAAc,OAAO,EAC5C,EAAM,GAAK,kBACX,EAAM,YAAc;;;;gCAIU,EAAS;gCACT,EAAS;gCACT,EAAS;;;;gCAIT,EAAS;gCACT,EAAS;gCACT,EAAS;;;;gCAIT,EAAS;gCACT,EAAS;gCACT,EAAS;;;IAIvC,SAAS,KAAK,YAAY,CAAK,CACjC,CAEA,SAAS,GAAmC,CAC1C,IAAM,EAAK,SAAS,cAAc,KAAK,EAkBvC,MAjBA,GAAG,GAAK,gBACR,EAAG,MAAM,QAAU;;;;;;;;;;;;4BAYO,EAAS;4BACT,EAAS;4BACT,EAAS;IAE5B,CACT,CAEA,SAAS,GAAmC,CAC1C,IAAM,EAAY,SAAS,cAAc,KAAK,EAC9C,EAAU,GAAK,0BACf,EAAU,MAAM,QAAU;;;;;;;;;;IAY1B,IAAM,EAAS,SAAS,cAAc,QAAQ,EA+C9C,MA9CA,GAAO,GAAK,uBACZ,EAAO,UAAY;;;;;IAMnB,EAAO,MAAM,QAAU;;;;;;;;;;;;;;;;yBAgBA,EAAS;wBACV,EAAS;;;;;;;IAS/B,EAAO,iBAAiB,iBAAoB,CACtC,IAAU,EAAO,MAAM,WAAa,UAC1C,CAAC,EAED,EAAO,iBAAiB,iBAAoB,CACtC,IAAU,EAAO,MAAM,WAAa,UAC1C,CAAC,EAED,EAAO,iBAAiB,QAAS,SAAY,CAC3C,MAAM,OAAO,QAAQ,YAAY,CAAE,KAAM,aAAc,UAAW,aAAc,CAAC,CACnF,CAAC,EAED,EAAU,YAAY,CAAM,EACrB,CACT,CAEA,SAAS,GAAwC,CAC/C,IAAM,EAAY,SAAS,cAAc,KAAK,EAC9C,EAAU,GAAK,4BACf,EAAU,UAAY;;8CAEsB,EAAS;;;;;;;;;;;;;;;IAgBrD,EAAU,MAAM,QAAU;;;;;;;;;;;;;;;;;IAmB1B,IAAM,EAAa,EAAU,cAAc,wBAAwB,EAC7D,EAAc,EAAU,cAAc,yBAAyB,EAqBrE,OAnBI,IACF,EAAW,MAAM,cAAgB,OACjC,EAAW,iBAAiB,iBAAoB,EAAW,MAAM,WAAa,SAAS,EACvF,EAAW,iBAAiB,iBAAoB,EAAW,MAAM,WAAa,aAAa,EAC3F,EAAW,iBAAiB,QAAS,SAAY,CAC/C,MAAM,OAAO,QAAQ,YAAY,CAAE,KAAM,gBAAiB,CAAC,CAC7D,CAAC,GAGC,IACF,EAAY,MAAM,cAAgB,OAClC,EAAY,iBAAiB,iBAAoB,EAAY,MAAM,WAAa,SAAS,EACzF,EAAY,iBAAiB,iBAAoB,EAAY,MAAM,WAAa,aAAa,EAC7F,EAAY,iBAAiB,QAAS,SAAY,CAChD,MAAM,OAAO,QAAQ,YAAY,CAAE,KAAM,0BAA2B,CAAC,EACrE,EAAoB,CACtB,CAAC,GAGI,CACT,CAEA,SAAS,GAAiB,CACxB,GAAI,CAAC,SAAS,KAAM,CACb,IACH,EAA0B,GAC1B,OAAO,iBACL,uBACM,CACC,IACL,EAA0B,GAC1B,EAAe,EACjB,EACA,CAAE,KAAM,EAAK,CACf,GAEF,MACF,CACA,EAA0B,GACtB,KACJ,EAAW,GAEX,EAAa,EAER,EAIH,EAAW,MAAM,QAAU,IAH3B,EAAa,EAAiB,EAC9B,SAAS,KAAK,YAAY,CAAU,GAKjC,EAIH,EAAW,MAAM,QAAU,IAH3B,EAAa,EAAiB,EAC9B,SAAS,KAAK,YAAY,CAAU,GAKtC,0BAA4B,CAE1B,GADI,IAAY,EAAW,MAAM,QAAU,KACvC,EAAY,CACd,IAAM,EAAM,EAAW,cAAc,uBAAuB,EACxD,IACF,EAAI,MAAM,UAAY,gBACtB,EAAI,MAAM,QAAU,IAExB,CACF,CAAC,EACH,CAEA,SAAS,GAAiB,CACxB,KAA0B,GACrB,EAIL,IAHA,EAAW,GAEP,IAAY,EAAW,MAAM,QAAU,KACvC,EAAY,CACd,IAAM,EAAM,EAAW,cAAc,uBAAuB,EACxD,IACF,EAAI,MAAM,UAAY,oBACtB,EAAI,MAAM,QAAU,IAExB,CAEA,eAAiB,CACV,IACC,GAAY,aACd,EAAW,WAAW,YAAY,CAAU,EAC5C,EAAa,MAEX,GAAY,aACd,EAAW,WAAW,YAAY,CAAU,EAC5C,EAAa,MAGnB,EAAG,GAAG,CAbN,CAcF,CAEA,SAAS,GAAsB,CAC7B,GAAI,CAAC,SAAS,KAAM,CACb,IACH,EAA+B,GAC/B,OAAO,iBACL,uBACM,CACC,IACL,EAA+B,GAC/B,EAAoB,EACtB,EACA,CAAE,KAAM,EAAK,CACf,GAEF,MACF,CACA,EAA+B,GAC3B,KACJ,EAAiB,GAEZ,EAIH,EAAgB,MAAM,QAAU,IAHhC,EAAkB,EAAsB,EACxC,SAAS,KAAK,YAAY,CAAe,GAKvC,GAAqB,cAAc,CAAmB,EAC1D,EAAe,EACjB,CAEA,SAAS,GAAsB,CAC7B,EAA+B,GAC1B,IACL,EAAiB,GAEjB,AAEE,KADA,cAAc,CAAmB,EACX,MAGpB,GAAiB,aACnB,EAAgB,WAAW,YAAY,CAAe,EACtD,EAAkB,MAEtB,CAEI,IACF,OAAO,kCAAqC,GAAS,CACnD,OAAQ,EAAR,CACE,IAAK,wBACH,EAAe,EACf,MACF,IAAK,wBACH,EAAe,EACf,MACF,IAAK,oBACH,EAAyB,GAAY,EACrC,EAA+B,GAAkB,EACjD,EAA0B,GAC1B,EAA+B,GAC3B,IAAY,EAAW,MAAM,QAAU,QACvC,IAAY,EAAW,MAAM,QAAU,QACvC,GAAmB,IAAgB,EAAgB,MAAM,QAAU,QACvE,MACF,IAAK,sBACC,IACE,GACE,IAAY,EAAW,MAAM,QAAU,IACvC,IAAY,EAAW,MAAM,QAAU,KAE3C,EAAe,GAGf,IACE,GAAkB,EACpB,EAAgB,MAAM,QAAU,GAEhC,EAAoB,GAGxB,EAAyB,GACzB,EAA+B,GAC/B,MACF,IAAK,wBACH,EAAoB,EACpB,MACF,IAAK,wBACH,EAAoB,CAExB,CACF,EAEA,OAAO,iBAAiB,mBAAsB,CAC5C,EAAe,EACf,EAAoB,CACtB,CAAC,GC5YH,IAAM,EAAmB,IAAI,IAAI,0qBAajC,CAAC,EAED,SAAS,EAAY,EAA2B,CAC9C,IAAM,EAAU,EAAQ,QAAQ,YAAY,EAC5C,GAAI,CAAC,SAAU,QAAS,SAAU,UAAU,CAAC,CAAC,SAAS,CAAO,EAC5D,MAAO,CAAE,EAA8B,SAEzC,GAAI,IAAY,KAAO,EAAQ,aAAa,MAAM,EAAG,MAAO,GAC5D,GAAI,EAAQ,aAAa,UAAU,EAAG,CACpC,IAAM,EAAW,SAAS,EAAQ,aAAa,UAAU,GAAK,GAAI,EAAE,EACpE,MAAO,CAAC,MAAM,CAAQ,GAAK,GAAY,CACzC,CAEA,OADI,EAAQ,aAAa,iBAAiB,IAAM,MAElD,CAEA,SAAS,EAAgB,EAAiC,CACxD,IAAM,EAAW,EAAQ,aAAa,MAAM,EAC5C,GAAI,CAAC,EAAU,OAAO,KACtB,IAAM,EAAQ,EAAS,MAAM,KAAK,CAAC,CAAC,OAAO,GAAK,CAAC,EACjD,IAAK,IAAM,KAAQ,EACjB,GAAI,EAAiB,IAAI,CAAI,EAC3B,OAAO,EAGX,OAAO,IACT,CAEA,SAAS,EAAgB,EAA0B,CACjD,IAAM,EAAM,EAAQ,QAAQ,YAAY,EAClC,EAAO,EAAQ,aAAa,MAAM,EAElC,EAA+D,CACnE,EAAI,GAAO,EAAG,aAAa,MAAM,EAAI,OAAS,UAC9C,QAAS,UACT,MAAO,gBACP,OAAQ,SACR,SAAU,UACV,GAAI,aACJ,QAAS,QACT,OAAQ,SACR,GAAI,OACJ,SAAU,QACV,OAAQ,SACR,OAAS,GAAO,EAAG,QAAQ,oCAAoC,EAAI,UAAY,cAC/E,KAAO,GAAO,EAAG,aAAa,YAAY,GAAK,EAAG,aAAa,iBAAiB,EAAI,OAAS,UAC7F,GAAI,UAAW,GAAI,UAAW,GAAI,UAAW,GAAI,UAAW,GAAI,UAAW,GAAI,UAC/E,OAAS,GAAO,EAAG,QAAQ,oCAAoC,EAAI,UAAY,SAC/E,GAAI,YACJ,IAAM,GAAO,EAAG,aAAa,KAAK,IAAM,GAAK,eAAiB,MAC9D,GAAI,WACJ,KAAM,OACN,KAAM,OACN,KAAM,OACN,MAAO,QACP,IAAK,aACL,GAAI,OACJ,SAAU,QACV,OAAQ,SACR,OAAQ,SACR,EAAG,YACH,SAAU,cACV,OAAQ,SACR,QAAU,GAAO,EAAG,aAAa,YAAY,GAAK,EAAG,aAAa,iBAAiB,EAAI,SAAW,UAClG,OAAS,GAAO,CACd,IAAM,EAAI,EACV,OAAO,EAAE,aAAa,UAAU,GAAM,EAAE,MAAQ,EAAE,KAAO,EAAK,UAAY,UAC5E,EACA,MAAO,QACP,MAAO,WACP,GAAI,OACJ,SAAU,UACV,MAAO,WACP,GAAI,eACJ,MAAO,WACP,KAAM,OACN,GAAI,MACJ,GAAI,MACN,EAEA,GAAI,IAAQ,QAiBV,MAAO,CAfL,OAAQ,SACR,SAAU,WACV,MAAO,UACP,KAAM,SACN,MAAO,SACP,OAAQ,aACR,MAAO,QACP,MAAO,SACP,MAAO,SACP,OAAQ,YACR,OAAQ,SACR,IAAK,UACL,KAAM,UACN,IAAK,SAEA,EAAW,GAAQ,KAAO,UAGnC,IAAM,EAAW,EAAS,GAI1B,OAHI,OAAO,GAAa,WACf,EAAS,CAAO,EAElB,GAAY,SACrB,CAEA,SAAS,EAAgB,EAA0B,CACjD,IAAM,EAAe,EAAgB,CAAO,EAU5C,MARI,CAAC,IAIA,IAAiB,QAAU,IAAiB,iBAAmB,EAAY,CAAO,EAC9E,EAAgB,CAAO,EAGzB,CACT,CAEK,OAAO,iBAAgB,OAAO,eAAiB,CAAC,GAQrD,IAAM,EAAc,IAAI,QACpB,EAAmB,EAEvB,SAAS,EAAe,EAAkB,EAAc,EAAsB,CAC5E,IAAM,EAAW,EAAY,IAAI,CAAO,EACxC,GAAI,GAAY,EAAS,OAAS,GAAQ,EAAS,OAAS,EAC1D,OAAO,EAAS,IAGlB,IAAM,EAAM,IAAI,EAAE,IAElB,OADA,EAAY,IAAI,EAAS,CAAE,OAAM,OAAM,KAAI,CAAC,EACrC,CACT,CAEA,SAAS,GAAkC,CACzC,IAAM,EAAuB,CAAC,EAwB9B,OArBA,SADyB,iBAAiB,qDAC1C,CAAA,CAAQ,QAAQ,GAAU,CACxB,IAAM,EAAQ,OAAO,iBAAiB,CAAM,EAM5C,GAAI,EALc,EAAM,UAAY,QAClB,EAAM,aAAe,UACrB,EAAM,UAAY,KACjB,EAAuB,YAAc,GACrC,EAAuB,aAAe,GACzC,OAEhB,IAAM,EAAO,EAAO,aAAa,MAAM,GAAK,SACxC,EAAQ,EAAO,aAAa,YAAY,GAChC,EAAO,cAAc,8BAA8B,CAAC,EAAE,aAAa,KAAK,GACxE,SACR,EAAM,OAAS,MAAK,EAAQ,EAAM,UAAU,EAAG,GAAG,EAAI,OAC1D,EAAO,KAAK,CACV,KAAM,EACN,YAAa,GAAG,EAAK,IAAI,IACzB,UAAW,mCACb,CAAC,CACH,CAAC,EAEM,CACT,CAEA,IAAM,EAAgB,CACpB,KAAK,EAA2B,CAC9B,OAAO,IAAI,QAAQ,GAAW,WAAW,EAAS,CAAE,CAAC,CACvD,EAEA,MAAM,gBACF,EACA,EAAwF,CAAC,EAChE,CACzB,GAAM,CAAE,QAAQ,UAAW,UAAU,KAAU,EAEzC,EAAoB,GAAgC,CACxD,GAAI,CAAC,EAAI,MAAO,GAChB,IAAM,EAAQ,OAAO,iBAAiB,CAAE,EACxC,OAAO,EAAM,UAAY,QAClB,EAAM,aAAe,UACrB,EAAM,UAAY,KACjB,EAAmB,YAAc,GACjC,EAAmB,aAAe,CAC5C,EAEM,MAAqC,CACzC,IAAM,EAAK,SAAS,cAAc,CAAQ,EAC1C,OAAQ,EAAR,CACE,IAAK,WACH,OAAO,EACT,IAAK,WACH,OAAO,EAAK,KAAO,SAAS,KAC9B,IAAK,SAEH,OADK,EACE,EAAiB,CAAE,EAAI,KAAO,EADrB,SAAS,KAG3B,QACE,OAAO,EAAiB,CAAE,EAAI,EAAK,IACvC,CACF,EAEA,OAAO,IAAI,SAAS,EAAS,IAAW,CACtC,IAAM,EAAS,EAAa,EAC5B,GAAI,EAAQ,CACV,EAAQ,IAAU,YAAc,IAAU,SAAW,KAAO,CAAM,EAClE,MACF,CAEA,IAAM,EAAW,IAAI,qBAAuB,CAC1C,IAAM,EAAS,EAAa,EACxB,IACF,EAAS,WAAW,EACpB,aAAa,CAAS,EACtB,EAAQ,IAAU,YAAc,IAAU,SAAW,KAAO,CAAM,EAEtE,CAAC,EAEK,EAAY,eAAiB,CACjC,EAAS,WAAW,EACpB,EAAW,MAAM,wBAAwB,EAAS,UAAU,GAAO,CAAC,CACtE,EAAG,CAAO,EAEV,EAAS,QAAQ,SAAS,gBAAiB,CACzC,UAAW,GACX,QAAS,GACT,WAAY,GACZ,gBAAiB,CAAC,QAAS,QAAS,QAAQ,CAC9C,CAAC,CACH,CAAC,CACH,EAEA,MAAM,YACJ,EACA,EAAmD,CAAC,EAC3B,CACzB,GAAM,CAAE,WAAU,UAAU,KAAU,EAEhC,MAAkC,CACtC,IAAM,EAAO,EAAW,SAAS,cAAc,CAAQ,EAAI,SAAS,KACpE,GAAI,CAAC,EAAM,OAAO,KAElB,IAAM,EAAS,SAAS,iBAAiB,EAAM,WAAW,SAAS,EACnE,KAAO,EAAO,SAAS,GACrB,GAAI,EAAO,YAAY,aAAa,SAAS,CAAI,EAC/C,OAAO,EAAO,YAAY,cAG9B,OAAO,IACT,EAEA,OAAO,IAAI,SAAS,EAAS,IAAW,CACtC,IAAM,EAAS,EAAU,EACzB,GAAI,EAAQ,CACV,EAAQ,CAAM,EACd,MACF,CAEA,IAAM,EAAW,IAAI,qBAAuB,CAC1C,IAAM,EAAS,EAAU,EACrB,IACF,EAAS,WAAW,EACpB,aAAa,CAAS,EACtB,EAAQ,CAAM,EAElB,CAAC,EAEK,EAAY,eAAiB,CACjC,EAAS,WAAW,EACpB,EAAW,MAAM,6BAA6B,EAAK,EAAE,CAAC,CACxD,EAAG,CAAO,EAEV,EAAS,QAAQ,SAAS,gBAAiB,CACzC,UAAW,GACX,QAAS,GACT,cAAe,EACjB,CAAC,CACH,CAAC,CACH,EAEA,MAAM,cAAc,EAAkB,EAAU,IAAsB,CACpE,MAAM,EAAc,gBAAgB,EAAU,CAAE,MAAO,SAAU,SAAQ,CAAC,CAC5E,EAEA,UAAU,EAAc,EAA6B,CAAC,EAAmB,CACvE,GAAM,CAAE,QAAS,EAEX,EAA0C,CAC9C,OAAQ,CAAC,SAAU,uBAAwB,uBAAwB,qBAAqB,EACxF,KAAM,CAAC,SAAS,EAChB,QAAS,CAAC,oBAAqB,qBAAsB,sBAAuB,yBAA0B,uBAAwB,oBAAqB,oBAAqB,UAAU,EAClL,SAAU,CAAC,wBAAwB,EACnC,MAAO,CAAC,qBAAqB,EAC7B,SAAU,CAAC,QAAQ,EACnB,QAAS,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,IAAI,EAC5C,KAAM,CAAC,KAAM,IAAI,EACjB,SAAU,CAAC,IAAI,EACf,WAAY,CAAC,KAAK,EAClB,KAAM,CAAC,MAAM,EACb,OAAQ,CAAC,QAAQ,EACjB,YAAa,CAAC,QAAQ,EACtB,KAAM,CAAC,MAAM,EACb,IAAK,CAAC,KAAK,EACX,MAAO,CAAC,OAAO,CACjB,EAEM,EAAwB,CAAC,EAC/B,EAAW,KAAK,GAAG,SAAS,iBAAiB,UAAU,EAAK,GAAG,CAAC,EAEhE,IAAM,EAAoB,EAAc,GACxC,GAAI,EACF,IAAK,IAAM,KAAO,EAChB,EAAW,KAAK,GAAG,SAAS,iBAAiB,GAAG,EAAI,aAAa,CAAC,EAItE,GAAI,CAAC,EAAM,OAAO,EAAW,IAAM,KAEnC,IAAM,EAAiB,EAAK,YAAY,CAAC,CAAC,KAAK,EAC/C,IAAK,IAAM,KAAM,EAAY,CAC3B,IAAM,EAAY,EAAG,aAAa,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC,KAAK,EAC9D,EAAc,EAAG,aAAa,YAAY,CAAC,CAAC,KAAK,EACjD,EAAQ,EAAG,aAAa,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,KAAK,EACrD,EAAc,EAAG,aAAa,aAAa,CAAC,EAAE,YAAY,CAAC,CAAC,KAAK,EAMvE,GAJI,IAAc,GAAkB,IAAgB,GAChD,IAAU,GAAkB,IAAgB,GAG5C,GAAW,SAAS,CAAc,GAAK,GAAa,SAAS,CAAc,EAC7E,OAAO,CAEX,CAEA,OAAO,IACT,CACJ,EAEK,OAAO,cACV,OAAO,YAAc,EACrB,OAAO,UAAY,GAGrB,SAAS,GAAgB,CACvB,OAAO,OAAO,cAChB,CAEA,SAAS,EACP,EAAgC,cAChC,EAAW,GACX,EACA,EAAoB,GACpB,EAAU,GASV,CACA,GAAI,CACF,OAAO,SAAW,CAAC,EAEnB,SAAS,EAAQ,EAA0B,CACzC,OAAO,EAAgB,CAAO,CAChC,CAEA,SAAS,EAAQ,EAA0B,CACzC,IAAM,EAAM,EAAQ,QAAQ,YAAY,EAElC,EAAa,EAAQ,aAAa,iBAAiB,EACzD,GAAI,EAAY,CACd,IAAM,EAAQ,EAAW,MAAM,KAAK,CAAC,CAAC,IAAI,GAC7B,SAAS,eAAe,CAC5B,CAAA,EAAI,aAAa,KAAK,GAAK,EACnC,CAAC,CAAC,OAAO,OAAO,EACjB,GAAI,EAAM,OAAQ,CAChB,IAAM,EAAS,EAAM,KAAK,GAAG,EAC7B,OAAO,EAAO,OAAS,IAAM,EAAO,UAAU,EAAG,GAAG,EAAI,MAAQ,CAClE,CACF,CAEA,GAAI,IAAQ,SAAU,CACpB,IAAM,EAAS,EACT,EAAW,EAAO,cAAc,kBAAkB,IACrD,EAAO,eAAiB,EAAI,EAAO,QAAQ,EAAO,eAAiB,MACtE,GAAI,GAAU,aAAa,KAAK,EAAG,OAAO,EAAS,YAAY,KAAK,CACtE,CAEA,IAAM,EAAY,EAAQ,aAAa,YAAY,EACnD,GAAI,GAAW,KAAK,EAAG,OAAO,EAAU,KAAK,EAE7C,IAAM,EAAc,EAAQ,aAAa,aAAa,EACtD,GAAI,GAAa,KAAK,EAAG,OAAO,EAAY,KAAK,EAEjD,IAAM,EAAQ,EAAQ,aAAa,OAAO,EAC1C,GAAI,GAAO,KAAK,EAAG,OAAO,EAAM,KAAK,EAErC,IAAM,EAAM,EAAQ,aAAa,KAAK,EACtC,GAAI,GAAK,KAAK,EAAG,OAAO,EAAI,KAAK,EAEjC,GAAI,EAAQ,GAAI,CACd,IAAM,EAAQ,SAAS,cAAc,cAAc,EAAQ,GAAG,GAAG,EACjE,GAAI,GAAO,aAAa,KAAK,EAAG,OAAO,EAAM,YAAY,KAAK,CAChE,CAEA,GAAI,IAAQ,QAAS,CACnB,IAAM,EAAQ,EACR,EAAO,EAAQ,aAAa,MAAM,GAAK,GACvC,EAAQ,EAAQ,aAAa,OAAO,EAC1C,GAAI,IAAS,UAAY,GAAO,KAAK,EAAG,OAAO,EAAM,KAAK,EAC1D,GAAI,EAAM,OAAS,EAAM,MAAM,OAAS,IAAM,EAAM,MAAM,KAAK,EAAG,OAAO,EAAM,MAAM,KAAK,CAC5F,CAEA,GAAI,CAAC,SAAU,IAAK,SAAS,CAAC,CAAC,SAAS,CAAG,EAAG,CAC5C,IAAM,EAAc,EAAQ,aAAe,GAC3C,GAAI,EAAY,KAAK,EAAG,OAAO,EAAY,KAAK,CAClD,CAEA,GAAI,WAAW,KAAK,CAAG,EAAG,CACxB,IAAM,EAAO,EAAQ,YACrB,GAAI,GAAM,KAAK,EAAG,CAChB,IAAM,EAAI,EAAK,KAAK,EACpB,OAAO,EAAE,OAAS,IAAM,EAAE,UAAU,EAAG,GAAG,EAAI,MAAQ,CACxD,CACF,CAEA,GAAI,IAAQ,MAAO,MAAO,GAE1B,IAAI,EAAa,GACjB,IAAK,IAAM,KAAQ,EAAQ,WACrB,EAAK,WAAa,KAAK,YACzB,GAAc,EAAK,aAGvB,GAAI,GAAY,KAAK,GAAK,EAAW,KAAK,CAAC,CAAC,QAAU,EAAG,CACvD,IAAM,EAAO,EAAW,KAAK,EAC7B,OAAO,EAAK,OAAS,IAAM,EAAK,UAAU,EAAG,GAAG,EAAI,MAAQ,CAC9D,CAEA,MAAO,EACT,CAYA,SAAS,EAAa,EAA6B,CACjD,IAAM,EAAmB,CAAC,EAEpB,EAAc,EAAQ,aAAa,cAAc,EACnD,IAAgB,OAAQ,EAAM,QAAU,GACnC,IAAgB,QAAS,EAAM,QAAU,GACzC,IAAgB,QAAS,EAAM,QAAU,QACzC,aAAmB,mBAAqB,EAAQ,OAAS,YAAc,EAAQ,OAAS,WAC/F,AAGE,EAAM,QAHJ,EAAQ,OAAS,YAAc,EAAQ,cACzB,QAEA,EAAQ,SAI5B,IAAM,EAAgB,aAAmB,mBACnB,aAAmB,kBACnB,aAAmB,mBACnB,aAAmB,qBACrC,EAAQ,aAAa,eAAe,IAAM,QACzC,GAAkB,EAA8B,UACjD,EAAQ,QAAQ,mBAAmB,KACrC,EAAM,SAAW,IAGnB,IAAM,EAAe,EAAQ,aAAa,eAAe,EACrD,IAAiB,OAAQ,EAAM,SAAW,GACrC,IAAiB,UAAS,EAAM,SAAW,IAEpD,IAAM,EAAc,EAAQ,aAAa,cAAc,EACnD,IAAgB,OAAQ,EAAM,QAAU,GACnC,IAAgB,QAAS,EAAM,QAAU,GACzC,IAAgB,UAAS,EAAM,QAAU,SAElD,IAAM,EAAe,EAAQ,aAAa,eAAe,EACrD,IAAiB,OAAQ,EAAM,SAAW,GACrC,IAAiB,UAAS,EAAM,SAAW,IAEpD,IAAM,EAAa,EAAQ,aAAa,cAAc,EAClD,GAAc,IAAe,UAC/B,EAAM,OAAS,IAGjB,IAAM,EAAM,EAAQ,QAAQ,YAAY,EACxC,GAAI,WAAW,KAAK,CAAG,EACrB,EAAM,MAAQ,SAAS,EAAI,GAAI,EAAE,MAC5B,CACL,IAAM,EAAY,EAAQ,aAAa,YAAY,EAC/C,IAAW,EAAM,MAAQ,SAAS,EAAW,EAAE,EACrD,CAEA,OAAO,CACT,CAEA,SAAS,EAAgB,EAA0B,CACjD,IAAM,EAAkB,CAAC,EAoBzB,OAlBI,EAAM,UAAY,IAAA,IACpB,EAAM,KAAK,EAAM,UAAY,QAAU,kBAAoB,EAAM,QAAU,YAAc,aAAa,EAEpG,EAAM,UAAU,EAAM,KAAK,YAAY,EACvC,EAAM,WAAa,IAAA,IACrB,EAAM,KAAK,EAAM,SAAW,aAAe,aAAa,EAEtD,EAAM,UAAY,IAAA,IACpB,EAAM,KAAK,EAAM,UAAY,QAAU,kBAAoB,EAAM,QAAU,YAAc,eAAe,EAEtG,EAAM,WAAa,IAAA,IACrB,EAAM,KAAK,EAAM,SAAW,aAAe,gBAAgB,EAEzD,EAAM,QAAQ,EAAM,KAAK,UAAU,EACnC,EAAM,QAAU,IAAA,IAClB,EAAM,KAAK,UAAU,EAAM,MAAM,EAAE,EAG9B,EAAM,KAAK,GAAG,CACvB,CAEA,SAAS,EAAU,EAA2B,CAC5C,IAAM,EAAQ,OAAO,iBAAiB,CAAO,EAC7C,OACE,EAAM,UAAY,QAClB,EAAM,aAAe,UACrB,EAAM,UAAY,KACjB,EAAwB,YAAc,GACtC,EAAwB,aAAe,CAE5C,CAEA,SAAS,EAAc,EAA2B,CAChD,IAAM,EAAM,EAAQ,QAAQ,YAAY,EACxC,MACE,CAAC,IAAK,SAAU,QAAS,SAAU,WAAY,UAAW,SAAS,CAAC,CAAC,SAAS,CAAG,GACjF,EAAQ,aAAa,SAAS,GAC9B,EAAQ,aAAa,UAAU,GAC/B,EAAQ,aAAa,MAAM,IAAM,UACjC,EAAQ,aAAa,MAAM,IAAM,QACjC,EAAQ,aAAa,iBAAiB,IAAM,MAEhD,CAEA,SAAS,EAAW,EAA2B,CAC7C,IAAM,EAAM,EAAQ,QAAQ,YAAY,EACxC,MACE,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,OAAQ,SAAU,SAAU,UAAW,UAAW,OAAO,CAAC,CAAC,SAAS,CAAG,GACnH,EAAQ,aAAa,MAAM,CAE/B,CAEA,SAAS,EAAiB,EAA2B,CAEnD,OADc,OAAO,iBAAiB,CAC/B,CAAA,CAAM,SAAW,SAC1B,CAEA,SAAS,EAAc,EAAkB,EAA8E,CACrH,IAAM,EAAM,EAAQ,QAAQ,YAAY,EAGxC,GAFI,CAAC,SAAU,QAAS,OAAQ,OAAQ,QAAS,UAAU,CAAC,CAAC,SAAS,CAAG,GACrE,EAAQ,SAAW,OAAS,EAAQ,aAAa,aAAa,IAAM,QACpE,EAAQ,SAAW,OAAS,CAAC,EAAU,CAAO,EAAG,MAAO,GAE5D,GAAI,EAAQ,SAAW,OAAS,CAAC,EAAQ,MAAO,CAC9C,IAAM,EAAO,EAAQ,sBAAsB,EAC3C,GAAI,EAAE,EAAK,IAAM,OAAO,aAAe,EAAK,OAAS,GAAK,EAAK,KAAO,OAAO,YAAc,EAAK,MAAQ,GACtG,MAAO,EAEX,CAEA,GAAI,EAAQ,SAAW,cAAe,OAAO,EAAc,CAAO,EAGlE,GAFI,EAAc,CAAO,GACrB,EAAW,CAAO,GAClB,EAAQ,CAAO,CAAC,CAAC,OAAS,EAAG,MAAO,GAExC,IAAM,EAAO,EAAQ,CAAO,EAU5B,OAPI,EAAQ,SAEN,IAD6B,IAAI,CAAC,UAAW,QAAS,SAAU,UAAW,UAAW,eAAe,CACrG,CAAA,CAAqB,IAAI,CAAI,GAAK,EAAQ,CAAO,CAAC,CAAC,SAAW,EACzD,GAIJ,IAAS,WAAa,IAAS,KACxC,CAEA,SAAS,EAAS,EAAkB,EAAyB,CAC3D,IAAM,EAAkB,CAAC,EACnB,EAAU,CAAE,SAAQ,MAAO,GAAS,KAAM,SAAQ,EAClD,EAAa,EAAc,EAE3B,EAAU,EAAc,EAAS,CAAO,GAAM,GAAS,IAAU,EAEvE,GAAI,EAAS,CACX,IAAM,EAAO,EAAQ,CAAO,EACtB,EAAO,EAAQ,CAAO,EACtB,EAAY,EAAa,CAAO,EAEhC,EAAY,EAAe,EAAS,EAAM,CAAI,EACpD,OAAO,SAAU,GAAa,EAC9B,EAAW,GAAa,CACtB,QAAS,IAAI,QAAQ,CAAO,EAC5B,OACA,MACF,EAGA,IAAI,EAAO,GADI,KAAK,OAAO,CACb,IAAS,IACvB,GAAI,EAAM,CACR,IAAM,EAAc,EAAK,QAAQ,OAAQ,GAAG,CAAC,CAAC,QAAQ,KAAM,KAAK,EACjE,GAAQ,KAAK,EAAY,EAC3B,CACA,GAAQ,KAAK,EAAU,GAEvB,IAAM,EAAW,EAAgB,CAAS,EACtC,IAAU,GAAQ,IAAI,KAEtB,EAAiB,CAAO,IAC1B,GAAQ,qBAGV,IAAM,EAAO,EAAQ,aAAa,MAAM,EACpC,IAAM,GAAQ,UAAU,EAAK,IAEjC,IAAM,EAAO,EAAQ,aAAa,MAAM,EACpC,IAAM,GAAQ,UAAU,EAAK,IAEjC,IAAM,EAAc,EAAQ,aAAa,aAAa,EAClD,IAAa,GAAQ,iBAAiB,EAAY,IAEtD,EAAM,KAAK,CAAI,CACjB,CAEA,GAAI,EAAQ,EACV,IAAK,IAAM,KAAS,EAAQ,SAC1B,EAAM,KAAK,GAAG,EAAS,EAAO,EAAU,EAAQ,EAAI,CAAK,CAAC,EAI9D,OAAO,CACT,CAEA,SAAS,EAAqB,EAAsB,CAClD,OAAO,EAAK,QAAQ,YAAa,OAAO,CAC1C,CAEA,SAAS,EAAiB,EAAsC,CAC9D,IAAM,EAAS,IAAI,IACnB,IAAK,IAAM,KAAQ,EAAO,CACxB,GAAI,CAAC,EAAK,KAAK,EAAG,SAClB,IAAM,EAAO,EAAqB,CAAI,EACtC,EAAO,IAAI,GAAO,EAAO,IAAI,CAAI,GAAK,GAAK,CAAC,CAC9C,CACA,OAAO,CACT,CAEA,SAAS,EAAkB,EAAoB,EAA2D,CACxG,IAAM,EAAW,EAAW,MAAM;CAAI,EAChC,EAAW,EAAW,MAAM;CAAI,EAEhC,EAAY,EAAiB,CAAQ,EACrC,EAAY,EAAiB,CAAQ,EAErC,EAAkB,CAAC,EACnB,EAAoB,CAAC,EAE3B,IAAK,IAAM,KAAQ,EAAU,CAC3B,GAAI,CAAC,EAAK,KAAK,EAAG,SAClB,IAAM,EAAO,EAAqB,CAAI,EAChC,EAAW,EAAU,IAAI,CAAI,GAAK,GACvB,EAAU,IAAI,CAAI,GAAK,GACzB,IACb,EAAM,KAAK,CAAI,EACf,EAAU,IAAI,EAAM,EAAW,CAAC,EAEpC,CAEA,IAAM,EAAiB,EAAiB,CAAQ,EAChD,IAAK,IAAM,KAAQ,EAAU,CAC3B,GAAI,CAAC,EAAK,KAAK,EAAG,SAClB,IAAM,EAAO,EAAqB,CAAI,EAChC,EAAW,EAAe,IAAI,CAAI,GAAK,EAEzC,GADa,EAAU,IAAI,CAAI,GAAK,KAEtC,EAAQ,KAAK,CAAI,EACjB,EAAe,IAAI,EAAM,EAAW,CAAC,EAEzC,CAEA,GAAI,EAAM,SAAW,GAAK,EAAQ,SAAW,EAC3C,MAAO,CAAE,KAAM,eAAgB,WAAY,EAAM,EAGnD,IAAM,EAAsB,CAAC,EAQ7B,OAPI,EAAQ,OAAS,GACnB,EAAU,KAAK,GAAG,EAAQ,IAAI,GAAK,KAAK,GAAG,CAAC,EAE1C,EAAM,OAAS,GACjB,EAAU,KAAK,GAAG,EAAM,IAAI,GAAK,KAAK,GAAG,CAAC,EAGrC,CAAE,KAAM,EAAU,KAAK;CAAI,EAAG,WAAY,EAAK,CACxD,CAEA,IAAM,EAAa,EAAc,EAC7B,EAA+B,KAEnC,GAAI,EAAO,CACT,IAAM,EAAU,EAAW,GAC3B,GAAI,CAAC,EACH,MAAO,CACL,MAAO,wBAAwB,EAAM,oEACrC,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,EAEF,IAAM,EAAU,EAAQ,QAAQ,MAAM,EACtC,GAAI,CAAC,EAEH,OADA,OAAO,EAAW,GACX,CACL,MAAO,wBAAwB,EAAM,2EACrC,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,EAEF,EAAe,CACjB,KACE,GAAe,SAAS,KAG1B,IAAM,EAAQ,EAAe,EAAS,EAAc,CAAC,EAAI,CAAC,EAE1D,IAAK,IAAM,KAAM,OAAO,KAAK,CAAU,EAChC,EAAW,EAAG,CAAC,QAAQ,MAAM,GAChC,OAAO,EAAW,GAItB,IAAM,EAAU,EAAM,KAAK;CAAI,EAE/B,GAAI,EAAQ,OAAS,IACnB,MAAO,CACL,MAAO,yCAAyC,EAAQ,OAAO,mEAC/D,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,EAGF,IAAM,EAAc,EAAkB,EAElC,EACA,EAAgB,GACd,EAAe,OAAO,iBAW5B,MATI,CAAC,GAAqB,CAAC,GAAS,GAChC,KAAK,IAAI,EAAI,EAAa,UAAY,MAExC,EADmB,EAAkB,EAAa,QAAS,CACpD,CAAA,CAAW,KAClB,EAAgB,IAGlB,OAAO,iBAAmB,CAAE,UAAS,UAAW,KAAK,IAAI,CAAE,EAEpD,CACL,YAAa,EAAU,kBAAkB,OAAO,WAAW,GAAG,OAAO,YAAY,GACjF,KAAM,EAAgB,EAAO,IAAA,GAC7B,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,EACjE,YAAa,EAAY,OAAS,EAAI,EAAc,IAAA,GACpD,iBAAkB,qJAClB,eACF,CACF,OAAS,EAAK,CACZ,MAAO,CACL,MAAO,wCAAwC,aAAe,MAAQ,EAAI,QAAU,kBACpF,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,CACF,CACF,CAEA,SAAS,EAAgB,EAAqB,CAK5C,OAJK,EAAI,OACL,SAAS,KAAK,CAAG,GAAK,QAAQ,KAAK,CAAG,GAAK,QAAQ,KAAK,CAAG,GAAK,YAAY,KAAK,CAAG,EAC/E,IAAM,EAAI,QAAQ,MAAO,MAAM,CAAC,CAAC,QAAQ,KAAM,KAAK,CAAC,CAAC,QAAQ,MAAO,KAAK,CAAC,CAAC,QAAQ,MAAO,KAAK,EAAI,IAEtG,EAJiB,IAK1B,CAEA,SAAS,EACP,EAAgC,cAChC,EAAW,GACoE,CAC/E,GAAI,CACF,OAAO,SAAW,CAAC,EAEnB,IAAM,EAAkB,CAAC,EAEzB,SAAS,EAAQ,EAA0B,CACzC,OAAO,EAAgB,CAAO,CAChC,CAEA,SAAS,EAAQ,EAA0B,CACzC,IAAM,EAAM,EAAQ,QAAQ,YAAY,EAElC,EAAa,EAAQ,aAAa,iBAAiB,EACzD,GAAI,EAAY,CACd,IAAM,EAAQ,EAAW,MAAM,KAAK,CAAC,CAAC,IAAI,GAC7B,SAAS,eAAe,CAC5B,CAAA,EAAI,aAAa,KAAK,GAAK,EACnC,CAAC,CAAC,OAAO,OAAO,EACjB,GAAI,EAAM,OAAQ,CAChB,IAAM,EAAS,EAAM,KAAK,GAAG,EAC7B,OAAO,EAAO,OAAS,IAAM,EAAO,UAAU,EAAG,GAAG,EAAI,MAAQ,CAClE,CACF,CAEA,GAAI,IAAQ,SAAU,CACpB,IAAM,EAAS,EACT,EAAW,EAAO,cAAc,kBAAkB,IACrD,EAAO,eAAiB,EAAI,EAAO,QAAQ,EAAO,eAAiB,MACtE,GAAI,GAAU,aAAa,KAAK,EAAG,OAAO,EAAS,YAAY,KAAK,CACtE,CAEA,IAAM,EAAY,EAAQ,aAAa,YAAY,EACnD,GAAI,GAAW,KAAK,EAAG,OAAO,EAAU,KAAK,EAE7C,IAAM,EAAc,EAAQ,aAAa,aAAa,EACtD,GAAI,GAAa,KAAK,EAAG,OAAO,EAAY,KAAK,EAEjD,IAAM,EAAQ,EAAQ,aAAa,OAAO,EAC1C,GAAI,GAAO,KAAK,EAAG,OAAO,EAAM,KAAK,EAErC,IAAM,EAAM,EAAQ,aAAa,KAAK,EACtC,GAAI,GAAK,KAAK,EAAG,OAAO,EAAI,KAAK,EAEjC,GAAI,EAAQ,GAAI,CACd,IAAM,EAAQ,SAAS,cAAc,cAAc,EAAQ,GAAG,GAAG,EACjE,GAAI,GAAO,aAAa,KAAK,EAAG,OAAO,EAAM,YAAY,KAAK,CAChE,CAEA,GAAI,IAAQ,QAAS,CACnB,IAAM,EAAQ,EACR,EAAO,EAAQ,aAAa,MAAM,GAAK,GACvC,EAAQ,EAAQ,aAAa,OAAO,EAC1C,GAAI,IAAS,UAAY,GAAO,KAAK,EAAG,OAAO,EAAM,KAAK,EAC1D,GAAI,EAAM,OAAS,EAAM,MAAM,OAAS,IAAM,EAAM,MAAM,KAAK,EAAG,OAAO,EAAM,MAAM,KAAK,CAC5F,CAEA,GAAI,CAAC,SAAU,IAAK,SAAS,CAAC,CAAC,SAAS,CAAG,EAAG,CAC5C,IAAM,EAAc,EAAQ,aAAe,GAC3C,GAAI,EAAY,KAAK,EAAG,OAAO,EAAY,KAAK,CAClD,CAEA,GAAI,WAAW,KAAK,CAAG,EAAG,CACxB,IAAM,EAAO,EAAQ,YACrB,GAAI,GAAM,KAAK,EAAG,CAChB,IAAM,EAAI,EAAK,KAAK,EACpB,OAAO,EAAE,OAAS,IAAM,EAAE,UAAU,EAAG,GAAG,EAAI,MAAQ,CACxD,CACF,CAEA,GAAI,IAAQ,MAAO,MAAO,GAE1B,IAAI,EAAa,GACjB,IAAK,IAAM,KAAQ,EAAQ,WACrB,EAAK,WAAa,KAAK,YACzB,GAAc,EAAK,aAGvB,GAAI,GAAY,KAAK,GAAK,EAAW,KAAK,CAAC,CAAC,QAAU,EAAG,CACvD,IAAM,EAAO,EAAW,KAAK,EAC7B,OAAO,EAAK,OAAS,IAAM,EAAK,UAAU,EAAG,GAAG,EAAI,MAAQ,CAC9D,CAEA,MAAO,EACT,CAYA,SAAS,EAAa,EAA6B,CACjD,IAAM,EAAmB,CAAC,EAEpB,EAAc,EAAQ,aAAa,cAAc,EACnD,IAAgB,OAAQ,EAAM,QAAU,GACnC,IAAgB,QAAS,EAAM,QAAU,GACzC,IAAgB,QAAS,EAAM,QAAU,QACzC,aAAmB,mBAAqB,EAAQ,OAAS,YAAc,EAAQ,OAAS,WAC/F,AAGE,EAAM,QAHJ,EAAQ,OAAS,YAAc,EAAQ,cACzB,QAEA,EAAQ,SAI5B,IAAM,EAAgB,aAAmB,mBACnB,aAAmB,kBACnB,aAAmB,mBACnB,aAAmB,qBACrC,EAAQ,aAAa,eAAe,IAAM,QACzC,GAAkB,EAA8B,UACjD,EAAQ,QAAQ,mBAAmB,KACrC,EAAM,SAAW,IAGnB,IAAM,EAAe,EAAQ,aAAa,eAAe,EACrD,IAAiB,OAAQ,EAAM,SAAW,GACrC,IAAiB,UAAS,EAAM,SAAW,IAEpD,IAAM,EAAc,EAAQ,aAAa,cAAc,EACnD,IAAgB,OAAQ,EAAM,QAAU,GACnC,IAAgB,QAAS,EAAM,QAAU,GACzC,IAAgB,UAAS,EAAM,QAAU,SAElD,IAAM,EAAe,EAAQ,aAAa,eAAe,EACrD,IAAiB,OAAQ,EAAM,SAAW,GACrC,IAAiB,UAAS,EAAM,SAAW,IAEpD,IAAM,EAAa,EAAQ,aAAa,cAAc,EAClD,GAAc,IAAe,UAC/B,EAAM,OAAS,IAGjB,IAAM,EAAM,EAAQ,QAAQ,YAAY,EACxC,GAAI,WAAW,KAAK,CAAG,EACrB,EAAM,MAAQ,SAAS,EAAI,GAAI,EAAE,MAC5B,CACL,IAAM,EAAY,EAAQ,aAAa,YAAY,EAC/C,IAAW,EAAM,MAAQ,SAAS,EAAW,EAAE,EACrD,CAEA,OAAO,CACT,CAEA,SAAS,EAAgB,EAA0B,CACjD,IAAM,EAAkB,CAAC,EAoBzB,OAlBI,EAAM,UAAY,IAAA,IACpB,EAAM,KAAK,EAAM,UAAY,QAAU,kBAAoB,EAAM,QAAU,YAAc,aAAa,EAEpG,EAAM,UAAU,EAAM,KAAK,YAAY,EACvC,EAAM,WAAa,IAAA,IACrB,EAAM,KAAK,EAAM,SAAW,aAAe,aAAa,EAEtD,EAAM,UAAY,IAAA,IACpB,EAAM,KAAK,EAAM,UAAY,QAAU,kBAAoB,EAAM,QAAU,YAAc,eAAe,EAEtG,EAAM,WAAa,IAAA,IACrB,EAAM,KAAK,EAAM,SAAW,aAAe,gBAAgB,EAEzD,EAAM,QAAQ,EAAM,KAAK,UAAU,EACnC,EAAM,QAAU,IAAA,IAClB,EAAM,KAAK,UAAU,EAAM,MAAM,EAAE,EAG9B,EAAM,KAAK,GAAG,CACvB,CAEA,SAAS,EAAU,EAA2B,CAC5C,IAAM,EAAQ,OAAO,iBAAiB,CAAO,EAC7C,OACE,EAAM,UAAY,QAClB,EAAM,aAAe,UACrB,EAAM,UAAY,KACjB,EAAwB,YAAc,GACtC,EAAwB,aAAe,CAE5C,CAEA,SAAS,EAAc,EAA2B,CAChD,IAAM,EAAM,EAAQ,QAAQ,YAAY,EACxC,MACE,CAAC,IAAK,SAAU,QAAS,SAAU,WAAY,UAAW,SAAS,CAAC,CAAC,SAAS,CAAG,GACjF,EAAQ,aAAa,SAAS,GAC9B,EAAQ,aAAa,UAAU,GAC/B,EAAQ,aAAa,MAAM,IAAM,UACjC,EAAQ,aAAa,MAAM,IAAM,QACjC,EAAQ,aAAa,iBAAiB,IAAM,MAEhD,CAEA,SAAS,EAAW,EAA2B,CAC7C,IAAM,EAAM,EAAQ,QAAQ,YAAY,EACxC,MACE,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,OAAQ,SAAU,SAAU,UAAW,UAAW,OAAO,CAAC,CAAC,SAAS,CAAG,GACnH,EAAQ,aAAa,MAAM,CAE/B,CAEA,SAAS,EAAiB,EAA2B,CAEnD,OADc,OAAO,iBAAiB,CAC/B,CAAA,CAAM,SAAW,SAC1B,CAEA,SAAS,EAAS,EAAc,EAAc,EAAkB,EAA8B,CAC5F,IAAI,EAAM,EACN,IACF,GAAO,IAAM,EAAgB,CAAI,GAGnC,IAAM,EAAM,EAAe,EAAS,EAAM,CAAI,EAC9C,OAAO,SAAU,GAAO,EACxB,GAAO,SAAS,EAAI,GAEpB,IAAM,EAAW,EAAgB,CAAS,EAO1C,OANI,IAAU,GAAO,IAAI,KAErB,EAAiB,CAAO,IAC1B,GAAO,qBAGF,CACT,CAEA,SAAS,EAAgB,EAA0C,CACjE,IAAM,EAAgC,CAAC,EACjC,EAAO,EAAQ,aAAa,MAAM,EACpC,IAAM,EAAM,IAAM,GACtB,IAAM,EAAc,EAAQ,aAAa,aAAa,EAEtD,OADI,IAAa,EAAM,YAAc,GAC9B,CACT,CAEA,SAAS,EAAS,EAAkB,EAAe,EAA+B,CAChF,GAAI,EAAQ,EAAU,OAEtB,IAAM,EAAM,EAAQ,QAAQ,YAAY,EAGxC,GAFI,CAAC,SAAU,QAAS,OAAQ,OAAQ,QAAS,UAAU,CAAC,CAAC,SAAS,CAAG,GACrE,IAAW,OAAS,EAAQ,aAAa,aAAa,IAAM,QAC5D,IAAW,OAAS,CAAC,EAAU,CAAO,EAAG,OAE7C,GAAI,IAAW,MAAO,CACpB,IAAM,EAAO,EAAQ,sBAAsB,EAC3C,GAAI,EAAE,EAAK,IAAM,OAAO,aAAe,EAAK,OAAS,GAAK,EAAK,KAAO,OAAO,YAAc,EAAK,MAAQ,GACtG,MAEJ,CAEA,IAAM,EAAO,EAAQ,CAAO,EACtB,EAAO,EAAQ,CAAO,EACtB,EAAY,EAAa,CAAO,EAEhC,EAAkB,EAAc,CAAO,EACvC,EAAe,EAAW,CAAO,EACjC,EAAU,EAAK,OAAS,EAE1B,EASJ,GARA,AAKE,EALE,IAAW,cACH,EACD,IAAW,OAGV,GAAmB,GAAgB,GAAY,IAAS,WAAa,IAAS,MAGtF,EAAS,CACX,IAAM,EAAS,KAAK,OAAO,CAAK,EAC1B,EAAM,EAAS,EAAM,EAAM,EAAS,CAAS,EAC7C,EAAQ,EAAgB,CAAO,EAE/B,EAAsB,CAAC,EAC7B,IAAK,IAAM,KAAS,EAAQ,SAC1B,EAAS,KAAK,CAAK,EAGrB,IAAM,EAAc,EAAS,OAAS,EAChC,EAAW,OAAO,KAAK,CAAK,CAAC,CAAC,OAAS,EAE7C,GAAI,CAAC,GAAe,CAAC,EACnB,EAAM,KAAK,GAAG,EAAO,IAAI,GAAK,MACzB,CACL,EAAM,KAAK,GAAG,EAAO,IAAI,EAAI,EAAE,EAC/B,IAAK,GAAM,CAAC,EAAU,KAAc,OAAO,QAAQ,CAAK,EACtD,EAAM,KAAK,GAAG,EAAO,OAAO,EAAS,IAAI,EAAgB,CAAS,GAAG,EAEvE,IAAK,IAAM,KAAS,EAClB,EAAS,EAAO,EAAQ,EAAG,EAAI,CAEnC,CACF,MACE,IAAK,IAAM,KAAS,EAAQ,SAC1B,EAAS,EAAO,EAAO,CAAc,CAG3C,CAEA,EAAS,SAAS,KAAM,EAAG,EAAK,EAEhC,IAAM,EAAO,EAAM,KAAK;CAAI,EAU5B,OARI,EAAK,OAAS,IACT,CACL,MAAO,yCAAyC,EAAK,OAAO,+CAC5D,KAAM,GACN,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,EAGK,CACL,KAAM,EAAO,kBAAkB,OAAO,WAAW,GAAG,OAAO,YAAY,GACvE,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,CACF,OAAS,EAAK,CACZ,MAAO,CACL,MAAO,+BAA+B,aAAe,MAAQ,EAAI,QAAU,kBAC3E,KAAM,GACN,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,CACF,CACF,CAEA,SAAS,EAAsB,EAAuD,CACpF,IAAM,EAAa,EAAc,EAC3B,EAAU,EAAW,GACvB,EAaJ,GAXI,IACF,EAAU,EAAQ,QAAQ,MAAM,EAC3B,GACH,OAAO,EAAW,IAIlB,CAAC,GAAW,OAAO,WACrB,EAAU,OAAO,SAAS,IAGxB,CAAC,EACH,MAAO,CAAE,EAAG,EAAG,EAAG,EAAG,MAAO,WAAW,EAAI,mDAAoD,EAGjG,IAAM,EAAO,EAAQ,sBAAsB,EAI3C,MAAO,CAAE,EAHC,KAAK,MAAM,EAAK,KAAO,EAAK,MAAQ,CAGrC,EAAG,EAFF,KAAK,MAAM,EAAK,IAAM,EAAK,OAAS,CAElC,CAAE,CAChB,CAEA,SAAS,EAAa,EAAa,EAAwE,CACzG,IAAM,EAAa,EAAc,EAC3B,EAAU,EAAW,GACvB,EAaJ,GAXI,IACF,EAAU,EAAQ,QAAQ,MAAM,EAC3B,GACH,OAAO,EAAW,IAIlB,CAAC,GAAW,OAAO,WACrB,EAAU,OAAO,SAAS,IAGxB,CAAC,EACH,MAAO,CAAE,QAAS,GAAO,MAAO,WAAW,EAAI,mDAAoD,EAGrG,IAAM,EAAU,EAAQ,QAAQ,YAAY,EAE5C,GAAI,CACF,GAAI,IAAY,QAAS,CACvB,IAAM,EAAQ,EACR,EAAO,EAAM,KAAK,YAAY,EAEhC,IAAS,YAAc,IAAS,SAClC,EAAM,QAAU,EAAQ,EACxB,EAAM,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,IAE1D,EAAM,MAAQ,OAAO,CAAK,EAC1B,EAAM,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,EACzD,EAAM,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,EAE9D,MAAO,GAAI,IAAY,WAAY,CACjC,IAAM,EAAW,EACjB,EAAS,MAAQ,OAAO,CAAK,EAC7B,EAAS,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,EAC5D,EAAS,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,CAC/D,MAAO,GAAI,IAAY,SAAU,CAC/B,IAAM,EAAS,EACT,EAAW,OAAO,CAAK,EAEzB,EAAQ,GACZ,IAAK,IAAM,KAAU,EAAO,QAC1B,GAAI,EAAO,QAAU,GAAY,EAAO,aAAa,KAAK,IAAM,EAAU,CACxE,EAAO,MAAQ,EAAO,MACtB,EAAQ,GACR,KACF,CAGF,GAAI,CAAC,EACH,MAAO,CAAE,QAAS,GAAO,MAAO,WAAW,EAAM,gCAAgC,GAAM,EAGzF,EAAO,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,CAC7D,MAAO,GAAI,EAAQ,aAAa,iBAAiB,IAAM,OACrD,EAAQ,YAAc,OAAO,CAAK,EAClC,EAAQ,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,OAE3D,MAAO,CAAE,QAAS,GAAO,MAAO,WAAW,EAAI,IAAI,EAAQ,sBAAuB,EAGpF,MAAO,CAAE,QAAS,EAAK,CACzB,OAAS,EAAK,CACZ,MAAO,CAAE,QAAS,GAAO,MAAO,wBAAwB,aAAe,MAAQ,EAAI,QAAU,iBAAkB,CACjH,CACF,CAEA,SAAS,EAAU,EAAkB,EAAc,EAAQ,GAAM,EAAS,GAAwE,CAChJ,GAAI,CACF,IAAM,EAAU,SAAS,cAAc,CAAQ,EAC/C,GAAI,CAAC,EAAS,MAAO,CAAE,QAAS,GAAO,MAAO,sBAAsB,GAAW,EAE/E,IAAM,EAAuB,EAAQ,cAA2B,0BAA0B,EACpF,EAAS,GAAwB,EACjC,EAAkB,EAAQ,mBAAqB,CAAC,CAAC,EAcvD,GAbA,EAAO,MAAM,EAET,IACE,EAAiB,EAAO,YAAc,GACrC,EAAmD,MAAQ,IAG9D,EAAiB,EAAO,YAAc,EACrC,EAAmD,MAAQ,EAEhE,EAAO,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,EAC1D,EAAO,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,EAEvD,EAAQ,CACV,IAAM,EAAO,EAAQ,QAAQ,MAAM,EAC7B,EAAe,GAAM,cAA2B,6CAA6C,GAC9F,SAAS,cAA2B,gFAAgF,EACrH,EAAc,EAAa,MAAM,EAC5B,EAAM,EAAK,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,EACnE,EAAO,cAAc,IAAI,cAAc,UAAW,CAAE,IAAK,QAAS,KAAM,QAAS,QAAS,GAAI,QAAS,EAAK,CAAC,CAAC,CACrH,CAEA,MAAO,CAAE,QAAS,GAAM,iBAAgB,CAC1C,OAAS,EAAK,CACZ,MAAO,CAAE,QAAS,GAAO,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CACnF,CACF,CAEA,SAAS,EAAoB,EAAe,EAA0B,CAEpE,IAAM,EAAU,IADI,YACJ,CAAA,CAAQ,OAAO,CAAK,EACpC,GAAI,EAAQ,QAAU,EAAU,OAAO,EACvC,IAAI,EAAM,EACV,KAAO,EAAM,IAAM,EAAQ,GAAO,MAAU,KAAM,IAClD,OAAO,IAAI,YAAY,QAAS,CAAE,MAAO,EAAM,CAAC,CAAC,CAAC,OAAO,EAAQ,SAAS,EAAG,CAAG,CAAC,CACnF,CAEA,SAAS,EAAY,EAAiC,CAAC,EAAiE,CACtH,GAAI,CACF,IAAM,EAAU,SAAS,cAAc,SAAS,EAC1C,EAAO,SAAS,cAAc,MAAM,EAGpC,GAFU,GAAW,GAAQ,SAAS,KAAA,CAEjB,aACvB,QAAQ,OAAQ,GAAG,CAAC,CACrB,KAAK,GAAK,GAKb,MAAO,CACL,KALW,OAAO,SAAS,EAAQ,QAAQ,GAAK,EAAQ,SAAY,EAClE,EAAoB,EAAY,EAAQ,QAAS,EACjD,EAAW,UAAU,EAAG,GAAK,EAI/B,MAAO,SAAS,MAChB,IAAK,OAAO,SAAS,IACvB,CACF,OAAS,EAAK,CACZ,MAAO,CACL,KAAM,GACN,MAAO,GACP,IAAK,GACL,MAAO,2BAA2B,aAAe,MAAQ,EAAI,QAAU,iBACzE,CACF,CACF,CAEA,SAAS,EAAgB,EAAmD,CAC1E,IAAM,EAAa,EAAc,EAC3B,EAAU,EAAW,GACvB,EAkBJ,OAhBI,IACF,EAAU,EAAQ,QAAQ,MAAM,EAC3B,GACH,OAAO,EAAW,IAIlB,CAAC,GAAW,OAAO,WACrB,EAAU,OAAO,SAAS,IAGvB,GAIL,EAAQ,eAAe,CAAE,SAAU,SAAU,MAAO,QAAS,CAAC,EACvD,CAAE,QAAS,EAAK,GAJd,CAAE,QAAS,GAAO,MAAO,WAAW,EAAI,uDAAwD,CAK3G,CAEA,SAAS,EACP,EACA,EACA,EACA,EAAmB,iBACmB,CACtC,GAAI,CACF,IAAM,EAAa,KAAK,CAAM,EACxB,EAAK,IAAI,YAAY,EAAW,MAAM,EACtC,EAAK,IAAI,WAAW,CAAE,EAC5B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IACrC,EAAG,GAAK,EAAW,WAAW,CAAC,EAEjC,IAAM,EAAO,IAAI,KAAK,CAAC,CAAE,EAAG,CAAE,KAAM,WAAY,CAAC,EAC3C,EAAO,IAAI,KAAK,CAAC,CAAI,EAAG,EAAU,CAAE,KAAM,WAAY,CAAC,EAEzD,EAAoC,KAExC,GAAI,EAAK,CACP,IAAM,EAAa,EAAc,EAC3B,EAAU,EAAW,GAa3B,GAXI,IACF,EAAgB,EAAQ,QAAQ,MAAM,EACjC,GACH,OAAO,EAAW,IAIlB,CAAC,GAAiB,OAAO,WAC3B,EAAgB,OAAO,SAAS,IAG9B,CAAC,EACH,MAAO,CAAE,QAAS,GAAO,MAAO,WAAW,EAAI,uDAAwD,CAE3G,MAAO,GAAI,IACT,EAAgB,SAAS,iBAAiB,EAAW,GAAI,EAAW,EAAE,EAClE,CAAC,GACH,MAAO,CAAE,QAAS,GAAO,MAAO,kBAAkB,EAAW,GAAG,IAAI,EAAW,GAAG,EAAG,EAIzF,GAAI,CAAC,EACH,MAAO,CAAE,QAAS,GAAO,MAAO,mBAAoB,EAGtD,GAAI,EAAc,UAAY,SAAY,EAAmC,OAAS,OAAQ,CAC5F,IAAM,EAAQ,EACR,EAAK,IAAI,aAIf,OAHA,EAAG,MAAM,IAAI,CAAI,EACjB,EAAM,MAAQ,EAAG,MACjB,EAAM,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,EACnD,CAAE,QAAS,EAAK,CACzB,CAEA,IAAM,EAAK,IAAI,aACf,EAAG,MAAM,IAAI,CAAI,EAEjB,IAAM,EAAY,IAAI,UAAU,OAAQ,CACtC,QAAS,GACT,WAAY,GACZ,aAAc,CAChB,CAAC,EAGD,OADA,EAAc,cAAc,CAAS,EAC9B,CAAE,QAAS,EAAK,CACzB,OAAS,EAAK,CACZ,MAAO,CACL,QAAS,GACT,MAAO,aAAe,MAAQ,EAAI,QAAU,eAC9C,CACF,CACF,CAEA,IAAI,EAAwD,KAE5D,SAAS,EAAc,EAA0B,CAC/C,GAAI,EAAQ,GAAI,MAAO,IAAI,IAAI,OAAO,EAAQ,EAAE,IAChD,IAAK,IAAM,IAAQ,CAAC,cAAe,eAAgB,OAAQ,YAAY,EAAG,CACxE,IAAM,EAAQ,EAAQ,aAAa,CAAI,EACvC,GAAI,EAAO,MAAO,GAAG,EAAQ,QAAQ,YAAY,EAAE,GAAG,EAAK,GAAG,KAAK,UAAU,CAAK,EAAE,EACtF,CACA,OAAO,EAAQ,QAAQ,YAAY,CACrC,CAEA,SAAS,EAAe,EAAe,EAAmB,EAAsB,CACzE,GACL,OAAO,QAAQ,YAAY,CACzB,KAAM,uBACN,QACA,SAAU,EAAU,EAAc,CAAO,EAAI,IAAA,GAC7C,QACA,IAAK,SAAS,KACd,UAAW,IAAI,KAAK,CAAA,CAAE,YAAY,CACpC,CAAC,CAAC,CAAC,UAAY,CAAC,CAAC,CACnB,CAEI,OAAO,SAAS,kBAAqB,aACvC,SAAS,iBAAiB,QAAU,GAAU,CACxC,EAAM,WAAa,EAAM,kBAAkB,SAAS,EAAe,QAAS,EAAM,MAAM,CAC9F,EAAG,EAAI,EACP,SAAS,iBAAiB,SAAW,GAAU,CAC7C,GAAI,CAAC,EAAM,WAAa,EAAE,EAAM,kBAAkB,kBAAoB,EAAM,kBAAkB,qBAAuB,EAAM,kBAAkB,mBAAoB,OACjK,IAAM,EAAS,EAAM,OACf,EAAS,aAAkB,kBAAoB,EAAO,OAAS,WAErE,EAAe,QAAS,EADV,GAAe,oBAAsB,CAAC,EAAS,EAAO,MAAQ,SACvC,CACvC,EAAG,EAAI,GAEL,OAAO,OAAO,kBAAqB,aACrC,OAAO,iBAAiB,eAAkB,EAAe,YAAY,CAAC,EACtE,OAAO,iBAAiB,iBAAoB,EAAe,YAAY,CAAC,GAG1E,OAAO,QAAQ,UAAU,aAAa,EAAS,EAAQ,IAAiB,CACtE,OAAQ,EAAQ,KAAhB,CACE,IAAK,uBACH,EAAgB,CAAE,mBAAoB,EAAQ,qBAAuB,EAAK,EAC1E,EAAa,CAAE,QAAS,EAAK,CAAC,EAC9B,MACF,IAAK,sBACH,EAAgB,KAChB,EAAa,CAAE,QAAS,EAAK,CAAC,EAC9B,MACF,IAAK,wBACL,IAAK,wBACL,IAAK,oBACL,IAAK,sBACL,IAAK,wBACL,IAAK,wBACH,GAAI,CAAC,OAAO,kCAAmC,CAC7C,EAAa,CAAE,MAAO,6CAA8C,CAAC,EACrE,KACF,CACA,OAAO,kCAAkC,EAAQ,IAAkC,EACnF,EAAa,CAAE,QAAS,EAAK,CAAC,EAC9B,MAEF,IAAK,8BAA+B,CAClC,IAAM,EAAU,EAAQ,SAAW,CAAC,EAEpC,GAAI,EAAQ,SAAW,OAAQ,CAC7B,IAAM,EAAS,EACb,EAAQ,QAAU,cAClB,EAAQ,OAAS,EACnB,EACM,EAAc,EAAkB,EAClC,EAAO,MACT,EAAa,CAAE,MAAO,EAAO,MAAO,YAAa,GAAI,SAAU,EAAO,QAAS,CAAC,EAEhF,EAAa,CACX,YAAa,EAAO,KACpB,SAAU,EAAO,SACjB,YAAa,EAAY,OAAS,EAAI,EAAc,IAAA,GACpD,iBAAkB,oJACpB,CAAC,CAEL,MAQE,EAPe,EACb,EAAQ,QAAU,cAClB,EAAQ,OAAS,GACjB,EAAQ,MACR,EAAQ,mBAAqB,GAC7B,EAAQ,SAAW,EAER,CAAM,EAErB,KACF,CACA,IAAK,0BAEH,EADe,EAAsB,EAAQ,GAChC,CAAM,EACnB,MAEF,IAAK,gBAAiB,CACpB,IAAM,EAAa,EAAc,EAC3B,EAAU,EAAW,EAAQ,KAC/B,EAQJ,GAPI,IACF,EAAU,EAAQ,QAAQ,MAAM,EAC3B,GAAS,OAAO,EAAW,EAAQ,MAEtC,CAAC,GAAW,OAAO,WACrB,EAAU,OAAO,SAAS,EAAQ,MAEhC,CAAC,EAAS,CACZ,EAAa,CAAE,MAAO,WAAW,EAAQ,IAAI,mDAAoD,CAAC,EAClG,KACF,CACA,GAAI,EAAQ,SAAW,SAAU,CAC/B,IAAM,EAAc,IAAI,WAAW,QAAS,CAAE,QAAS,GAAM,WAAY,GAAM,KAAM,OAAQ,OAAQ,CAAE,CAAC,EACxG,EAAQ,cAAc,CAAW,CACnC,MAAW,EAAQ,SAAW,SAC5B,EAAQ,cAAc,IAAI,WAAW,WAAY,CAAE,QAAS,GAAM,WAAY,GAAM,KAAM,MAAO,CAAC,CAAC,EAC1F,EAAQ,SAAW,QAC5B,EAAQ,cAAc,IAAI,WAAW,cAAe,CAAE,QAAS,GAAM,WAAY,GAAM,KAAM,MAAO,CAAC,CAAC,EAEtG,EAAyB,MAAM,EAEjC,EAAa,CAAE,QAAS,EAAK,CAAC,EAC9B,KACF,CACA,IAAK,aAEH,EADe,EAAa,EAAQ,IAAK,EAAQ,KACpC,CAAM,EACnB,MAEF,IAAK,eACH,GAAI,CACF,IAAM,EAAS,SAAS,cAAc,QAAQ,EAC9C,EAAO,YAAc,iBAAiB,EAAQ,KAAK,QACnD,SAAS,gBAAgB,YAAY,CAAM,EAC3C,EAAO,OAAO,EACd,EAAa,CAAE,QAAS,EAAK,CAAC,CAChC,OAAS,EAAK,CACZ,EAAa,CAAE,QAAS,GAAO,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1F,CACA,MAEF,IAAK,gBAEH,EADe,EAAY,EAAQ,SAAW,CAAC,CAClC,CAAM,EACnB,MAEF,IAAK,aACH,EAAa,EAAU,EAAQ,SAAU,EAAQ,KAAM,EAAQ,MAAO,EAAQ,MAAM,CAAC,EACrF,MAEF,IAAK,wBACH,GAAI,CACF,IAAM,EAAS,SAAS,cAAc,EAAQ,QAAQ,EACtD,GAAI,CAAC,GAAU,EAAO,QAAQ,YAAY,IAAM,SAAU,CACxD,EAAa,CAAE,MAAO,kCAAkC,EAAQ,SAAS,EAAG,CAAC,EAC7E,KACF,CAEA,EAAa,CACX,IAAK,EAAO,IACZ,KAAM,EAAO,MAAQ,IAAA,EACvB,CAAC,CACH,OAAS,EAAK,CACZ,EAAa,CAAE,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1E,CACA,MAEF,IAAK,iBAEH,GAAI,CACF,EAAa,CAAE,KAAM,OAAO,MAAQ,IAAK,CAAC,CAC5C,MAAc,CACZ,EAAa,CAAE,KAAM,IAAK,CAAC,CAC7B,CACA,MAEF,IAAK,cACH,GAAI,CACF,GAAM,CAAE,OAAM,OAAM,OAAQ,EACtB,EAAa,EAAc,EAwB3B,EAAY,CApBhB,OAAQ,CAAC,SAAU,uBAAwB,uBAAwB,sBAAuB,iBAAiB,EAC3G,KAAM,CAAC,UAAW,eAAe,EACjC,QAAS,CAAC,oBAAqB,qBAAsB,sBAAuB,yBAA0B,uBAAwB,oBAAqB,oBAAqB,WAAY,kBAAkB,EACtM,SAAU,CAAC,yBAA0B,mBAAmB,EACxD,MAAO,CAAC,sBAAuB,gBAAgB,EAC/C,SAAU,CAAC,SAAU,mBAAmB,EACxC,QAAS,CAAC,mBAAoB,kBAAkB,EAChD,OAAQ,CAAC,SAAU,iBAAiB,EACpC,QAAS,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,kBAAkB,EAChE,WAAY,CAAC,MAAO,qBAAqB,EACzC,KAAM,CAAC,OAAQ,eAAe,EAC9B,IAAK,CAAC,WAAY,cAAc,EAChC,OAAQ,CAAC,SAAU,kBAAmB,sBAAsB,EAC5D,IAAK,CAAC,cAAc,EACpB,SAAU,CAAC,mBAAmB,EAC9B,KAAM,CAAC,eAAe,EACtB,SAAU,CAAC,mBAAmB,CAId,EAAc,IAAS,CAAC,UAAU,EAAK,GAAG,EACtD,EAAwB,CAAC,EAE/B,IAAK,IAAM,KAAO,EAChB,GAAI,CACF,EAAW,KAAK,GAAG,SAAS,iBAAiB,CAAG,CAAC,CACnD,MAAQ,CAAC,CAIX,IAAM,EAAU,EAAW,OAAO,GAAM,CACtC,IAAM,EAAQ,OAAO,iBAAiB,CAAE,EACxC,OAAO,EAAM,UAAY,QAClB,EAAM,aAAe,UACpB,EAAmB,YAAc,GACjC,EAAmB,aAAe,CAC5C,CAAC,EAGG,EAAU,EACd,GAAI,EAAM,CACR,IAAM,EAAY,EAAK,YAAY,EACnC,EAAU,EAAQ,OAAO,GAAM,CAC7B,IAAM,EAAY,EAAG,aAAa,YAAY,CAAC,EAAE,YAAY,EACvD,EAAO,EAAG,aAAa,KAAK,CAAC,CAAC,YAAY,EAC1C,EAAQ,EAAG,aAAa,OAAO,CAAC,EAAE,YAAY,EAC9C,EAAe,EAAwB,aAAa,YAAY,EAChE,EAAS,EAAwB,OAAO,YAAY,EAE1D,OAAO,GAAW,SAAS,CAAS,GAC7B,GAAM,SAAS,CAAS,GACxB,GAAO,SAAS,CAAS,GACzB,GAAa,SAAS,CAAS,GAC/B,GAAO,SAAS,CAAS,CAClC,CAAC,CACH,CAEA,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAa,CAAE,MAAO,+BAA+B,EAAK,GAAG,EAAO,cAAc,EAAK,GAAK,IAAK,CAAC,EAClG,KACF,CAGA,IAAM,EAAU,EAAQ,IAAI,GAAM,CAChC,IAAM,EAAM,EAAe,EAAI,EAAM,GAAQ,EAAE,EAI/C,MAHA,QAAO,SAAW,OAAO,UAAY,CAAC,EACtC,OAAO,SAAS,GAAO,EACvB,EAAW,GAAO,CAAE,QAAS,IAAI,QAAQ,CAAE,EAAG,OAAM,KAAM,GAAQ,EAAG,EAC9D,CAAE,MAAK,KAAM,EAAG,aAAa,KAAK,CAAC,CAAC,MAAM,EAAG,EAAE,CAAE,CAC1D,CAAC,EAGC,EADE,EACW,CAAE,QAAS,CAAQ,EAEnB,CAAE,IAAK,EAAQ,EAAE,CAAC,IAAK,KAAM,EAAQ,EAAE,CAAC,IAAK,CAAC,CAE/D,OAAS,EAAK,CACZ,EAAa,CAAE,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1E,CACA,MAEF,IAAK,cACH,GAAI,CACF,GAAM,CAAE,OAAM,SAAU,EAClB,EAAa,EAAc,EAG3B,EAAS,SAAS,iBAAiB,SAAS,KAAM,WAAW,SAAS,EACtE,EAAqB,CAAC,EAE5B,KAAO,EAAO,SAAS,GAAG,CACxB,IAAM,EAAW,EAAO,YAAY,aAAe,GAKnD,GAJiB,EACb,EAAS,KAAK,IAAM,EACpB,EAAS,YAAY,CAAC,CAAC,SAAS,EAAK,YAAY,CAAC,EAExC,CACZ,IAAM,EAAS,EAAO,YAAY,cAClC,GAAI,GAAU,CAAC,EAAQ,SAAS,CAAM,EAAG,CAEvC,IAAM,EAAQ,OAAO,iBAAiB,CAAM,EACxC,EAAM,UAAY,QAAU,EAAM,aAAe,UACnD,EAAQ,KAAK,CAAM,CAEvB,CACF,CACF,CAEA,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAa,CAAE,MAAO,+BAA+B,EAAK,EAAG,CAAC,EAC9D,KACF,CAGA,IAAM,EAAK,EAAQ,MAAM,EAAG,KACzB,EAAE,aAAa,QAAU,IAAM,EAAE,aAAa,QAAU,EAC3D,CAAC,CAAC,GAEI,EAAO,EAAgB,CAAE,EACzB,EAAM,EAAe,EAAI,EAAM,CAAI,EACzC,OAAO,SAAW,OAAO,UAAY,CAAC,EACtC,OAAO,SAAS,GAAO,EACvB,EAAW,GAAO,CAAE,QAAS,IAAI,QAAQ,CAAE,EAAG,OAAM,KAAM,CAAK,EAE/D,EAAa,CAAE,MAAK,KAAM,EAAG,aAAa,KAAK,CAAC,CAAC,MAAM,EAAG,EAAE,CAAE,CAAC,CACjE,OAAS,EAAK,CACZ,EAAa,CAAE,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1E,CACA,MAEF,IAAK,eACH,GAAI,CACF,GAAM,CAAE,SAAU,EACZ,EAAa,EAAc,EAG3B,EAAS,SAAS,iBAAiB,OAAO,EAC5C,EAAwB,KAE5B,IAAK,IAAM,KAAO,EAEhB,IADgB,EAAI,aAAa,KAAK,CAAC,CAAC,YAAY,EAAA,EACvC,SAAS,EAAM,YAAY,CAAC,EAAG,CAE1C,IAAM,EAAQ,EAAI,aAAa,KAAK,EAQpC,GAPI,IACF,EAAQ,SAAS,eAAe,CAAK,GAGvC,AACE,IAAQ,EAAI,cAAc,yBAAyB,EAEjD,EAAO,KACb,CAaF,GATA,AAEE,KADmB,EAAM,YAAY,EAC7B,SAAS,cACf,sBAAsB,EAAM,4BAA4B,EAAM,8BACrC,EAAM,+BAA+B,EAAM,4BAC7C,EAAM,KAC/B,GAGE,CAAC,EAAO,CACV,EAAa,CAAE,MAAO,mCAAmC,EAAM,EAAG,CAAC,EACnE,KACF,CAEA,IAAM,EAAO,EAAgB,CAAK,EAC5B,EAAM,EAAe,EAAO,EAAM,CAAK,EAC7C,OAAO,SAAW,OAAO,UAAY,CAAC,EACtC,OAAO,SAAS,GAAO,EACvB,EAAW,GAAO,CAAE,QAAS,IAAI,QAAQ,CAAK,EAAG,OAAM,KAAM,CAAM,EAEnE,EAAa,CAAE,MAAK,OAAM,CAAC,CAC7B,OAAS,EAAK,CACZ,EAAa,CAAE,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1E,CACA,MAEF,IAAK,qBACH,GAAI,CACF,GAAM,CAAE,YAAa,EACf,EAAa,EAAc,EAG3B,EAAiB,GAAgB,CACrC,IAAM,EAAI,iBAAiB,CAAE,EACvB,EAAI,EAAG,sBAAsB,EACnC,MAAO,CACL,IAAK,EAAG,QAAQ,YAAY,EAC5B,KAAO,EAAmB,WAAW,KAAK,CAAC,CAAC,MAAM,EAAG,EAAE,GAAK,KAC5D,IAAK,CACH,EAAG,KAAK,MAAM,EAAE,CAAC,EACjB,EAAG,KAAK,MAAM,EAAE,CAAC,EACjB,MAAO,KAAK,MAAM,EAAE,KAAK,EACzB,OAAQ,KAAK,MAAM,EAAE,MAAM,CAC7B,EACA,OAAQ,CACN,SAAU,EAAE,SACZ,WAAY,EAAE,WACd,WAAY,EAAE,WAAW,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAM,EAAE,EAC9D,MAAO,EAAE,MACT,gBAAiB,EAAE,gBACnB,aAAc,EAAE,aAChB,OAAQ,EAAE,SAAW,QAAU,EAAE,cAAgB,MAAQ,EAAE,OAAS,KACpE,UAAW,EAAE,YAAc,OAAuB,KAAd,EAAE,UACtC,QAAS,EAAE,OACb,CACF,CACF,EAGA,GAAI,SAAS,KAAK,CAAQ,EAAG,CAC3B,IAAM,EAAU,EAAW,GACvB,EASJ,GARI,IACF,EAAU,EAAQ,QAAQ,MAAM,EAC3B,GAAS,OAAO,EAAW,IAE9B,CAAC,GAAW,OAAO,WACrB,EAAU,OAAO,SAAS,IAGxB,CAAC,EAAS,CACZ,EAAa,CAAE,MAAO,WAAW,EAAS,WAAY,CAAC,EACvD,KACF,CAEA,EAAa,CAAE,OAAQ,CAAC,EAAc,CAAO,CAAC,CAAE,CAAC,CACnD,KAAO,CAEL,IAAM,EAAW,SAAS,iBAAiB,CAAQ,EACnD,GAAI,EAAS,SAAW,EAAG,CACzB,EAAa,CAAE,MAAO,+BAA+B,EAAS,EAAG,CAAC,EAClE,KACF,CAGA,EAAa,CAAE,OADA,MAAM,KAAK,CAAQ,CAAC,CAAC,IAAI,CACzB,CAAO,CAAC,CACzB,CACF,OAAS,EAAK,CACZ,EAAa,CAAE,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1E,CACA,MAEF,IAAK,gBACH,GAAI,CACF,GAAM,CAAE,WAAU,SAAQ,MAAO,EAC3B,EAAa,EAAc,EAG7B,EAAqC,KAEzC,GAAI,SAAS,KAAK,CAAQ,EAAG,CAC3B,IAAM,EAAU,EAAW,GACvB,EASJ,GARI,IACF,EAAU,EAAQ,QAAQ,MAAM,EAC3B,GAAS,OAAO,EAAW,IAE9B,CAAC,GAAW,OAAO,WACrB,EAAU,OAAO,SAAS,IAGxB,CAAC,EAAS,CACZ,EAAa,CAAE,MAAO,WAAW,EAAS,WAAY,CAAC,EACvD,KACF,CACA,GAAI,EAAQ,UAAY,SAAU,CAChC,EAAa,CAAE,MAAO,WAAW,EAAS,mBAAoB,CAAC,EAC/D,KACF,CACA,EAAW,CACb,KAAO,CAEL,GADA,EAAW,SAAS,cAAc,CAAQ,EACtC,CAAC,EAAU,CACb,EAAa,CAAE,MAAO,8BAA8B,EAAS,EAAG,CAAC,EACjE,KACF,CACA,GAAI,EAAS,UAAY,SAAU,CACjC,EAAa,CAAE,MAAO,YAAY,EAAS,oBAAqB,CAAC,EACjE,KACF,CACF,CAGA,GAAI,EAAS,SACX,IAAK,IAAM,KAAO,EAAS,QACzB,EAAI,SAAW,GAInB,IAAM,EAAqB,CAAC,EACtB,EAAqB,CAAC,EAGtB,EAAiB,EAAS,SAAW,EAAS,CAAC,EAAO,EAAE,EAE9D,IAAK,IAAM,KAAO,EAAgB,CAChC,IAAI,EAAQ,GAEZ,IAAK,IAAM,KAAO,EAAS,QAAS,CAClC,IAAI,EAAU,GAWd,GATA,AAME,EANE,IAAO,QACC,EAAI,QAAU,SAAS,EAAK,EAAE,EAC/B,IAAO,QACN,EAAI,KAAK,YAAY,CAAC,CAAC,SAAS,EAAI,YAAY,CAAC,EAGjD,EAAI,QAAU,EAGtB,EAAS,CACX,EAAI,SAAW,GACf,EAAS,KAAK,EAAI,KAAK,EACvB,EAAQ,GACR,KACF,CACF,CAEK,GAAO,EAAS,KAAK,CAAG,CAC/B,CAGA,EAAS,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,EAEzD,EAAS,OAAS,EACpB,EAAa,CACX,WACA,QAAS,qBAAqB,EAAS,KAAK,IAAI,GAClD,CAAC,EAED,EAAa,CAAE,UAAS,CAAC,CAE7B,OAAS,EAAK,CACZ,EAAa,CAAE,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1E,CACA,MAEF,IAAK,mBACH,GAAI,CACF,GAAM,CAAE,OAAQ,EACV,EAAa,EAAc,EAC3B,EAAU,EAAW,GAEvB,EASJ,GARI,IACF,EAAU,EAAQ,QAAQ,MAAM,EAC3B,GAAS,OAAO,EAAW,IAE9B,CAAC,GAAW,OAAO,WACrB,EAAU,OAAO,SAAS,IAGxB,CAAC,EAAS,CACZ,EAAa,CAAE,MAAO,WAAW,EAAI,WAAY,CAAC,EAClD,KACF,CAEA,EAAa,CAAE,KAAM,EAAQ,aAAa,KAAK,GAAK,EAAG,CAAC,CAC1D,OAAS,EAAK,CACZ,EAAa,CAAE,MAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CAAE,CAAC,CAC1E,CACA,MAEF,IAAK,oBAEH,EADe,EAAgB,EAAQ,GAC1B,CAAM,EACnB,MAEF,IAAK,eAEH,EADe,EAAY,EAAQ,OAAQ,EAAQ,IAAK,EAAQ,WAAY,EAAQ,QACvE,CAAM,EACnB,MAEF,IAAK,mBAAoB,CACvB,GAAM,CAAE,WAAU,QAAQ,UAAW,UAAU,KAAU,EACnD,EAAa,KAAK,IAAI,EAAS,GAAK,EAEpC,EAAoB,GAAgC,CACxD,GAAI,CAAC,EAAI,MAAO,GAChB,IAAM,EAAQ,OAAO,iBAAiB,CAAE,EACxC,OAAO,EAAM,UAAY,QAClB,EAAM,aAAe,UACrB,EAAM,UAAY,KACjB,EAAmB,YAAc,GACjC,EAAmB,aAAe,CAC5C,EAEM,MAA8B,CAClC,IAAM,EAAK,SAAS,cAAc,CAAQ,EAC1C,OAAQ,EAAR,CACE,IAAK,WAAY,MAAO,CAAC,CAAC,EAC1B,IAAK,WAAY,MAAO,CAAC,EACzB,IAAK,SAAU,MAAO,CAAC,GAAM,CAAC,EAAiB,CAAE,EAEjD,QAAS,OAAO,EAAiB,CAAE,CACrC,CACF,EAEM,EAAY,KAAK,IAAI,EAgD3B,OA7CS,IAAI,QAAS,GAAY,CAC9B,GAAI,EAAa,EAAG,CAClB,EAAQ,CAAE,QAAS,GAAM,OAAQ,KAAK,IAAI,EAAI,CAAU,CAAC,EACzD,MACF,CAEA,IAAM,EAAW,IAAI,qBAAuB,CACtC,EAAa,IACf,EAAS,WAAW,EACpB,aAAa,CAAS,EACtB,EAAQ,CAAE,QAAS,GAAM,OAAQ,KAAK,IAAI,EAAI,CAAU,CAAC,EAE7D,CAAC,EAEK,EAAY,eAAiB,CACjC,EAAS,WAAW,EACpB,EAAQ,CACN,QAAS,GACT,OAAQ,KAAK,IAAI,EAAI,EACrB,MAAO,wBAAwB,EAAS,UAAU,GACpD,CAAC,CACH,EAAG,CAAU,EAEb,EAAS,QAAQ,SAAS,gBAAiB,CACzC,UAAW,GACX,QAAS,GACT,WAAY,GACZ,gBAAiB,CAAC,QAAS,QAAS,SAAU,UAAU,CAC1D,CAAC,CACH,CAAC,CAAA,CAGgB,KAAM,GAAe,CACtC,GAAI,CAAC,EAAW,QAAS,CACvB,EAAa,CACX,MAAO,EAAW,MAClB,OAAQ,EAAW,OACnB,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,CAAC,EACD,MACF,CAEA,EAAa,CAAE,GADI,EAA0B,cAAe,GAAI,IAAA,GAAW,EACzD,EAAY,OAAQ,EAAW,MAAO,CAAC,CAC3D,CAAC,EACM,EACT,CACA,IAAK,eAAgB,CACnB,GAAM,CAAE,UAAS,UAAU,KAAU,EAC/B,EAAa,KAAK,IAAI,EAAS,GAAK,EAEpC,EAAkB,GAAyB,CAC/C,GAAI,EAAQ,SAAS,GAAG,EAAG,CACzB,IAAM,EAAe,EAClB,QAAQ,qBAAsB,MAAM,CAAC,CACrC,QAAQ,QAAS,gBAAgB,CAAC,CAClC,QAAQ,MAAO,OAAO,CAAC,CACvB,QAAQ,kBAAmB,IAAI,EAClC,OAAW,OAAO,IAAI,EAAa,EAAE,CAAC,CAAC,KAAK,CAAG,CACjD,CACA,OAAO,EAAI,SAAS,CAAO,CAC7B,EAEM,EAAY,KAAK,IAAI,EAsD3B,OAnDS,IAAI,QAAS,GAAY,CAC9B,GAAI,EAAe,OAAO,SAAS,IAAI,EAAG,CACxC,EAAQ,CAAE,QAAS,GAAM,OAAQ,KAAK,IAAI,EAAI,CAAU,CAAC,EACzD,MACF,CAEA,IAAI,EAAW,GACT,MAAiB,CACjB,GACA,EAAe,OAAO,SAAS,IAAI,IACrC,EAAW,GACX,cAAc,CAAU,EACxB,aAAa,CAAS,EACtB,OAAO,oBAAoB,WAAY,CAAQ,EAC/C,OAAO,oBAAoB,aAAc,CAAQ,EACjD,EAAQ,CAAE,QAAS,GAAM,OAAQ,KAAK,IAAI,EAAI,CAAU,CAAC,EAE7D,EAEM,EAAa,YAAY,EAAU,GAAG,EACtC,EAAY,eAAiB,CAC7B,IACJ,EAAW,GACX,cAAc,CAAU,EACxB,OAAO,oBAAoB,WAAY,CAAQ,EAC/C,OAAO,oBAAoB,aAAc,CAAQ,EACjD,EAAQ,CACN,QAAS,GACT,OAAQ,KAAK,IAAI,EAAI,EACrB,MAAO,qCAAqC,EAAQ,cAAc,OAAO,SAAS,MACpF,CAAC,EACH,EAAG,CAAU,EAEb,OAAO,iBAAiB,WAAY,CAAQ,EAC5C,OAAO,iBAAiB,aAAc,CAAQ,CAChD,CAAC,CAAA,CAGU,KAAM,GAAe,CAChC,GAAI,CAAC,EAAW,QAAS,CACvB,EAAa,CACX,MAAO,EAAW,MAClB,OAAQ,EAAW,OACnB,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,CAAC,EACD,MACF,CAEA,EAAa,CAAE,GADI,EAA0B,cAAe,GAAI,IAAA,GAAW,EACzD,EAAY,OAAQ,EAAW,MAAO,CAAC,CAC3D,CAAC,EACM,EACT,CACA,IAAK,sBAAuB,CAC1B,GAAM,CAAE,SAAS,IAAK,UAAU,KAAS,EACnC,EAAa,KAAK,IAAI,EAAS,GAAK,EACpC,EAAY,KAAK,IAAI,EA6D3B,OA1DS,IAAI,QAAS,GAAY,CAC9B,IAAI,EAAmB,KAAK,IAAI,EAC5B,EAAW,GAET,MAAuB,CACvB,GAC0B,KAAK,IAAI,EAAI,GACd,IAC3B,EAAW,GACX,EAAS,WAAW,EACpB,aAAa,CAAS,EACtB,cAAc,CAAa,EAC3B,EAAQ,CAAE,QAAS,GAAM,OAAQ,KAAK,IAAI,EAAI,CAAU,CAAC,EAE7D,EAEM,EAAW,IAAI,qBAAuB,CAC1C,EAAmB,KAAK,IAAI,CAC9B,CAAC,EAEK,EAAY,eAAiB,CAC7B,IACJ,EAAW,GACX,EAAS,WAAW,EACpB,cAAc,CAAa,EAC3B,EAAQ,CACN,QAAS,GACT,OAAQ,KAAK,IAAI,EAAI,EACrB,MAAO,yCAAyC,EAAW,GAC7D,CAAC,EACH,EAAG,CAAU,EAEP,EAAgB,YAAY,EAAgB,KAAK,IAAI,GAAI,KAAK,IAAI,GAAI,EAAS,CAAC,CAAC,CAAC,EAExF,EAAS,QAAQ,SAAS,gBAAiB,CACzC,UAAW,GACX,QAAS,GACT,WAAY,GACZ,cAAe,EACjB,CAAC,EAED,EAAe,CACjB,CAAC,CAAA,CAGgB,KAAM,GAAe,CACtC,GAAI,CAAC,EAAW,QAAS,CACvB,EAAa,CACX,MAAO,EAAW,MAClB,OAAQ,EAAW,OACnB,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,CAAC,EACD,MACF,CAEA,EAAa,CAAE,GADI,EAA0B,cAAe,GAAI,IAAA,GAAW,EACzD,EAAY,OAAQ,EAAW,MAAO,CAAC,CAC3D,CAAC,EACM,EACT,CACA,IAAK,YAAa,CAChB,GAAM,CAAE,QAAS,EACjB,GAAI,CAAC,MAAM,QAAQ,CAAI,EAErB,OADA,EAAa,CAAE,MAAO,6CAA8C,CAAC,EAC9D,GAET,IAAM,EAAa,EAAc,EAC3B,EAA+D,CAAC,EACtE,IAAK,IAAM,KAAQ,EAAM,CACvB,GAAM,CAAE,MAAK,SAAU,EACvB,GAAI,CAAC,EAAK,CACR,EAAQ,KAAK,CAAE,IAAK,GAAO,UAAW,QAAS,GAAO,MAAO,aAAc,CAAC,EAC5E,QACF,CACA,IAAM,EAAU,EAAW,GAC3B,GAAI,CAAC,EAAS,CACZ,EAAQ,KAAK,CAAE,MAAK,QAAS,GAAO,MAAO,yCAA0C,CAAC,EACtF,QACF,CACA,IAAM,EAAK,EAAQ,QAAQ,MAAM,EACjC,GAAI,CAAC,EAAI,CACP,OAAO,EAAW,GAClB,EAAQ,KAAK,CAAE,MAAK,QAAS,GAAO,MAAO,0BAA2B,CAAC,EACvE,QACF,CACA,GAAI,CACF,GAAI,aAAc,iBAAkB,CAClC,IAAM,EAAY,EAAG,KAAK,YAAY,EAClC,IAAc,YAAc,IAAc,SAE5C,EAAG,QADiB,IAAU,IAAQ,IAAU,QAAU,IAAU,KAAO,IAAU,UAErF,EAAG,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,IAEvD,EAAG,MAAM,EACT,EAAG,MAAQ,OAAO,CAAK,EACvB,EAAG,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,EACtD,EAAG,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,GAEzD,EAAQ,KAAK,CAAE,MAAK,QAAS,EAAK,CAAC,CACrC,MAAW,aAAc,qBACvB,EAAG,MAAM,EACT,EAAG,MAAQ,OAAO,CAAK,EACvB,EAAG,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,EACtD,EAAG,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,EACvD,EAAQ,KAAK,CAAE,MAAK,QAAS,EAAK,CAAC,GAC1B,aAAc,mBACvB,EAAG,MAAQ,OAAO,CAAK,EACvB,EAAG,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,EACvD,EAAQ,KAAK,CAAE,MAAK,QAAS,EAAK,CAAC,GAC1B,EAAG,mBACZ,EAAG,MAAM,EACT,EAAG,YAAc,OAAO,CAAK,EAC7B,EAAG,cAAc,IAAI,MAAM,QAAS,CAAE,QAAS,EAAK,CAAC,CAAC,EACtD,EAAQ,KAAK,CAAE,MAAK,QAAS,EAAK,CAAC,GAEnC,EAAQ,KAAK,CAAE,MAAK,QAAS,GAAO,MAAO,yBAA0B,CAAC,CAE1E,OAAS,EAAG,CACV,EAAQ,KAAK,CAAE,MAAK,QAAS,GAAO,MAAO,aAAa,MAAQ,EAAE,QAAU,OAAO,CAAC,CAAE,CAAC,CACzF,CACF,CACA,IAAM,EAAS,EAAQ,OAAO,GAAK,CAAC,EAAE,OAAO,EAO7C,OANA,EAAa,CACX,QAAS,EAAO,SAAW,EAC3B,OAAQ,EAAQ,OAAO,GAAK,EAAE,OAAO,CAAC,CAAC,OACvC,OAAQ,EAAO,OACf,SACF,CAAC,EACM,EACT,CACA,IAAK,0BAA2B,CAC9B,GAAM,CAAE,OAAQ,EAChB,GAAI,CAAC,EAEH,OADA,EAAa,CAAE,MAAO,iBAAkB,CAAC,EAClC,GAET,IAAM,EAAa,EAAc,EAC3B,EAAU,EAAW,GAC3B,GAAI,CAAC,EAEH,OADA,EAAa,CAAE,MAAO,yCAA0C,CAAC,EAC1D,GAET,IAAM,EAAK,EAAQ,QAAQ,MAAM,EACjC,GAAI,CAAC,EAGH,OAFA,OAAO,EAAW,GAClB,EAAa,CAAE,MAAO,0BAA2B,CAAC,EAC3C,GAET,GAAI,EAAE,aAAc,mBAAqB,EAAG,OAAS,OAEnD,OADA,EAAa,CAAE,MAAO,6BAA8B,CAAC,EAC9C,GAET,IAAM,EAAW,aAAa,KAAK,IAAI,IAGvC,OAFA,EAAG,aAAa,kBAAmB,CAAQ,EAC3C,EAAa,CAAE,SAAU,qBAAqB,EAAS,GAAI,CAAC,EACrD,EACT,CACA,IAAK,wBAAyB,CAC5B,GAAM,CAAE,UAAU,KAAU,EACtB,EAAa,KAAK,IAAI,EAAS,GAAK,EAEpC,EAAa,CACjB,kBAAmB,wBAAyB,uBAC5C,uBAAwB,eAAgB,uBACxC,YAAa,MAAO,WAAY,QAAS,aAAc,aACvD,eAAgB,cAAe,eAAgB,cAC/C,YAAa,cAAe,WAAY,cAAe,QACvD,WAAY,UAAW,WACzB,EAEM,EAAmB,CAAC,MAAO,QAAS,OAAQ,MAAM,EAElD,EAAkB,GACf,EAAW,KAAK,GAAW,EAAI,SAAS,CAAO,CAAC,EAGnD,EAAiB,GAA8C,CACnE,IAAM,EAAO,EAAM,eAAiB,UAGpC,MADA,GADI,EAAiB,SAAS,CAAI,GAC9B,8DAA8D,KAAK,EAAM,IAAI,EAEnF,EAEM,MAAwD,CAC5D,IAAM,EAAM,YAAY,IAAI,EAE5B,OADkB,YAAY,iBAAiB,UACxC,CAAA,CAAU,OAAO,GAAS,CAI/B,GAHI,EAAM,cAAgB,GACtB,EAAM,KAAK,WAAW,OAAO,GAC7B,EAAM,KAAK,OAAS,KACpB,EAAe,EAAM,IAAI,EAAG,MAAO,GACvC,IAAM,EAAkB,EAAM,EAAM,UAGpC,MADA,EADI,EAAkB,KAClB,EAAc,CAAK,GAAK,EAAkB,IAEhD,CAAC,CACH,EAEM,EAAY,KAAK,IAAI,EAqC3B,OAlCS,IAAI,QAAS,GAAY,CAC9B,IAAM,MAAc,CAClB,IAAM,EAAU,EAAmB,EAC7B,EAAU,KAAK,IAAI,EAAI,EAE7B,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAQ,CAAE,QAAS,GAAM,OAAQ,CAAQ,CAAC,EAC1C,MACF,CAEA,GAAI,GAAW,EAAY,CACzB,EAAQ,CAAE,QAAS,GAAO,OAAQ,EAAS,aAAc,EAAQ,MAAO,CAAC,EACzE,MACF,CAEA,WAAW,EAAO,GAAG,CACvB,EACA,EAAM,CACR,CAAC,CAAA,CAGW,KAAM,GAAe,CACjC,GAAI,CAAC,EAAW,QAAS,CACvB,EAAa,CACX,MAAO,0BAA0B,EAAW,OAAO,MAAM,EAAW,aAAa,oBACjF,OAAQ,EAAW,OACnB,YAAa,GACb,SAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAY,CACnE,CAAC,EACD,MACF,CAEA,EAAa,CAAE,GADI,EAA0B,cAAe,GAAI,IAAA,GAAW,EACzD,EAAY,OAAQ,EAAW,MAAO,CAAC,CAC3D,CAAC,EACM,EACT,CACA,IAAK,cAAe,CAClB,GAAM,CAAE,OAAM,gBAAe,SAAU,EACjC,EAAU,EAAe,EAAM,GAAiB,GAAO,GAAS,EAAE,EACxE,EAAa,CAAE,MAAO,EAAM,MAAO,EAAQ,OAAQ,SAAQ,CAAC,EAC5D,KACF,CACA,IAAK,oCAAqC,CACxC,IAAM,EAAa,EAAc,EAC3B,EAAiH,CAAC,EAExH,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAU,EAAG,CACrD,IAAM,EAAK,EAAM,QAAQ,MAAM,EAC/B,GAAI,CAAC,EAAI,SAET,IAAM,EAAO,EAAG,sBAAsB,EAClC,EAAK,OAAS,GAAK,EAAK,QAAU,GAClC,EAAK,OAAS,GAAK,EAAK,IAAM,OAAO,aACrC,EAAK,MAAQ,GAAK,EAAK,KAAO,OAAO,YAEzC,EAAS,KAAK,CACZ,MACA,IAAK,EAAG,QAAQ,YAAY,EAC5B,OAAQ,CACN,EAAG,EAAK,EACR,EAAG,EAAK,EACR,MAAO,EAAK,MACZ,OAAQ,EAAK,MACf,CACF,CAAC,CACH,CAEA,EAAa,CAAE,UAAS,CAAC,EACzB,KACF,CACA,QACE,MAAO,EACX,CACA,MAAO,EACT,CAAC,EAED,SAAS,EAAe,EAAc,EAAwB,EAAe,CAC3E,IAAM,EAMD,CAAC,EAEA,EAAa,EAAgB,EAAO,EAAK,YAAY,EACrD,EAAS,SAAS,iBAAiB,SAAS,KAAM,WAAW,SAAS,EACtE,EAAa,EAAc,EAC7B,EAAa,EAEjB,KAAO,EAAO,SAAS,GAAK,EAAQ,OAAS,GAAO,CAClD,IAAM,EAAO,EAAO,YACd,EAAc,EAAK,aAAe,GAClC,EAAW,EAAgB,EAAc,EAAY,YAAY,EAEnE,EAAM,EACV,MAAQ,EAAM,EAAS,QAAQ,EAAY,CAAG,KAAO,IAAM,EAAQ,OAAS,GAAO,CACjF,IAAM,EAAS,EAAK,cACpB,GAAI,CAAC,EAAQ,CAAE,IAAO,QAAU,CAEhC,IAAM,EAAQ,SAAS,YAAY,EACnC,EAAM,SAAS,EAAM,CAAG,EACxB,EAAM,OAAO,EAAM,KAAK,IAAI,EAAM,EAAK,OAAQ,EAAY,MAAM,CAAC,EAClE,IAAM,EAAO,EAAM,sBAAsB,EAEzC,GAAI,EAAK,QAAU,GAAK,EAAK,SAAW,EAAG,CAAE,IAAO,QAAU,CAE9D,IAAM,EAAW,EAAK,aAAe,GAC/B,EAAe,KAAK,IAAI,EAAG,EAAM,EAAE,EACnC,EAAa,KAAK,IAAI,EAAS,OAAQ,EAAM,EAAK,OAAS,EAAE,EAC7D,EAAU,EAAS,MAAM,EAAc,CAAU,CAAC,CAAC,KAAK,EAE1D,EAA4B,KAChC,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAU,EAAG,CACrD,IAAM,EAAK,EAAM,QAAQ,MAAM,EAC/B,GAAI,IAAO,IAAO,GAAU,EAAG,SAAS,CAAM,GAAI,CAChD,EAAa,EACb,KACF,CACF,CAEA,EAAQ,KAAK,CACX,IAAK,IAAI,EAAE,IACX,KAAM,EAAS,MAAM,EAAK,EAAM,EAAK,MAAM,EAC3C,UACA,OAAQ,CACN,EAAG,KAAK,MAAM,EAAK,CAAC,EACpB,EAAG,KAAK,MAAM,EAAK,CAAC,EACpB,MAAO,KAAK,MAAM,EAAK,KAAK,EAC5B,OAAQ,KAAK,MAAM,EAAK,MAAM,CAChC,EACA,YACF,CAAC,EAED,GACF,CACF,CAEA,OAAO,CACT"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/content/visual-indicator.ts","../../src/content/native-value.ts","../../src/utils/page-readiness.ts","../../src/content/page-readiness-probe.ts","../../src/utils/scroll-position.ts","../../src/content/accessibility-tree.ts"],"sourcesContent":["export type VisualIndicatorMessageType =\n | \"SHOW_AGENT_INDICATORS\"\n | \"HIDE_AGENT_INDICATORS\"\n | \"HIDE_FOR_TOOL_USE\"\n | \"SHOW_AFTER_TOOL_USE\"\n | \"SHOW_STATIC_INDICATOR\"\n | \"HIDE_STATIC_INDICATOR\";\n\ndeclare global {\n interface Window {\n __piVisualIndicatorMessageHandler?: (type: VisualIndicatorMessageType) => void;\n }\n}\n\nconst PI_COLOR = \"59, 178, 191\";\nconst DEFAULT_HEARTBEAT_INTERVAL = 10000;\n\nlet glowBorder: HTMLDivElement | null = null;\nlet stopButton: HTMLDivElement | null = null;\nlet staticIndicator: HTMLDivElement | null = null;\nlet isActive = false;\nlet isStaticActive = false;\nlet wasActiveBeforeToolUse = false;\nlet wasStaticActiveBeforeToolUse = false;\nlet heartbeatIntervalId: number | null = null;\nlet heartbeatIntervalMs = DEFAULT_HEARTBEAT_INTERVAL;\nlet showIndicatorsWhenReady = false;\nlet showStaticIndicatorWhenReady = false;\nconst isTopFrame = window === window.top;\n\nif (isTopFrame) {\n chrome.storage.local.get(\"heartbeatInterval\").then(({ heartbeatInterval }) => {\n if (heartbeatInterval && typeof heartbeatInterval === \"number\") {\n heartbeatIntervalMs = heartbeatInterval * 1000;\n }\n });\n\n chrome.storage.onChanged.addListener((changes, areaName) => {\n if (areaName === \"local\" && changes.heartbeatInterval) {\n const newValue = changes.heartbeatInterval.newValue;\n if (newValue && typeof newValue === \"number\") {\n heartbeatIntervalMs = newValue * 1000;\n if (isStaticActive && heartbeatIntervalId) {\n clearInterval(heartbeatIntervalId);\n startHeartbeat();\n }\n }\n }\n });\n}\n\nfunction startHeartbeat() {\n heartbeatIntervalId = window.setInterval(async () => {\n try {\n const response = await chrome.runtime.sendMessage({ type: \"STATIC_INDICATOR_HEARTBEAT\" });\n if (!response?.success) hideStaticIndicator();\n } catch {\n hideStaticIndicator();\n }\n }, heartbeatIntervalMs);\n}\n\nfunction injectStyles() {\n if (document.getElementById(\"pi-agent-styles\")) return;\n\n const style = document.createElement(\"style\");\n style.id = \"pi-agent-styles\";\n style.textContent = `\n @keyframes pi-pulse {\n 0% {\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n }\n 50% {\n box-shadow: \n inset 0 0 15px rgba(${PI_COLOR}, 0.7),\n inset 0 0 25px rgba(${PI_COLOR}, 0.5),\n inset 0 0 35px rgba(${PI_COLOR}, 0.2);\n }\n 100% {\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n }\n }\n `;\n document.head.appendChild(style);\n}\n\nfunction createGlowBorder(): HTMLDivElement {\n const el = document.createElement(\"div\");\n el.id = \"pi-agent-glow\";\n el.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n z-index: 2147483646;\n opacity: 0;\n transition: opacity 0.3s ease-in-out;\n animation: pi-pulse 2s ease-in-out infinite;\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n `;\n return el;\n}\n\nfunction createStopButton(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.id = \"pi-agent-stop-container\";\n container.style.cssText = `\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n z-index: 2147483647;\n `;\n\n const button = document.createElement(\"button\");\n button.id = \"pi-agent-stop-button\";\n button.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 256 256\" fill=\"currentColor\" style=\"margin-right: 12px; vertical-align: middle;\">\n <path d=\"M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm40-112v56a12,12,0,0,1-12,12H100a12,12,0,0,1-12-12V100a12,12,0,0,1,12-12h56A12,12,0,0,1,168,100Z\"></path>\n </svg>\n <span style=\"vertical-align: middle;\">Stop Surf</span>\n `;\n button.style.cssText = `\n position: relative;\n transform: translateY(100px);\n padding: 12px 16px;\n background: #FAF9F5;\n color: #141413;\n border: 0.5px solid rgba(31, 30, 29, 0.4);\n border-radius: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-shadow: \n 0 40px 80px rgba(${PI_COLOR}, 0.24),\n 0 4px 14px rgba(${PI_COLOR}, 0.24);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n opacity: 0;\n user-select: none;\n pointer-events: auto;\n white-space: nowrap;\n margin: 0 auto;\n `;\n\n button.addEventListener(\"mouseenter\", () => {\n if (isActive) button.style.background = \"#F5F4F0\";\n });\n\n button.addEventListener(\"mouseleave\", () => {\n if (isActive) button.style.background = \"#FAF9F5\";\n });\n\n button.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"STOP_AGENT\", fromTabId: \"CURRENT_TAB\" });\n });\n\n container.appendChild(button);\n return container;\n}\n\nfunction createStaticIndicator(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.id = \"pi-agent-static-indicator\";\n container.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style=\"width: 16px; height: 16px; margin-right: 8px; flex-shrink: 0;\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"rgb(${PI_COLOR})\"/>\n <text x=\"8\" y=\"11\" font-size=\"9\" fill=\"white\" text-anchor=\"middle\" font-weight=\"bold\">π</text>\n </svg>\n <span style=\"color: #141413; font-size: 14px;\">Surf is active in this tab group</span>\n <div style=\"width: 0.5px; height: 32px; background: rgba(31, 30, 29, 0.15); margin: 0 8px;\"></div>\n <button id=\"pi-static-chat-button\" style=\"display: inline-flex; align-items: center; justify-content: center; padding: 6px; background: transparent; border: none; cursor: pointer; width: 32px; height: 32px; border-radius: 8px; transition: background 0.2s;\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"#141413\">\n <path d=\"M10 2.5C14.1421 2.5 17.5 5.85786 17.5 10C17.5 14.1421 14.1421 17.5 10 17.5H3C2.79779 17.5 2.61549 17.3782 2.53809 17.1914C2.4607 17.0046 2.50349 16.7895 2.64648 16.6465L4.35547 14.9365C3.20124 13.6175 2.5 11.8906 2.5 10C2.5 5.85786 5.85786 2.5 10 2.5Z\"/>\n </svg>\n </button>\n <button id=\"pi-static-close-button\" style=\"display: inline-flex; align-items: center; justify-content: center; padding: 6px; background: transparent; border: none; cursor: pointer; width: 32px; height: 32px; margin-left: 4px; border-radius: 8px; transition: background 0.2s;\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M15.1464 4.14642C15.3417 3.95121 15.6582 3.95118 15.8534 4.14642C16.0486 4.34168 16.0486 4.65822 15.8534 4.85346L10.7069 9.99997L15.8534 15.1465C16.0486 15.3417 16.0486 15.6583 15.8534 15.8535C15.6826 16.0244 15.4186 16.0461 15.2245 15.918L15.1464 15.8535L9.99989 10.707L4.85338 15.8535C4.65813 16.0486 4.34155 16.0486 4.14634 15.8535C3.95115 15.6583 3.95129 15.3418 4.14634 15.1465L9.29286 9.99997L4.14634 4.85346C3.95129 4.65818 3.95115 4.34162 4.14634 4.14642C4.34154 3.95128 4.65812 3.95138 4.85338 4.14642L9.99989 9.29294L15.1464 4.14642Z\" fill=\"#141413\"/>\n </svg>\n </button>\n `;\n container.style.cssText = `\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: inline-flex;\n align-items: center;\n padding: 6px 6px 6px 16px;\n background: #FAF9F5;\n border: 0.5px solid rgba(31, 30, 29, 0.30);\n border-radius: 14px;\n box-shadow: 0 40px 80px 0 rgba(0, 0, 0, 0.15);\n z-index: 2147483647;\n pointer-events: none;\n white-space: nowrap;\n user-select: none;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n `;\n\n const chatButton = container.querySelector(\"#pi-static-chat-button\") as HTMLButtonElement;\n const closeButton = container.querySelector(\"#pi-static-close-button\") as HTMLButtonElement;\n\n if (chatButton) {\n chatButton.style.pointerEvents = \"auto\";\n chatButton.addEventListener(\"mouseenter\", () => chatButton.style.background = \"#F0EEE6\");\n chatButton.addEventListener(\"mouseleave\", () => chatButton.style.background = \"transparent\");\n chatButton.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"OPEN_SIDEPANEL\" });\n });\n }\n\n if (closeButton) {\n closeButton.style.pointerEvents = \"auto\";\n closeButton.addEventListener(\"mouseenter\", () => closeButton.style.background = \"#F0EEE6\");\n closeButton.addEventListener(\"mouseleave\", () => closeButton.style.background = \"transparent\");\n closeButton.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"DISMISS_STATIC_INDICATOR\" });\n hideStaticIndicator();\n });\n }\n\n return container;\n}\n\nfunction showIndicators() {\n if (!document.body) {\n if (!showIndicatorsWhenReady) {\n showIndicatorsWhenReady = true;\n window.addEventListener(\n \"DOMContentLoaded\",\n () => {\n if (!showIndicatorsWhenReady) return;\n showIndicatorsWhenReady = false;\n showIndicators();\n },\n { once: true },\n );\n }\n return;\n }\n showIndicatorsWhenReady = false;\n if (isActive) return;\n isActive = true;\n\n injectStyles();\n\n if (!glowBorder) {\n glowBorder = createGlowBorder();\n document.body.appendChild(glowBorder);\n } else {\n glowBorder.style.display = \"\";\n }\n\n if (!stopButton) {\n stopButton = createStopButton();\n document.body.appendChild(stopButton);\n } else {\n stopButton.style.display = \"\";\n }\n\n requestAnimationFrame(() => {\n if (glowBorder) glowBorder.style.opacity = \"1\";\n if (stopButton) {\n const btn = stopButton.querySelector(\"#pi-agent-stop-button\") as HTMLElement;\n if (btn) {\n btn.style.transform = \"translateY(0)\";\n btn.style.opacity = \"1\";\n }\n }\n });\n}\n\nfunction hideIndicators() {\n showIndicatorsWhenReady = false;\n if (!isActive) return;\n isActive = false;\n\n if (glowBorder) glowBorder.style.opacity = \"0\";\n if (stopButton) {\n const btn = stopButton.querySelector(\"#pi-agent-stop-button\") as HTMLElement;\n if (btn) {\n btn.style.transform = \"translateY(100px)\";\n btn.style.opacity = \"0\";\n }\n }\n\n setTimeout(() => {\n if (!isActive) {\n if (glowBorder?.parentNode) {\n glowBorder.parentNode.removeChild(glowBorder);\n glowBorder = null;\n }\n if (stopButton?.parentNode) {\n stopButton.parentNode.removeChild(stopButton);\n stopButton = null;\n }\n }\n }, 300);\n}\n\nfunction showStaticIndicator() {\n if (!document.body) {\n if (!showStaticIndicatorWhenReady) {\n showStaticIndicatorWhenReady = true;\n window.addEventListener(\n \"DOMContentLoaded\",\n () => {\n if (!showStaticIndicatorWhenReady) return;\n showStaticIndicatorWhenReady = false;\n showStaticIndicator();\n },\n { once: true },\n );\n }\n return;\n }\n showStaticIndicatorWhenReady = false;\n if (isStaticActive) return;\n isStaticActive = true;\n\n if (!staticIndicator) {\n staticIndicator = createStaticIndicator();\n document.body.appendChild(staticIndicator);\n } else {\n staticIndicator.style.display = \"\";\n }\n\n if (heartbeatIntervalId) clearInterval(heartbeatIntervalId);\n startHeartbeat();\n}\n\nfunction hideStaticIndicator() {\n showStaticIndicatorWhenReady = false;\n if (!isStaticActive) return;\n isStaticActive = false;\n\n if (heartbeatIntervalId) {\n clearInterval(heartbeatIntervalId);\n heartbeatIntervalId = null;\n }\n\n if (staticIndicator?.parentNode) {\n staticIndicator.parentNode.removeChild(staticIndicator);\n staticIndicator = null;\n }\n}\n\nif (isTopFrame) {\n window.__piVisualIndicatorMessageHandler = (type) => {\n switch (type) {\n case \"SHOW_AGENT_INDICATORS\":\n showIndicators();\n break;\n case \"HIDE_AGENT_INDICATORS\":\n hideIndicators();\n break;\n case \"HIDE_FOR_TOOL_USE\":\n wasActiveBeforeToolUse = isActive || showIndicatorsWhenReady;\n wasStaticActiveBeforeToolUse = isStaticActive || showStaticIndicatorWhenReady;\n showIndicatorsWhenReady = false;\n showStaticIndicatorWhenReady = false;\n if (glowBorder) glowBorder.style.display = \"none\";\n if (stopButton) stopButton.style.display = \"none\";\n if (staticIndicator && isStaticActive) staticIndicator.style.display = \"none\";\n break;\n case \"SHOW_AFTER_TOOL_USE\":\n if (wasActiveBeforeToolUse) {\n if (isActive) {\n if (glowBorder) glowBorder.style.display = \"\";\n if (stopButton) stopButton.style.display = \"\";\n } else {\n showIndicators();\n }\n }\n if (wasStaticActiveBeforeToolUse) {\n if (isStaticActive && staticIndicator) {\n staticIndicator.style.display = \"\";\n } else {\n showStaticIndicator();\n }\n }\n wasActiveBeforeToolUse = false;\n wasStaticActiveBeforeToolUse = false;\n break;\n case \"SHOW_STATIC_INDICATOR\":\n showStaticIndicator();\n break;\n case \"HIDE_STATIC_INDICATOR\":\n hideStaticIndicator();\n break;\n }\n };\n\n window.addEventListener(\"beforeunload\", () => {\n hideIndicators();\n hideStaticIndicator();\n });\n}\n","/**\n * Value assignment for framework-controlled form fields.\n *\n * React, Angular, Vue and similar frameworks watch the `value` of an input\n * through their own tracker (React installs an instance property that\n * shadows the prototype accessor). Writing `element.value = text` updates\n * that tracker first, so the `input` event dispatched afterwards looks like a\n * no-op and the framework state never changes. Writing through the native\n * prototype setter leaves the tracker untouched, and the events that follow\n * report a real change.\n */\n\nexport type ValueEventName = \"input\" | \"change\" | \"blur\";\n\nexport interface NativeValueTarget {\n value: string;\n dispatchEvent(event: Event): boolean;\n}\n\nexport interface SetNativeValueResult {\n method: \"native-setter\" | \"assignment\";\n events: ValueEventName[];\n}\n\nexport const DEFAULT_VALUE_EVENTS: readonly ValueEventName[] = [\"input\", \"change\"];\n\n/**\n * Walk the prototype chain of `element` and return the first `value` setter\n * defined on a prototype. Own properties on the instance are skipped on\n * purpose: they are the framework trackers this helper must bypass.\n */\nexport function findNativeValueSetter(element: object): ((value: string) => void) | null {\n let proto: object | null = Object.getPrototypeOf(element);\n while (proto && proto !== Object.prototype) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, \"value\");\n if (descriptor?.set) {\n return descriptor.set as (value: string) => void;\n }\n proto = Object.getPrototypeOf(proto);\n }\n return null;\n}\n\n/**\n * Set `value` on a text-like input or textarea so both plain pages and\n * framework-controlled forms observe the change, then dispatch `events` in\n * order (default: `input`, then `change`).\n */\nexport function setNativeValue(\n element: NativeValueTarget,\n value: string,\n events: readonly ValueEventName[] = DEFAULT_VALUE_EVENTS,\n): SetNativeValueResult {\n const setter = findNativeValueSetter(element);\n if (setter) {\n setter.call(element, value);\n } else {\n element.value = value;\n }\n for (const name of events) {\n element.dispatchEvent(new Event(name, { bubbles: name !== \"blur\" }));\n }\n return { method: setter ? \"native-setter\" : \"assignment\", events: [...events] };\n}\n","/**\n * Page readiness classification.\n *\n * A navigation can settle in states other than \"the page you wanted\": an\n * anti-bot interstitial, a bounce to a login form, a not-found page, a\n * browser error page, or an explicit \"no results\" render. Waiting for a\n * selector on such a page only times out and hides the cause. This module\n * turns a DOM snapshot into a typed verdict so callers can branch on the\n * state instead of on a timeout.\n *\n * The classifier is pure: it only looks at the `ReadinessSnapshot` it is\n * given. The snapshot is collected in the content script (see\n * `src/content/page-readiness-probe.ts`), and every rule below is\n * site-independent: it relies on browser behaviour, vendor-neutral markup\n * conventions and generic wording, never on a particular site's layout.\n *\n * This module is bundled into the content script only. The service worker\n * side (state lists, error codes, the poll loop) lives in\n * `./readiness-poll.ts`; the two share only types, so the extension build\n * does not emit a chunk that a classic content script could not import.\n */\n\nimport type { ReadinessState } from \"./readiness-poll\";\n\nexport interface ReadinessExpectations {\n /** CSS selector that must be present and visible before the page counts as ready. */\n selector?: string;\n /** Text that must appear in the page before it counts as ready. */\n text?: string;\n /** The page URL must start with this prefix; a different URL is a bounce. */\n urlPrefix?: string;\n /** Text that marks an explicit \"no results\" render (state `empty`). */\n emptyText?: string;\n}\n\nexport interface ExpectationOutcome<T> {\n expected: T;\n matched: boolean;\n}\n\nexport interface ReadinessSnapshot {\n href: string;\n title: string;\n readyState: string;\n /** `chrome.tabs.Tab.status` when the caller knows it. */\n tabStatus?: string;\n /** Normalized visible body text, truncated to a few thousand characters. */\n bodyTextSample: string;\n /** Length of the full normalized body text. */\n bodyTextLength: number;\n /** Visible h1/h2 texts, document order. */\n headings: string[];\n visiblePasswordInputs: number;\n visibleTextInputs: number;\n /** Selectors from CHALLENGE_MARKER_SELECTORS that matched. */\n challengeMarkers: string[];\n /** Visible captcha or challenge iframes. */\n captchaFrames: number;\n selector?: ExpectationOutcome<string>;\n text?: ExpectationOutcome<string>;\n urlPrefix?: ExpectationOutcome<string>;\n emptyText?: ExpectationOutcome<string>;\n}\n\nexport interface ReadinessVerdict {\n state: ReadinessState;\n /** Human-readable reasons, most decisive first. */\n evidence: string[];\n}\n\n/**\n * Vendor-neutral markup left by common anti-bot interstitials. These are\n * markers of the challenge vendors themselves, not of any target site.\n */\nexport const CHALLENGE_MARKER_SELECTORS: readonly string[] = [\n \"#challenge-running\",\n \"#challenge-form\",\n \"#challenge-stage\",\n \"#cf-challenge-running\",\n \"form[action*='captcha' i]\",\n \"[data-sitekey][data-callback]\",\n];\n\n/** iframes that host captcha widgets. Only decisive on otherwise empty pages. */\nexport const CAPTCHA_FRAME_SELECTORS: readonly string[] = [\n \"iframe[src*='captcha' i]\",\n \"iframe[src*='challenge' i]\",\n \"iframe[title*='captcha' i]\",\n];\n\nexport const CHALLENGE_TITLE_PATTERN =\n /just a moment|attention required|access denied|verify(?:ing)? (?:that )?you are (?:a )?human|security check|checking your browser|are you a robot|bot (?:detection|check|protection)|captcha|one more step|please wait while we verify/i;\n\nexport const CHALLENGE_TEXT_PATTERN =\n /verify(?:ing)? (?:that )?you are (?:a )?human|checking (?:your|the) browser|enable javascript and cookies|unusual traffic|automated (?:access|requests|queries)|complete the security check|prove you are human/i;\n\nexport const NOT_FOUND_PATTERN =\n /\\b404\\b|\\bnot found\\b|page (?:doesn.t|does not|cannot be|could not be|can.t be) (?:exist|found)|no longer (?:available|exists)|(?:doesn.t|does not) exist\\b/i;\n\nexport const LOGIN_PATH_PATTERN =\n /(?:^|\\/)(?:log-?in|sign-?in|sign-?on|auth|authenticate|authorize|sso|oauth2?|session\\/new|users\\/sign_in|account\\/login)(?:\\/|$|\\?|#)/i;\n\nexport const LOGIN_TITLE_PATTERN = /\\b(?:log ?in|sign ?in|sign ?on|authenticate|authentication)\\b/i;\n\nexport const BROWSER_ERROR_PATTERN =\n /this site can.t be reached|took too long to respond|ERR_[A-Z_]{4,}|no internet|connection (?:was )?(?:reset|refused)/i;\n\n/** Body text shorter than this is treated as an interstitial or error page, not content. */\nexport const SHORT_PAGE_TEXT_LENGTH = 800;\n\nexport function normalizeText(value: string | null | undefined): string {\n return (value ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n\nexport function pathnameOf(href: string): string {\n try {\n return new URL(href).pathname;\n } catch {\n return \"\";\n }\n}\n\nfunction isBlankHref(href: string): boolean {\n return href === \"\" || href === \"about:blank\" || href.startsWith(\"about:blank?\");\n}\n\nfunction classifyError(snapshot: ReadinessSnapshot): ReadinessVerdict | null {\n if (snapshot.href.startsWith(\"chrome-error://\")) {\n return { state: \"error\", evidence: [`browser error page ${snapshot.href}`] };\n }\n if (snapshot.bodyTextLength < SHORT_PAGE_TEXT_LENGTH) {\n const match = snapshot.bodyTextSample.match(BROWSER_ERROR_PATTERN);\n if (match) {\n return { state: \"error\", evidence: [`page text reads like a browser error: \"${match[0]}\"`] };\n }\n }\n return null;\n}\n\nfunction classifyChallenge(snapshot: ReadinessSnapshot): ReadinessVerdict | null {\n const evidence: string[] = [];\n const shortPage = snapshot.bodyTextLength < SHORT_PAGE_TEXT_LENGTH;\n if (shortPage && snapshot.challengeMarkers.length > 0) {\n evidence.push(`challenge markup present: ${snapshot.challengeMarkers.join(\", \")}`);\n }\n const titleMatch = snapshot.title.match(CHALLENGE_TITLE_PATTERN);\n if (titleMatch) {\n evidence.push(`title \"${snapshot.title}\" matches challenge wording`);\n }\n if (shortPage) {\n const headingMatch = snapshot.headings.find((heading) => CHALLENGE_TITLE_PATTERN.test(heading));\n if (headingMatch) {\n evidence.push(`heading \"${headingMatch}\" matches challenge wording`);\n }\n const textMatch = snapshot.bodyTextSample.match(CHALLENGE_TEXT_PATTERN);\n if (textMatch) {\n evidence.push(`short page text contains \"${textMatch[0]}\"`);\n }\n if (snapshot.captchaFrames > 0) {\n evidence.push(`${snapshot.captchaFrames} captcha frame(s) on a short page`);\n }\n }\n if (evidence.length === 0) {\n return null;\n }\n // A lone captcha frame on a short page is weak on its own (cookie banners,\n // tiny login forms); require a second signal for it.\n if (evidence.length === 1 && snapshot.captchaFrames > 0 && snapshot.challengeMarkers.length === 0 && !titleMatch) {\n return null;\n }\n return { state: \"challenge\", evidence };\n}\n\nfunction classifyNotFound(snapshot: ReadinessSnapshot): ReadinessVerdict | null {\n const titleMatch = snapshot.title.match(NOT_FOUND_PATTERN);\n if (titleMatch) {\n return { state: \"not-found\", evidence: [`title \"${snapshot.title}\" matches not-found wording`] };\n }\n const heading = snapshot.headings.find((text) => NOT_FOUND_PATTERN.test(text));\n if (heading) {\n return { state: \"not-found\", evidence: [`heading \"${heading}\" matches not-found wording`] };\n }\n return null;\n}\n\nfunction classifyLogin(snapshot: ReadinessSnapshot): ReadinessVerdict | null {\n const evidence: string[] = [];\n const passwordVisible = snapshot.visiblePasswordInputs > 0;\n const urlLooksLogin = LOGIN_PATH_PATTERN.test(pathnameOf(snapshot.href));\n const titleLooksLogin = LOGIN_TITLE_PATTERN.test(snapshot.title);\n const bounced = snapshot.urlPrefix !== undefined && !snapshot.urlPrefix.matched;\n\n if (passwordVisible) evidence.push(`${snapshot.visiblePasswordInputs} visible password field(s)`);\n if (urlLooksLogin) evidence.push(`URL path ${pathnameOf(snapshot.href)} looks like a login route`);\n if (titleLooksLogin) evidence.push(`title \"${snapshot.title}\" mentions signing in`);\n if (bounced && snapshot.urlPrefix) {\n evidence.push(`URL ${snapshot.href} left the expected prefix ${snapshot.urlPrefix.expected}`);\n }\n\n const isLogin =\n (passwordVisible && (urlLooksLogin || titleLooksLogin || bounced)) ||\n (urlLooksLogin && (titleLooksLogin || bounced));\n return isLogin ? { state: \"login\", evidence } : null;\n}\n\nfunction describeExpectation(name: string, outcome: ExpectationOutcome<string> | undefined): string | null {\n if (!outcome) return null;\n return `${name} \"${outcome.expected}\" ${outcome.matched ? \"found\" : \"not found\"}`;\n}\n\n/**\n * Classify a snapshot. Negative states win over loading so a bounce is\n * reported as soon as it renders instead of after a timeout; an explicit\n * empty render wins over a missing content selector; expectations gate\n * `ready`.\n */\nexport function classifyReadiness(snapshot: ReadinessSnapshot): ReadinessVerdict {\n const negative =\n classifyError(snapshot) ??\n classifyChallenge(snapshot) ??\n classifyNotFound(snapshot) ??\n classifyLogin(snapshot);\n if (negative) {\n return negative;\n }\n\n const evidence: string[] = [];\n const blank = isBlankHref(snapshot.href);\n const expectsBlank = snapshot.urlPrefix?.expected.startsWith(\"about:blank\") === true;\n if (blank && !expectsBlank) {\n return { state: \"loading\", evidence: [`URL is ${snapshot.href || \"empty\"}`] };\n }\n if (snapshot.urlPrefix && !snapshot.urlPrefix.matched) {\n return {\n state: \"loading\",\n evidence: [`URL ${snapshot.href} does not start with ${snapshot.urlPrefix.expected}`],\n };\n }\n\n const contentPresent = snapshot.selector?.matched === true || snapshot.text?.matched === true;\n if (snapshot.readyState !== \"complete\" && !contentPresent) {\n evidence.push(`document.readyState is ${snapshot.readyState}`);\n if (snapshot.tabStatus && snapshot.tabStatus !== \"complete\") {\n evidence.push(`tab status is ${snapshot.tabStatus}`);\n }\n return { state: \"loading\", evidence };\n }\n\n if (snapshot.emptyText?.matched) {\n return { state: \"empty\", evidence: [`empty-state text \"${snapshot.emptyText.expected}\" found`] };\n }\n\n const missing = [\n snapshot.selector && !snapshot.selector.matched ? describeExpectation(\"selector\", snapshot.selector) : null,\n snapshot.text && !snapshot.text.matched ? describeExpectation(\"text\", snapshot.text) : null,\n ].filter((entry): entry is string => entry !== null);\n if (missing.length > 0) {\n return { state: \"loading\", evidence: missing };\n }\n\n const matched = [\n describeExpectation(\"selector\", snapshot.selector),\n describeExpectation(\"text\", snapshot.text),\n ].filter((entry): entry is string => entry !== null);\n if (matched.length === 0) {\n matched.push(`document.readyState is ${snapshot.readyState}`);\n }\n if (snapshot.visiblePasswordInputs > 0) {\n matched.push(`${snapshot.visiblePasswordInputs} visible password field(s), page otherwise looks ready`);\n }\n return { state: \"ready\", evidence: matched };\n}\n","import {\n CAPTCHA_FRAME_SELECTORS,\n CHALLENGE_MARKER_SELECTORS,\n type ReadinessExpectations,\n type ReadinessSnapshot,\n type ReadinessVerdict,\n classifyReadiness,\n normalizeText,\n} from \"../utils/page-readiness\";\n\n/**\n * The minimal view of a document the snapshot collector needs. Real pages\n * go through `createDomProbe`; tests can hand in a plain object.\n */\nexport interface ReadinessProbeDom {\n href: string;\n title: string;\n readyState: string;\n /** Full normalized visible text of the body. */\n bodyText(): string;\n /** Number of elements matching `selector` that are rendered and visible. */\n countVisible(selector: string): number;\n /** Visible h1/h2 texts in document order. */\n visibleHeadings(): string[];\n}\n\nexport const BODY_TEXT_SAMPLE_LENGTH = 4000;\n\nconst TEXT_INPUT_SELECTOR =\n \"input:not([type]), input[type='text'], input[type='email'], input[type='tel'], input[type='search'], input[type='url'], textarea\";\n\nexport class InvalidReadinessSelectorError extends Error {\n constructor(selector: string, cause: unknown) {\n const reason = cause instanceof Error ? cause.message : String(cause);\n super(`Invalid CSS selector \"${selector}\": ${reason}`);\n this.name = \"InvalidReadinessSelectorError\";\n }\n}\n\nfunction safeCount(dom: ReadinessProbeDom, selector: string): number {\n try {\n return dom.countVisible(selector);\n } catch {\n return 0;\n }\n}\n\n/** Rejects invalid caller-provided CSS. */\nexport function collectReadinessSnapshot(\n dom: ReadinessProbeDom,\n expect: ReadinessExpectations = {},\n): ReadinessSnapshot {\n const bodyText = dom.bodyText();\n const lowerBody = bodyText.toLowerCase();\n const snapshot: ReadinessSnapshot = {\n href: dom.href,\n title: normalizeText(dom.title),\n readyState: dom.readyState,\n bodyTextSample: bodyText.slice(0, BODY_TEXT_SAMPLE_LENGTH),\n bodyTextLength: bodyText.length,\n headings: dom.visibleHeadings().map(normalizeText).filter(Boolean).slice(0, 5),\n visiblePasswordInputs: safeCount(dom, \"input[type='password']\"),\n visibleTextInputs: safeCount(dom, TEXT_INPUT_SELECTOR),\n challengeMarkers: CHALLENGE_MARKER_SELECTORS.filter((selector) => safeCount(dom, selector) > 0),\n captchaFrames: CAPTCHA_FRAME_SELECTORS.reduce((sum, selector) => sum + safeCount(dom, selector), 0),\n };\n\n if (expect.selector) {\n try {\n snapshot.selector = { expected: expect.selector, matched: dom.countVisible(expect.selector) > 0 };\n } catch (error) {\n throw new InvalidReadinessSelectorError(expect.selector, error);\n }\n }\n if (expect.text) {\n snapshot.text = {\n expected: expect.text,\n matched: lowerBody.includes(normalizeText(expect.text).toLowerCase()),\n };\n }\n if (expect.urlPrefix) {\n snapshot.urlPrefix = { expected: expect.urlPrefix, matched: dom.href.startsWith(expect.urlPrefix) };\n }\n if (expect.emptyText) {\n snapshot.emptyText = {\n expected: expect.emptyText,\n matched: lowerBody.includes(normalizeText(expect.emptyText).toLowerCase()),\n };\n }\n return snapshot;\n}\n\nexport interface PageReadinessReport extends ReadinessVerdict {\n href: string;\n title: string;\n readyState: string;\n snapshot: Omit<ReadinessSnapshot, \"bodyTextSample\">;\n}\n\nexport function probePageReadiness(\n dom: ReadinessProbeDom,\n expect: ReadinessExpectations = {},\n): PageReadinessReport {\n const snapshot = collectReadinessSnapshot(dom, expect);\n const verdict = classifyReadiness(snapshot);\n const { bodyTextSample: _sample, ...rest } = snapshot;\n return {\n ...verdict,\n href: snapshot.href,\n title: snapshot.title,\n readyState: snapshot.readyState,\n snapshot: rest,\n };\n}\n\n/** Adapter over a live document. Visibility follows the same rules as wait.element. */\nexport function createDomProbe(doc: Document, win: Window): ReadinessProbeDom {\n const isVisible = (element: Element): boolean => {\n const style = win.getComputedStyle(element);\n const box = element as HTMLElement;\n return (\n style.display !== \"none\" &&\n style.visibility !== \"hidden\" &&\n style.opacity !== \"0\" &&\n box.offsetWidth > 0 &&\n box.offsetHeight > 0\n );\n };\n return {\n href: win.location.href,\n title: doc.title,\n readyState: doc.readyState,\n bodyText: () => normalizeText(doc.body?.innerText ?? doc.body?.textContent ?? \"\"),\n countVisible: (selector) => Array.from(doc.querySelectorAll(selector)).filter(isVisible).length,\n visibleHeadings: () =>\n Array.from(doc.querySelectorAll(\"h1, h2\"))\n .filter(isVisible)\n .map((element) => normalizeText(element.textContent)),\n };\n}\n","export function scrollToPosition(pos: string | number, selector: string | null = null) {\n const findScrollable = (): Element => {\n const candidates = [...document.querySelectorAll(\"*\")]\n .filter((element) => element.scrollHeight > element.clientHeight && element.clientHeight > 200)\n .sort((left, right) => right.scrollHeight - left.scrollHeight);\n return candidates[0] || document.documentElement;\n };\n\n const container = selector ? document.querySelector(selector) || findScrollable() : findScrollable();\n if (!container) return { error: \"No scrollable container found\" };\n\n if (pos === \"bottom\") {\n container.scrollTop = container.scrollHeight;\n } else if (pos === \"top\") {\n container.scrollTop = 0;\n } else if (typeof pos === \"number\") {\n container.scrollTop = pos;\n }\n\n return {\n scrollTop: container.scrollTop,\n scrollHeight: container.scrollHeight,\n clientHeight: container.clientHeight,\n atBottom: container.scrollTop + container.clientHeight >= container.scrollHeight - 10,\n atTop: container.scrollTop < 10,\n };\n}\n\nexport interface SemanticScrollGeometry {\n scrollTop: number;\n scrollHeight: number;\n clientHeight: number;\n intervalStart: number;\n intervalEnd: number;\n atTop: boolean;\n atBottom: boolean;\n}\n\ntype PinnedScope = { element: WeakRef<Element>; documentToken: string };\nconst semanticScrollScopes = new Map<string, PinnedScope>();\n\nfunction selectSemanticScrollContainer(): Element | null {\n const candidates = [...document.querySelectorAll(\"*\")]\n .filter((element) => element.scrollHeight > element.clientHeight && element.clientHeight > 0)\n .sort((left, right) => right.scrollHeight - left.scrollHeight);\n return candidates[0] || document.scrollingElement || document.documentElement || null;\n}\n\nfunction clippedGeometry(container: Element): SemanticScrollGeometry | null {\n const scrollHeight = Math.max(0, Number(container.scrollHeight) || 0);\n const rawClientHeight = Math.max(0, Number(container.clientHeight) || 0);\n const scrollTop = Math.min(\n Math.max(0, Number(container.scrollTop) || 0),\n Math.max(0, scrollHeight - rawClientHeight),\n );\n const isDocument = container === document.documentElement || container === document.scrollingElement;\n let clippedOffset = 0;\n let clientHeight = Math.min(rawClientHeight || window.innerHeight, window.innerHeight);\n\n if (!isDocument) {\n const rect = container.getBoundingClientRect();\n const clippedTop = Math.max(0, rect.top);\n const clippedBottom = Math.min(window.innerHeight, rect.bottom);\n clientHeight = Math.max(0, Math.min(rawClientHeight, clippedBottom - clippedTop));\n clippedOffset = Math.max(0, clippedTop - rect.top);\n }\n if (clientHeight <= 0) return null;\n\n const intervalStart = Math.min(scrollHeight, scrollTop + clippedOffset);\n const intervalEnd = Math.min(scrollHeight, intervalStart + clientHeight);\n return {\n scrollTop,\n scrollHeight,\n clientHeight,\n intervalStart,\n intervalEnd,\n atTop: intervalStart <= 0,\n atBottom: intervalEnd >= scrollHeight,\n };\n}\n\nexport function inspectSemanticScrollScope(documentToken: string) {\n const container = selectSemanticScrollContainer();\n if (!container) return { success: false, reason: \"unsupported_scroll_scope\" };\n const geometry = clippedGeometry(container);\n if (!geometry) return { success: false, reason: \"unsupported_scroll_scope\" };\n const scopeToken = globalThis.crypto?.randomUUID?.() ||\n `scope-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n semanticScrollScopes.set(scopeToken, { element: new WeakRef(container), documentToken });\n return { success: true, scopeToken, geometry };\n}\n\nexport function moveSemanticScrollScope(\n action: \"top\" | \"advance\",\n scopeToken: string,\n documentToken: string,\n) {\n const scope = semanticScrollScopes.get(scopeToken);\n const container = scope?.element.deref();\n if (\n !scope || scope.documentToken !== documentToken || !container ||\n (\"isConnected\" in container && container.isConnected === false)\n ) {\n semanticScrollScopes.delete(scopeToken);\n return { success: false, reason: \"stale_scroll_scope\" };\n }\n const before = clippedGeometry(container);\n if (!before) return { success: false, reason: \"stale_scroll_scope\" };\n\n if (action === \"top\") {\n container.scrollTop = 0;\n } else if (action === \"advance\") {\n container.scrollTop = before.scrollTop + Math.floor(before.clientHeight * 0.75);\n } else {\n return { success: false, reason: \"unsupported_scroll_action\" };\n }\n\n const geometry = clippedGeometry(container);\n if (!geometry) return { success: false, reason: \"stale_scroll_scope\" };\n return { success: true, scopeToken, geometry };\n}\n","import { setNativeValue } from \"./native-value\";\nimport {\n createDomProbe,\n InvalidReadinessSelectorError,\n probePageReadiness,\n} from \"./page-readiness-probe\";\nimport type { VisualIndicatorMessageType } from \"./visual-indicator.ts\";\nimport {\n inspectSemanticScrollScope,\n moveSemanticScrollScope,\n scrollToPosition,\n} from \"../utils/scroll-position\";\n\nexport {};\n\ndeclare global {\n interface Window {\n __piElementMap?: Record<string, { element: WeakRef<Element>; role: string; name: string }>;\n __piLastSnapshot?: { content: string; timestamp: number };\n __piHelpers?: typeof piHelpersImpl;\n piHelpers?: typeof piHelpersImpl;\n __piRefs?: Record<string, Element>;\n }\n}\n\ninterface ModalState {\n type: 'dialog' | 'alertdialog';\n description: string;\n clearedBy: string;\n}\n\nconst SEMANTIC_MAX_CANDIDATES = 64;\nconst SEMANTIC_MAX_CHUNKS = 48;\nconst SEMANTIC_MAX_BYTES = 24 * 1024;\nconst semanticDocumentToken = (() => {\n try {\n return globalThis.crypto?.randomUUID?.() || `doc-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n } catch {\n return `doc-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n})();\n\nfunction boundedText(value: string | null | undefined, maxLength: number): string {\n return (value || \"\").replace(/\\s+/g, \" \").trim().slice(0, maxLength);\n}\n\nfunction semanticElementType(element: Element): string {\n const tag = element.tagName.toLowerCase();\n if (tag === \"input\") return boundedText(element.getAttribute(\"type\") || \"text\", 32).toLowerCase();\n return tag;\n}\n\ntype SemanticInteractiveState = {\n checked?: boolean | \"mixed\";\n selected?: boolean;\n};\n\nfunction semanticInteractiveState(element: Element): SemanticInteractiveState | undefined {\n const state: SemanticInteractiveState = {};\n const checked = element.getAttribute(\"aria-checked\");\n if (checked === \"true\" || checked === \"false\" || checked === \"mixed\") {\n state.checked = checked === \"mixed\" ? \"mixed\" : checked === \"true\";\n } else if (element instanceof HTMLInputElement && (element.type === \"checkbox\" || element.type === \"radio\")) {\n state.checked = element.type === \"checkbox\" && element.indeterminate ? \"mixed\" : element.checked;\n }\n const selected = element.getAttribute(\"aria-selected\");\n if (selected === \"true\" || selected === \"false\") {\n state.selected = selected === \"true\";\n } else if (element.tagName.toLowerCase() === \"option\") {\n state.selected = (element as HTMLOptionElement).selected;\n }\n return Object.keys(state).length ? state : undefined;\n}\n\nfunction semanticStateEvidence(candidate: {\n role: string;\n name: string;\n state?: SemanticInteractiveState;\n}): string {\n if (!candidate.state) return \"\";\n const labels: string[] = [];\n if (candidate.state.checked !== undefined) {\n labels.push(candidate.state.checked === \"mixed\" ? \"[checked=mixed]\" : candidate.state.checked ? \"[checked]\" : \"[unchecked]\");\n }\n if (candidate.state.selected !== undefined) {\n labels.push(candidate.state.selected ? \"[selected]\" : \"[not-selected]\");\n }\n const name = candidate.name ? ` \"${candidate.name.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"` : \"\";\n return boundedText(`${candidate.role}${name} ${labels.join(\" \")}`, 240);\n}\n\n// Accessible labels are deliberately rebuilt here rather than copied from the\n// ordinary read tree: the latter preserves legacy behavior that can use an\n// input's current value as its name.\nfunction getValueFreeSemanticName(element: Element): string {\n const labelledBy = element.getAttribute(\"aria-labelledby\");\n if (labelledBy) {\n const label = labelledBy.split(/\\s+/).map((id) => document.getElementById(id)?.textContent || \"\").join(\" \");\n if (boundedText(label, 160)) return boundedText(label, 160);\n }\n for (const attribute of [\"aria-label\", \"placeholder\", \"title\", \"alt\"]) {\n const label = boundedText(element.getAttribute(attribute), 160);\n if (label) return label;\n }\n if (element.id) {\n const label = document.querySelector(`label[for=\"${element.id}\"]`);\n const text = boundedText(label?.textContent, 160);\n if (text) return text;\n }\n const tag = element.tagName.toLowerCase();\n if ([\"button\", \"a\", \"summary\"].includes(tag)) {\n const text = boundedText(element.textContent, 160);\n if (text) return text;\n if (tag === \"a\") {\n const image = element.querySelector(\"img\");\n for (const attribute of [\"aria-label\", \"alt\", \"title\"]) {\n const label = boundedText(image?.getAttribute(attribute), 160);\n if (label) return label;\n }\n }\n }\n return \"\";\n}\n\nfunction isSemanticControl(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return [\"input\", \"textarea\", \"select\", \"option\", \"button\"].includes(tag) || element.getAttribute(\"contenteditable\") === \"true\";\n}\n\nfunction isVisibleSemanticElement(element: Element): boolean {\n const style = window.getComputedStyle(element);\n const rect = element.getBoundingClientRect();\n return style.display !== \"none\" && style.visibility !== \"hidden\" && style.opacity !== \"0\" &&\n rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0;\n}\n\nfunction collectValueFreeText(root: Element, maxLength: number): string {\n const parts: string[] = [];\n const visit = (node: Node): void => {\n if (parts.join(\" \").length >= maxLength) return;\n if (node.nodeType === Node.TEXT_NODE) {\n const value = boundedText(node.textContent, maxLength);\n if (value) parts.push(value);\n return;\n }\n if (!(node instanceof Element) || isSemanticControl(node)) return;\n const tag = node.tagName.toLowerCase();\n if ([\"script\", \"style\", \"noscript\", \"template\"].includes(tag)) return;\n for (const child of Array.from(node.childNodes)) visit(child);\n };\n visit(root);\n return boundedText(parts.join(\" \"), maxLength);\n}\n\nfunction semanticNearbyContext(element: Element, name: string): string {\n const normalizedName = boundedText(name, 160).toLocaleLowerCase();\n let fallback = \"\";\n let ancestor = element.parentElement;\n for (let depth = 0; ancestor && depth < 4; depth++, ancestor = ancestor.parentElement) {\n const text = collectValueFreeText(ancestor, 240);\n if (!text) continue;\n fallback = text;\n if (text.toLocaleLowerCase() !== normalizedName) return text;\n }\n return fallback;\n}\n\nfunction buildSemanticObservation() {\n const seenElements = new Set<Element>();\n const allCandidates = Object.entries(getElementMap()).flatMap(([ref, entry]) => {\n const element = entry.element.deref();\n if (!element || seenElements.has(element) || (\"isConnected\" in element && element.isConnected === false) || !isVisibleSemanticElement(element)) return [];\n seenElements.add(element);\n const role = getResolvedRole(element);\n if (!isFocusable(element) && role === \"generic\") return [];\n const name = getValueFreeSemanticName(element);\n return [{\n ref,\n role: boundedText(role, 40),\n name,\n type: semanticElementType(element),\n state: semanticInteractiveState(element),\n representation: element.tagName.toLowerCase() === \"a\"\n ? boundedText(element.textContent, 160) ? \"text\" : element.querySelector(\"img\") ? \"image\" : \"other\"\n : undefined,\n href: element.tagName.toLowerCase() === \"a\" ? boundedText(element.getAttribute(\"href\"), 2048) || undefined : undefined,\n download: element.tagName.toLowerCase() === \"a\" && element.hasAttribute(\"download\") || undefined,\n nearbyText: semanticNearbyContext(element, name),\n }];\n });\n const candidates = allCandidates.slice(0, SEMANTIC_MAX_CANDIDATES);\n\n const stateChunks = candidates.flatMap((candidate) => {\n const text = semanticStateEvidence(candidate);\n return text ? [{ text, refs: [candidate.ref] }] : [];\n });\n const associatedText = new Map<string, string[]>();\n for (const candidate of candidates) {\n if (!candidate.nearbyText) continue;\n const refs = associatedText.get(candidate.nearbyText) || [];\n refs.push(candidate.ref);\n associatedText.set(candidate.nearbyText, refs);\n }\n const text = document.body ? collectValueFreeText(document.body, 12 * 1024) : \"\";\n const pageChunks = text.match(/.{1,400}(?:\\s|$)/g)?.map((chunk) => boundedText(chunk, 400)).filter(Boolean) || [];\n const rawChunks = [\n ...stateChunks,\n ...Array.from(associatedText, ([text, refs]) => ({ text, refs })),\n ...pageChunks.filter((text) => !associatedText.has(text)).map((text) => ({ text, refs: [] as string[] })),\n ];\n const chunks = rawChunks.slice(0, SEMANTIC_MAX_CHUNKS).map(({ text, refs }, index) => ({ id: `c${index + 1}`, text, refs }));\n const observation = {\n version: 1,\n identity: {\n fullUrl: window.location.href,\n documentToken: semanticDocumentToken,\n },\n page: {\n title: boundedText(document.title, 300),\n readyState: document.readyState,\n modals: detectModalStates().slice(0, 8),\n },\n candidates,\n chunks,\n omitted: {\n candidates: Math.max(0, allCandidates.length - candidates.length),\n chunks: Math.max(0, rawChunks.length - chunks.length),\n },\n };\n while (new TextEncoder().encode(JSON.stringify(observation)).length > SEMANTIC_MAX_BYTES && observation.chunks.length) {\n observation.chunks.pop();\n observation.omitted.chunks++;\n }\n while (new TextEncoder().encode(JSON.stringify(observation)).length > SEMANTIC_MAX_BYTES && observation.candidates.length) {\n observation.candidates.pop();\n observation.omitted.candidates++;\n }\n return observation;\n}\n\nfunction semanticGuardError(element: Element | undefined, expected: any, requireElement = true): string | null {\n if (!expected || typeof expected !== \"object\") return null;\n if (window.location.href !== expected.fullUrl || semanticDocumentToken !== expected.documentToken) return \"stale_observation\";\n if (!requireElement) return null;\n if (!element || (\"isConnected\" in element && element.isConnected === false)) return \"stale_observation\";\n if (\n expected.ref !== undefined &&\n (getResolvedRole(element) !== expected.role ||\n getValueFreeSemanticName(element) !== expected.name ||\n semanticElementType(element) !== expected.type)\n ) return \"stale_observation\";\n return null;\n}\n\nfunction semanticElementIdentity(element?: Element, ref?: string) {\n return {\n fullUrl: window.location.href,\n documentToken: semanticDocumentToken,\n ...(element && ref ? {\n ref,\n role: getResolvedRole(element),\n name: getValueFreeSemanticName(element),\n type: semanticElementType(element),\n } : {}),\n };\n}\n\nfunction compareSemanticElement(element: Element, predicate: any): { success: boolean; matches: boolean; reason: string } {\n if (!predicate || typeof predicate !== \"object\" || typeof predicate.kind !== \"string\") {\n return { success: false, matches: false, reason: \"unsupported_predicate\" };\n }\n switch (predicate.kind) {\n case \"visible\":\n return { success: true, matches: isVisibleSemanticElement(element), reason: \"compared\" };\n case \"checkedEquals\": { // Actual state is deliberately never included in the response.\n if (typeof predicate.expected !== \"boolean\") {\n return { success: false, matches: false, reason: \"unsupported_predicate\" };\n }\n const tag = element.tagName.toLowerCase();\n const type = semanticElementType(element);\n if (tag === \"input\" && (type === \"checkbox\" || type === \"radio\")) {\n const control = element as HTMLInputElement;\n if (control.indeterminate) return { success: true, matches: false, reason: \"indeterminate\" };\n return { success: true, matches: control.checked === predicate.expected, reason: \"compared\" };\n }\n const role = getResolvedRole(element);\n if ([\"checkbox\", \"radio\", \"switch\", \"menuitemcheckbox\", \"menuitemradio\"].includes(role)) {\n const state = element.getAttribute(\"aria-checked\");\n if (state !== \"true\" && state !== \"false\") {\n return { success: false, matches: false, reason: \"unsupported_control\" };\n }\n return { success: true, matches: (state === \"true\") === predicate.expected, reason: \"compared\" };\n }\n return { success: false, matches: false, reason: \"unsupported_control\" };\n }\n case \"valueEquals\": {\n if (typeof predicate.expected !== \"string\") {\n return { success: false, matches: false, reason: \"unsupported_predicate\" };\n }\n const tag = element.tagName.toLowerCase();\n if (![\"input\", \"textarea\", \"select\"].includes(tag) ||\n tag === \"input\" && semanticElementType(element) === \"file\") {\n return { success: false, matches: false, reason: \"unsupported_control\" };\n }\n return {\n success: true,\n matches: (element as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement).value === predicate.expected,\n reason: \"compared\",\n };\n }\n case \"textEquals\":\n case \"textContains\": {\n if (typeof predicate.expected !== \"string\") {\n return { success: false, matches: false, reason: \"unsupported_predicate\" };\n }\n const actual = boundedText(element.textContent, 16 * 1024);\n const expected = boundedText(predicate.expected, 16 * 1024);\n return {\n success: true,\n matches: predicate.kind === \"textEquals\" ? actual === expected : actual.includes(expected),\n reason: \"compared\",\n };\n }\n default:\n return { success: false, matches: false, reason: \"unsupported_predicate\" };\n }\n}\n\nconst VALID_ARIA_ROLES = new Set([\n \"alert\", \"alertdialog\", \"application\", \"article\", \"banner\", \"blockquote\",\n \"button\", \"caption\", \"cell\", \"checkbox\", \"code\", \"columnheader\", \"combobox\",\n \"complementary\", \"contentinfo\", \"definition\", \"deletion\", \"dialog\", \"directory\",\n \"document\", \"emphasis\", \"feed\", \"figure\", \"form\", \"generic\", \"grid\", \"gridcell\",\n \"group\", \"heading\", \"img\", \"insertion\", \"link\", \"list\", \"listbox\", \"listitem\",\n \"log\", \"main\", \"mark\", \"marquee\", \"math\", \"menu\", \"menubar\", \"menuitem\",\n \"menuitemcheckbox\", \"menuitemradio\", \"meter\", \"navigation\", \"none\", \"note\",\n \"option\", \"paragraph\", \"presentation\", \"progressbar\", \"radio\", \"radiogroup\",\n \"region\", \"row\", \"rowgroup\", \"rowheader\", \"scrollbar\", \"search\", \"searchbox\",\n \"separator\", \"slider\", \"spinbutton\", \"status\", \"strong\", \"subscript\",\n \"superscript\", \"switch\", \"tab\", \"table\", \"tablist\", \"tabpanel\", \"term\",\n \"textbox\", \"time\", \"timer\", \"toolbar\", \"tooltip\", \"tree\", \"treegrid\", \"treeitem\"\n]);\n\nfunction isFocusable(element: Element): boolean {\n const tagName = element.tagName.toLowerCase();\n if ([\"button\", \"input\", \"select\", \"textarea\"].includes(tagName)) {\n return !(element as HTMLButtonElement).disabled;\n }\n if (tagName === \"a\" && element.hasAttribute(\"href\")) return true;\n if (element.hasAttribute(\"tabindex\")) {\n const tabindex = parseInt(element.getAttribute(\"tabindex\") || \"\", 10);\n return !isNaN(tabindex) && tabindex >= 0;\n }\n if (element.getAttribute(\"contenteditable\") === \"true\") return true;\n return false;\n}\n\nfunction getExplicitRole(element: Element): string | null {\n const roleAttr = element.getAttribute(\"role\");\n if (!roleAttr) return null;\n const roles = roleAttr.split(/\\s+/).filter(r => r);\n for (const role of roles) {\n if (VALID_ARIA_ROLES.has(role)) {\n return role;\n }\n }\n return null;\n}\n\nfunction getImplicitRole(element: Element): string {\n const tag = element.tagName.toLowerCase();\n const type = element.getAttribute(\"type\");\n\n const tagRoles: Record<string, string | ((el: Element) => string)> = {\n a: (el) => el.hasAttribute(\"href\") ? \"link\" : \"generic\",\n article: \"article\",\n aside: \"complementary\",\n button: \"button\",\n datalist: \"listbox\",\n dd: \"definition\",\n details: \"group\",\n dialog: \"dialog\",\n dt: \"term\",\n fieldset: \"group\",\n figure: \"figure\",\n footer: (el) => el.closest(\"article, aside, main, nav, section\") ? \"generic\" : \"contentinfo\",\n form: (el) => el.hasAttribute(\"aria-label\") || el.hasAttribute(\"aria-labelledby\") ? \"form\" : \"generic\",\n h1: \"heading\", h2: \"heading\", h3: \"heading\", h4: \"heading\", h5: \"heading\", h6: \"heading\",\n header: (el) => el.closest(\"article, aside, main, nav, section\") ? \"generic\" : \"banner\",\n hr: \"separator\",\n img: (el) => el.getAttribute(\"alt\") === \"\" ? \"presentation\" : \"img\",\n li: \"listitem\",\n main: \"main\",\n math: \"math\",\n menu: \"list\",\n meter: \"meter\",\n nav: \"navigation\",\n ol: \"list\",\n optgroup: \"group\",\n option: \"option\",\n output: \"status\",\n p: \"paragraph\",\n progress: \"progressbar\",\n search: \"search\",\n section: (el) => el.hasAttribute(\"aria-label\") || el.hasAttribute(\"aria-labelledby\") ? \"region\" : \"generic\",\n select: (el) => {\n const s = el as HTMLSelectElement;\n return s.hasAttribute(\"multiple\") || (s.size && s.size > 1) ? \"listbox\" : \"combobox\";\n },\n table: \"table\",\n tbody: \"rowgroup\",\n td: \"cell\",\n textarea: \"textbox\",\n tfoot: \"rowgroup\",\n th: \"columnheader\",\n thead: \"rowgroup\",\n time: \"time\",\n tr: \"row\",\n ul: \"list\",\n };\n\n if (tag === \"input\") {\n const inputRoles: Record<string, string> = {\n button: \"button\",\n checkbox: \"checkbox\",\n email: \"textbox\",\n file: \"button\",\n image: \"button\",\n number: \"spinbutton\",\n radio: \"radio\",\n range: \"slider\",\n reset: \"button\",\n search: \"searchbox\",\n submit: \"button\",\n tel: \"textbox\",\n text: \"textbox\",\n url: \"textbox\",\n };\n return inputRoles[type || \"\"] || \"textbox\";\n }\n\n const roleOrFn = tagRoles[tag];\n if (typeof roleOrFn === \"function\") {\n return roleOrFn(element);\n }\n return roleOrFn || \"generic\";\n}\n\nfunction getResolvedRole(element: Element): string {\n const explicitRole = getExplicitRole(element);\n \n if (!explicitRole) {\n return getImplicitRole(element);\n }\n \n if ((explicitRole === \"none\" || explicitRole === \"presentation\") && isFocusable(element)) {\n return getImplicitRole(element);\n }\n \n return explicitRole;\n}\n\nif (!window.__piElementMap) window.__piElementMap = {};\n\ninterface ElementRef {\n role: string;\n name: string;\n ref: string;\n}\n\nconst elementRefs = new WeakMap<Element, ElementRef>();\nlet globalRefCounter = 0;\n\nfunction getOrAssignRef(element: Element, role: string, name: string): string {\n const existing = elementRefs.get(element);\n if (existing && existing.role === role && existing.name === name) {\n return existing.ref;\n }\n \n const ref = `e${++globalRefCounter}`;\n elementRefs.set(element, { role, name, ref });\n return ref;\n}\n\nfunction detectModalStates(): ModalState[] {\n const modals: ModalState[] = [];\n \n const dialogs = document.querySelectorAll('[role=\"dialog\"], [role=\"alertdialog\"], dialog[open]');\n dialogs.forEach(dialog => {\n const style = window.getComputedStyle(dialog);\n const isVisible = style.display !== 'none' && \n style.visibility !== 'hidden' && \n style.opacity !== '0' &&\n (dialog as HTMLElement).offsetWidth > 0 &&\n (dialog as HTMLElement).offsetHeight > 0;\n if (!isVisible) return;\n \n const role = dialog.getAttribute('role') || 'dialog';\n let title = dialog.getAttribute('aria-label') || \n dialog.querySelector('[role=\"heading\"], h1, h2, h3')?.textContent?.trim() ||\n 'Dialog';\n if (title.length > 100) title = title.substring(0, 100) + '...';\n modals.push({\n type: role as 'dialog' | 'alertdialog',\n description: `${role}: ${title}`,\n clearedBy: 'computer(action=key, text=Escape)',\n });\n });\n \n return modals;\n}\n\nconst piHelpersImpl = {\n wait(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n\n async waitForSelector(\n selector: string,\n options: { state?: 'visible' | 'hidden' | 'attached' | 'detached'; timeout?: number } = {}\n ): Promise<Element | null> {\n const { state = 'visible', timeout = 20000 } = options;\n\n const isElementVisible = (el: Element | null): boolean => {\n if (!el) return false;\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && \n style.visibility !== 'hidden' && \n style.opacity !== '0' &&\n (el as HTMLElement).offsetWidth > 0 &&\n (el as HTMLElement).offsetHeight > 0;\n };\n\n const checkElement = (): Element | null => {\n const el = document.querySelector(selector);\n switch (state) {\n case 'attached':\n return el;\n case 'detached':\n return el ? null : document.body;\n case 'hidden':\n if (!el) return document.body;\n return isElementVisible(el) ? null : el;\n case 'visible':\n default:\n return isElementVisible(el) ? el : null;\n }\n };\n\n return new Promise((resolve, reject) => {\n const result = checkElement();\n if (result) {\n resolve(state === 'detached' || state === 'hidden' ? null : result);\n return;\n }\n\n const observer = new MutationObserver(() => {\n const result = checkElement();\n if (result) {\n observer.disconnect();\n clearTimeout(timeoutId);\n resolve(state === 'detached' || state === 'hidden' ? null : result);\n }\n });\n\n const timeoutId = setTimeout(() => {\n observer.disconnect();\n reject(new Error(`Timeout waiting for \"${selector}\" to be ${state}`));\n }, timeout);\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'class', 'hidden']\n });\n });\n },\n\n async waitForText(\n text: string,\n options: { selector?: string; timeout?: number } = {}\n ): Promise<Element | null> {\n const { selector, timeout = 20000 } = options;\n\n const checkText = (): Element | null => {\n const root = selector ? document.querySelector(selector) : document.body;\n if (!root) return null;\n \n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n while (walker.nextNode()) {\n if (walker.currentNode.textContent?.includes(text)) {\n return walker.currentNode.parentElement;\n }\n }\n return null;\n };\n\n return new Promise((resolve, reject) => {\n const result = checkText();\n if (result) {\n resolve(result);\n return;\n }\n\n const observer = new MutationObserver(() => {\n const result = checkText();\n if (result) {\n observer.disconnect();\n clearTimeout(timeoutId);\n resolve(result);\n }\n });\n\n const timeoutId = setTimeout(() => {\n observer.disconnect();\n reject(new Error(`Timeout waiting for text \"${text}\"`));\n }, timeout);\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n characterData: true\n });\n });\n },\n\n async waitForHidden(selector: string, timeout = 20000): Promise<void> {\n await piHelpersImpl.waitForSelector(selector, { state: 'hidden', timeout });\n },\n\n getByRole(role: string, options: { name?: string } = {}): Element | null {\n const { name } = options;\n \n const implicitRoles: Record<string, string[]> = {\n button: ['button', 'input[type=\"button\"]', 'input[type=\"submit\"]', 'input[type=\"reset\"]'],\n link: ['a[href]'],\n textbox: ['input:not([type])', 'input[type=\"text\"]', 'input[type=\"email\"]', 'input[type=\"password\"]', 'input[type=\"search\"]', 'input[type=\"tel\"]', 'input[type=\"url\"]', 'textarea'],\n checkbox: ['input[type=\"checkbox\"]'],\n radio: ['input[type=\"radio\"]'],\n combobox: ['select'],\n heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n list: ['ul', 'ol'],\n listitem: ['li'],\n navigation: ['nav'],\n main: ['main'],\n banner: ['header'],\n contentinfo: ['footer'],\n form: ['form'],\n img: ['img'],\n table: ['table'],\n };\n\n const candidates: Element[] = [];\n candidates.push(...document.querySelectorAll(`[role=\"${role}\"]`));\n \n const implicitSelectors = implicitRoles[role];\n if (implicitSelectors) {\n for (const sel of implicitSelectors) {\n candidates.push(...document.querySelectorAll(`${sel}:not([role])`));\n }\n }\n\n if (!name) return candidates[0] || null;\n\n const normalizedName = name.toLowerCase().trim();\n for (const el of candidates) {\n const ariaLabel = el.getAttribute('aria-label')?.toLowerCase().trim();\n const textContent = el.textContent?.toLowerCase().trim();\n const title = el.getAttribute('title')?.toLowerCase().trim();\n const placeholder = el.getAttribute('placeholder')?.toLowerCase().trim();\n\n if (ariaLabel === normalizedName || textContent === normalizedName || \n title === normalizedName || placeholder === normalizedName) {\n return el;\n }\n if (ariaLabel?.includes(normalizedName) || textContent?.includes(normalizedName)) {\n return el;\n }\n }\n\n return null;\n }\n};\n\nif (!window.__piHelpers) {\n window.__piHelpers = piHelpersImpl;\n window.piHelpers = piHelpersImpl;\n}\n\nfunction getElementMap() {\n return window.__piElementMap!;\n}\n\nfunction generateAccessibilityTree(\n filter: \"all\" | \"interactive\" = \"interactive\",\n maxDepth = 15,\n refId?: string,\n forceFullSnapshot = false,\n compact = false\n): { \n pageContent: string;\n diff?: string;\n viewport: { width: number; height: number }; \n error?: string;\n modalStates?: ModalState[];\n modalLimitations?: string;\n isIncremental?: boolean;\n} {\n try {\n window.__piRefs = {};\n\n function getRole(element: Element): string {\n return getResolvedRole(element);\n }\n\n function getName(element: Element): string {\n const tag = element.tagName.toLowerCase();\n\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const names = labelledBy.split(/\\s+/).map(id => {\n const el = document.getElementById(id);\n return el?.textContent?.trim() || '';\n }).filter(Boolean);\n if (names.length) {\n const joined = names.join(' ');\n return joined.length > 100 ? joined.substring(0, 100) + '...' : joined;\n }\n }\n\n if (tag === \"select\") {\n const select = element as HTMLSelectElement;\n const selected = select.querySelector(\"option[selected]\") || \n (select.selectedIndex >= 0 ? select.options[select.selectedIndex] : null);\n if (selected?.textContent?.trim()) return selected.textContent.trim();\n }\n\n const ariaLabel = element.getAttribute(\"aria-label\");\n if (ariaLabel?.trim()) return ariaLabel.trim();\n\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder?.trim()) return placeholder.trim();\n\n const title = element.getAttribute(\"title\");\n if (title?.trim()) return title.trim();\n\n const alt = element.getAttribute(\"alt\");\n if (alt?.trim()) return alt.trim();\n\n if (element.id) {\n const label = document.querySelector(`label[for=\"${element.id}\"]`);\n if (label?.textContent?.trim()) return label.textContent.trim();\n }\n\n if (tag === \"input\") {\n const input = element as HTMLInputElement;\n const type = element.getAttribute(\"type\") || \"\";\n const value = element.getAttribute(\"value\");\n if (type === \"submit\" && value?.trim()) return value.trim();\n if (input.value && input.value.length < 50 && input.value.trim()) return input.value.trim();\n }\n\n if ([\"button\", \"a\", \"summary\"].includes(tag)) {\n const textContent = element.textContent || \"\";\n if (textContent.trim()) return textContent.trim();\n }\n\n if (/^h[1-6]$/.test(tag)) {\n const text = element.textContent;\n if (text?.trim()) {\n const t = text.trim();\n return t.length > 100 ? t.substring(0, 100) + \"...\" : t;\n }\n }\n\n if (tag === \"img\") return \"\";\n\n let directText = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n directText += node.textContent;\n }\n }\n if (directText?.trim() && directText.trim().length >= 3) {\n const text = directText.trim();\n return text.length > 100 ? text.substring(0, 100) + \"...\" : text;\n }\n\n return \"\";\n }\n\n interface AriaProps {\n checked?: boolean | 'mixed';\n disabled?: boolean;\n expanded?: boolean;\n level?: number;\n pressed?: boolean | 'mixed';\n selected?: boolean;\n active?: boolean;\n }\n\n function getAriaProps(element: Element): AriaProps {\n const props: AriaProps = {};\n \n const checkedAttr = element.getAttribute('aria-checked');\n if (checkedAttr === 'true') props.checked = true;\n else if (checkedAttr === 'false') props.checked = false;\n else if (checkedAttr === 'mixed') props.checked = 'mixed';\n else if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {\n if (element.type === 'checkbox' && element.indeterminate) {\n props.checked = 'mixed';\n } else {\n props.checked = element.checked;\n }\n }\n \n const isDisableable = element instanceof HTMLButtonElement || \n element instanceof HTMLInputElement || \n element instanceof HTMLSelectElement || \n element instanceof HTMLTextAreaElement;\n if (element.getAttribute('aria-disabled') === 'true' || \n (isDisableable && (element as HTMLButtonElement).disabled) ||\n element.closest('fieldset:disabled')) {\n props.disabled = true;\n }\n \n const expandedAttr = element.getAttribute('aria-expanded');\n if (expandedAttr === 'true') props.expanded = true;\n else if (expandedAttr === 'false') props.expanded = false;\n \n const pressedAttr = element.getAttribute('aria-pressed');\n if (pressedAttr === 'true') props.pressed = true;\n else if (pressedAttr === 'false') props.pressed = false;\n else if (pressedAttr === 'mixed') props.pressed = 'mixed';\n \n const selectedAttr = element.getAttribute('aria-selected');\n if (selectedAttr === 'true') props.selected = true;\n else if (selectedAttr === 'false') props.selected = false;\n \n const activeAttr = element.getAttribute('aria-current');\n if (activeAttr && activeAttr !== 'false') {\n props.active = true;\n }\n \n const tag = element.tagName.toLowerCase();\n if (/^h[1-6]$/.test(tag)) {\n props.level = parseInt(tag[1], 10);\n } else {\n const levelAttr = element.getAttribute('aria-level');\n if (levelAttr) props.level = parseInt(levelAttr, 10);\n }\n \n return props;\n }\n\n function formatAriaProps(props: AriaProps): string {\n const parts: string[] = [];\n \n if (props.checked !== undefined) {\n parts.push(props.checked === 'mixed' ? '[checked=mixed]' : props.checked ? '[checked]' : '[unchecked]');\n }\n if (props.disabled) parts.push('[disabled]');\n if (props.expanded !== undefined) {\n parts.push(props.expanded ? '[expanded]' : '[collapsed]');\n }\n if (props.pressed !== undefined) {\n parts.push(props.pressed === 'mixed' ? '[pressed=mixed]' : props.pressed ? '[pressed]' : '[not-pressed]');\n }\n if (props.selected !== undefined) {\n parts.push(props.selected ? '[selected]' : '[not-selected]');\n }\n if (props.active) parts.push('[active]');\n if (props.level !== undefined) {\n parts.push(`[level=${props.level}]`);\n }\n \n return parts.join(' ');\n }\n\n function isVisible(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return (\n style.display !== \"none\" &&\n style.visibility !== \"hidden\" &&\n style.opacity !== \"0\" &&\n (element as HTMLElement).offsetWidth > 0 &&\n (element as HTMLElement).offsetHeight > 0\n );\n }\n\n function isInteractive(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"a\", \"button\", \"input\", \"select\", \"textarea\", \"details\", \"summary\"].includes(tag) ||\n element.hasAttribute(\"onclick\") ||\n element.hasAttribute(\"tabindex\") ||\n element.getAttribute(\"role\") === \"button\" ||\n element.getAttribute(\"role\") === \"link\" ||\n element.getAttribute(\"contenteditable\") === \"true\"\n );\n }\n\n function isLandmark(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"nav\", \"main\", \"header\", \"footer\", \"section\", \"article\", \"aside\"].includes(tag) ||\n element.hasAttribute(\"role\")\n );\n }\n\n function hasCursorPointer(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return style.cursor === \"pointer\";\n }\n\n function shouldInclude(element: Element, options: { filter: string; refId: string | null; compact: boolean }): boolean {\n const tag = element.tagName.toLowerCase();\n if ([\"script\", \"style\", \"meta\", \"link\", \"title\", \"noscript\"].includes(tag)) return false;\n if (options.filter !== \"all\" && element.getAttribute(\"aria-hidden\") === \"true\") return false;\n if (options.filter !== \"all\" && !isVisible(element)) return false;\n\n if (options.filter !== \"all\" && !options.refId) {\n const rect = element.getBoundingClientRect();\n if (!(rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0)) {\n return false;\n }\n }\n\n if (options.filter === \"interactive\") return isInteractive(element);\n if (isInteractive(element)) return true;\n if (isLandmark(element)) return true;\n if (getName(element).length > 0) return true;\n\n const role = getRole(element);\n \n // In compact mode, skip empty structural elements\n if (options.compact) {\n const emptyStructuralRoles = new Set([\"generic\", \"group\", \"region\", \"article\", \"section\", \"complementary\"]);\n if (emptyStructuralRoles.has(role) && getName(element).length === 0) {\n return false;\n }\n }\n \n return role !== \"generic\" && role !== \"img\";\n }\n\n function traverse(element: Element, depth: number): string[] {\n const lines: string[] = [];\n const options = { filter, refId: refId || null, compact };\n const elementMap = getElementMap();\n\n const include = shouldInclude(element, options) || (refId && depth === 0);\n\n if (include) {\n const role = getRole(element);\n const name = getName(element);\n const ariaProps = getAriaProps(element);\n\n const elemRefId = getOrAssignRef(element, role, name);\n window.__piRefs![elemRefId] = element;\n elementMap[elemRefId] = {\n element: new WeakRef(element),\n role,\n name,\n };\n\n const indent = \" \".repeat(depth);\n let line = `${indent}${role}`;\n if (name) {\n const escapedName = name.replace(/\\s+/g, \" \").replace(/\"/g, '\\\\\"');\n line += ` \"${escapedName}\"`;\n }\n line += ` [${elemRefId}]`;\n\n const propsStr = formatAriaProps(ariaProps);\n if (propsStr) line += ` ${propsStr}`;\n\n if (hasCursorPointer(element)) {\n line += \" [cursor=pointer]\";\n }\n\n const href = element.getAttribute(\"href\");\n if (href) line += ` href=\"${href}\"`;\n\n const type = element.getAttribute(\"type\");\n if (type) line += ` type=\"${type}\"`;\n\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder) line += ` placeholder=\"${placeholder}\"`;\n\n lines.push(line);\n }\n\n if (depth < maxDepth) {\n for (const child of element.children) {\n lines.push(...traverse(child, include ? depth + 1 : depth));\n }\n }\n\n return lines;\n }\n\n function normalizeLineForDiff(line: string): string {\n return line.replace(/\\[e\\d+\\]/g, '[REF]');\n }\n\n function countOccurrences(lines: string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const line of lines) {\n if (!line.trim()) continue;\n const norm = normalizeLineForDiff(line);\n counts.set(norm, (counts.get(norm) || 0) + 1);\n }\n return counts;\n }\n\n function computeSimpleDiff(oldContent: string, newContent: string): { diff: string; hasChanges: boolean } {\n const oldLines = oldContent.split('\\n');\n const newLines = newContent.split('\\n');\n \n const oldCounts = countOccurrences(oldLines);\n const newCounts = countOccurrences(newLines);\n \n const added: string[] = [];\n const removed: string[] = [];\n \n for (const line of newLines) {\n if (!line.trim()) continue;\n const norm = normalizeLineForDiff(line);\n const oldCount = oldCounts.get(norm) || 0;\n const newCount = newCounts.get(norm) || 0;\n if (newCount > oldCount) {\n added.push(line);\n oldCounts.set(norm, oldCount + 1);\n }\n }\n \n const oldCountsReset = countOccurrences(oldLines);\n for (const line of oldLines) {\n if (!line.trim()) continue;\n const norm = normalizeLineForDiff(line);\n const oldCount = oldCountsReset.get(norm) || 0;\n const newCount = newCounts.get(norm) || 0;\n if (oldCount > newCount) {\n removed.push(line);\n oldCountsReset.set(norm, oldCount - 1);\n }\n }\n \n if (added.length === 0 && removed.length === 0) {\n return { diff: '[NO CHANGES]', hasChanges: false };\n }\n \n const diffLines: string[] = [];\n if (removed.length > 0) {\n diffLines.push(...removed.map(l => `- ${l}`));\n }\n if (added.length > 0) {\n diffLines.push(...added.map(l => `+ ${l}`));\n }\n \n return { diff: diffLines.join('\\n'), hasChanges: true };\n }\n\n const elementMap = getElementMap();\n let startElement: Element | null = null;\n\n if (refId) {\n const elemRef = elementMap[refId];\n if (!elemRef) {\n return {\n error: `Element with ref_id '${refId}' not found. Use read_page without ref_id to get current elements.`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n const element = elemRef.element.deref();\n if (!element) {\n delete elementMap[refId];\n return {\n error: `Element with ref_id '${refId}' no longer exists. Use read_page without ref_id to get current elements.`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n startElement = element;\n } else {\n startElement = document.body;\n }\n\n const lines = startElement ? traverse(startElement, 0) : [];\n\n for (const id of Object.keys(elementMap)) {\n if (!elementMap[id].element.deref()) {\n delete elementMap[id];\n }\n }\n\n const content = lines.join(\"\\n\");\n\n if (content.length > 50000) {\n return {\n error: `Output exceeds 50000 character limit (${content.length} characters). Try using filter=\"interactive\" or specify a ref_id.`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n\n const modalStates = detectModalStates();\n\n let diff: string | undefined;\n let isIncremental = false;\n const lastSnapshot = window.__piLastSnapshot;\n\n if (!forceFullSnapshot && !refId && lastSnapshot && \n Date.now() - lastSnapshot.timestamp < 5000) {\n const diffResult = computeSimpleDiff(lastSnapshot.content, content);\n diff = diffResult.diff;\n isIncremental = true;\n }\n\n window.__piLastSnapshot = { content, timestamp: Date.now() };\n\n return {\n pageContent: content + `\\n\\n[Viewport: ${window.innerWidth}x${window.innerHeight}]`,\n diff: isIncremental ? diff : undefined,\n viewport: { width: window.innerWidth, height: window.innerHeight },\n modalStates: modalStates.length > 0 ? modalStates : undefined,\n modalLimitations: 'Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts.',\n isIncremental,\n };\n } catch (err) {\n return {\n error: `Error generating accessibility tree: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n}\n\nfunction yamlEscapeValue(str: string): string {\n if (!str.length) return '\"\"';\n if (/[\\n\\r]/.test(str) || /^[\\s]/.test(str) || /[\\s]$/.test(str) || /[:\"{}[\\]]/.test(str)) {\n return '\"' + str.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r') + '\"';\n }\n return str;\n}\n\nfunction generateYamlTree(\n filter: \"all\" | \"interactive\" = \"interactive\",\n maxDepth = 15\n): { yaml: string; viewport: { width: number; height: number }; error?: string } {\n try {\n window.__piRefs = {};\n \n const lines: string[] = [];\n\n function getRole(element: Element): string {\n return getResolvedRole(element);\n }\n\n function getName(element: Element): string {\n const tag = element.tagName.toLowerCase();\n\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const names = labelledBy.split(/\\s+/).map(id => {\n const el = document.getElementById(id);\n return el?.textContent?.trim() || '';\n }).filter(Boolean);\n if (names.length) {\n const joined = names.join(' ');\n return joined.length > 100 ? joined.substring(0, 100) + '...' : joined;\n }\n }\n\n if (tag === \"select\") {\n const select = element as HTMLSelectElement;\n const selected = select.querySelector(\"option[selected]\") || \n (select.selectedIndex >= 0 ? select.options[select.selectedIndex] : null);\n if (selected?.textContent?.trim()) return selected.textContent.trim();\n }\n\n const ariaLabel = element.getAttribute(\"aria-label\");\n if (ariaLabel?.trim()) return ariaLabel.trim();\n\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder?.trim()) return placeholder.trim();\n\n const title = element.getAttribute(\"title\");\n if (title?.trim()) return title.trim();\n\n const alt = element.getAttribute(\"alt\");\n if (alt?.trim()) return alt.trim();\n\n if (element.id) {\n const label = document.querySelector(`label[for=\"${element.id}\"]`);\n if (label?.textContent?.trim()) return label.textContent.trim();\n }\n\n if (tag === \"input\") {\n const input = element as HTMLInputElement;\n const type = element.getAttribute(\"type\") || \"\";\n const value = element.getAttribute(\"value\");\n if (type === \"submit\" && value?.trim()) return value.trim();\n if (input.value && input.value.length < 50 && input.value.trim()) return input.value.trim();\n }\n\n if ([\"button\", \"a\", \"summary\"].includes(tag)) {\n const textContent = element.textContent || \"\";\n if (textContent.trim()) return textContent.trim();\n }\n\n if (/^h[1-6]$/.test(tag)) {\n const text = element.textContent;\n if (text?.trim()) {\n const t = text.trim();\n return t.length > 100 ? t.substring(0, 100) + \"...\" : t;\n }\n }\n\n if (tag === \"img\") return \"\";\n\n let directText = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n directText += node.textContent;\n }\n }\n if (directText?.trim() && directText.trim().length >= 3) {\n const text = directText.trim();\n return text.length > 100 ? text.substring(0, 100) + \"...\" : text;\n }\n\n return \"\";\n }\n\n interface AriaProps {\n checked?: boolean | 'mixed';\n disabled?: boolean;\n expanded?: boolean;\n level?: number;\n pressed?: boolean | 'mixed';\n selected?: boolean;\n active?: boolean;\n }\n\n function getAriaProps(element: Element): AriaProps {\n const props: AriaProps = {};\n \n const checkedAttr = element.getAttribute('aria-checked');\n if (checkedAttr === 'true') props.checked = true;\n else if (checkedAttr === 'false') props.checked = false;\n else if (checkedAttr === 'mixed') props.checked = 'mixed';\n else if (element instanceof HTMLInputElement && (element.type === 'checkbox' || element.type === 'radio')) {\n if (element.type === 'checkbox' && element.indeterminate) {\n props.checked = 'mixed';\n } else {\n props.checked = element.checked;\n }\n }\n \n const isDisableable = element instanceof HTMLButtonElement || \n element instanceof HTMLInputElement || \n element instanceof HTMLSelectElement || \n element instanceof HTMLTextAreaElement;\n if (element.getAttribute('aria-disabled') === 'true' || \n (isDisableable && (element as HTMLButtonElement).disabled) ||\n element.closest('fieldset:disabled')) {\n props.disabled = true;\n }\n \n const expandedAttr = element.getAttribute('aria-expanded');\n if (expandedAttr === 'true') props.expanded = true;\n else if (expandedAttr === 'false') props.expanded = false;\n \n const pressedAttr = element.getAttribute('aria-pressed');\n if (pressedAttr === 'true') props.pressed = true;\n else if (pressedAttr === 'false') props.pressed = false;\n else if (pressedAttr === 'mixed') props.pressed = 'mixed';\n \n const selectedAttr = element.getAttribute('aria-selected');\n if (selectedAttr === 'true') props.selected = true;\n else if (selectedAttr === 'false') props.selected = false;\n \n const activeAttr = element.getAttribute('aria-current');\n if (activeAttr && activeAttr !== 'false') {\n props.active = true;\n }\n \n const tag = element.tagName.toLowerCase();\n if (/^h[1-6]$/.test(tag)) {\n props.level = parseInt(tag[1], 10);\n } else {\n const levelAttr = element.getAttribute('aria-level');\n if (levelAttr) props.level = parseInt(levelAttr, 10);\n }\n \n return props;\n }\n\n function formatAriaProps(props: AriaProps): string {\n const parts: string[] = [];\n \n if (props.checked !== undefined) {\n parts.push(props.checked === 'mixed' ? '[checked=mixed]' : props.checked ? '[checked]' : '[unchecked]');\n }\n if (props.disabled) parts.push('[disabled]');\n if (props.expanded !== undefined) {\n parts.push(props.expanded ? '[expanded]' : '[collapsed]');\n }\n if (props.pressed !== undefined) {\n parts.push(props.pressed === 'mixed' ? '[pressed=mixed]' : props.pressed ? '[pressed]' : '[not-pressed]');\n }\n if (props.selected !== undefined) {\n parts.push(props.selected ? '[selected]' : '[not-selected]');\n }\n if (props.active) parts.push('[active]');\n if (props.level !== undefined) {\n parts.push(`[level=${props.level}]`);\n }\n \n return parts.join(' ');\n }\n\n function isVisible(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return (\n style.display !== \"none\" &&\n style.visibility !== \"hidden\" &&\n style.opacity !== \"0\" &&\n (element as HTMLElement).offsetWidth > 0 &&\n (element as HTMLElement).offsetHeight > 0\n );\n }\n\n function isInteractive(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"a\", \"button\", \"input\", \"select\", \"textarea\", \"details\", \"summary\"].includes(tag) ||\n element.hasAttribute(\"onclick\") ||\n element.hasAttribute(\"tabindex\") ||\n element.getAttribute(\"role\") === \"button\" ||\n element.getAttribute(\"role\") === \"link\" ||\n element.getAttribute(\"contenteditable\") === \"true\"\n );\n }\n\n function isLandmark(element: Element): boolean {\n const tag = element.tagName.toLowerCase();\n return (\n [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"nav\", \"main\", \"header\", \"footer\", \"section\", \"article\", \"aside\"].includes(tag) ||\n element.hasAttribute(\"role\")\n );\n }\n\n function hasCursorPointer(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return style.cursor === \"pointer\";\n }\n\n function buildKey(role: string, name: string, element: Element, ariaProps: AriaProps): string {\n let key = role;\n if (name) {\n key += ' ' + yamlEscapeValue(name);\n }\n \n const ref = getOrAssignRef(element, role, name);\n window.__piRefs![ref] = element;\n key += ` [ref=${ref}]`;\n \n const propsStr = formatAriaProps(ariaProps);\n if (propsStr) key += ` ${propsStr}`;\n \n if (hasCursorPointer(element)) {\n key += ' [cursor=pointer]';\n }\n \n return key;\n }\n\n function getElementProps(element: Element): Record<string, string> {\n const props: Record<string, string> = {};\n const href = element.getAttribute(\"href\");\n if (href) props.url = href;\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder) props.placeholder = placeholder;\n return props;\n }\n\n function traverse(element: Element, depth: number, parentIncluded: boolean): void {\n if (depth > maxDepth) return;\n \n const tag = element.tagName.toLowerCase();\n if ([\"script\", \"style\", \"meta\", \"link\", \"title\", \"noscript\"].includes(tag)) return;\n if (filter !== \"all\" && element.getAttribute(\"aria-hidden\") === \"true\") return;\n if (filter !== \"all\" && !isVisible(element)) return;\n \n if (filter !== \"all\") {\n const rect = element.getBoundingClientRect();\n if (!(rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0)) {\n return;\n }\n }\n \n const role = getRole(element);\n const name = getName(element);\n const ariaProps = getAriaProps(element);\n \n const isInteractiveEl = isInteractive(element);\n const isLandmarkEl = isLandmark(element);\n const hasName = name.length > 0;\n \n let include: boolean;\n if (filter === \"interactive\") {\n include = isInteractiveEl;\n } else if (filter === \"all\") {\n include = true;\n } else {\n include = isInteractiveEl || isLandmarkEl || hasName || (role !== \"generic\" && role !== \"img\");\n }\n \n if (include) {\n const indent = \" \".repeat(depth);\n const key = buildKey(role, name, element, ariaProps);\n const props = getElementProps(element);\n \n const children: Element[] = [];\n for (const child of element.children) {\n children.push(child);\n }\n \n const hasChildren = children.length > 0;\n const hasProps = Object.keys(props).length > 0;\n \n if (!hasChildren && !hasProps) {\n lines.push(`${indent}- ${key}`);\n } else {\n lines.push(`${indent}- ${key}:`);\n for (const [propName, propValue] of Object.entries(props)) {\n lines.push(`${indent} - /${propName}: ${yamlEscapeValue(propValue)}`);\n }\n for (const child of children) {\n traverse(child, depth + 1, true);\n }\n }\n } else {\n for (const child of element.children) {\n traverse(child, depth, parentIncluded);\n }\n }\n }\n\n traverse(document.body, 0, false);\n\n const yaml = lines.join('\\n');\n \n if (yaml.length > 50000) {\n return {\n error: `Output exceeds 50000 character limit (${yaml.length} characters). Try using filter=\"interactive\".`,\n yaml: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n\n return {\n yaml: yaml + `\\n\\n[Viewport: ${window.innerWidth}x${window.innerHeight}]`,\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n } catch (err) {\n return {\n error: `Error generating YAML tree: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n yaml: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight },\n };\n }\n}\n\nfunction getElementCoordinates(ref: string): { x: number; y: number; error?: string } {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n let element: Element | undefined;\n \n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) {\n delete elementMap[ref];\n }\n }\n \n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n return { x: 0, y: 0, error: `Element ${ref} not found. Use read_page to get current elements.` };\n }\n\n const rect = element.getBoundingClientRect();\n const x = Math.round(rect.left + rect.width / 2);\n const y = Math.round(rect.top + rect.height / 2);\n\n return { x, y };\n}\n\nfunction setFormValue(ref: string, value: string | boolean | number): { success: boolean; error?: string } {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n let element: Element | undefined;\n \n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) {\n delete elementMap[ref];\n }\n }\n \n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n return { success: false, error: `Element ${ref} not found. Use read_page to get current elements.` };\n }\n\n const tagName = element.tagName.toLowerCase();\n\n try {\n if (tagName === \"input\") {\n const input = element as HTMLInputElement;\n const type = input.type.toLowerCase();\n\n if (type === \"checkbox\" || type === \"radio\") {\n input.checked = Boolean(value);\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else {\n setNativeValue(input, String(value));\n }\n } else if (tagName === \"textarea\") {\n setNativeValue(element as HTMLTextAreaElement, String(value));\n } else if (tagName === \"select\") {\n const select = element as HTMLSelectElement;\n const strValue = String(value);\n\n let found = false;\n for (const option of select.options) {\n if (option.value === strValue || option.textContent?.trim() === strValue) {\n select.value = option.value;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return { success: false, error: `Option \"${value}\" not found in select element ${ref}` };\n }\n\n select.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else if (element.getAttribute(\"contenteditable\") === \"true\") {\n element.textContent = String(value);\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n } else {\n return { success: false, error: `Element ${ref} (${tagName}) is not a form field` };\n }\n\n return { success: true };\n } catch (err) {\n return { success: false, error: `Failed to set value: ${err instanceof Error ? err.message : \"Unknown error\"}` };\n }\n}\n\nfunction smartType(selector: string, text: string, clear = true, submit = false): { success: boolean; contentEditable?: boolean; error?: string } {\n try {\n const element = document.querySelector(selector) as HTMLElement | null;\n if (!element) return { success: false, error: `Element not found: ${selector}` };\n\n const contentEditableChild = element.querySelector<HTMLElement>('[contenteditable=\"true\"]');\n const target = contentEditableChild || element;\n const contentEditable = element.isContentEditable || !!contentEditableChild;\n target.focus();\n\n if (contentEditable) {\n if (clear) target.textContent = \"\";\n target.textContent = text;\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else {\n // Assigning a value always replaces the previous one, so `clear` only\n // matters for the contenteditable branch above.\n setNativeValue(target as HTMLInputElement | HTMLTextAreaElement, text);\n }\n\n if (submit) {\n const form = element.closest(\"form\");\n const submitButton = form?.querySelector<HTMLElement>('button[type=\"submit\"], input[type=\"submit\"]')\n || document.querySelector<HTMLElement>('button[type=\"submit\"], button[data-testid*=\"send\"], button[aria-label*=\"Send\"]');\n if (submitButton) submitButton.click();\n else if (form) form.dispatchEvent(new Event(\"submit\", { bubbles: true }));\n else target.dispatchEvent(new KeyboardEvent(\"keydown\", { key: \"Enter\", code: \"Enter\", keyCode: 13, bubbles: true }));\n }\n\n return { success: true, contentEditable };\n } catch (err) {\n return { success: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction truncateToUtf8Bytes(input: string, maxBytes: number): string {\n const encoder = new TextEncoder();\n const encoded = encoder.encode(input);\n if (encoded.length <= maxBytes) return input;\n let end = maxBytes;\n while (end > 0 && (encoded[end] & 0xc0) === 0x80) end--;\n return new TextDecoder(\"utf-8\", { fatal: false }).decode(encoded.subarray(0, end));\n}\n\nfunction getPageText(options: { maxBytes?: number } = {}): { text: string; title: string; url: string; error?: string } {\n try {\n const article = document.querySelector(\"article\");\n const main = document.querySelector(\"main\");\n const content = article || main || document.body;\n\n const normalized = content.textContent\n ?.replace(/\\s+/g, \" \")\n .trim() || \"\";\n const text = Number.isFinite(options.maxBytes) && options.maxBytes! > 0\n ? truncateToUtf8Bytes(normalized, options.maxBytes!)\n : normalized.substring(0, 50000);\n\n return {\n text,\n title: document.title,\n url: window.location.href,\n };\n } catch (err) {\n return {\n text: \"\",\n title: \"\",\n url: \"\",\n error: `Failed to extract text: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n };\n }\n}\n\nfunction scrollToElement(ref: string): { success: boolean; error?: string } {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n let element: Element | undefined;\n \n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) {\n delete elementMap[ref];\n }\n }\n \n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n return { success: false, error: `Element ${ref} not found. Run read_page to get current element refs.` };\n }\n\n element.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n return { success: true };\n}\n\nfunction uploadImage(\n base64: string,\n ref?: string,\n coordinate?: [number, number],\n filename: string = \"screenshot.png\"\n): { success: boolean; error?: string } {\n try {\n const byteString = atob(base64);\n const ab = new ArrayBuffer(byteString.length);\n const ia = new Uint8Array(ab);\n for (let i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n const blob = new Blob([ab], { type: \"image/png\" });\n const file = new File([blob], filename, { type: \"image/png\" });\n\n let targetElement: HTMLElement | null = null;\n\n if (ref) {\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n \n if (elemRef) {\n targetElement = elemRef.element.deref() as HTMLElement | null;\n if (!targetElement) {\n delete elementMap[ref];\n }\n }\n \n if (!targetElement && window.__piRefs) {\n targetElement = window.__piRefs[ref] as HTMLElement | null;\n }\n \n if (!targetElement) {\n return { success: false, error: `Element ${ref} not found. Run read_page to get current element refs.` };\n }\n } else if (coordinate) {\n targetElement = document.elementFromPoint(coordinate[0], coordinate[1]) as HTMLElement | null;\n if (!targetElement) {\n return { success: false, error: `No element at (${coordinate[0]}, ${coordinate[1]})` };\n }\n }\n\n if (!targetElement) {\n return { success: false, error: \"No target element\" };\n }\n\n if (targetElement.tagName === \"INPUT\" && (targetElement as HTMLInputElement).type === \"file\") {\n const input = targetElement as HTMLInputElement;\n const dt = new DataTransfer();\n dt.items.add(file);\n input.files = dt.files;\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { success: true };\n }\n\n const dt = new DataTransfer();\n dt.items.add(file);\n\n const dropEvent = new DragEvent(\"drop\", {\n bubbles: true,\n cancelable: true,\n dataTransfer: dt,\n });\n\n targetElement.dispatchEvent(dropEvent);\n return { success: true };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : \"Upload failed\",\n };\n }\n}\n\nlet playbookWatch: { includeInputValues: boolean } | null = null;\n\nfunction watchSelector(element: Element): string {\n if (element.id) return `#${CSS.escape(element.id)}`;\n for (const name of [\"data-testid\", \"data-test-id\", \"name\", \"aria-label\"]) {\n const value = element.getAttribute(name);\n if (value) return `${element.tagName.toLowerCase()}[${name}=${JSON.stringify(value)}]`;\n }\n return element.tagName.toLowerCase();\n}\n\nfunction postWatchEvent(event: string, element?: Element, value?: string): void {\n if (!playbookWatch) return;\n chrome.runtime.sendMessage({\n type: \"PLAYBOOK_WATCH_EVENT\",\n event,\n selector: element ? watchSelector(element) : undefined,\n value,\n url: location.href,\n timestamp: new Date().toISOString(),\n }).catch(() => {});\n}\n\nif (typeof document.addEventListener === \"function\") {\n document.addEventListener(\"click\", (event) => {\n if (event.isTrusted && event.target instanceof Element) postWatchEvent(\"click\", event.target);\n }, true);\n document.addEventListener(\"change\", (event) => {\n if (!event.isTrusted || !(event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement || event.target instanceof HTMLSelectElement)) return;\n const target = event.target;\n const secret = target instanceof HTMLInputElement && target.type === \"password\";\n const value = playbookWatch?.includeInputValues && !secret ? target.value : \"<input>\";\n postWatchEvent(\"input\", target, value);\n }, true);\n}\nif (typeof window.addEventListener === \"function\") {\n window.addEventListener(\"popstate\", () => postWatchEvent(\"navigation\"));\n window.addEventListener(\"hashchange\", () => postWatchEvent(\"navigation\"));\n}\n\nchrome.runtime.onMessage.addListener((message, sender, sendResponse) => {\n switch (message.type) {\n case \"PLAYBOOK_WATCH_START\":\n playbookWatch = { includeInputValues: message.includeInputValues === true };\n sendResponse({ success: true });\n break;\n case \"PLAYBOOK_WATCH_STOP\":\n playbookWatch = null;\n sendResponse({ success: true });\n break;\n case \"SHOW_AGENT_INDICATORS\":\n case \"HIDE_AGENT_INDICATORS\":\n case \"HIDE_FOR_TOOL_USE\":\n case \"SHOW_AFTER_TOOL_USE\":\n case \"SHOW_STATIC_INDICATOR\":\n case \"HIDE_STATIC_INDICATOR\": {\n if (!window.__piVisualIndicatorMessageHandler) {\n sendResponse({ error: \"Visual indicator content script not loaded.\" });\n break;\n }\n window.__piVisualIndicatorMessageHandler(message.type as VisualIndicatorMessageType);\n sendResponse({ success: true });\n break;\n }\n case \"GENERATE_ACCESSIBILITY_TREE\": {\n const options = message.options || {};\n \n if (options.format === \"yaml\") {\n const result = generateYamlTree(\n options.filter || \"interactive\",\n options.depth ?? 15\n );\n const modalStates = detectModalStates();\n if (result.error) {\n sendResponse({ error: result.error, pageContent: \"\", viewport: result.viewport });\n } else {\n sendResponse({ \n pageContent: result.yaml, \n viewport: result.viewport,\n modalStates: modalStates.length > 0 ? modalStates : undefined,\n modalLimitations: 'Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts.',\n });\n }\n } else {\n const result = generateAccessibilityTree(\n options.filter || \"interactive\",\n options.depth ?? 15,\n options.refId,\n options.forceFullSnapshot ?? false,\n options.compact ?? false\n );\n if (options.semanticObservation === true && !result.error) {\n (result as typeof result & { semanticObservation: ReturnType<typeof buildSemanticObservation> }).semanticObservation = buildSemanticObservation();\n }\n sendResponse(result);\n }\n break;\n }\n case \"GET_ELEMENT_COORDINATES\": {\n const result = getElementCoordinates(message.ref);\n sendResponse(result);\n break;\n }\n case \"SEMANTIC_NAVIGATE\": {\n const guardError = semanticGuardError(undefined, message.expectedIdentity, false);\n if (guardError) {\n sendResponse({ error: guardError, code: guardError });\n break;\n }\n window.location.href = message.url;\n sendResponse({ success: true });\n break;\n }\n case \"SEMANTIC_LOCAL_COMPARE\": {\n const element = getElementMap()[message.ref]?.element.deref();\n const identity = semanticElementIdentity(element, message.ref);\n if (!message.expectedIdentity) {\n sendResponse({ success: false, matches: false, reason: \"invalid_expected_identity\", identity });\n break;\n }\n const guardError = semanticGuardError(element, message.expectedIdentity);\n if (guardError) {\n sendResponse({ success: false, matches: false, reason: guardError, identity });\n break;\n }\n const result = compareSemanticElement(element!, message.predicate);\n sendResponse({ ...result, identity });\n break;\n }\n case \"SEMANTIC_SCROLL_SCOPE\": {\n if (!message.expectedIdentity) {\n sendResponse({ success: false, reason: \"invalid_expected_identity\" });\n break;\n }\n const guardError = semanticGuardError(undefined, message.expectedIdentity, false);\n if (guardError) {\n sendResponse({ success: false, reason: guardError });\n break;\n }\n if (message.action === \"inspect\") {\n sendResponse(inspectSemanticScrollScope(semanticDocumentToken));\n } else {\n sendResponse(moveSemanticScrollScope(message.action, message.scopeToken, semanticDocumentToken));\n }\n break;\n }\n case \"SEMANTIC_SCROLL\": {\n const guardError = semanticGuardError(undefined, message.expectedIdentity, false);\n if (guardError) {\n sendResponse({ error: guardError, code: guardError });\n break;\n }\n if (message.position === \"top\" || message.position === \"bottom\") {\n sendResponse(scrollToPosition(message.position));\n break;\n } else {\n window.scrollBy(message.deltaX || 0, message.deltaY || 0);\n }\n sendResponse({ success: true, scrollX: window.scrollX, scrollY: window.scrollY });\n break;\n }\n case \"SCROLL_TO_POSITION\": {\n sendResponse(scrollToPosition(message.position, message.selector || null));\n break;\n }\n case \"CLICK_ELEMENT\": {\n const elementMap = getElementMap();\n const elemRef = elementMap[message.ref];\n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[message.ref];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[message.ref];\n }\n if (!element) {\n sendResponse({ error: `Element ${message.ref} not found. Use read_page to get current elements.` });\n break;\n }\n const guardError = semanticGuardError(element, message.expectedIdentity);\n if (guardError) {\n sendResponse({ error: guardError, code: guardError });\n break;\n }\n if (message.button === \"triple\") {\n const tripleClick = new MouseEvent(\"click\", { bubbles: true, cancelable: true, view: window, detail: 3 });\n element.dispatchEvent(tripleClick);\n } else if (message.button === \"double\") {\n element.dispatchEvent(new MouseEvent(\"dblclick\", { bubbles: true, cancelable: true, view: window }));\n } else if (message.button === \"right\") {\n element.dispatchEvent(new MouseEvent(\"contextmenu\", { bubbles: true, cancelable: true, view: window }));\n } else {\n (element as HTMLElement).click();\n }\n sendResponse({ success: true });\n break;\n }\n case \"FORM_INPUT\": {\n const result = setFormValue(message.ref, message.value);\n sendResponse(result);\n break;\n }\n case \"PAGE_READINESS\": {\n try {\n sendResponse(probePageReadiness(createDomProbe(document, window), message.expect || {}));\n } catch (err) {\n sendResponse({\n error: err instanceof Error ? err.message : String(err),\n code: err instanceof InvalidReadinessSelectorError ? \"invalid_selector\" : \"page_probe_error\",\n });\n }\n break;\n }\n case \"PING\": {\n sendResponse({ success: true, href: location.href, readyState: document.readyState });\n break;\n }\n case \"EVAL_IN_PAGE\": {\n try {\n const script = document.createElement('script');\n script.textContent = `(function() { ${message.code} })();`;\n document.documentElement.appendChild(script);\n script.remove();\n sendResponse({ success: true });\n } catch (err) {\n sendResponse({ success: false, error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_PAGE_TEXT\": {\n const result = getPageText(message.options || {});\n sendResponse(result);\n break;\n }\n case \"SMART_TYPE\": {\n sendResponse(smartType(message.selector, message.text, message.clear, message.submit));\n break;\n }\n case \"GET_FRAME_BY_SELECTOR\": {\n try {\n const iframe = document.querySelector(message.selector) as HTMLIFrameElement;\n if (!iframe || iframe.tagName.toLowerCase() !== 'iframe') {\n sendResponse({ error: `No iframe found with selector \"${message.selector}\"` });\n break;\n }\n // Return what info we can - the service worker will match by URL or name\n sendResponse({ \n url: iframe.src,\n name: iframe.name || undefined,\n });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_FRAME_NAME\": {\n // Return this frame's name (for frame matching by name)\n try {\n sendResponse({ name: window.name || null });\n } catch (err) {\n sendResponse({ name: null });\n }\n break;\n }\n case \"LOCATE_ROLE\": {\n try {\n const { role, name, all } = message;\n const elementMap = getElementMap();\n \n // Mapping of role to possible selectors\n const implicitRoles: Record<string, string[]> = {\n button: ['button', 'input[type=\"button\"]', 'input[type=\"submit\"]', 'input[type=\"reset\"]', '[role=\"button\"]'],\n link: ['a[href]', '[role=\"link\"]'],\n textbox: ['input:not([type])', 'input[type=\"text\"]', 'input[type=\"email\"]', 'input[type=\"password\"]', 'input[type=\"search\"]', 'input[type=\"tel\"]', 'input[type=\"url\"]', 'textarea', '[role=\"textbox\"]'],\n checkbox: ['input[type=\"checkbox\"]', '[role=\"checkbox\"]'],\n radio: ['input[type=\"radio\"]', '[role=\"radio\"]'],\n combobox: ['select', '[role=\"combobox\"]'],\n listbox: ['[role=\"listbox\"]', 'select[multiple]'],\n option: ['option', '[role=\"option\"]'],\n heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', '[role=\"heading\"]'],\n navigation: ['nav', '[role=\"navigation\"]'],\n main: ['main', '[role=\"main\"]'],\n img: ['img[alt]', '[role=\"img\"]'],\n dialog: ['dialog', '[role=\"dialog\"]', '[role=\"alertdialog\"]'],\n tab: ['[role=\"tab\"]'],\n tabpanel: ['[role=\"tabpanel\"]'],\n menu: ['[role=\"menu\"]'],\n menuitem: ['[role=\"menuitem\"]'],\n };\n \n // Build selectors for the role\n const selectors = implicitRoles[role] || [`[role=\"${role}\"]`];\n const candidates: Element[] = [];\n \n for (const sel of selectors) {\n try {\n candidates.push(...document.querySelectorAll(sel));\n } catch {}\n }\n \n // Filter by visibility\n const visible = candidates.filter(el => {\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && \n style.visibility !== 'hidden' && \n (el as HTMLElement).offsetWidth > 0 &&\n (el as HTMLElement).offsetHeight > 0;\n });\n \n // Filter by name if provided\n let matches = visible;\n if (name) {\n const lowerName = name.toLowerCase();\n matches = visible.filter(el => {\n const ariaLabel = el.getAttribute('aria-label')?.toLowerCase();\n const text = el.textContent?.trim().toLowerCase();\n const title = el.getAttribute('title')?.toLowerCase();\n const placeholder = (el as HTMLInputElement).placeholder?.toLowerCase();\n const value = (el as HTMLInputElement).value?.toLowerCase();\n \n return ariaLabel?.includes(lowerName) || \n text?.includes(lowerName) || \n title?.includes(lowerName) ||\n placeholder?.includes(lowerName) ||\n value?.includes(lowerName);\n });\n }\n \n if (matches.length === 0) {\n sendResponse({ error: `No element found with role \"${role}\"${name ? ` and name \"${name}\"` : ''}` });\n break;\n }\n \n // Generate refs for matches\n const results = matches.map(el => {\n const ref = getOrAssignRef(el, role, name || '');\n window.__piRefs = window.__piRefs || {};\n window.__piRefs[ref] = el;\n elementMap[ref] = { element: new WeakRef(el), role, name: name || '' };\n return { ref, text: el.textContent?.trim().slice(0, 50) };\n });\n \n if (all) {\n sendResponse({ matches: results });\n } else {\n sendResponse({ ref: results[0].ref, text: results[0].text });\n }\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"LOCATE_TEXT\": {\n try {\n const { text, exact } = message;\n const elementMap = getElementMap();\n \n // Find elements containing the text\n const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);\n const matches: Element[] = [];\n \n while (walker.nextNode()) {\n const nodeText = walker.currentNode.textContent || '';\n const hasMatch = exact \n ? nodeText.trim() === text \n : nodeText.toLowerCase().includes(text.toLowerCase());\n \n if (hasMatch) {\n const parent = walker.currentNode.parentElement;\n if (parent && !matches.includes(parent)) {\n // Check visibility\n const style = window.getComputedStyle(parent);\n if (style.display !== 'none' && style.visibility !== 'hidden') {\n matches.push(parent);\n }\n }\n }\n }\n \n if (matches.length === 0) {\n sendResponse({ error: `No element found with text \"${text}\"` });\n break;\n }\n \n // Pick the most specific (smallest) element\n const el = matches.sort((a, b) => \n (a.textContent?.length || 0) - (b.textContent?.length || 0)\n )[0];\n \n const role = getResolvedRole(el);\n const ref = getOrAssignRef(el, role, text);\n window.__piRefs = window.__piRefs || {};\n window.__piRefs[ref] = el;\n elementMap[ref] = { element: new WeakRef(el), role, name: text };\n \n sendResponse({ ref, text: el.textContent?.trim().slice(0, 50) });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"LOCATE_LABEL\": {\n try {\n const { label } = message;\n const elementMap = getElementMap();\n \n // Find label element\n const labels = document.querySelectorAll('label');\n let input: Element | null = null;\n \n for (const lbl of labels) {\n const lblText = lbl.textContent?.trim().toLowerCase();\n if (lblText?.includes(label.toLowerCase())) {\n // Check for 'for' attribute\n const forId = lbl.getAttribute('for');\n if (forId) {\n input = document.getElementById(forId);\n }\n // Check for nested input\n if (!input) {\n input = lbl.querySelector('input, select, textarea');\n }\n if (input) break;\n }\n }\n \n // Also check aria-label and placeholder\n if (!input) {\n const lowerLabel = label.toLowerCase();\n input = document.querySelector(\n `input[aria-label*=\"${label}\" i], input[placeholder*=\"${label}\" i], ` +\n `textarea[aria-label*=\"${label}\" i], textarea[placeholder*=\"${label}\" i], ` +\n `select[aria-label*=\"${label}\" i]`\n );\n }\n \n if (!input) {\n sendResponse({ error: `No form field found with label \"${label}\"` });\n break;\n }\n \n const role = getResolvedRole(input);\n const ref = getOrAssignRef(input, role, label);\n window.__piRefs = window.__piRefs || {};\n window.__piRefs[ref] = input;\n elementMap[ref] = { element: new WeakRef(input), role, name: label };\n \n sendResponse({ ref, label });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_ELEMENT_STYLES\": {\n try {\n const { selector } = message;\n const elementMap = getElementMap();\n \n // Helper to extract styles from an element\n const extractStyles = (el: Element) => {\n const s = getComputedStyle(el);\n const r = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n text: (el as HTMLElement).innerText?.trim().slice(0, 80) || null,\n box: {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n },\n styles: {\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n fontFamily: s.fontFamily.split(',')[0].trim().replace(/\"/g, ''),\n color: s.color,\n backgroundColor: s.backgroundColor,\n borderRadius: s.borderRadius,\n border: s.border !== 'none' && s.borderWidth !== '0px' ? s.border : null,\n boxShadow: s.boxShadow !== 'none' ? s.boxShadow : null,\n padding: s.padding,\n },\n };\n };\n \n // Check if selector is a ref (e.g., \"e5\")\n if (/^e\\d+$/.test(selector)) {\n const elemRef = elementMap[selector];\n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[selector];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[selector];\n }\n \n if (!element) {\n sendResponse({ error: `Element ${selector} not found` });\n break;\n }\n \n sendResponse({ styles: [extractStyles(element)] });\n } else {\n // CSS selector - can match multiple elements\n const elements = document.querySelectorAll(selector);\n if (elements.length === 0) {\n sendResponse({ error: `No elements found matching \"${selector}\"` });\n break;\n }\n \n const styles = Array.from(elements).map(extractStyles);\n sendResponse({ styles });\n }\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"SELECT_OPTION\": {\n try {\n const { selector, values, by } = message;\n const elementMap = getElementMap();\n \n // Find the select element\n let selectEl: HTMLSelectElement | null = null;\n \n if (/^e\\d+$/.test(selector)) {\n const elemRef = elementMap[selector];\n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[selector];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[selector];\n }\n \n if (!element) {\n sendResponse({ error: `Element ${selector} not found` });\n break;\n }\n if (element.tagName !== 'SELECT') {\n sendResponse({ error: `Element ${selector} is not a <select>` });\n break;\n }\n selectEl = element as HTMLSelectElement;\n } else {\n selectEl = document.querySelector(selector) as HTMLSelectElement;\n if (!selectEl) {\n sendResponse({ error: `No element found matching \"${selector}\"` });\n break;\n }\n if (selectEl.tagName !== 'SELECT') {\n sendResponse({ error: `Element \"${selector}\" is not a <select>` });\n break;\n }\n }\n \n // Clear current selection for multi-select\n if (selectEl.multiple) {\n for (const opt of selectEl.options) {\n opt.selected = false;\n }\n }\n \n const selected: string[] = [];\n const notFound: string[] = [];\n \n // For single-select, only use the first value\n const valuesToSelect = selectEl.multiple ? values : [values[0]];\n \n for (const val of valuesToSelect) {\n let found = false;\n \n for (const opt of selectEl.options) {\n let matches = false;\n \n if (by === 'index') {\n matches = opt.index === parseInt(val, 10);\n } else if (by === 'label') {\n matches = opt.text.toLowerCase().includes(val.toLowerCase());\n } else {\n // Default: match by value\n matches = opt.value === val;\n }\n \n if (matches) {\n opt.selected = true;\n selected.push(opt.value);\n found = true;\n break; // Found match for this value, move to next\n }\n }\n \n if (!found) notFound.push(val);\n }\n \n // Dispatch change event\n selectEl.dispatchEvent(new Event('change', { bubbles: true }));\n \n if (notFound.length > 0) {\n sendResponse({ \n selected, \n warning: `Values not found: ${notFound.join(', ')}` \n });\n } else {\n sendResponse({ selected });\n }\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"GET_ELEMENT_TEXT\": {\n try {\n const { ref } = message;\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n \n let element: Element | undefined;\n if (elemRef) {\n element = elemRef.element.deref();\n if (!element) delete elementMap[ref];\n }\n if (!element && window.__piRefs) {\n element = window.__piRefs[ref];\n }\n \n if (!element) {\n sendResponse({ error: `Element ${ref} not found` });\n break;\n }\n \n sendResponse({ text: element.textContent?.trim() || '' });\n } catch (err) {\n sendResponse({ error: err instanceof Error ? err.message : String(err) });\n }\n break;\n }\n case \"SCROLL_TO_ELEMENT\": {\n const result = scrollToElement(message.ref);\n sendResponse(result);\n break;\n }\n case \"UPLOAD_IMAGE\": {\n const result = uploadImage(message.base64, message.ref, message.coordinate, message.filename);\n sendResponse(result);\n break;\n }\n case \"WAIT_FOR_ELEMENT\": {\n const { selector, state = 'visible', timeout = 20000 } = message;\n const maxTimeout = Math.min(timeout, 60000);\n\n const isElementVisible = (el: Element | null): boolean => {\n if (!el) return false;\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && \n style.visibility !== 'hidden' && \n style.opacity !== '0' &&\n (el as HTMLElement).offsetWidth > 0 &&\n (el as HTMLElement).offsetHeight > 0;\n };\n\n const checkElement = (): boolean => {\n const el = document.querySelector(selector);\n switch (state) {\n case 'attached': return !!el;\n case 'detached': return !el;\n case 'hidden': return !el || !isElementVisible(el);\n case 'visible':\n default: return isElementVisible(el);\n }\n };\n\n const startTime = Date.now();\n \n const waitForCondition = (): Promise<{ success: boolean; waited: number; error?: string }> => {\n return new Promise((resolve) => {\n if (checkElement()) {\n resolve({ success: true, waited: Date.now() - startTime });\n return;\n }\n\n const observer = new MutationObserver(() => {\n if (checkElement()) {\n observer.disconnect();\n clearTimeout(timeoutId);\n resolve({ success: true, waited: Date.now() - startTime });\n }\n });\n\n const timeoutId = setTimeout(() => {\n observer.disconnect();\n resolve({ \n success: false, \n waited: Date.now() - startTime,\n error: `Timeout waiting for \"${selector}\" to be ${state}` \n });\n }, maxTimeout);\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'class', 'hidden', 'disabled']\n });\n });\n };\n\n waitForCondition().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({ \n error: waitResult.error, \n waited: waitResult.waited,\n pageContent: \"\", \n viewport: { width: window.innerWidth, height: window.innerHeight } \n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"WAIT_FOR_URL\": {\n const { pattern, timeout = 20000 } = message;\n const maxTimeout = Math.min(timeout, 60000);\n\n const matchesPattern = (url: string): boolean => {\n if (pattern.includes('*')) {\n const regexPattern = pattern\n .replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<<GLOBSTAR>>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<<GLOBSTAR>>>/g, '.*');\n return new RegExp(`^${regexPattern}$`).test(url);\n }\n return url.includes(pattern);\n };\n\n const startTime = Date.now();\n\n const waitForUrl = (): Promise<{ success: boolean; waited: number; error?: string }> => {\n return new Promise((resolve) => {\n if (matchesPattern(window.location.href)) {\n resolve({ success: true, waited: Date.now() - startTime });\n return;\n }\n\n let resolved = false;\n const checkUrl = () => {\n if (resolved) return;\n if (matchesPattern(window.location.href)) {\n resolved = true;\n clearInterval(intervalId);\n clearTimeout(timeoutId);\n window.removeEventListener('popstate', checkUrl);\n window.removeEventListener('hashchange', checkUrl);\n resolve({ success: true, waited: Date.now() - startTime });\n }\n };\n\n const intervalId = setInterval(checkUrl, 100);\n const timeoutId = setTimeout(() => {\n if (resolved) return;\n resolved = true;\n clearInterval(intervalId);\n window.removeEventListener('popstate', checkUrl);\n window.removeEventListener('hashchange', checkUrl);\n resolve({ \n success: false, \n waited: Date.now() - startTime,\n error: `Timeout waiting for URL to match \"${pattern}\". Current: ${window.location.href}` \n });\n }, maxTimeout);\n\n window.addEventListener('popstate', checkUrl);\n window.addEventListener('hashchange', checkUrl);\n });\n };\n\n waitForUrl().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({ \n error: waitResult.error, \n waited: waitResult.waited,\n pageContent: \"\", \n viewport: { width: window.innerWidth, height: window.innerHeight } \n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"WAIT_FOR_DOM_STABLE\": {\n const { stable = 100, timeout = 5000 } = message;\n const maxTimeout = Math.min(timeout, 30000);\n const startTime = Date.now();\n\n const waitForStability = (): Promise<{ success: boolean; waited: number; error?: string }> => {\n return new Promise((resolve) => {\n let lastMutationTime = Date.now();\n let resolved = false;\n\n const checkStability = () => {\n if (resolved) return;\n const timeSinceLastMutation = Date.now() - lastMutationTime;\n if (timeSinceLastMutation >= stable) {\n resolved = true;\n observer.disconnect();\n clearTimeout(timeoutId);\n clearInterval(checkInterval);\n resolve({ success: true, waited: Date.now() - startTime });\n }\n };\n\n const observer = new MutationObserver(() => {\n lastMutationTime = Date.now();\n });\n\n const timeoutId = setTimeout(() => {\n if (resolved) return;\n resolved = true;\n observer.disconnect();\n clearInterval(checkInterval);\n resolve({\n success: false,\n waited: Date.now() - startTime,\n error: `Timeout: DOM did not stabilize within ${maxTimeout}ms`\n });\n }, maxTimeout);\n\n const checkInterval = setInterval(checkStability, Math.max(10, Math.min(50, stable / 2)));\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n checkStability();\n });\n };\n\n waitForStability().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({\n error: waitResult.error,\n waited: waitResult.waited,\n pageContent: \"\",\n viewport: { width: window.innerWidth, height: window.innerHeight }\n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"FORM_FILL\": {\n const { data } = message;\n if (!Array.isArray(data)) {\n sendResponse({ error: \"data must be an array of {ref, value} pairs\" });\n return true;\n }\n if (message.expectedIdentity && data.length !== 1) {\n sendResponse({ error: \"guarded fill requires exactly one field\", code: \"stale_observation\" });\n return true;\n }\n const elementMap = getElementMap();\n const results: { ref: string; success: boolean; error?: string }[] = [];\n for (const item of data) {\n const { ref, value } = item;\n if (!ref) {\n results.push({ ref: ref || \"unknown\", success: false, error: \"Missing ref\" });\n continue;\n }\n const elemRef = elementMap[ref];\n if (!elemRef) {\n results.push({ ref, success: false, error: \"Element not found (run page.read first)\" });\n continue;\n }\n const el = elemRef.element.deref() as HTMLElement | null;\n if (!el) {\n delete elementMap[ref];\n results.push({ ref, success: false, error: \"Element no longer exists\" });\n continue;\n }\n const guardError = semanticGuardError(el, message.expectedIdentity);\n if (guardError) {\n sendResponse({ success: false, error: guardError, code: guardError, filled: 0, failed: 1, results: [] });\n return true;\n }\n try {\n if (el instanceof HTMLInputElement) {\n const inputType = el.type.toLowerCase();\n if (inputType === \"checkbox\" || inputType === \"radio\") {\n const shouldCheck = value === true || value === \"true\" || value === \"1\" || value === \"checked\";\n el.checked = shouldCheck;\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else {\n el.focus();\n setNativeValue(el, String(value));\n }\n results.push({ ref, success: true });\n } else if (el instanceof HTMLTextAreaElement) {\n el.focus();\n setNativeValue(el, String(value));\n results.push({ ref, success: true });\n } else if (el instanceof HTMLSelectElement) {\n el.value = String(value);\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n results.push({ ref, success: true });\n } else if (el.isContentEditable) {\n el.focus();\n el.textContent = String(value);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n results.push({ ref, success: true });\n } else {\n results.push({ ref, success: false, error: \"Element is not fillable\" });\n }\n } catch (e) {\n results.push({ ref, success: false, error: e instanceof Error ? e.message : String(e) });\n }\n }\n const failed = results.filter(r => !r.success);\n sendResponse({\n success: failed.length === 0,\n filled: results.filter(r => r.success).length,\n failed: failed.length,\n results,\n });\n return true;\n }\n case \"GET_FILE_INPUT_SELECTOR\": {\n const { ref } = message;\n if (!ref) {\n sendResponse({ error: \"No ref provided\" });\n return true;\n }\n const elementMap = getElementMap();\n const elemRef = elementMap[ref];\n if (!elemRef) {\n sendResponse({ error: \"Element not found (run page.read first)\" });\n return true;\n }\n const el = elemRef.element.deref() as HTMLElement | null;\n if (!el) {\n delete elementMap[ref];\n sendResponse({ error: \"Element no longer exists\" });\n return true;\n }\n if (!(el instanceof HTMLInputElement) || el.type !== \"file\") {\n sendResponse({ error: \"Element is not a file input\" });\n return true;\n }\n const uniqueId = `__pi_file_${Date.now()}`;\n el.setAttribute(\"data-pi-file-id\", uniqueId);\n sendResponse({ selector: `[data-pi-file-id=\"${uniqueId}\"]` });\n return true;\n }\n case \"WAIT_FOR_NETWORK_IDLE\": {\n const { timeout = 10000 } = message;\n const maxTimeout = Math.min(timeout, 60000);\n\n const adPatterns = [\n \"doubleclick.net\", \"googlesyndication.com\", \"googletagmanager.com\",\n \"google-analytics.com\", \"facebook.net\", \"connect.facebook.net\",\n \"analytics\", \"ads\", \"tracking\", \"pixel\", \"hotjar.com\", \"clarity.ms\",\n \"mixpanel.com\", \"segment.com\", \"newrelic.com\", \"nr-data.net\",\n \"/tracker/\", \"/collector/\", \"/beacon/\", \"/telemetry/\", \"/log/\",\n \"/events/\", \"/track.\", \"/metrics/\"\n ];\n\n const nonCriticalTypes = [\"img\", \"image\", \"font\", \"icon\"];\n\n const isAdOrTracking = (url: string): boolean => {\n return adPatterns.some(pattern => url.includes(pattern));\n };\n\n const isNonCritical = (entry: PerformanceResourceTiming): boolean => {\n const type = entry.initiatorType || \"unknown\";\n if (nonCriticalTypes.includes(type)) return true;\n if (/\\.(jpg|jpeg|png|gif|webp|svg|ico|woff|woff2|ttf|eot)(\\?|$)/i.test(entry.name)) return true;\n return false;\n };\n\n const getPendingRequests = (): PerformanceResourceTiming[] => {\n const now = performance.now();\n const resources = performance.getEntriesByType(\"resource\") as PerformanceResourceTiming[];\n return resources.filter(entry => {\n if (entry.responseEnd !== 0) return false;\n if (entry.name.startsWith(\"data:\")) return false;\n if (entry.name.length > 500) return false;\n if (isAdOrTracking(entry.name)) return false;\n const loadingDuration = now - entry.startTime;\n if (loadingDuration > 10000) return false;\n if (isNonCritical(entry) && loadingDuration > 3000) return false;\n return true;\n });\n };\n\n const startTime = Date.now();\n\n const waitForIdle = (): Promise<{ success: boolean; waited: number; pendingCount?: number }> => {\n return new Promise((resolve) => {\n const check = () => {\n const pending = getPendingRequests();\n const elapsed = Date.now() - startTime;\n \n if (pending.length === 0) {\n resolve({ success: true, waited: elapsed });\n return;\n }\n \n if (elapsed >= maxTimeout) {\n resolve({ success: false, waited: elapsed, pendingCount: pending.length });\n return;\n }\n \n setTimeout(check, 100);\n };\n check();\n });\n };\n\n waitForIdle().then((waitResult) => {\n if (!waitResult.success) {\n sendResponse({ \n error: `Network not idle after ${waitResult.waited}ms (${waitResult.pendingCount} requests pending)`,\n waited: waitResult.waited,\n pageContent: \"\", \n viewport: { width: window.innerWidth, height: window.innerHeight } \n });\n return;\n }\n const treeResult = generateAccessibilityTree(\"interactive\", 15, undefined, true);\n sendResponse({ ...treeResult, waited: waitResult.waited });\n });\n return true;\n }\n case \"SEARCH_PAGE\": {\n const { term, caseSensitive, limit } = message;\n const matches = searchPageText(term, caseSensitive || false, limit || 10);\n sendResponse({ query: term, count: matches.length, matches });\n break;\n }\n case \"GET_ELEMENT_BOUNDS_FOR_ANNOTATION\": {\n const elementMap = getElementMap();\n const elements: Array<{ ref: string; tag: string; bounds: { x: number; y: number; width: number; height: number } }> = [];\n \n for (const [ref, entry] of Object.entries(elementMap)) {\n const el = entry.element.deref();\n if (!el) continue;\n \n const rect = el.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) continue;\n if (rect.bottom < 0 || rect.top > window.innerHeight) continue;\n if (rect.right < 0 || rect.left > window.innerWidth) continue;\n \n elements.push({\n ref,\n tag: el.tagName.toLowerCase(),\n bounds: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n },\n });\n }\n \n sendResponse({ elements });\n break;\n }\n default:\n return false;\n }\n return false;\n});\n\nfunction searchPageText(term: string, caseSensitive: boolean, limit: number) {\n const matches: Array<{\n ref: string;\n text: string;\n context: string;\n bounds: { x: number; y: number; width: number; height: number };\n elementRef: string | null;\n }> = [];\n \n const searchTerm = caseSensitive ? term : term.toLowerCase();\n const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);\n const elementMap = getElementMap();\n let matchIndex = 0;\n \n while (walker.nextNode() && matches.length < limit) {\n const node = walker.currentNode;\n const textContent = node.textContent || \"\";\n const searchIn = caseSensitive ? textContent : textContent.toLowerCase();\n \n let pos = 0;\n while ((pos = searchIn.indexOf(searchTerm, pos)) !== -1 && matches.length < limit) {\n const parent = node.parentElement;\n if (!parent) { pos++; continue; }\n \n const range = document.createRange();\n range.setStart(node, pos);\n range.setEnd(node, Math.min(pos + term.length, textContent.length));\n const rect = range.getBoundingClientRect();\n \n if (rect.width === 0 || rect.height === 0) { pos++; continue; }\n \n const fullText = node.textContent || \"\";\n const contextStart = Math.max(0, pos - 30);\n const contextEnd = Math.min(fullText.length, pos + term.length + 30);\n const context = fullText.slice(contextStart, contextEnd).trim();\n \n let elementRef: string | null = null;\n for (const [ref, entry] of Object.entries(elementMap)) {\n const el = entry.element.deref();\n if (el && (el === parent || el.contains(parent))) {\n elementRef = ref;\n break;\n }\n }\n \n matches.push({\n ref: `m${++matchIndex}`,\n text: fullText.slice(pos, pos + term.length),\n context,\n bounds: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n },\n elementRef,\n });\n \n pos++;\n }\n }\n \n return matches;\n}\n"],"mappings":"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"}
|