export declare const buildDomViewJs = "(() => {\n  // src/context-providers/dom/const.ts\n  var INTERACTIVE_ELEMENTS = /* @__PURE__ */ new Set([\n    \"a\",\n    \"input\",\n    \"button\",\n    \"select\",\n    \"menu\",\n    \"menuitem\",\n    \"textarea\",\n    \"canvas\",\n    \"embed\"\n  ]);\n  var INTERACTIVE_ROLES = /* @__PURE__ */ new Set([\n    \"button\",\n    \"link\",\n    \"checkbox\",\n    \"radio\",\n    \"textbox\",\n    \"menuitem\",\n    \"tab\",\n    \"tabpanel\",\n    \"tooltip\",\n    \"slider\",\n    \"progressbar\",\n    \"switch\",\n    \"listbox\",\n    \"option\",\n    \"combobox\",\n    \"menu\",\n    \"treeitem\",\n    \"tree\",\n    \"spinbutton\",\n    \"scrollbar\",\n    \"menuitemcheckbox\",\n    \"menuitemradio\",\n    \"action\"\n  ]);\n  var INTERACTIVE_ARIA_PROPS = [\n    \"aria-expanded\",\n    \"aria-pressed\",\n    \"aria-selected\",\n    \"aria-checked\"\n  ];\n  var CLICK_ATTRIBUTES = [\"onclick\", \"ng-click\", \"@click\", \"v-on:click\"];\n  var CONTEXT_ATTRIBUTES = [\n    \"title\",\n    \"type\",\n    \"name\",\n    \"role\",\n    \"aria-label\",\n    \"placeholder\",\n    \"value\",\n    \"checked\",\n    \"alt\",\n    \"aria-expanded\"\n  ];\n\n  // src/context-providers/dom/elem-interactive.ts\n  var isInteractiveElem = (element) => {\n    const tagName = element.tagName.toLowerCase();\n    const role = element.getAttribute(\"role\");\n    const ariaRole = element.getAttribute(\"aria-role\");\n    const hasInteractiveRole = INTERACTIVE_ELEMENTS.has(tagName) || INTERACTIVE_ROLES.has(role || \"\") || INTERACTIVE_ROLES.has(ariaRole || \"\");\n    if (hasInteractiveRole) {\n      let reason = \"\";\n      if (INTERACTIVE_ELEMENTS.has(tagName)) {\n        reason = `Interactive HTML element: <${tagName}>`;\n      } else if (INTERACTIVE_ROLES.has(role || \"\")) {\n        reason = `Interactive role: ${role}`;\n      } else if (INTERACTIVE_ROLES.has(ariaRole || \"\")) {\n        reason = `Interactive aria-role: ${ariaRole}`;\n      }\n      return { isInteractive: true, reason };\n    }\n    const hasClickHandler = element.onclick !== null || element.getAttribute(\"onclick\") !== null || CLICK_ATTRIBUTES.some((attr) => element.hasAttribute(attr));\n    if (hasClickHandler) {\n      return { isInteractive: true, reason: \"Has click handler\" };\n    }\n    const hasInjectedListener = element.hasAttribute(\"data-has-interactive-listener\");\n    if (hasInjectedListener) {\n      return { isInteractive: true, reason: \"Has interactive event listener (tracked)\" };\n    }\n    const hasAriaProps = INTERACTIVE_ARIA_PROPS.some(\n      (prop) => element.hasAttribute(prop)\n    );\n    if (hasAriaProps) {\n      const props = INTERACTIVE_ARIA_PROPS.filter(\n        (prop) => element.hasAttribute(prop)\n      );\n      return {\n        isInteractive: true,\n        reason: `Has interactive ARIA properties: ${props.join(\", \")}`\n      };\n    }\n    const isContentEditable = element.getAttribute(\"contenteditable\") === \"true\" || element.isContentEditable;\n    if (isContentEditable) {\n      return { isInteractive: true, reason: \"Is content editable\" };\n    }\n    const isDraggable = element.draggable || element.getAttribute(\"draggable\") === \"true\";\n    if (isDraggable) {\n      return { isInteractive: true, reason: \"Is draggable\" };\n    }\n    return { isInteractive: false, reason: \"Not interactive\" };\n  };\n  var isIgnoredElem = (element) => {\n    const rect = element.getBoundingClientRect();\n    const isNotVisible = rect.width === 0 || rect.height === 0;\n    return element.tagName.toLowerCase() === \"html\" || element.tagName.toLowerCase() === \"body\" || isNotVisible || element.hasAttribute(\"disabled\") || element.getAttribute(\"aria-disabled\") === \"true\";\n  };\n\n  // src/context-providers/dom/find-interactive-elements.ts\n  var findInteractiveElements = () => {\n    const intereactiveElements = [];\n    const processedElements = /* @__PURE__ */ new Set();\n    const processRoot = (root, rootInfo = {}) => {\n      const elements = root.querySelectorAll(\"*\");\n      for (let i = 0; i < elements.length; i++) {\n        const element = elements[i];\n        if (processedElements.has(element)) {\n          continue;\n        }\n        processedElements.add(element);\n        if (element.shadowRoot) {\n          processRoot(element.shadowRoot, {\n            iframe: rootInfo.iframe,\n            shadowHost: element\n          });\n        }\n        const { isInteractive, reason } = isInteractiveElem(element);\n        if (isIgnoredElem(element) || !isInteractive) {\n          continue;\n        }\n        intereactiveElements.push({\n          element,\n          iframe: rootInfo.iframe,\n          shadowHost: rootInfo.shadowHost,\n          rect: element.getBoundingClientRect(),\n          interactiveReason: reason,\n          isUnderShadowRoot: element.getRootNode().nodeType === Node.DOCUMENT_FRAGMENT_NODE,\n          cssPath: \"\",\n          xpath: \"\"\n        });\n      }\n    };\n    processRoot(document);\n    const iframes = document.querySelectorAll(\"iframe\");\n    for (let i = 0; i < iframes.length; i++) {\n      const iframe = iframes[i];\n      try {\n        const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;\n        if (iframeDoc) {\n          processRoot(iframeDoc, { iframe });\n        }\n      } catch (e) {\n        console.warn(\"error processing iframe\", e);\n      }\n    }\n    return intereactiveElements;\n  };\n\n  // src/context-providers/dom/highlight.ts\n  var isElementPartiallyVisible = (rect) => {\n    return rect.width > 0 && rect.height > 0 && rect.top < window.innerHeight && // These checks are relative to the current viewport\n    rect.bottom > 0 && // where the rect was calculated.\n    rect.left < window.innerWidth && rect.right > 0;\n  };\n  var getHighlightColor = (index) => {\n    const colors = [\n      \"#FF0000\",\n      \"#00FF00\",\n      \"#0000FF\",\n      \"#FFA500\",\n      \"#800080\",\n      \"#008080\",\n      \"#FF69B4\",\n      \"#4B0082\",\n      \"#FF4500\",\n      \"#2E8B57\",\n      \"#DC143C\",\n      \"#4682B4\"\n    ];\n    const colorIndex = index % colors.length;\n    const baseColor = colors[colorIndex];\n    const backgroundColor = baseColor + \"1A\";\n    return { baseColor, backgroundColor };\n  };\n  var calculateLabelPosition = (rect, iframeOffset, labelWidth, labelHeight, canvasWidth, canvasHeight) => {\n    const top = rect.top + iframeOffset.y;\n    const left = rect.left + iframeOffset.x;\n    let labelTop = top - labelHeight;\n    let labelLeft = left + rect.width - labelWidth;\n    labelTop = Math.min(labelTop, canvasHeight - labelHeight);\n    labelLeft = Math.min(labelLeft, canvasWidth - labelWidth);\n    const elementBottom = top + rect.height;\n    const elementRight = left + rect.width;\n    if (labelTop + labelHeight > top && labelTop < elementBottom && labelLeft + labelWidth > left && labelLeft < elementRight) {\n      labelTop = elementBottom;\n      labelLeft = elementRight - labelWidth;\n      labelTop = Math.min(labelTop, canvasHeight - labelHeight);\n      labelLeft = Math.min(labelLeft, canvasWidth - labelWidth);\n    }\n    return { top: labelTop, left: labelLeft };\n  };\n  function renderHighlightsOffscreen(highlightInfos, width, height) {\n    if (width <= 0 || height <= 0) {\n      console.warn(\n        \"Attempted to render highlights on zero-sized canvas. Will default to innerWidth x innerHeight\"\n      );\n      const emptyCanvas = new OffscreenCanvas(\n        window.innerWidth,\n        window.innerHeight\n      );\n      return emptyCanvas.transferToImageBitmap();\n    }\n    const dpr = window.devicePixelRatio || 1;\n    const canvasWidth = width * dpr;\n    const canvasHeight = height * dpr;\n    const offscreenCanvas = new OffscreenCanvas(canvasWidth, canvasHeight);\n    const ctx = offscreenCanvas.getContext(\"2d\", {\n      alpha: true\n    });\n    ctx.scale(dpr, dpr);\n    ctx.clearRect(0, 0, width, height);\n    try {\n      highlightInfos.forEach(({ element, index, parentIframe }) => {\n        if (!document.body.contains(element)) {\n          return;\n        }\n        const rect = element.getBoundingClientRect();\n        if (!rect || rect.width === 0 || rect.height === 0 || !isElementPartiallyVisible(rect)) {\n          return;\n        }\n        const iframeOffset = { x: 0, y: 0 };\n        if (parentIframe && document.body.contains(parentIframe)) {\n          const iframeRect = parentIframe.getBoundingClientRect();\n          iframeOffset.x = iframeRect.left;\n          iframeOffset.y = iframeRect.top;\n        }\n        const colors = getHighlightColor(index);\n        const drawTop = rect.top + iframeOffset.y;\n        const drawLeft = rect.left + iframeOffset.x;\n        ctx.fillStyle = colors.backgroundColor;\n        ctx.fillRect(drawLeft, drawTop, rect.width, rect.height);\n        ctx.strokeStyle = colors.baseColor;\n        ctx.lineWidth = 1;\n        ctx.strokeRect(drawLeft, drawTop, rect.width, rect.height);\n        const labelText = index.toString();\n        const fontSize = Math.min(12, Math.max(9, rect.height * 0.3));\n        ctx.font = `bold ${fontSize}px sans-serif`;\n        ctx.textAlign = \"center\";\n        ctx.textBaseline = \"middle\";\n        const textMetrics = ctx.measureText(labelText);\n        const labelPadding = 4;\n        const labelHeight = fontSize + labelPadding;\n        const labelWidth = Math.max(\n          labelHeight,\n          textMetrics.width + labelPadding * 2\n        );\n        const labelPos = calculateLabelPosition(\n          rect,\n          iframeOffset,\n          labelWidth,\n          labelHeight,\n          width,\n          height\n        );\n        ctx.fillStyle = colors.baseColor;\n        ctx.fillRect(labelPos.left, labelPos.top, labelWidth, labelHeight);\n        ctx.fillStyle = \"white\";\n        ctx.fillText(\n          labelText,\n          labelPos.left + labelWidth / 2,\n          labelPos.top + labelHeight / 2\n        );\n      });\n      return offscreenCanvas.transferToImageBitmap();\n    } catch (error) {\n      console.error(\"Error drawing highlights onto OffscreenCanvas:\", error);\n      const emptyCanvas = new OffscreenCanvas(1, 1);\n      return emptyCanvas.transferToImageBitmap();\n    }\n  }\n\n  // src/context-providers/dom/get-css-path.ts\n  var escapeSelector = (value) => {\n    return CSS.escape(value);\n  };\n  var getUniqueSegment = (element) => {\n    const tagName = element.tagName.toLowerCase();\n    const parent = element.parentElement;\n    if (element.id) {\n      const idSelector = `#${escapeSelector(element.id)}`;\n      return idSelector;\n    }\n    const classes = Array.from(element.classList).map(escapeSelector).join(\".\");\n    if (classes && parent) {\n      const classSelector = `${tagName}.${classes}`;\n      const siblingsWithSameClasses = Array.from(\n        parent.querySelectorAll(`:scope > ${classSelector}`)\n      );\n      if (siblingsWithSameClasses.length === 1 && siblingsWithSameClasses[0] === element) {\n        return classSelector;\n      }\n    }\n    let index = 1;\n    let sibling = element.previousElementSibling;\n    while (sibling) {\n      if (sibling.tagName === element.tagName) {\n        index++;\n      }\n      sibling = sibling.previousElementSibling;\n    }\n    let hasSameTypeSiblings = index > 1;\n    if (!hasSameTypeSiblings && parent) {\n      sibling = element.nextElementSibling;\n      while (sibling) {\n        if (sibling.tagName === element.tagName) {\n          hasSameTypeSiblings = true;\n          break;\n        }\n        sibling = sibling.nextElementSibling;\n      }\n    }\n    return hasSameTypeSiblings ? `${tagName}:nth-of-type(${index})` : tagName;\n  };\n  var getRelativeCSSPath = (element, boundary) => {\n    if (element === boundary) {\n      return \"\";\n    }\n    const segments = [];\n    let currentElement = element;\n    while (currentElement && currentElement !== boundary && currentElement.nodeType === Node.ELEMENT_NODE) {\n      const segment = getUniqueSegment(currentElement);\n      segments.unshift(segment);\n      const parent = currentElement.parentElement;\n      if (!parent || parent === boundary || parent.nodeType !== Node.ELEMENT_NODE) {\n        break;\n      }\n      currentElement = parent;\n    }\n    return segments.join(\" > \");\n  };\n  var getCSSPath = (element) => {\n    if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n      return \"\";\n    }\n    if (!element.isConnected) {\n    }\n    const root = element.getRootNode();\n    if (root instanceof ShadowRoot) {\n      const host = root.host;\n      if (!host) {\n        console.warn(\"ShadowRoot found without a host element:\", root);\n        return \"\";\n      }\n      const hostPath = getCSSPath(host);\n      const relativePath = getRelativeCSSPath(element, root);\n      if (!hostPath) {\n        console.warn(\"Could not determine CSS path for host element:\", host);\n        return \"\";\n      }\n      if (!relativePath) {\n        console.warn(\n          \"Could not determine relative CSS path within ShadowRoot for:\",\n          element\n        );\n        return \"\";\n      }\n      return `${hostPath} >> ${relativePath}`;\n    } else if (root instanceof Document) {\n      return getRelativeCSSPath(element, root);\n    } else {\n      console.warn(\n        \"Element root is neither Document nor ShadowRoot:\",\n        root,\n        \"for element:\",\n        element\n      );\n      return getRelativeCSSPath(element, root);\n    }\n  };\n\n  // src/context-providers/dom/get-x-path.ts\n  var getXPath = (element) => {\n    const segments = [];\n    let currentElement = element;\n    while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {\n      if (currentElement.parentNode instanceof ShadowRoot || currentElement.parentNode instanceof HTMLIFrameElement) {\n        break;\n      }\n      let index = 0;\n      let hasSiblings = false;\n      let sibling = currentElement.previousSibling;\n      while (sibling) {\n        if (sibling.nodeType === Node.ELEMENT_NODE && sibling.nodeName === currentElement.nodeName) {\n          index++;\n          hasSiblings = true;\n        }\n        sibling = sibling.previousSibling;\n      }\n      if (!hasSiblings) {\n        sibling = currentElement.nextSibling;\n        while (sibling) {\n          if (sibling.nodeType === Node.ELEMENT_NODE && sibling.nodeName === currentElement.nodeName) {\n            hasSiblings = true;\n            break;\n          }\n          sibling = sibling.nextSibling;\n        }\n      }\n      const tagName = currentElement.nodeName.toLowerCase();\n      const xpathIndex = hasSiblings ? `[${index + 1}]` : \"\";\n      if (currentElement.id && currentElement.id.toString().trim() !== \"\") {\n        segments.unshift(`${tagName}[@id=\"${currentElement.id}\"]`);\n      } else {\n        segments.unshift(`${tagName}${xpathIndex}`);\n      }\n      currentElement = currentElement.parentElement;\n    }\n    return segments.join(\"/\");\n  };\n\n  // src/context-providers/dom/build-dom-view.ts\n  var imageBitmapToPngDataUrl = (bitmap) => {\n    try {\n      const canvas = document.createElement(\"canvas\");\n      canvas.width = bitmap.width;\n      canvas.height = bitmap.height;\n      const ctx = canvas.getContext(\"2d\");\n      ctx.drawImage(bitmap, 0, 0);\n      return canvas.toDataURL(\"image/png\");\n    } finally {\n      bitmap.close();\n    }\n  };\n  var getElementTextContent = (el) => {\n    const tagName = el.tagName.toLowerCase();\n    if (tagName === \"input\") {\n      const inputElement = el;\n      let labelText = null;\n      if (inputElement.id) {\n        const label = document.querySelector(`label[for=\"${inputElement.id}\"]`);\n        if (label) {\n          labelText = label.textContent?.trim() || null;\n        }\n      }\n      return labelText ?? inputElement.value?.trim() ?? \"\";\n    } else {\n      return el.textContent?.trim() || \"\";\n    }\n  };\n  var buildDomView = () => {\n    const interactiveElements = findInteractiveElements();\n    const screenBitmap = renderHighlightsOffscreen(\n      interactiveElements.map((element, index) => ({\n        element: element.element,\n        index: index + 1,\n        // index range from 1 -> index\n        parentIframe: element.iframe ?? null\n      })),\n      window.innerWidth,\n      window.innerHeight\n    );\n    const screenshotPngDataUrl = imageBitmapToPngDataUrl(screenBitmap);\n    for (let idx = 0; idx < interactiveElements.length; idx++) {\n      const element = interactiveElements[idx];\n      element.highlightIndex = idx + 1;\n      element.cssPath = getCSSPath(element.element);\n      element.xpath = getXPath(element.element);\n    }\n    const domRepresentation = [];\n    const getTextBetween = (node, nextNode) => {\n      const texts = [];\n      let current = node.nextSibling;\n      while (current && current !== nextNode) {\n        if (current.nodeType === Node.TEXT_NODE && current.textContent) {\n          const text = current.textContent.trim();\n          if (text) texts.push(text);\n        }\n        current = current.nextSibling;\n      }\n      return texts.join(\" \");\n    };\n    for (let i = 0; i < interactiveElements.length; i++) {\n      const element = interactiveElements[i];\n      const el = element.element;\n      const tagName = el.tagName.toLowerCase();\n      let attributes = \"\";\n      Array.from(el.attributes).forEach((attr) => {\n        if (CONTEXT_ATTRIBUTES.includes(attr.name)) {\n          attributes += ` ${attr.name}=\"${attr.value}\"`;\n        }\n      });\n      const textContent = getElementTextContent(el);\n      const indexPrefix = `[${element.highlightIndex}]`;\n      const elementString = `${indexPrefix}<${tagName}${attributes}>${textContent.replace(/\\s+/g, \" \")}</${tagName}>`;\n      domRepresentation.push(elementString);\n      const nextElement = interactiveElements[i + 1]?.element || null;\n      const betweenText = getTextBetween(el, nextElement);\n      if (betweenText) {\n        domRepresentation.push(betweenText);\n      }\n    }\n    return {\n      elements: interactiveElements,\n      domState: domRepresentation.join(\"\\n\"),\n      screenshot: screenshotPngDataUrl\n    };\n  };\n  return buildDomView();\n})();";
