@loupekit/sdk 0.10.8-next.53 → 0.10.9-next.54
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/dist/index.global.js +62 -5
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +62 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/styles.ts","../src/fingerprint.ts","../../../node_modules/modern-screenshot/dist/index.mjs","../src/capture.ts","../src/store.ts","../src/http-adapter.ts","../../shared/dist/index.js","../src/app.ts","../src/index.ts"],"sourcesContent":["// Scoped to the Shadow DOM — none of this leaks to (or is affected by) the host page.\nexport const STYLES = /* css */ `\n:host { all: initial; }\n* { box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif; }\n\n/* Theme tokens live on :host (inside the Shadow DOM :root matches nothing).\n Dark is the default; the host element gets .theme-light to flip to light. */\n:host {\n --accent: #6b73e6;\n --pin: #ff5842;\n --bg: #14161d;\n --bg-2: #1b1e27;\n --bg-3: #262a36;\n --ink: #e7e9f0;\n --muted: #9aa0af;\n --line: #2b2f3b;\n --shadow: 0 12px 48px rgba(0,0,0,.42);\n}\n:host(.theme-light) {\n --accent: #4a55d6;\n --pin: #ff5842;\n --bg: #ffffff;\n --bg-2: #f6f7fb;\n --bg-3: #eceef4;\n --ink: #16181f;\n --muted: #6b7180;\n --line: #e2e5ee;\n --shadow: 0 12px 40px rgba(0,0,0,.22);\n}\n\n.overlay { position: fixed; inset: 0; z-index: 2147483000; pointer-events: none; }\n\n/* inspector highlight */\n.hl {\n position: fixed; pointer-events: none; z-index: 2147483001;\n border: 2px solid var(--accent);\n background: rgba(107, 115, 230, 0.12);\n border-radius: 4px; display: none;\n transition: all 60ms linear;\n}\n.hl .tip {\n position: absolute; top: -24px; left: 0; background: var(--accent); color: #fff;\n font-size: 11px; font-weight: 600; padding: 2px 7px; border-radius: 4px; white-space: nowrap;\n font-family: ui-monospace, Menlo, monospace;\n}\n\n/* region selection (during drag) + active-comment outline */\n.selbox {\n position: fixed; pointer-events: none; z-index: 2147483001; display: none;\n border: 2px dashed var(--accent); background: rgba(107, 115, 230, 0.14); border-radius: 4px;\n}\n.region-box {\n position: fixed; pointer-events: none; z-index: 2147483001; display: none;\n border: 2px solid var(--pin); border-radius: 4px;\n box-shadow: 0 0 0 2px rgba(255, 88, 66, .25), 0 4px 16px rgba(0,0,0,.25);\n}\n\n/* pins */\n.pin {\n position: fixed; pointer-events: auto; z-index: 2147483002;\n width: 26px; height: 26px; border-radius: 50% 50% 50% 2px;\n background: var(--pin); color: #fff; border: 2px solid #fff;\n font-size: 12px; font-weight: 700; cursor: pointer;\n box-shadow: 0 2px 8px rgba(0,0,0,.35);\n display: grid; place-items: center; transform: translate(-4px, -4px);\n transition: transform 80ms ease;\n}\n.pin:hover { transform: translate(-4px, -4px) scale(1.12); }\n.pin.detached { background: #9aa0af; }\n.pin.done { background: #10935a; }\n.pin.free { background: var(--accent); border-radius: 50% 50% 2px 50%; }\n.pin.free.done { background: #10935a; }\n.pin.active { outline: 3px solid rgba(107,115,230,.45); }\n/* The quick-action \"Markers\" toggle hides every pin without discarding it.\n !important beats the inline display the pin positioner sets on each frame. */\n.overlay.hide-pins .pin { display: none !important; }\n\n/* --------------------------------------------------------------- FAB cluster */\n/* The collapsed state: a primary brand button (with the comment count) plus the\n quick actions that expand out of it. Replaces the old single launcher. */\n.fab-cluster {\n position: fixed; z-index: 2147483003; bottom: 20px; right: 20px;\n display: none; flex-direction: column; align-items: flex-end; gap: 10px;\n}\n.fab-cluster.show { display: flex; }\n\n.fab-minis { display: none; flex-direction: column; align-items: flex-end; gap: 10px; }\n.fab-cluster.expanded .fab-minis { display: flex; }\n.fab-cluster.expanded .fab-minis .fab-mini { animation: loupe-fab-in 180ms cubic-bezier(.16, 1, .3, 1) both; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(1) { animation-delay: 0ms; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(2) { animation-delay: 30ms; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(3) { animation-delay: 60ms; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(4) { animation-delay: 90ms; }\n@keyframes loupe-fab-in { from { opacity: 0; transform: translateY(8px) scale(.9); } to { opacity: 1; transform: none; } }\n\n.fab-mini {\n position: relative; width: 40px; height: 40px; border-radius: 50%; padding: 0;\n border: 1px solid var(--line); background: var(--bg); color: var(--ink);\n cursor: pointer; display: inline-flex; align-items: center; justify-content: center;\n box-shadow: var(--shadow);\n}\n.fab-mini:hover { border-color: var(--accent); color: var(--accent); }\n.fab-mini.on { background: var(--accent); border-color: var(--accent); color: #fff; }\n.fab-mini.on:hover { color: #fff; }\n.fab-mini svg { display: block; width: 16px; height: 16px; }\n/* The action's label, revealed on hover so the collapsed cluster stays calm. */\n.fab-mini .fab-tip {\n position: absolute; right: calc(100% + 8px); top: 50%; transform: translateY(-50%);\n background: var(--bg); color: var(--ink); border: 1px solid var(--line);\n border-radius: 7px; padding: 4px 8px; font-size: 11px; font-weight: 600; white-space: nowrap;\n box-shadow: var(--shadow); opacity: 0; pointer-events: none; transition: opacity 120ms ease;\n}\n.fab-mini:hover .fab-tip { opacity: 1; }\n\n.launcher {\n position: relative; width: 46px; height: 46px; border-radius: 50%; padding: 0;\n border: 1px solid var(--line); background: var(--bg-2); color: var(--ink);\n cursor: pointer; display: inline-flex; align-items: center; justify-content: center;\n box-shadow: var(--shadow);\n}\n.launcher:hover { border-color: var(--accent); }\n.launcher .logo { font-size: 24px; line-height: 1; color: var(--accent); }\n/* Chevron pinned to the corner: up = actions are tucked away, down = they are out. */\n.launcher .lchev {\n position: absolute; right: -3px; bottom: -3px; width: 18px; height: 18px; border-radius: 50%;\n background: var(--bg); border: 1px solid var(--line); color: var(--muted);\n display: grid; place-items: center; transition: transform 160ms cubic-bezier(.16, 1, .3, 1);\n}\n.launcher .lchev svg { width: 11px; height: 11px; display: block; }\n.fab-cluster.expanded .launcher .lchev { transform: rotate(180deg); }\n.launcher .lcount {\n position: absolute; top: -5px; right: -5px; background: var(--pin); color: #fff;\n font-size: 10px; font-weight: 700; line-height: 1; border-radius: 999px; padding: 3px 6px;\n border: 2px solid var(--bg);\n}\n.launcher .lcount:empty { display: none; }\n@media (prefers-reduced-motion: reduce) {\n .fab-cluster.expanded .fab-minis .fab-mini { animation: none; }\n .launcher .lchev { transition: none; }\n .fab-mini .fab-tip { transition: none; }\n}\n\n/* --------------------------------------------------------------------- dock */\n/* The control panel. One container, four dock modes (left/right/bottom/float),\n overlaying the host page (never reflows it). */\n.dock {\n position: fixed; z-index: 2147483003; pointer-events: auto;\n display: none; flex-direction: column;\n background: var(--bg); color: var(--ink);\n border: 1px solid var(--line); box-shadow: var(--shadow);\n overflow: hidden; font-size: 13px;\n}\n.dock.open { display: flex; }\n.dock.mode-right { top: 0; right: 0; bottom: 0; width: 360px; border-width: 0 0 0 1px; }\n.dock.mode-left { top: 0; left: 0; bottom: 0; width: 360px; border-width: 0 1px 0 0; }\n.dock.mode-bottom { left: 0; right: 0; bottom: 0; height: 320px; border-width: 1px 0 0 0; }\n.dock.mode-float { border-radius: 14px; /* left/top/width/height set inline */ }\n\n/* header: brand + dock controls */\n.dhead {\n display: flex; align-items: center; gap: 8px; flex: none;\n padding: 8px 10px; border-bottom: 1px solid var(--line); background: var(--bg-2);\n}\n.dock.mode-float .dhead { cursor: grab; }\n.dock.mode-float.dragging .dhead { cursor: grabbing; }\n.dock.dragging { user-select: none; }\n.brand { display: flex; align-items: center; gap: 8px; font-weight: 700; letter-spacing: -.01em; }\n.brand .logo { font-size: 16px; line-height: 1; color: var(--accent); flex: none; }\n.brand .title { font-size: 13px; }\n.dctl { display: flex; align-items: center; gap: 2px; margin-left: auto; }\n.dctl button {\n display: inline-flex; align-items: center; justify-content: center;\n width: 26px; height: 26px; padding: 0; border: 0; border-radius: 6px;\n background: transparent; color: var(--muted); cursor: pointer;\n}\n.dctl button:hover { background: var(--bg-3); color: var(--ink); }\n.dctl button.on { background: var(--bg-3); color: var(--accent); }\n.dctl svg { display: block; }\n.dctl .gap { width: 1px; height: 16px; background: var(--line); margin: 0 4px; flex: none; }\n\n/* tools row */\n.tools { display: flex; gap: 6px; flex: none; padding: 10px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }\n.tools button {\n display: flex; align-items: center; gap: 6px; padding: 7px 10px; line-height: 1;\n border: 1px solid var(--line); border-radius: 8px; background: var(--bg-2); color: var(--ink);\n font-size: 12px; font-weight: 600; cursor: pointer;\n}\n.tools button:hover { background: var(--bg-3); }\n.tools button.on { background: var(--accent); border-color: var(--accent); color: #fff; }\n.tools .ico { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; }\n.tools .ico svg { width: 15px; height: 15px; display: block; }\n\n/* list */\n.listhead {\n display: flex; align-items: center; gap: 8px; flex: none; padding: 12px 12px 6px;\n font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700;\n}\n.count { background: var(--pin); color: #fff; font-size: 11px; font-weight: 700; line-height: 1; border-radius: 999px; padding: 3px 7px; }\n.list { flex: 1; overflow-y: auto; padding: 6px 10px 12px; display: flex; flex-direction: column; gap: 8px; }\n.empty { color: var(--muted); font-size: 13px; padding: 24px 12px; text-align: center; line-height: 1.5; }\n/* bottom dock lays the list out in flowing columns so it isn't a tall single strip */\n.dock.mode-bottom .list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); align-content: start; }\n\n.item { border: 1px solid var(--line); border-radius: 10px; padding: 10px; cursor: pointer; background: var(--bg-2); }\n.item:hover { border-color: var(--accent); }\n.item .top { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }\n.item .num { background: var(--pin); color: #fff; width: 20px; height: 20px; border-radius: 50%; font-size: 11px; font-weight: 700; display: grid; place-items: center; flex: none; }\n.item .num.detached { background: #9aa0af; }\n.item .num.done { background: #10935a; }\n.item .who { font-size: 12px; font-weight: 600; }\n.item .device { font-size: 10px; color: var(--muted); background: var(--bg-3); border-radius: 999px; padding: 1px 7px; white-space: nowrap; }\n.item .body { font-size: 13px; line-height: 1.4; }\n.item .meta { font-size: 11px; color: var(--muted); margin-top: 6px; font-family: ui-monospace, Menlo, monospace; word-break: break-all; }\n.item .badge { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 1px 6px; border-radius: 5px; margin-left: auto; white-space: nowrap; }\n.badge.detached { background: var(--bg-3); color: var(--muted); }\n.badge.done { background: #d8f0e4; color: #10935a; }\n.item .actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }\n.item .actions button { font-size: 11px; border: 1px solid var(--line); background: var(--bg-3); border-radius: 6px; padding: 4px 8px; cursor: pointer; color: var(--ink); }\n.item .actions button:hover { border-color: var(--accent); }\n.item img.shot { width: 100%; border-radius: 6px; margin-top: 8px; border: 1px solid var(--line); }\n.item video.shot { width: 100%; border-radius: 6px; margin-top: 8px; border: 1px solid var(--line); }\n.item .caret { margin-left: auto; color: var(--muted); font-size: 11px; }\n.item .summary { font-size: 13px; font-weight: 600; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.item .detail { margin-top: 6px; }\n.item.collapsed .detail { display: none; }\n.listhead .search {\n margin-left: auto; flex: 1; max-width: 170px; font-size: 12px; text-transform: none; letter-spacing: 0;\n padding: 4px 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg-2); color: var(--ink); outline: none;\n}\n.listhead .search:focus { border-color: var(--accent); }\n\n/* float resize grip (bottom-right corner) */\n.resize { display: none; position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 1; }\n.dock.mode-float .resize { display: block; }\n.resize::after {\n content: \"\"; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px;\n border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); opacity: .7;\n}\n\n/* composer popover */\n.composer {\n position: fixed; z-index: 2147483004; pointer-events: auto; width: 320px;\n background: var(--bg); color: var(--ink); border: 1px solid var(--line);\n border-radius: 12px; box-shadow: var(--shadow); padding: 12px; display: none;\n}\n.composer .target {\n font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--accent);\n background: var(--bg-2); border-radius: 6px; padding: 5px 8px; margin-bottom: 8px;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n}\n.composer textarea {\n width: 100%; min-height: 68px; resize: vertical; border: 1px solid var(--line);\n border-radius: 8px; padding: 8px; font-size: 13px; color: var(--ink); background: var(--bg-2); outline: none;\n}\n.composer textarea:focus { border-color: var(--accent); }\n.composer .row { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; gap: 8px; }\n.composer label.chk { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 6px; cursor: pointer; }\n.composer .btns { display: flex; gap: 6px; }\n.composer button { border: 0; border-radius: 8px; font-size: 13px; font-weight: 600; padding: 7px 12px; cursor: pointer; }\n.composer .primary { background: var(--accent); color: #fff; }\n.composer .primary:disabled { opacity: .5; cursor: default; }\n.composer .ghost { background: var(--bg-3); color: var(--ink); }\n.composer input.title {\n width: 100%; border: 1px solid var(--line); border-radius: 8px; padding: 8px; margin-bottom: 8px;\n font-size: 13px; font-weight: 600; color: var(--ink); background: var(--bg-2); outline: none;\n}\n.composer input.title:focus { border-color: var(--accent); }\n.composer .attach { margin-top: 8px; }\n.composer .pick {\n width: 100%; border: 1px dashed var(--line); background: transparent; color: var(--muted);\n border-radius: 8px; padding: 7px; font-size: 12px; font-weight: 600; cursor: pointer;\n}\n.composer .pick:hover { border-color: var(--accent); color: var(--accent); }\n.composer .chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }\n.composer .chip {\n display: inline-flex; align-items: center; gap: 4px; max-width: 100%;\n background: var(--bg-3); border-radius: 6px; padding: 2px 4px 2px 7px; font-size: 11px; color: var(--ink);\n}\n.composer .chip .x { border: 0; background: transparent; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 0 2px; }\n.composer .err { color: var(--pin); font-size: 11px; margin-top: 4px; }\n.composer .err:empty { display: none; }\n\n/* ------------------------------------------------------------ sidebar tabs */\n.tabs { display: flex; gap: 4px; flex: none; padding: 8px 10px 0; border-bottom: 1px solid var(--line); }\n.tabs .tab {\n flex: 1; padding: 8px 10px; border: 0; border-bottom: 2px solid transparent;\n background: transparent; color: var(--muted); font-size: 12px; font-weight: 700; cursor: pointer;\n border-radius: 6px 6px 0 0;\n}\n.tabs .tab:hover { color: var(--ink); background: var(--bg-2); }\n.tabs .tab.on { color: var(--accent); border-bottom-color: var(--accent); }\n\n/* Two sidebar pages: only the active one shows. */\n.view { display: none; }\n.dock.tab-comments .comments-view { display: flex; flex-direction: column; flex: 1; min-height: 0; }\n.dock.tab-connect .connect-view { display: block; flex: 1; overflow-y: auto; }\n\n/* recording marker + video in the list */\n.item .rectag { font-size: 10px; font-weight: 700; color: var(--pin); background: var(--bg-3); border-radius: 999px; padding: 1px 7px; white-space: nowrap; }\n.item video.shot { width: 100%; border-radius: 6px; margin-top: 8px; border: 1px solid var(--line); background: #000; display: block; }\n\n/* ------------------------------------------------ \"integrates with\" footer */\n.integrations { flex: none; padding: 12px 12px 14px; border-top: 1px solid var(--line); text-align: center; }\n.integrations .ilabel { font-size: 10px; letter-spacing: .12em; color: var(--muted); font-weight: 700; margin-bottom: 8px; }\n.integrations .irow { display: flex; align-items: center; justify-content: center; gap: 14px; }\n.integrations .ibtn { color: var(--muted); display: inline-flex; opacity: .8; cursor: default; }\n.integrations .ibtn:hover { color: var(--accent); opacity: 1; }\n.integrations .ibtn svg { display: block; }\n\n/* ------------------------------------------------------- Connect Claude page */\n.connect-view { padding: 16px 14px 20px; }\n.connect-hero { text-align: center; margin-bottom: 18px; }\n.connect-hero .chero-logo { font-size: 34px; line-height: 1; color: var(--accent); }\n.connect-hero .chero-title { font-size: 18px; font-weight: 800; letter-spacing: -.02em; margin-top: 8px; }\n.connect-hero .chero-sub { font-size: 12.5px; color: var(--muted); line-height: 1.45; margin-top: 6px; }\n.accentink { color: var(--accent); }\n.connect-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }\n.connect-steps .cstep-t { font-size: 13px; font-weight: 700; }\n.connect-steps .cstep-d { font-size: 12px; color: var(--muted); line-height: 1.45; margin-top: 3px; }\n.connect-steps .cstep-code {\n margin: 8px 0 0; padding: 10px; background: var(--bg-2); border: 1px solid var(--line);\n border-radius: 8px; font-family: ui-monospace, Menlo, monospace; font-size: 11px; line-height: 1.4;\n color: var(--ink); white-space: pre; overflow-x: auto;\n}\n\n/* ------------------------------------------------------- recording indicator */\n.recbar {\n position: fixed; z-index: 2147483005; top: 16px; left: 50%; transform: translateX(-50%);\n display: none; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px;\n background: var(--bg); color: var(--ink); border: 1px solid var(--pin);\n box-shadow: var(--shadow); font-size: 12px; font-weight: 600; cursor: pointer;\n}\n.recbar.show { display: inline-flex; }\n.recbar b { color: var(--pin); }\n.recbar .recdot { width: 9px; height: 9px; border-radius: 50%; background: var(--pin); animation: loupe-recpulse 1.1s infinite; }\n@keyframes loupe-recpulse { 0%,100% { opacity: 1; } 50% { opacity: .25; } }\n@media (prefers-reduced-motion: reduce) { .recbar .recdot { animation: none; } }\n\n/* Mobile: left/right/float docking is a desktop affordance. On small screens the\n panel collapses to a bottom sheet that OVERLAYS the page (pushing a side dock\n here would squeeze the page to a useless sliver), regardless of the chosen dock\n mode. !important overrides the inline geometry JS applies for float mode. */\n@media (max-width: 640px) {\n .dock.open {\n top: auto !important; left: 0 !important; right: 0 !important; bottom: 0 !important;\n width: auto !important; height: 76vh !important;\n border-width: 1px 0 0 0 !important; border-radius: 16px 16px 0 0 !important;\n }\n .dctl [data-dock], .dctl .gap { display: none; } /* dock positions don't apply on mobile */\n .resize { display: none !important; }\n .tools button { flex: 1; justify-content: center; } /* full-width tap targets */\n .dock.mode-bottom .list { grid-template-columns: 1fr; }\n .fab-cluster { bottom: 16px; right: 16px; }\n /* While a tool is active, shrink the sheet to just header + tools so most of the\n page stays visible and tappable; the list returns when the tool closes. */\n .dock.inspecting { height: auto !important; }\n .dock.inspecting .listhead, .dock.inspecting .list { display: none; }\n /* The composer is a bottom sheet on a phone: full width, thumb-reachable, and it\n scrolls when the on-screen keyboard is up. JS sets its position inline (hence the\n !important) — on small screens the sheet wins. */\n .composer {\n top: auto !important; left: 0 !important; right: 0 !important; bottom: 0 !important;\n width: auto !important; max-height: 80vh; overflow-y: auto;\n border-radius: 16px 16px 0 0; padding-bottom: 16px;\n }\n}\n`;\n","import type { Anchor, ResolveResult } from \"./types.js\";\n\n// ---- config ----------------------------------------------------------------\n\nconst TEXT_MAX = 120;\nconst ATTR_KEYS = [\"role\", \"aria-label\", \"name\", \"type\", \"alt\", \"href\", \"placeholder\", \"title\"];\n/** Minimum composite score to accept a scan match. Below this we treat the element as gone. */\nconst ACCEPT_THRESHOLD = 0.5;\n/** Weights for the composite similarity score (sum need not be 1; we normalize). */\nconst W = { tag: 0.12, text: 0.34, attrs: 0.22, testid: 0.22, cssPath: 0.2, position: 0.1 };\n\n// ---- capture ----------------------------------------------------------------\n\nexport function captureAnchor(el: Element): Anchor {\n const rect = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n cssPath: cssPath(el),\n xpath: xPath(el),\n testid: stableId(el),\n text: normText(el.textContent),\n attrs: readAttrs(el),\n nthOfType: nthOfType(el),\n rect: {\n x: Math.round(rect.left + window.scrollX),\n y: Math.round(rect.top + window.scrollY),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n viewport: { w: window.innerWidth, h: window.innerHeight },\n };\n}\n\n// ---- resolve ----------------------------------------------------------------\n\n/**\n * Try to re-locate the element described by `anchor` on the current page.\n * Returns the best candidate above threshold, or null (→ caller falls back to\n * a coordinate pin on the screenshot). Never returns an element inside our own UI.\n */\nexport function resolveAnchor(anchor: Anchor, root: ParentNode = document): ResolveResult | null {\n // 1. Stable id / testid — the strongest signal. Accept immediately if unique.\n if (anchor.testid) {\n const byTestid = safeQueryAll(root, `[data-testid=\"${cssStr(anchor.testid)}\"], [data-test=\"${cssStr(anchor.testid)}\"]`);\n const byId = document.getElementById(anchor.testid);\n const hits = dedupe([...byTestid, ...(byId ? [byId] : [])]).filter(usable);\n if (hits.length === 1) return { element: hits[0]!, score: 0.98, via: \"testid\" };\n // Multiple matches → fall through to scoring to disambiguate.\n }\n\n // 1.5. A cssPath rooted at a stable id/testid + structural position is\n // high-confidence even when the element's own text/content has changed\n // (e.g. a value that updates on redeploy). Require the tag to still match.\n if (/^(\\[data-testid=|#)/.test(anchor.cssPath)) {\n const hits = safeQueryAll(root, anchor.cssPath).filter(usable);\n if (hits.length === 1 && hits[0]!.tagName.toLowerCase() === anchor.tag) {\n return { element: hits[0]!, score: 0.9, via: \"cssPath\" };\n }\n }\n\n const candidates = new Map<Element, ResolveResult[\"via\"]>();\n const consider = (el: Element | null, via: ResolveResult[\"via\"]) => {\n if (el && usable(el) && !candidates.has(el)) candidates.set(el, via);\n };\n\n // 2. Exact locators.\n consider(safeQuery(root, anchor.cssPath), \"cssPath\");\n consider(byXPath(anchor.xpath), \"xpath\");\n for (const el of safeQueryAll(root, anchor.tag)) consider(el, \"scan\");\n\n // 3. Broaden by text when the tag scan is too narrow (e.g. wrapper changed tag).\n if (anchor.text) {\n for (const el of safeQueryAll(root, \"*\")) {\n if (candidates.size > 4000) break; // safety cap on huge pages\n if (normText(el.textContent) === anchor.text) consider(el, \"scan\");\n }\n }\n\n let best: ResolveResult | null = null;\n for (const [el, via] of candidates) {\n const score = similarity(anchor, el, via);\n if (!best || score > best.score) best = { element: el, score, via };\n }\n return best && best.score >= ACCEPT_THRESHOLD ? best : null;\n}\n\nfunction similarity(a: Anchor, el: Element, via: ResolveResult[\"via\"]): number {\n let sum = 0;\n let total = 0;\n\n const add = (w: number, v: number) => { sum += w * v; total += w; };\n\n add(W.tag, el.tagName.toLowerCase() === a.tag ? 1 : 0);\n\n if (a.text) {\n const t = normText(el.textContent);\n add(W.text, t === a.text ? 1 : t && (t.includes(a.text) || a.text.includes(t)) ? 0.5 : 0);\n }\n\n const attrKeys = Object.keys(a.attrs);\n if (attrKeys.length) {\n let matched = 0;\n for (const k of attrKeys) if (el.getAttribute(k) === a.attrs[k]) matched++;\n add(W.attrs, matched / attrKeys.length);\n }\n\n if (a.testid) add(W.testid, stableId(el) === a.testid ? 1 : 0);\n\n add(W.cssPath, via === \"cssPath\" ? 1 : 0);\n\n // Positional proximity — normalized by the (possibly changed) viewport diagonal.\n const r = el.getBoundingClientRect();\n const cx = r.left + window.scrollX + r.width / 2;\n const cy = r.top + window.scrollY + r.height / 2;\n const ax = a.rect.x + a.rect.w / 2;\n const ay = a.rect.y + a.rect.h / 2;\n const diag = Math.hypot(a.viewport.w, a.viewport.h) || 1;\n const dist = Math.hypot(cx - ax, cy - ay);\n add(W.position, Math.max(0, 1 - dist / diag));\n\n return total ? sum / total : 0;\n}\n\n// ---- locator builders -------------------------------------------------------\n\nfunction cssPath(el: Element): string {\n const segs: string[] = [];\n let node: Element | null = el;\n while (node && node.nodeType === 1 && node !== document.documentElement) {\n const id = node.getAttribute(\"id\");\n const testid = node.getAttribute(\"data-testid\") || node.getAttribute(\"data-test\");\n if (id && isStable(id)) { segs.unshift(`#${cssEsc(id)}`); break; }\n if (testid) { segs.unshift(`[data-testid=\"${cssStr(testid)}\"]`); break; }\n segs.unshift(`${node.tagName.toLowerCase()}:nth-of-type(${nthOfType(node)})`);\n node = node.parentElement;\n if (node === document.body) { segs.unshift(\"body\"); break; }\n }\n return segs.join(\" > \");\n}\n\nfunction xPath(el: Element): string {\n const segs: string[] = [];\n let node: Element | null = el;\n while (node && node.nodeType === 1 && node !== document.documentElement) {\n segs.unshift(`${node.tagName.toLowerCase()}[${nthOfType(node)}]`);\n node = node.parentElement;\n }\n return \"/html/\" + segs.join(\"/\");\n}\n\n// ---- small helpers ----------------------------------------------------------\n\nfunction nthOfType(el: Element): number {\n let i = 1;\n let sib = el.previousElementSibling;\n while (sib) {\n if (sib.tagName === el.tagName) i++;\n sib = sib.previousElementSibling;\n }\n return i;\n}\n\nfunction stableId(el: Element): string | null {\n const testid = el.getAttribute(\"data-testid\") || el.getAttribute(\"data-test\");\n if (testid) return testid;\n const id = el.getAttribute(\"id\");\n return id && isStable(id) ? id : null;\n}\n\n/** Reject framework-generated ids (e.g. \":r3:\", \"ember42\", long hashes). */\nfunction isStable(id: string): boolean {\n if (id.length > 40) return false;\n if (/^(ember|react|radix|headlessui|:r)/i.test(id)) return false;\n if (/[:]/.test(id)) return false;\n return true;\n}\n\nfunction readAttrs(el: Element): Record<string, string> {\n const out: Record<string, string> = {};\n for (const k of ATTR_KEYS) {\n const v = el.getAttribute(k);\n if (v != null && v !== \"\") out[k] = v.length > 200 ? v.slice(0, 200) : v;\n }\n return out;\n}\n\nfunction normText(t: string | null): string {\n return (t || \"\").replace(/\\s+/g, \" \").trim().slice(0, TEXT_MAX);\n}\n\n/** Exclude anything inside our own Shadow-DOM host and non-visible nodes. */\nfunction usable(el: Element): boolean {\n if (el.id === \"loupe-root\" || el.closest(\"#loupe-root\")) return false;\n if (el === document.body || el === document.documentElement) return false;\n return true;\n}\n\nfunction byXPath(xp: string): Element | null {\n try {\n const r = document.evaluate(xp, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n return r.singleNodeValue instanceof Element ? r.singleNodeValue : null;\n } catch {\n return null;\n }\n}\n\nfunction safeQuery(root: ParentNode, sel: string): Element | null {\n try { return sel ? root.querySelector(sel) : null; } catch { return null; }\n}\nfunction safeQueryAll(root: ParentNode, sel: string): Element[] {\n try { return sel ? Array.from(root.querySelectorAll(sel)) : []; } catch { return []; }\n}\nfunction dedupe(els: Element[]): Element[] {\n return Array.from(new Set(els));\n}\nfunction cssEsc(s: string): string {\n return (window.CSS && CSS.escape) ? CSS.escape(s) : s.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n/** Escape a value for use inside a double-quoted attribute selector. */\nfunction cssStr(s: string): string {\n return s.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n","function changeJpegDpi(uint8Array, dpi) {\n uint8Array[13] = 1;\n uint8Array[14] = dpi >> 8;\n uint8Array[15] = dpi & 255;\n uint8Array[16] = dpi >> 8;\n uint8Array[17] = dpi & 255;\n return uint8Array;\n}\n\nconst _P = \"p\".charCodeAt(0);\nconst _H = \"H\".charCodeAt(0);\nconst _Y = \"Y\".charCodeAt(0);\nconst _S = \"s\".charCodeAt(0);\nlet pngDataTable;\nfunction createPngDataTable() {\n const crcTable = new Int32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;\n }\n crcTable[n] = c;\n }\n return crcTable;\n}\nfunction calcCrc(uint8Array) {\n let c = -1;\n if (!pngDataTable)\n pngDataTable = createPngDataTable();\n for (let n = 0; n < uint8Array.length; n++) {\n c = pngDataTable[(c ^ uint8Array[n]) & 255] ^ c >>> 8;\n }\n return c ^ -1;\n}\nfunction searchStartOfPhys(uint8Array) {\n const length = uint8Array.length - 1;\n for (let i = length; i >= 4; i--) {\n if (uint8Array[i - 4] === 9 && uint8Array[i - 3] === _P && uint8Array[i - 2] === _H && uint8Array[i - 1] === _Y && uint8Array[i] === _S) {\n return i - 3;\n }\n }\n return 0;\n}\nfunction changePngDpi(uint8Array, dpi, overwritepHYs = false) {\n const physChunk = new Uint8Array(13);\n dpi *= 39.3701;\n physChunk[0] = _P;\n physChunk[1] = _H;\n physChunk[2] = _Y;\n physChunk[3] = _S;\n physChunk[4] = dpi >>> 24;\n physChunk[5] = dpi >>> 16;\n physChunk[6] = dpi >>> 8;\n physChunk[7] = dpi & 255;\n physChunk[8] = physChunk[4];\n physChunk[9] = physChunk[5];\n physChunk[10] = physChunk[6];\n physChunk[11] = physChunk[7];\n physChunk[12] = 1;\n const crc = calcCrc(physChunk);\n const crcChunk = new Uint8Array(4);\n crcChunk[0] = crc >>> 24;\n crcChunk[1] = crc >>> 16;\n crcChunk[2] = crc >>> 8;\n crcChunk[3] = crc & 255;\n if (overwritepHYs) {\n const startingIndex = searchStartOfPhys(uint8Array);\n uint8Array.set(physChunk, startingIndex);\n uint8Array.set(crcChunk, startingIndex + 13);\n return uint8Array;\n } else {\n const chunkLength = new Uint8Array(4);\n chunkLength[0] = 0;\n chunkLength[1] = 0;\n chunkLength[2] = 0;\n chunkLength[3] = 9;\n const finalHeader = new Uint8Array(54);\n finalHeader.set(uint8Array, 0);\n finalHeader.set(chunkLength, 33);\n finalHeader.set(physChunk, 37);\n finalHeader.set(crcChunk, 50);\n return finalHeader;\n }\n}\nconst b64PhysSignature1 = \"AAlwSFlz\";\nconst b64PhysSignature2 = \"AAAJcEhZ\";\nconst b64PhysSignature3 = \"AAAACXBI\";\nfunction detectPhysChunkFromDataUrl(dataUrl) {\n let b64index = dataUrl.indexOf(b64PhysSignature1);\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature2);\n }\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature3);\n }\n return b64index;\n}\n\nconst PREFIX = \"[modern-screenshot]\";\nconst IN_BROWSER = typeof window !== \"undefined\";\nconst SUPPORT_WEB_WORKER = IN_BROWSER && \"Worker\" in window;\nconst SUPPORT_ATOB = IN_BROWSER && \"atob\" in window;\nconst SUPPORT_BTOA = IN_BROWSER && \"btoa\" in window;\nconst USER_AGENT = IN_BROWSER ? window.navigator?.userAgent : \"\";\nconst IN_CHROME = USER_AGENT.includes(\"Chrome\");\nconst IN_SAFARI = USER_AGENT.includes(\"AppleWebKit\") && !IN_CHROME;\nconst IN_FIREFOX = USER_AGENT.includes(\"Firefox\");\nconst isContext = (value) => value && \"__CONTEXT__\" in value;\nconst isCssFontFaceRule = (rule) => rule.constructor.name === \"CSSFontFaceRule\";\nconst isCSSImportRule = (rule) => rule.constructor.name === \"CSSImportRule\";\nconst isLayerBlockRule = (rule) => rule.constructor.name === \"CSSLayerBlockRule\";\nconst isElementNode = (node) => node.nodeType === 1;\nconst isSVGElementNode = (node) => typeof node.className === \"object\";\nconst isSVGImageElementNode = (node) => node.tagName === \"image\";\nconst isSVGUseElementNode = (node) => node.tagName === \"use\";\nconst isHTMLElementNode = (node) => isElementNode(node) && typeof node.style !== \"undefined\" && !isSVGElementNode(node);\nconst isCommentNode = (node) => node.nodeType === 8;\nconst isTextNode = (node) => node.nodeType === 3;\nconst isImageElement = (node) => node.tagName === \"IMG\";\nconst isVideoElement = (node) => node.tagName === \"VIDEO\";\nconst isCanvasElement = (node) => node.tagName === \"CANVAS\";\nconst isTextareaElement = (node) => node.tagName === \"TEXTAREA\";\nconst isInputElement = (node) => node.tagName === \"INPUT\";\nconst isStyleElement = (node) => node.tagName === \"STYLE\";\nconst isScriptElement = (node) => node.tagName === \"SCRIPT\";\nconst isSelectElement = (node) => node.tagName === \"SELECT\";\nconst isSlotElement = (node) => node.tagName === \"SLOT\";\nconst isIFrameElement = (node) => node.tagName === \"IFRAME\";\nconst consoleWarn = (...args) => console.warn(PREFIX, ...args);\nfunction supportWebp(ownerDocument) {\n const canvas = ownerDocument?.createElement?.(\"canvas\");\n if (canvas) {\n canvas.height = canvas.width = 1;\n }\n return Boolean(canvas) && \"toDataURL\" in canvas && Boolean(canvas.toDataURL(\"image/webp\").includes(\"image/webp\"));\n}\nconst isDataUrl = (url) => url.startsWith(\"data:\");\nfunction resolveUrl(url, baseUrl) {\n if (url.match(/^[a-z]+:\\/\\//i))\n return url;\n if (IN_BROWSER && url.match(/^\\/\\//))\n return window.location.protocol + url;\n if (url.match(/^[a-z]+:/i))\n return url;\n if (!IN_BROWSER)\n return url;\n const doc = getDocument().implementation.createHTMLDocument();\n const base = doc.createElement(\"base\");\n const a = doc.createElement(\"a\");\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl)\n base.href = baseUrl;\n a.href = url;\n return a.href;\n}\nfunction getDocument(target) {\n return (target && isElementNode(target) ? target?.ownerDocument : target) ?? window.document;\n}\nconst XMLNS = \"http://www.w3.org/2000/svg\";\nfunction createSvg(width, height, ownerDocument) {\n const svg = getDocument(ownerDocument).createElementNS(XMLNS, \"svg\");\n svg.setAttributeNS(null, \"width\", width.toString());\n svg.setAttributeNS(null, \"height\", height.toString());\n svg.setAttributeNS(null, \"viewBox\", `0 0 ${width} ${height}`);\n return svg;\n}\nfunction svgToDataUrl(svg, removeControlCharacter) {\n let xhtml = new XMLSerializer().serializeToString(svg);\n if (removeControlCharacter) {\n xhtml = xhtml.replace(/[\\u0000-\\u0008\\v\\f\\u000E-\\u001F\\uD800-\\uDFFF\\uFFFE\\uFFFF]/gu, \"\");\n }\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(xhtml)}`;\n}\nasync function canvasToBlob(canvas, type = \"image/png\", quality = 1) {\n try {\n return await new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error(\"Blob is null\"));\n }\n }, type, quality);\n });\n } catch (error) {\n if (SUPPORT_ATOB) {\n return dataUrlToBlob(canvas.toDataURL(type, quality));\n }\n throw error;\n }\n}\nfunction dataUrlToBlob(dataUrl) {\n const [header, base64] = dataUrl.split(\",\");\n const type = header.match(/data:(.+);/)?.[1] ?? void 0;\n const decoded = window.atob(base64);\n const length = decoded.length;\n const buffer = new Uint8Array(length);\n for (let i = 0; i < length; i += 1) {\n buffer[i] = decoded.charCodeAt(i);\n }\n return new Blob([buffer], { type });\n}\nfunction readBlob(blob, type) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.onabort = () => reject(new Error(`Failed read blob to ${type}`));\n if (type === \"dataUrl\") {\n reader.readAsDataURL(blob);\n } else if (type === \"arrayBuffer\") {\n reader.readAsArrayBuffer(blob);\n }\n });\n}\nconst blobToDataUrl = (blob) => readBlob(blob, \"dataUrl\");\nconst blobToArrayBuffer = (blob) => readBlob(blob, \"arrayBuffer\");\nfunction createImage(url, ownerDocument) {\n const img = getDocument(ownerDocument).createElement(\"img\");\n img.decoding = \"sync\";\n img.loading = \"eager\";\n img.src = url;\n return img;\n}\nfunction loadMedia(media, options) {\n return new Promise((resolve) => {\n const { timeout, ownerDocument, onError: userOnError, onWarn } = options ?? {};\n const node = typeof media === \"string\" ? createImage(media, getDocument(ownerDocument)) : media;\n let timer = null;\n let removeEventListeners = null;\n function onResolve() {\n resolve(node);\n timer && clearTimeout(timer);\n removeEventListeners?.();\n }\n if (timeout) {\n timer = setTimeout(onResolve, timeout);\n }\n if (isVideoElement(node)) {\n const currentSrc = node.currentSrc || node.src;\n if (!currentSrc) {\n if (node.poster) {\n return loadMedia(node.poster, options).then(resolve);\n }\n return onResolve();\n }\n if (node.readyState >= 2) {\n return onResolve();\n }\n const onLoadeddata = onResolve;\n const onError = (error) => {\n onWarn?.(\n \"Failed video load\",\n currentSrc,\n error\n );\n userOnError?.(error);\n onResolve();\n };\n removeEventListeners = () => {\n node.removeEventListener(\"loadeddata\", onLoadeddata);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"loadeddata\", onLoadeddata, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n } else {\n const currentSrc = isSVGImageElementNode(node) ? node.href.baseVal : node.currentSrc || node.src;\n if (!currentSrc) {\n return onResolve();\n }\n const onLoad = async () => {\n if (isImageElement(node) && \"decode\" in node) {\n try {\n await node.decode();\n } catch (error) {\n onWarn?.(\n \"Failed to decode image, trying to render anyway\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n }\n }\n onResolve();\n };\n const onError = (error) => {\n onWarn?.(\n \"Failed image load\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n onResolve();\n };\n if (isImageElement(node) && node.complete) {\n return onLoad();\n }\n removeEventListeners = () => {\n node.removeEventListener(\"load\", onLoad);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"load\", onLoad, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n }\n });\n}\nasync function waitUntilLoad(node, options) {\n if (isHTMLElementNode(node)) {\n if (isImageElement(node) || isVideoElement(node)) {\n await loadMedia(node, options);\n } else {\n await Promise.all(\n [\"img\", \"video\"].flatMap((selectors) => {\n return Array.from(node.querySelectorAll(selectors)).map((el) => loadMedia(el, options));\n })\n );\n }\n }\n}\nconst uuid = /* @__PURE__ */ function uuid2() {\n let counter = 0;\n const random = () => `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n}();\nfunction splitFontFamily(fontFamily) {\n return fontFamily?.split(\",\").map((val) => val.trim().replace(/\"|'/g, \"\").toLowerCase()).filter(Boolean);\n}\n\nlet uid = 0;\nfunction createLogger(debug) {\n const prefix = `${PREFIX}[#${uid}]`;\n uid++;\n return {\n // eslint-disable-next-line no-console\n time: (label) => debug && console.time(`${prefix} ${label}`),\n // eslint-disable-next-line no-console\n timeEnd: (label) => debug && console.timeEnd(`${prefix} ${label}`),\n warn: (...args) => debug && consoleWarn(...args)\n };\n}\n\nfunction getDefaultRequestInit(bypassingCache) {\n return {\n cache: bypassingCache ? \"no-cache\" : \"force-cache\"\n };\n}\n\nasync function orCreateContext(node, options) {\n return isContext(node) ? node : createContext(node, { ...options, autoDestruct: true });\n}\nasync function createContext(node, options) {\n const { scale = 1, workerUrl, workerNumber = 1 } = options || {};\n const debug = Boolean(options?.debug);\n const features = options?.features ?? true;\n const ownerDocument = node.ownerDocument ?? (IN_BROWSER ? window.document : void 0);\n const ownerWindow = node.ownerDocument?.defaultView ?? (IN_BROWSER ? window : void 0);\n const requests = /* @__PURE__ */ new Map();\n const context = {\n // Options\n width: 0,\n height: 0,\n quality: 1,\n type: \"image/png\",\n scale,\n backgroundColor: null,\n style: null,\n filter: null,\n maximumCanvasSize: 0,\n timeout: 3e4,\n progress: null,\n debug,\n fetch: {\n requestInit: getDefaultRequestInit(options?.fetch?.bypassingCache),\n placeholderImage: \"data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\",\n bypassingCache: false,\n ...options?.fetch\n },\n fetchFn: null,\n font: {},\n drawImageInterval: 100,\n workerUrl: null,\n workerNumber,\n onCloneEachNode: null,\n onCloneNode: null,\n onEmbedNode: null,\n onCreateForeignObjectSvg: null,\n includeStyleProperties: null,\n autoDestruct: false,\n ...options,\n // InternalContext\n __CONTEXT__: true,\n log: createLogger(debug),\n node,\n ownerDocument,\n ownerWindow,\n dpi: scale === 1 ? null : 96 * scale,\n svgStyleElement: createStyleElement(ownerDocument),\n svgDefsElement: ownerDocument?.createElementNS(XMLNS, \"defs\"),\n svgStyles: /* @__PURE__ */ new Map(),\n defaultComputedStyles: /* @__PURE__ */ new Map(),\n workers: [\n ...Array.from({\n length: SUPPORT_WEB_WORKER && workerUrl && workerNumber ? workerNumber : 0\n })\n ].map(() => {\n try {\n const worker = new Worker(workerUrl);\n worker.onmessage = async (event) => {\n const { url, result } = event.data;\n if (result) {\n requests.get(url)?.resolve?.(result);\n } else {\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n }\n };\n worker.onmessageerror = (event) => {\n const { url } = event.data;\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n };\n return worker;\n } catch (error) {\n context.log.warn(\"Failed to new Worker\", error);\n return null;\n }\n }).filter(Boolean),\n fontFamilies: /* @__PURE__ */ new Map(),\n fontCssTexts: /* @__PURE__ */ new Map(),\n acceptOfImage: `${[\n supportWebp(ownerDocument) && \"image/webp\",\n \"image/svg+xml\",\n \"image/*\",\n \"*/*\"\n ].filter(Boolean).join(\",\")};q=0.8`,\n requests,\n drawImageCount: 0,\n tasks: [],\n features,\n isEnable: (key) => {\n if (key === \"restoreScrollPosition\") {\n return typeof features === \"boolean\" ? false : features[key] ?? false;\n }\n if (typeof features === \"boolean\") {\n return features;\n }\n return features[key] ?? true;\n },\n shadowRoots: []\n };\n context.log.time(\"wait until load\");\n await waitUntilLoad(node, { timeout: context.timeout, onWarn: context.log.warn });\n context.log.timeEnd(\"wait until load\");\n const { width, height } = resolveBoundingBox(node, context);\n context.width = width;\n context.height = height;\n return context;\n}\nfunction createStyleElement(ownerDocument) {\n if (!ownerDocument)\n return void 0;\n const style = ownerDocument.createElement(\"style\");\n const cssText = style.ownerDocument.createTextNode(`\n.______background-clip--text {\n background-clip: text;\n -webkit-background-clip: text;\n}\n`);\n style.appendChild(cssText);\n return style;\n}\nfunction resolveBoundingBox(node, context) {\n let { width, height } = context;\n if (isElementNode(node) && (!width || !height)) {\n const box = node.getBoundingClientRect();\n width = width || box.width || Number(node.getAttribute(\"width\")) || 0;\n height = height || box.height || Number(node.getAttribute(\"height\")) || 0;\n }\n return { width, height };\n}\n\nasync function imageToCanvas(image, context) {\n const {\n log,\n timeout,\n drawImageCount,\n drawImageInterval\n } = context;\n log.time(\"image to canvas\");\n const loaded = await loadMedia(image, { timeout, onWarn: context.log.warn });\n const { canvas, context2d } = createCanvas(image.ownerDocument, context);\n const drawImage = () => {\n try {\n context2d?.drawImage(loaded, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to drawImage\", error);\n }\n };\n drawImage();\n if (context.isEnable(\"fixSvgXmlDecode\")) {\n for (let i = 0; i < drawImageCount; i++) {\n await new Promise((resolve) => {\n setTimeout(() => {\n context2d?.clearRect(0, 0, canvas.width, canvas.height);\n drawImage();\n resolve();\n }, i + drawImageInterval);\n });\n }\n }\n context.drawImageCount = 0;\n log.timeEnd(\"image to canvas\");\n return canvas;\n}\nfunction createCanvas(ownerDocument, context) {\n const { width, height, scale, backgroundColor, maximumCanvasSize: max } = context;\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = Math.floor(width * scale);\n canvas.height = Math.floor(height * scale);\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n if (max) {\n if (canvas.width > max || canvas.height > max) {\n if (canvas.width > max && canvas.height > max) {\n if (canvas.width > canvas.height) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n } else if (canvas.width > max) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n }\n }\n const context2d = canvas.getContext(\"2d\");\n if (context2d && backgroundColor) {\n context2d.fillStyle = backgroundColor;\n context2d.fillRect(0, 0, canvas.width, canvas.height);\n }\n return { canvas, context2d };\n}\n\nfunction cloneCanvas(canvas, context) {\n if (canvas.ownerDocument) {\n try {\n const dataURL = canvas.toDataURL();\n if (dataURL !== \"data:,\") {\n return createImage(dataURL, canvas.ownerDocument);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n }\n const cloned = canvas.cloneNode(false);\n const ctx = canvas.getContext(\"2d\");\n const clonedCtx = cloned.getContext(\"2d\");\n try {\n if (ctx && clonedCtx) {\n clonedCtx.putImageData(\n ctx.getImageData(0, 0, canvas.width, canvas.height),\n 0,\n 0\n );\n }\n return cloned;\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n return cloned;\n}\n\nfunction cloneIframe(iframe, context) {\n try {\n if (iframe?.contentDocument?.documentElement) {\n return cloneNode(iframe.contentDocument.documentElement, context);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone iframe\", error);\n }\n return iframe.cloneNode(false);\n}\n\nfunction cloneImage(image) {\n const cloned = image.cloneNode(false);\n if (image.currentSrc && image.currentSrc !== image.src) {\n cloned.src = image.currentSrc;\n cloned.srcset = \"\";\n }\n if (cloned.loading === \"lazy\") {\n cloned.loading = \"eager\";\n }\n return cloned;\n}\n\nasync function cloneVideo(video, context) {\n if (video.ownerDocument && !video.currentSrc && video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n const cloned = video.cloneNode(false);\n cloned.crossOrigin = \"anonymous\";\n if (video.currentSrc && video.currentSrc !== video.src) {\n cloned.src = video.currentSrc;\n }\n const ownerDocument = cloned.ownerDocument;\n if (ownerDocument) {\n let canPlay = true;\n await loadMedia(cloned, { onError: () => canPlay = false, onWarn: context.log.warn });\n if (!canPlay) {\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n cloned.currentTime = video.currentTime;\n await new Promise((resolve) => {\n cloned.addEventListener(\"seeked\", resolve, { once: true });\n });\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = video.offsetWidth;\n canvas.height = video.offsetHeight;\n try {\n const ctx = canvas.getContext(\"2d\");\n if (ctx)\n ctx.drawImage(cloned, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to clone video\", error);\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n return cloneCanvas(canvas, context);\n }\n return cloned;\n}\n\nfunction cloneElement(node, context) {\n if (isCanvasElement(node)) {\n return cloneCanvas(node, context);\n }\n if (isIFrameElement(node)) {\n return cloneIframe(node, context);\n }\n if (isImageElement(node)) {\n return cloneImage(node);\n }\n if (isVideoElement(node)) {\n return cloneVideo(node, context);\n }\n return node.cloneNode(false);\n}\n\nfunction getSandBox(context) {\n let sandbox = context.sandbox;\n if (!sandbox) {\n const { ownerDocument } = context;\n try {\n if (ownerDocument) {\n sandbox = ownerDocument.createElement(\"iframe\");\n sandbox.id = `__SANDBOX__${uuid()}`;\n sandbox.width = \"0\";\n sandbox.height = \"0\";\n sandbox.style.visibility = \"hidden\";\n sandbox.style.position = \"fixed\";\n ownerDocument.body.appendChild(sandbox);\n sandbox.srcdoc = '<!DOCTYPE html><meta charset=\"UTF-8\"><title></title><body>';\n context.sandbox = sandbox;\n }\n } catch (error) {\n context.log.warn(\"Failed to getSandBox\", error);\n }\n }\n return sandbox;\n}\n\nconst ignoredStyles = [\n \"width\",\n \"height\",\n \"-webkit-text-fill-color\"\n];\nconst includedAttributes = [\n \"stroke\",\n \"fill\"\n];\nfunction getDefaultStyle(node, pseudoElement, context) {\n const { defaultComputedStyles } = context;\n const nodeName = node.nodeName.toLowerCase();\n const isSvgNode = isSVGElementNode(node) && nodeName !== \"svg\";\n const attributes = isSvgNode ? includedAttributes.map((name) => [name, node.getAttribute(name)]).filter(([, value]) => value !== null) : [];\n const key = [\n isSvgNode && \"svg\",\n nodeName,\n attributes.map((name, value) => `${name}=${value}`).join(\",\"),\n pseudoElement\n ].filter(Boolean).join(\":\");\n if (defaultComputedStyles.has(key))\n return defaultComputedStyles.get(key);\n const sandbox = getSandBox(context);\n const sandboxWindow = sandbox?.contentWindow;\n if (!sandboxWindow)\n return /* @__PURE__ */ new Map();\n const sandboxDocument = sandboxWindow?.document;\n let root;\n let el;\n if (isSvgNode) {\n root = sandboxDocument.createElementNS(XMLNS, \"svg\");\n el = root.ownerDocument.createElementNS(root.namespaceURI, nodeName);\n attributes.forEach(([name, value]) => {\n el.setAttributeNS(null, name, value);\n });\n root.appendChild(el);\n } else {\n root = el = sandboxDocument.createElement(nodeName);\n }\n el.textContent = \" \";\n sandboxDocument.body.appendChild(root);\n const computedStyle = sandboxWindow.getComputedStyle(el, pseudoElement);\n const styles = /* @__PURE__ */ new Map();\n for (let len = computedStyle.length, i = 0; i < len; i++) {\n const name = computedStyle.item(i);\n if (ignoredStyles.includes(name))\n continue;\n styles.set(name, computedStyle.getPropertyValue(name));\n }\n sandboxDocument.body.removeChild(root);\n defaultComputedStyles.set(key, styles);\n return styles;\n}\n\nfunction getDiffStyle(style, defaultStyle, includeStyleProperties) {\n const diffStyle = /* @__PURE__ */ new Map();\n const prefixs = [];\n const prefixTree = /* @__PURE__ */ new Map();\n if (includeStyleProperties) {\n for (const name of includeStyleProperties) {\n applyTo(name);\n }\n } else {\n for (let len = style.length, i = 0; i < len; i++) {\n const name = style.item(i);\n applyTo(name);\n }\n }\n for (let len = prefixs.length, i = 0; i < len; i++) {\n prefixTree.get(prefixs[i])?.forEach((value, name) => diffStyle.set(name, value));\n }\n function applyTo(name) {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n const subIndex = name.lastIndexOf(\"-\");\n const prefix = subIndex > -1 ? name.substring(0, subIndex) : void 0;\n if (prefix) {\n let map = prefixTree.get(prefix);\n if (!map) {\n map = /* @__PURE__ */ new Map();\n prefixTree.set(prefix, map);\n }\n map.set(name, [value, priority]);\n }\n if (defaultStyle.get(name) === value && !priority)\n return;\n if (prefix) {\n prefixs.push(prefix);\n } else {\n diffStyle.set(name, [value, priority]);\n }\n }\n return diffStyle;\n}\n\nfunction copyCssStyles(node, cloned, isRoot, context) {\n const { ownerWindow, includeStyleProperties, currentParentNodeStyle } = context;\n const clonedStyle = cloned.style;\n const computedStyle = ownerWindow.getComputedStyle(node);\n const defaultStyle = getDefaultStyle(node, null, context);\n currentParentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, includeStyleProperties);\n style.delete(\"transition-property\");\n style.delete(\"all\");\n style.delete(\"d\");\n style.delete(\"content\");\n if (isRoot) {\n style.delete(\"position\");\n style.delete(\"margin-top\");\n style.delete(\"margin-right\");\n style.delete(\"margin-bottom\");\n style.delete(\"margin-left\");\n style.delete(\"margin-block-start\");\n style.delete(\"margin-block-end\");\n style.delete(\"margin-inline-start\");\n style.delete(\"margin-inline-end\");\n style.set(\"box-sizing\", [\"border-box\", \"\"]);\n }\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n if (IN_CHROME) {\n if (!style.has(\"font-kerning\"))\n style.set(\"font-kerning\", [\"normal\", \"\"]);\n if ((style.get(\"overflow-x\")?.[0] === \"hidden\" || style.get(\"overflow-y\")?.[0] === \"hidden\") && style.get(\"text-overflow\")?.[0] === \"ellipsis\" && node.scrollWidth === node.clientWidth) {\n style.set(\"text-overflow\", [\"clip\", \"\"]);\n }\n }\n for (let len = clonedStyle.length, i = 0; i < len; i++) {\n clonedStyle.removeProperty(clonedStyle.item(i));\n }\n style.forEach(([value, priority], name) => {\n clonedStyle.setProperty(name, value, priority);\n });\n return style;\n}\n\nfunction copyInputValue(node, cloned) {\n if (isTextareaElement(node) || isInputElement(node) || isSelectElement(node)) {\n cloned.setAttribute(\"value\", node.value);\n }\n}\n\nconst pseudoClasses = [\n \"::before\",\n \"::after\"\n // '::placeholder', TODO\n];\nconst scrollbarPseudoClasses = [\n \"::-webkit-scrollbar\",\n \"::-webkit-scrollbar-button\",\n // '::-webkit-scrollbar:horizontal', TODO\n \"::-webkit-scrollbar-thumb\",\n \"::-webkit-scrollbar-track\",\n \"::-webkit-scrollbar-track-piece\",\n // '::-webkit-scrollbar:vertical', TODO\n \"::-webkit-scrollbar-corner\",\n \"::-webkit-resizer\"\n];\nfunction copyPseudoClass(node, cloned, copyScrollbar, context, addWordToFontFamilies) {\n const { ownerWindow, svgStyleElement, svgStyles, currentNodeStyle } = context;\n if (!svgStyleElement || !ownerWindow)\n return;\n function copyBy(pseudoClass) {\n const computedStyle = ownerWindow.getComputedStyle(node, pseudoClass);\n let content = computedStyle.getPropertyValue(\"content\");\n if (!content || content === \"none\")\n return;\n addWordToFontFamilies?.(content);\n content = content.replace(/(')|(\")|(counter\\(.+\\))/g, \"\");\n const klasses = [uuid()];\n const defaultStyle = getDefaultStyle(node, pseudoClass, context);\n currentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, context.includeStyleProperties);\n style.delete(\"content\");\n style.delete(\"-webkit-locale\");\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n const cloneStyle = [\n `content: '${content}';`\n ];\n style.forEach(([value, priority], name) => {\n cloneStyle.push(`${name}: ${value}${priority ? \" !important\" : \"\"};`);\n });\n if (cloneStyle.length === 1)\n return;\n try {\n cloned.className = [cloned.className, ...klasses].join(\" \");\n } catch (err) {\n context.log.warn(\"Failed to copyPseudoClass\", err);\n return;\n }\n const cssText = cloneStyle.join(\"\\n \");\n let allClasses = svgStyles.get(cssText);\n if (!allClasses) {\n allClasses = [];\n svgStyles.set(cssText, allClasses);\n }\n allClasses.push(`.${klasses[0]}${pseudoClass}`);\n }\n pseudoClasses.forEach(copyBy);\n if (copyScrollbar)\n scrollbarPseudoClasses.forEach(copyBy);\n}\n\nconst excludeParentNodes = /* @__PURE__ */ new Set([\n \"symbol\"\n // test/fixtures/svg.symbol.html\n]);\nasync function appendChildNode(node, cloned, child, context, addWordToFontFamilies) {\n if (isElementNode(child) && (isStyleElement(child) || isScriptElement(child)))\n return;\n if (context.filter && !context.filter(child))\n return;\n if (excludeParentNodes.has(cloned.nodeName) || excludeParentNodes.has(child.nodeName)) {\n context.currentParentNodeStyle = void 0;\n } else {\n context.currentParentNodeStyle = context.currentNodeStyle;\n }\n const childCloned = await cloneNode(child, context, false, addWordToFontFamilies);\n if (context.isEnable(\"restoreScrollPosition\")) {\n restoreScrollPosition(node, childCloned);\n }\n cloned.appendChild(childCloned);\n}\nasync function cloneChildNodes(node, cloned, context, addWordToFontFamilies) {\n let firstChild = node.firstChild;\n if (isElementNode(node)) {\n if (node.shadowRoot) {\n firstChild = node.shadowRoot?.firstChild;\n context.shadowRoots.push(node.shadowRoot);\n }\n }\n for (let child = firstChild; child; child = child.nextSibling) {\n if (isCommentNode(child))\n continue;\n if (isElementNode(child) && isSlotElement(child) && typeof child.assignedNodes === \"function\") {\n const nodes = child.assignedNodes();\n for (let i = 0; i < nodes.length; i++) {\n await appendChildNode(node, cloned, nodes[i], context, addWordToFontFamilies);\n }\n } else {\n await appendChildNode(node, cloned, child, context, addWordToFontFamilies);\n }\n }\n}\nfunction restoreScrollPosition(node, chlidCloned) {\n if (!isHTMLElementNode(node) || !isHTMLElementNode(chlidCloned))\n return;\n const { scrollTop, scrollLeft } = node;\n if (!scrollTop && !scrollLeft) {\n return;\n }\n const { transform } = chlidCloned.style;\n const matrix = new DOMMatrix(transform);\n const { a, b, c, d } = matrix;\n matrix.a = 1;\n matrix.b = 0;\n matrix.c = 0;\n matrix.d = 1;\n matrix.translateSelf(-scrollLeft, -scrollTop);\n matrix.a = a;\n matrix.b = b;\n matrix.c = c;\n matrix.d = d;\n chlidCloned.style.transform = matrix.toString();\n}\nfunction applyCssStyleWithOptions(cloned, context) {\n const { backgroundColor, width, height, style: styles } = context;\n const clonedStyle = cloned.style;\n if (backgroundColor)\n clonedStyle.setProperty(\"background-color\", backgroundColor, \"important\");\n if (width)\n clonedStyle.setProperty(\"width\", `${width}px`, \"important\");\n if (height)\n clonedStyle.setProperty(\"height\", `${height}px`, \"important\");\n if (styles) {\n for (const name in styles) clonedStyle[name] = styles[name];\n }\n}\nconst NORMAL_ATTRIBUTE_RE = /^[\\w-:]+$/;\nasync function cloneNode(node, context, isRoot = false, addWordToFontFamilies) {\n const { ownerDocument, ownerWindow, fontFamilies, onCloneEachNode } = context;\n if (ownerDocument && isTextNode(node)) {\n if (addWordToFontFamilies && /\\S/.test(node.data)) {\n addWordToFontFamilies(node.data);\n }\n return ownerDocument.createTextNode(node.data);\n }\n if (ownerDocument && ownerWindow && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {\n const cloned2 = await cloneElement(node, context);\n if (context.isEnable(\"removeAbnormalAttributes\")) {\n const names = cloned2.getAttributeNames();\n for (let len = names.length, i = 0; i < len; i++) {\n const name = names[i];\n if (!NORMAL_ATTRIBUTE_RE.test(name)) {\n cloned2.removeAttribute(name);\n }\n }\n }\n const style = context.currentNodeStyle = copyCssStyles(node, cloned2, isRoot, context);\n if (isRoot)\n applyCssStyleWithOptions(cloned2, context);\n let copyScrollbar = false;\n if (context.isEnable(\"copyScrollbar\")) {\n const overflow = [\n style.get(\"overflow-x\")?.[0],\n style.get(\"overflow-y\")?.[0]\n ];\n copyScrollbar = overflow.includes(\"scroll\") || (overflow.includes(\"auto\") || overflow.includes(\"overlay\")) && (node.scrollHeight > node.clientHeight || node.scrollWidth > node.clientWidth);\n }\n const textTransform = style.get(\"text-transform\")?.[0];\n const families = splitFontFamily(style.get(\"font-family\")?.[0]);\n const addWordToFontFamilies2 = families ? (word) => {\n if (textTransform === \"uppercase\") {\n word = word.toUpperCase();\n } else if (textTransform === \"lowercase\") {\n word = word.toLowerCase();\n } else if (textTransform === \"capitalize\") {\n word = word[0].toUpperCase() + word.substring(1);\n }\n families.forEach((family) => {\n let fontFamily = fontFamilies.get(family);\n if (!fontFamily) {\n fontFamilies.set(family, fontFamily = /* @__PURE__ */ new Set());\n }\n word.split(\"\").forEach((text) => fontFamily.add(text));\n });\n } : void 0;\n copyPseudoClass(\n node,\n cloned2,\n copyScrollbar,\n context,\n addWordToFontFamilies2\n );\n copyInputValue(node, cloned2);\n if (!isVideoElement(node)) {\n await cloneChildNodes(\n node,\n cloned2,\n context,\n addWordToFontFamilies2\n );\n }\n await onCloneEachNode?.(cloned2);\n return cloned2;\n }\n const cloned = node.cloneNode(false);\n await cloneChildNodes(node, cloned, context);\n await onCloneEachNode?.(cloned);\n return cloned;\n}\n\nfunction destroyContext(context) {\n context.ownerDocument = void 0;\n context.ownerWindow = void 0;\n context.svgStyleElement = void 0;\n context.svgDefsElement = void 0;\n context.svgStyles.clear();\n context.defaultComputedStyles.clear();\n if (context.sandbox) {\n try {\n context.sandbox.remove();\n } catch (err) {\n context.log.warn(\"Failed to destroyContext\", err);\n }\n context.sandbox = void 0;\n }\n context.workers = [];\n context.fontFamilies.clear();\n context.fontCssTexts.clear();\n context.requests.clear();\n context.tasks = [];\n context.shadowRoots = [];\n}\n\nfunction baseFetch(options) {\n const { url, timeout, responseType, ...requestInit } = options;\n const controller = new AbortController();\n const timer = timeout ? setTimeout(() => controller.abort(), timeout) : void 0;\n return fetch(url, { signal: controller.signal, ...requestInit }).then((response) => {\n if (!response.ok) {\n throw new Error(\"Failed fetch, not 2xx response\", { cause: response });\n }\n switch (responseType) {\n case \"arrayBuffer\":\n return response.arrayBuffer();\n case \"dataUrl\":\n return response.blob().then(blobToDataUrl);\n case \"text\":\n default:\n return response.text();\n }\n }).finally(() => clearTimeout(timer));\n}\nfunction contextFetch(context, options) {\n const { url: rawUrl, requestType = \"text\", responseType = \"text\", imageDom } = options;\n let url = rawUrl;\n const {\n timeout,\n acceptOfImage,\n requests,\n fetchFn,\n fetch: {\n requestInit,\n bypassingCache,\n placeholderImage\n },\n font,\n workers,\n fontFamilies\n } = context;\n if (requestType === \"image\" && (IN_SAFARI || IN_FIREFOX)) {\n context.drawImageCount++;\n }\n let request = requests.get(rawUrl);\n if (!request) {\n if (bypassingCache) {\n if (bypassingCache instanceof RegExp && bypassingCache.test(url)) {\n url += (/\\?/.test(url) ? \"&\" : \"?\") + (/* @__PURE__ */ new Date()).getTime();\n }\n }\n const canFontMinify = requestType.startsWith(\"font\") && font && font.minify;\n const fontTexts = /* @__PURE__ */ new Set();\n if (canFontMinify) {\n const families = requestType.split(\";\")[1].split(\",\");\n families.forEach((family) => {\n if (!fontFamilies.has(family))\n return;\n fontFamilies.get(family).forEach((text) => fontTexts.add(text));\n });\n }\n const needFontMinify = canFontMinify && fontTexts.size;\n const baseFetchOptions = {\n url,\n timeout,\n responseType: needFontMinify ? \"arrayBuffer\" : responseType,\n headers: requestType === \"image\" ? { accept: acceptOfImage } : void 0,\n ...requestInit\n };\n request = {\n type: requestType,\n resolve: void 0,\n reject: void 0,\n response: null\n };\n request.response = (async () => {\n if (fetchFn && requestType === \"image\") {\n const result = await fetchFn(rawUrl);\n if (result)\n return result;\n }\n if (!IN_SAFARI && rawUrl.startsWith(\"http\") && workers.length) {\n return new Promise((resolve, reject) => {\n const worker = workers[requests.size & workers.length - 1];\n worker.postMessage({ rawUrl, ...baseFetchOptions });\n request.resolve = resolve;\n request.reject = reject;\n });\n }\n return baseFetch(baseFetchOptions);\n })().catch((error) => {\n requests.delete(rawUrl);\n if (requestType === \"image\" && placeholderImage) {\n context.log.warn(\"Failed to fetch image base64, trying to use placeholder image\", url);\n return typeof placeholderImage === \"string\" ? placeholderImage : placeholderImage(imageDom);\n }\n throw error;\n });\n requests.set(rawUrl, request);\n }\n return request.response;\n}\n\nasync function replaceCssUrlToDataUrl(cssText, baseUrl, context, isImage) {\n if (!hasCssUrl(cssText))\n return cssText;\n for (const [rawUrl, url] of parseCssUrls(cssText, baseUrl)) {\n try {\n const dataUrl = await contextFetch(\n context,\n {\n url,\n requestType: isImage ? \"image\" : \"text\",\n responseType: \"dataUrl\"\n }\n );\n cssText = cssText.replace(toRE(rawUrl), `$1${dataUrl}$3`);\n } catch (error) {\n context.log.warn(\"Failed to fetch css data url\", rawUrl, error);\n }\n }\n return cssText;\n}\nfunction hasCssUrl(cssText) {\n return /url\\((['\"]?)([^'\"]+?)\\1\\)/.test(cssText);\n}\nconst URL_RE = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nfunction parseCssUrls(cssText, baseUrl) {\n const result = [];\n cssText.replace(URL_RE, (raw, quotation, url) => {\n result.push([url, resolveUrl(url, baseUrl)]);\n return raw;\n });\n return result.filter(([url]) => !isDataUrl(url));\n}\nfunction toRE(url) {\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, \"\\\\$1\");\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, \"g\");\n}\n\nconst properties = [\n \"background-image\",\n \"border-image-source\",\n \"-webkit-border-image\",\n \"-webkit-mask-image\",\n \"list-style-image\"\n];\nfunction embedCssStyleImage(style, context) {\n return properties.map((property) => {\n const value = style.getPropertyValue(property);\n if (!value || value === \"none\") {\n return null;\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n return replaceCssUrlToDataUrl(value, null, context, true).then((newValue) => {\n if (!newValue || value === newValue)\n return;\n style.setProperty(\n property,\n newValue,\n style.getPropertyPriority(property)\n );\n });\n }).filter(Boolean);\n}\n\nfunction embedImageElement(cloned, context) {\n if (isImageElement(cloned)) {\n const originalSrc = cloned.currentSrc || cloned.src;\n if (!isDataUrl(originalSrc)) {\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.srcset = \"\";\n cloned.dataset.originalSrc = originalSrc;\n cloned.src = url || \"\";\n })\n ];\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n } else if (isSVGElementNode(cloned) && !isDataUrl(cloned.href.baseVal)) {\n const originalSrc = cloned.href.baseVal;\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.dataset.originalSrc = originalSrc;\n cloned.href.baseVal = url || \"\";\n })\n ];\n }\n return [];\n}\n\nfunction embedSvgUse(cloned, context) {\n const { ownerDocument, svgDefsElement } = context;\n const href = cloned.getAttribute(\"href\") ?? cloned.getAttribute(\"xlink:href\");\n if (!href)\n return [];\n const [svgUrl, id] = href.split(\"#\");\n if (id) {\n const query = `#${id}`;\n const definition = context.shadowRoots.reduce(\n (res, root) => {\n return res ?? root.querySelector(`svg ${query}`);\n },\n ownerDocument?.querySelector(`svg ${query}`)\n );\n if (svgUrl) {\n cloned.setAttribute(\"href\", query);\n }\n if (svgDefsElement?.querySelector(query))\n return [];\n if (definition) {\n svgDefsElement?.appendChild(definition.cloneNode(true));\n return [];\n } else if (svgUrl) {\n return [\n contextFetch(context, {\n url: svgUrl,\n responseType: \"text\"\n }).then((svgData) => {\n svgDefsElement?.insertAdjacentHTML(\"beforeend\", svgData);\n })\n ];\n }\n }\n return [];\n}\n\nfunction embedNode(cloned, context) {\n const { tasks } = context;\n if (isElementNode(cloned)) {\n if (isImageElement(cloned) || isSVGImageElementNode(cloned)) {\n tasks.push(...embedImageElement(cloned, context));\n }\n if (isSVGUseElementNode(cloned)) {\n tasks.push(...embedSvgUse(cloned, context));\n }\n }\n if (isHTMLElementNode(cloned)) {\n tasks.push(...embedCssStyleImage(cloned.style, context));\n }\n cloned.childNodes.forEach((child) => {\n embedNode(child, context);\n });\n}\n\nasync function embedWebFont(clone, context) {\n const {\n ownerDocument,\n svgStyleElement,\n fontFamilies,\n fontCssTexts,\n tasks,\n font\n } = context;\n if (!ownerDocument || !svgStyleElement || !fontFamilies.size) {\n return;\n }\n if (font && font.cssText) {\n const cssText = filterPreferredFormat(font.cssText, context);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n const styleSheets = Array.from(ownerDocument.styleSheets).filter((styleSheet) => {\n try {\n return \"cssRules\" in styleSheet && Boolean(styleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(`Error while reading CSS rules from ${styleSheet.href}`, error);\n return false;\n }\n });\n const tempDoc = ownerDocument.implementation.createHTMLDocument(\"\");\n const tempStyleEl = tempDoc.createElement(\"style\");\n tempDoc.head.appendChild(tempStyleEl);\n const tempStyleSheet = tempStyleEl.sheet;\n await Promise.all(\n styleSheets.flatMap((styleSheet) => {\n return Array.from(styleSheet.cssRules).map(async (cssRule) => {\n if (isCSSImportRule(cssRule)) {\n const baseUrl = cssRule.href;\n let cssText = \"\";\n try {\n cssText = await contextFetch(context, {\n url: baseUrl,\n requestType: \"text\",\n responseType: \"text\"\n });\n } catch (error) {\n context.log.warn(`Error fetch remote css import from ${baseUrl}`, error);\n }\n const replacedCssText = cssText.replace(\n URL_RE,\n (raw, quotation, url) => raw.replace(url, resolveUrl(url, baseUrl))\n );\n for (const rule of parseCss(replacedCssText)) {\n try {\n tempStyleSheet.insertRule(rule, tempStyleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(\"Error inserting rule from remote css import\", { rule, error });\n }\n }\n }\n });\n })\n );\n if (tempStyleSheet.cssRules.length)\n styleSheets.push(tempStyleSheet);\n const cssRules = [];\n styleSheets.forEach((sheet) => {\n unwrapCssLayers(sheet.cssRules, cssRules);\n });\n cssRules.filter((cssRule) => isCssFontFaceRule(cssRule) && hasCssUrl(cssRule.style.getPropertyValue(\"src\")) && splitFontFamily(cssRule.style.getPropertyValue(\"font-family\"))?.some((val) => fontFamilies.has(val))).forEach((value) => {\n const rule = value;\n const cssText = fontCssTexts.get(rule.cssText);\n if (cssText) {\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n tasks.push(\n replaceCssUrlToDataUrl(\n rule.cssText,\n rule.parentStyleSheet ? rule.parentStyleSheet.href : null,\n context\n ).then((cssText2) => {\n cssText2 = filterPreferredFormat(cssText2, context);\n fontCssTexts.set(rule.cssText, cssText2);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText2}\n`));\n })\n );\n }\n });\n }\n}\nconst COMMENTS_RE = /(\\/\\*[\\s\\S]*?\\*\\/)/g;\nconst KEYFRAMES_RE = /((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})/gi;\nfunction parseCss(source) {\n if (source == null)\n return [];\n const result = [];\n let cssText = source.replace(COMMENTS_RE, \"\");\n while (true) {\n const matches = KEYFRAMES_RE.exec(cssText);\n if (!matches)\n break;\n result.push(matches[0]);\n }\n cssText = cssText.replace(KEYFRAMES_RE, \"\");\n const IMPORT_RE = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n const UNIFIED_RE = new RegExp(\n // eslint-disable-next-line\n \"((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})\",\n \"gi\"\n );\n while (true) {\n let matches = IMPORT_RE.exec(cssText);\n if (!matches) {\n matches = UNIFIED_RE.exec(cssText);\n if (!matches) {\n break;\n } else {\n IMPORT_RE.lastIndex = UNIFIED_RE.lastIndex;\n }\n } else {\n UNIFIED_RE.lastIndex = IMPORT_RE.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nconst URL_WITH_FORMAT_RE = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_RE = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction filterPreferredFormat(str, context) {\n const { font } = context;\n const preferredFormat = font ? font?.preferredFormat : void 0;\n return preferredFormat ? str.replace(FONT_SRC_RE, (match) => {\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_RE.exec(match) || [];\n if (!format)\n return \"\";\n if (format === preferredFormat)\n return `src: ${src};`;\n }\n }) : str;\n}\nfunction unwrapCssLayers(rules, out = []) {\n for (const rule of Array.from(rules)) {\n if (isLayerBlockRule(rule)) {\n out.push(...unwrapCssLayers(rule.cssRules));\n } else if (\"cssRules\" in rule) {\n unwrapCssLayers(rule.cssRules, out);\n } else {\n out.push(rule);\n }\n }\n return out;\n}\n\nconst SVG_EXTERNAL_RESOURCE_REGEX = /\\bx?link:?href\\s*=\\s*[\"'](?!data:)[^\"']+[\"']/i;\nfunction svgHasExternalResources(svg) {\n return SVG_EXTERNAL_RESOURCE_REGEX.test(svg.innerHTML);\n}\nasync function domToForeignObjectSvg(node, options) {\n const context = await orCreateContext(node, options);\n if (isElementNode(context.node) && isSVGElementNode(context.node) && !svgHasExternalResources(context.node))\n return context.node;\n const {\n ownerDocument,\n log,\n tasks,\n svgStyleElement,\n svgDefsElement,\n svgStyles,\n font,\n progress,\n autoDestruct,\n onCloneNode,\n onEmbedNode,\n onCreateForeignObjectSvg\n } = context;\n log.time(\"clone node\");\n const clone = await cloneNode(context.node, context, true);\n if (svgStyleElement && ownerDocument) {\n let allCssText = \"\";\n svgStyles.forEach((klasses, cssText) => {\n allCssText += `${klasses.join(\",\\n\")} {\n ${cssText}\n}\n`;\n });\n svgStyleElement.appendChild(ownerDocument.createTextNode(allCssText));\n }\n log.timeEnd(\"clone node\");\n await onCloneNode?.(clone);\n if (font !== false && isElementNode(clone)) {\n log.time(\"embed web font\");\n await embedWebFont(clone, context);\n log.timeEnd(\"embed web font\");\n }\n log.time(\"embed node\");\n embedNode(clone, context);\n const count = tasks.length;\n let current = 0;\n const runTask = async () => {\n while (true) {\n const task = tasks.pop();\n if (!task)\n break;\n try {\n await task;\n } catch (error) {\n context.log.warn(\"Failed to run task\", error);\n }\n progress?.(++current, count);\n }\n };\n progress?.(current, count);\n await Promise.all([...Array.from({ length: 4 })].map(runTask));\n log.timeEnd(\"embed node\");\n await onEmbedNode?.(clone);\n const svg = createForeignObjectSvg(clone, context);\n svgDefsElement && svg.insertBefore(svgDefsElement, svg.children[0]);\n svgStyleElement && svg.insertBefore(svgStyleElement, svg.children[0]);\n autoDestruct && destroyContext(context);\n await onCreateForeignObjectSvg?.(svg);\n return svg;\n}\nfunction createForeignObjectSvg(clone, context) {\n const { width, height } = context;\n const svg = createSvg(width, height, clone.ownerDocument);\n const foreignObject = svg.ownerDocument.createElementNS(svg.namespaceURI, \"foreignObject\");\n foreignObject.setAttributeNS(null, \"x\", \"0%\");\n foreignObject.setAttributeNS(null, \"y\", \"0%\");\n foreignObject.setAttributeNS(null, \"width\", \"100%\");\n foreignObject.setAttributeNS(null, \"height\", \"100%\");\n foreignObject.append(clone);\n svg.appendChild(foreignObject);\n return svg;\n}\n\nasync function domToCanvas(node, options) {\n const context = await orCreateContext(node, options);\n const svg = await domToForeignObjectSvg(context);\n const dataUrl = svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n if (!context.autoDestruct) {\n context.svgStyleElement = createStyleElement(context.ownerDocument);\n context.svgDefsElement = context.ownerDocument?.createElementNS(XMLNS, \"defs\");\n context.svgStyles.clear();\n }\n const image = createImage(dataUrl, svg.ownerDocument);\n return await imageToCanvas(image, context);\n}\n\nasync function domToBlob(node, options) {\n const context = await orCreateContext(node, options);\n const { log, type, quality, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to blob\");\n const blob = await canvasToBlob(canvas, type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi) {\n const arrayBuffer = await blobToArrayBuffer(blob.slice(0, 33));\n let uint8Array = new Uint8Array(arrayBuffer);\n if (type === \"image/png\") {\n uint8Array = changePngDpi(uint8Array, dpi);\n } else if (type === \"image/jpeg\") {\n uint8Array = changeJpegDpi(uint8Array, dpi);\n }\n log.timeEnd(\"canvas to blob\");\n return new Blob([uint8Array, blob.slice(33)], { type });\n }\n log.timeEnd(\"canvas to blob\");\n return blob;\n}\n\nasync function domToDataUrl(node, options) {\n const context = await orCreateContext(node, options);\n const { log, quality, type, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to data url\");\n let dataUrl = canvas.toDataURL(type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi && SUPPORT_ATOB && SUPPORT_BTOA) {\n const [format, body] = dataUrl.split(\",\");\n let headerLength = 0;\n let overwritepHYs = false;\n if (type === \"image/png\") {\n const b64Index = detectPhysChunkFromDataUrl(body);\n if (b64Index >= 0) {\n headerLength = Math.ceil((b64Index + 28) / 3) * 4;\n overwritepHYs = true;\n } else {\n headerLength = 33 / 3 * 4;\n }\n } else if (type === \"image/jpeg\") {\n headerLength = 18 / 3 * 4;\n }\n const stringHeader = body.substring(0, headerLength);\n const restOfData = body.substring(headerLength);\n const headerBytes = window.atob(stringHeader);\n const uint8Array = new Uint8Array(headerBytes.length);\n for (let i = 0; i < uint8Array.length; i++) {\n uint8Array[i] = headerBytes.charCodeAt(i);\n }\n const finalArray = type === \"image/png\" ? changePngDpi(uint8Array, dpi, overwritepHYs) : changeJpegDpi(uint8Array, dpi);\n const base64Header = window.btoa(String.fromCharCode(...finalArray));\n dataUrl = [format, \",\", base64Header, restOfData].join(\"\");\n }\n log.timeEnd(\"canvas to data url\");\n return dataUrl;\n}\n\nasync function domToSvg(node, options) {\n const context = await orCreateContext(node, options);\n const { width, height, ownerDocument } = context;\n const dataUrl = await domToDataUrl(context);\n const svg = createSvg(width, height, ownerDocument);\n const svgImage = svg.ownerDocument.createElementNS(svg.namespaceURI, \"image\");\n svgImage.setAttributeNS(null, \"href\", dataUrl);\n svgImage.setAttributeNS(null, \"height\", \"100%\");\n svgImage.setAttributeNS(null, \"width\", \"100%\");\n svg.appendChild(svgImage);\n return svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n}\n\nasync function domToImage(node, options) {\n const context = await orCreateContext(node, options);\n const { ownerDocument, width, height, scale, type } = context;\n const url = type === \"image/svg+xml\" ? await domToSvg(context) : await domToDataUrl(context);\n const image = createImage(url, ownerDocument);\n image.width = Math.floor(width * scale);\n image.height = Math.floor(height * scale);\n image.style.width = `${width}px`;\n image.style.height = `${height}px`;\n return image;\n}\n\nasync function domToJpeg(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/jpeg\" })\n );\n}\n\nasync function domToPixel(node, options) {\n const context = await orCreateContext(node, options);\n const canvas = await domToCanvas(context);\n return canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height).data;\n}\n\nasync function domToPng(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/png\" })\n );\n}\n\nasync function domToWebp(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/webp\" })\n );\n}\n\nexport { createContext, destroyContext, domToBlob, domToCanvas, domToDataUrl, domToForeignObjectSvg, domToImage, domToJpeg, domToPixel, domToPng, domToSvg, domToWebp, loadMedia, waitUntilLoad };\n","import { domToPng } from \"modern-screenshot\";\nimport type { ElementContext, RegionRect } from \"./types.js\";\n\nconst STYLE_KEYS = [\n \"display\", \"position\", \"width\", \"height\", \"margin\", \"padding\",\n \"color\", \"background-color\", \"font-size\", \"font-weight\", \"font-family\",\n \"border\", \"border-radius\", \"box-shadow\", \"flex\", \"grid-template-columns\",\n \"text-align\", \"line-height\", \"opacity\",\n];\n\n/** outerHTML + a curated slice of computed styles — the context handed to Claude. */\nexport function captureElementContext(el: Element): ElementContext {\n const html = el.outerHTML.length > 6000 ? el.outerHTML.slice(0, 6000) + \"…\" : el.outerHTML;\n const cs = getComputedStyle(el);\n const styles: Record<string, string> = {};\n for (const k of STYLE_KEYS) {\n const v = cs.getPropertyValue(k);\n if (v) styles[k] = v.trim();\n }\n return { html, styles };\n}\n\n/** Max time (ms) any single capture may spend fetching/embedding assets. */\nconst CAPTURE_TIMEOUT = 6000;\n\n/** Resolve `undefined` if `p` doesn't settle within `ms` — so a capture can never hang the UI. */\nfunction withTimeout<T>(p: Promise<T>, ms: number): Promise<T | undefined> {\n return Promise.race([p, new Promise<undefined>((resolve) => setTimeout(() => resolve(undefined), ms))]);\n}\n\n/**\n * Give web fonts a brief chance to finish loading so they embed instead of\n * falling back — but NEVER block on it. On some SPAs `document.fonts.ready`\n * settles slowly (or keeps loading), which would otherwise hang the capture,\n * so we race it against a short cap.\n */\nasync function fontsReady(): Promise<void> {\n try {\n const fonts = (document as Document & { fonts?: FontFaceSet }).fonts;\n if (!fonts?.ready) return;\n await Promise.race([\n fonts.ready,\n new Promise<void>((resolve) => setTimeout(resolve, 800)),\n ]);\n } catch {\n /* FontFaceSet unsupported — carry on */\n }\n}\n\n/** Skip Loupe's own UI and redacted elements in any capture. */\nfunction captureFilter(node: Node): boolean {\n if (!(node instanceof Element)) return true;\n if (node.id === \"loupe-root\") return false;\n if (node.hasAttribute(\"data-loupe-redact\")) return false;\n return true;\n}\n\n/**\n * Screenshot the target element. Elements marked [data-loupe-redact] are\n * excluded before anything leaves the browser, and our own UI is never captured.\n */\nexport async function captureScreenshot(el: Element): Promise<string | undefined> {\n try {\n await fontsReady();\n return await withTimeout(\n domToPng(el as HTMLElement, {\n scale: Math.min(window.devicePixelRatio || 1, 2),\n backgroundColor: getComputedStyle(document.body).backgroundColor || \"#ffffff\",\n timeout: CAPTURE_TIMEOUT,\n filter: captureFilter,\n }),\n CAPTURE_TIMEOUT + 2000,\n );\n } catch (err) {\n console.warn(\"[loupe] screenshot capture failed\", err);\n return undefined;\n }\n}\n\n/**\n * Screenshot a free-form rectangle (the \"region shot\"). `rect` is in **viewport**\n * coordinates (what's on screen now). The default renders the whole page and crops;\n * the extension overrides this with a real captureVisibleTab crop. Redacted regions\n * are painted over before the pixels leave the browser.\n */\nexport async function captureRegionScreenshot(rect: RegionRect): Promise<string | undefined> {\n try {\n await fontsReady();\n const scale = Math.min(window.devicePixelRatio || 1, 2);\n // Render the SMALLEST element that fully covers the selection, not the whole\n // page. Rendering document.body is heavy and its cross-origin font embedding\n // often times out (→ fallback fonts, reflow); a scoped subtree behaves like\n // the reliable element capture.\n const container = regionContainer(rect);\n const origin = container.getBoundingClientRect();\n const full = await withTimeout(\n domToPng(container, {\n scale,\n backgroundColor: getComputedStyle(document.body).backgroundColor || \"#ffffff\",\n timeout: CAPTURE_TIMEOUT,\n filter: captureFilter,\n }),\n CAPTURE_TIMEOUT + 2000,\n );\n if (!full) return undefined;\n const redact = Array.from(document.querySelectorAll(\"[data-loupe-redact]\")).map((n) =>\n (n as Element).getBoundingClientRect(),\n );\n return await cropRegion(full, rect, origin.left, origin.top, scale, redact);\n } catch (err) {\n console.warn(\"[loupe] region capture failed\", err);\n return undefined;\n }\n}\n\n/** The smallest on-page element whose box fully covers the selection rectangle. */\nfunction regionContainer(rect: RegionRect): HTMLElement {\n const cx = rect.x + rect.w / 2;\n const cy = rect.y + rect.h / 2;\n let node = document.elementFromPoint(cx, cy) as HTMLElement | null;\n if (node && node.closest(\"#loupe-root\")) node = null; // never our own UI\n const covers = (r: DOMRect) =>\n r.left <= rect.x && r.top <= rect.y && r.right >= rect.x + rect.w && r.bottom >= rect.y + rect.h;\n while (node && node !== document.body && node !== document.documentElement) {\n if (covers(node.getBoundingClientRect())) return node;\n node = node.parentElement;\n }\n return document.body;\n}\n\n/** Options for a screen recording. */\nexport interface RecordOptions {\n /** Auto-stop after this many ms (a safety cap so recordings never run forever). */\n maxMs?: number;\n /** Called once with a `stop()` fn so the caller can wire a Stop button to it. */\n register?: (stop: () => void) => void;\n}\n\n/** Best available webm MIME the browser can record, or \"\" to let MediaRecorder pick. */\nfunction pickRecordingMime(): string {\n const MR: any = (window as any).MediaRecorder;\n if (!MR?.isTypeSupported) return \"\";\n for (const t of [\"video/webm;codecs=vp9\", \"video/webm;codecs=vp8\", \"video/webm\"]) {\n if (MR.isTypeSupported(t)) return t;\n }\n return \"\";\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const r = new FileReader();\n r.onload = () => resolve(String(r.result));\n r.onerror = () => reject(r.error);\n r.readAsDataURL(blob);\n });\n}\n\n/** Read a file the reporter picked into a data URL (for upload, or offline storage). */\nexport function fileToDataUrl(file: File): Promise<string> {\n return blobToDataUrl(file);\n}\n\n/** Classify an attachment by MIME type — videos play inline, images render as thumbs. */\nexport function attachmentKind(mime: string | undefined): \"image\" | \"video\" {\n return (mime ?? \"\").startsWith(\"video/\") ? \"video\" : \"image\";\n}\n\n/**\n * Record a screen video cropped to `rect` (viewport coords), mirroring the region\n * screenshot flow. Uses getDisplayMedia (real pixels) — the browser shows a share\n * prompt; picking the current tab keeps the crop aligned. Each frame is drawn to a\n * canvas cropped to the selection, then re-encoded to webm. Returns a data URL, or\n * undefined if the user cancels the prompt or recording isn't supported. The default\n * is overridable via LoupeConfig.captureRecording (e.g. the extension).\n */\nexport async function captureRegionRecording(rect: RegionRect, opts?: RecordOptions): Promise<string | undefined> {\n const md = navigator.mediaDevices as MediaDevices & {\n getDisplayMedia?: (c?: any) => Promise<MediaStream>;\n };\n if (!md?.getDisplayMedia || !(window as any).MediaRecorder) return undefined;\n\n let stream: MediaStream;\n try {\n stream = await md.getDisplayMedia({ video: { frameRate: 30 }, audio: false, preferCurrentTab: true } as any);\n } catch {\n return undefined; // user dismissed the picker\n }\n\n try {\n return await recordCropped(stream, rect, opts);\n } catch (err) {\n console.warn(\"[loupe] screen recording failed\", err);\n return undefined;\n } finally {\n stream.getTracks().forEach((t) => t.stop());\n }\n}\n\nasync function recordCropped(stream: MediaStream, rect: RegionRect, opts?: RecordOptions): Promise<string | undefined> {\n const maxMs = opts?.maxMs ?? 20000;\n const video = document.createElement(\"video\");\n video.srcObject = stream;\n video.muted = true;\n (video as any).playsInline = true;\n await video.play().catch(() => undefined);\n\n const track = stream.getVideoTracks()[0];\n const s = track?.getSettings?.() ?? {};\n const vw = (s.width as number) || video.videoWidth || window.innerWidth;\n const vh = (s.height as number) || video.videoHeight || window.innerHeight;\n // The shared surface (ideally the current tab) maps to the page viewport by scale.\n const sx = vw / window.innerWidth;\n const sy = vh / window.innerHeight;\n const cw = Math.max(2, Math.round(rect.w * sx));\n const ch = Math.max(2, Math.round(rect.h * sy));\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = cw;\n canvas.height = ch;\n const ctx = canvas.getContext(\"2d\")!;\n let raf = 0;\n const draw = () => {\n try { ctx.drawImage(video, rect.x * sx, rect.y * sy, cw, ch, 0, 0, cw, ch); } catch { /* not ready yet */ }\n raf = requestAnimationFrame(draw);\n };\n draw();\n\n const out = (canvas as HTMLCanvasElement & { captureStream(fps?: number): MediaStream }).captureStream(30);\n const mime = pickRecordingMime();\n const rec = new MediaRecorder(out, mime ? { mimeType: mime } : undefined);\n const chunks: BlobPart[] = [];\n rec.ondataavailable = (e) => { if (e.data && e.data.size) chunks.push(e.data); };\n\n const stop = () => { if (rec.state !== \"inactive\") rec.stop(); };\n opts?.register?.(stop);\n // Auto-stop on the cap, or when the user ends the share via the browser UI.\n const timer = window.setTimeout(stop, maxMs);\n track?.addEventListener(\"ended\", stop);\n\n const done = new Promise<void>((resolve) => { rec.onstop = () => resolve(); });\n rec.start();\n await done;\n\n window.clearTimeout(timer);\n cancelAnimationFrame(raf);\n if (!chunks.length) return undefined;\n return blobToDataUrl(new Blob(chunks, { type: mime || \"video/webm\" }));\n}\n\n/** Crop `rect` (viewport coords) out of a full-page data URL whose origin sits at (ox, oy). */\nfunction cropRegion(\n dataUrl: string,\n rect: RegionRect,\n ox: number,\n oy: number,\n scale: number,\n redact: DOMRect[],\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n const sw = Math.max(1, Math.round(rect.w * scale));\n const sh = Math.max(1, Math.round(rect.h * scale));\n const canvas = document.createElement(\"canvas\");\n canvas.width = sw;\n canvas.height = sh;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.drawImage(img, (rect.x - ox) * scale, (rect.y - oy) * scale, sw, sh, 0, 0, sw, sh);\n ctx.fillStyle = \"#0f0f14\";\n for (const r of redact) {\n ctx.fillRect((r.left - rect.x) * scale, (r.top - rect.y) * scale, r.width * scale, r.height * scale);\n }\n resolve(canvas.toDataURL(\"image/png\"));\n };\n img.onerror = reject;\n img.src = dataUrl;\n });\n}\n","import type { Attachment, Comment, StorageAdapter } from \"./types.js\";\nimport { attachmentKind, fileToDataUrl } from \"./capture.js\";\n\n/**\n * Prototype storage: everything lives in localStorage, keyed by project + path.\n * The production adapter swaps this for HTTP calls to the backend — the SDK\n * only depends on the StorageAdapter interface, so nothing else changes.\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n private key(projectKey: string, url: string) {\n return `loupe:${projectKey}:${url}`;\n }\n\n private readAll(projectKey: string, url: string): Comment[] {\n try {\n const raw = localStorage.getItem(this.key(projectKey, url));\n return raw ? (JSON.parse(raw) as Comment[]) : [];\n } catch {\n return [];\n }\n }\n\n private writeAll(projectKey: string, url: string, comments: Comment[]) {\n localStorage.setItem(this.key(projectKey, url), JSON.stringify(comments));\n }\n\n async list(projectKey: string, url: string): Promise<Comment[]> {\n return this.readAll(projectKey, url);\n }\n\n async save(comment: Comment): Promise<Comment> {\n const all = this.readAll(comment.projectKey, comment.url);\n all.push(comment);\n this.writeAll(comment.projectKey, comment.url, all);\n return comment;\n }\n\n /**\n * Offline mode: keep the file inline. localStorage is only a few MB, so refuse\n * anything that would blow the quota rather than silently dropping it.\n */\n async upload(_projectKey: string, file: File): Promise<Attachment> {\n if (file.size > 3_000_000) throw new Error(\"attachment too large for offline mode\");\n return {\n url: await fileToDataUrl(file),\n name: file.name,\n mime: file.type || undefined,\n kind: attachmentKind(file.type),\n size: file.size,\n };\n }\n\n async update(id: string, patch: Partial<Comment>): Promise<void> {\n // We don't know the url here, so scan the loupe:* keys for the id.\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (!k || !k.startsWith(\"loupe:\")) continue;\n const list = JSON.parse(localStorage.getItem(k) || \"[]\") as Comment[];\n const idx = list.findIndex((c) => c.id === id);\n if (idx >= 0) {\n list[idx] = { ...list[idx]!, ...patch };\n localStorage.setItem(k, JSON.stringify(list));\n return;\n }\n }\n }\n\n async remove(id: string): Promise<void> {\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (!k || !k.startsWith(\"loupe:\")) continue;\n const list = JSON.parse(localStorage.getItem(k) || \"[]\") as Comment[];\n const next = list.filter((c) => c.id !== id);\n if (next.length !== list.length) {\n localStorage.setItem(k, JSON.stringify(next));\n return;\n }\n }\n }\n}\n","import type { Attachment, Comment, LoupeUser, StorageAdapter } from \"./types.js\";\nimport { attachmentKind, fileToDataUrl } from \"./capture.js\";\n\n/**\n * Talks to the Loupe backend. Selected automatically when `apiBase` is set in\n * init(). Sends the identity headers the backend verifies (HMAC in production).\n */\nexport class HttpAdapter implements StorageAdapter {\n constructor(\n private base: string,\n private user: LoupeUser,\n private userHmac?: string,\n private extraHeaders?: Record<string, string>,\n private credentials?: RequestCredentials,\n ) {\n this.base = base.replace(/\\/$/, \"\");\n }\n\n private headers(): HeadersInit {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\", \"X-Loupe-User\": this.user.id };\n if (this.userHmac) h[\"X-Loupe-Hmac\"] = this.userHmac;\n if (this.extraHeaders) Object.assign(h, this.extraHeaders);\n return h;\n }\n\n /** Base fetch options shared by every request (credentials mode, if set). */\n private opts(init?: RequestInit): RequestInit {\n return this.credentials ? { credentials: this.credentials, ...init } : { ...init };\n }\n\n async list(projectKey: string, url: string): Promise<Comment[]> {\n const q = new URLSearchParams({ projectKey, url });\n const res = await fetch(`${this.base}/v1/comments?${q}`, this.opts({ headers: this.headers() }));\n if (!res.ok) throw new Error(`list failed: ${res.status}`);\n return (await res.json()) as Comment[];\n }\n\n /** Upload an inline data-URL asset to object storage; return its URL (or the data URL on failure). */\n private async uploadBlob(projectKey: string, data: string): Promise<string> {\n try {\n const up = await fetch(`${this.base}/v1/blobs`, this.opts({\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify({ projectKey, data }),\n }));\n if (up.ok) return (await up.json()).url as string;\n } catch {\n /* fall back to inlining below */\n }\n return data;\n }\n\n async save(comment: Comment): Promise<Comment> {\n // Upload media to object storage first, then store only the URL — keeps the\n // comment row (and every later list/read) small.\n if (comment.screenshot?.startsWith(\"data:\")) {\n comment = { ...comment, screenshot: await this.uploadBlob(comment.projectKey, comment.screenshot) };\n }\n if (comment.recording?.startsWith(\"data:\")) {\n comment = { ...comment, recording: await this.uploadBlob(comment.projectKey, comment.recording) };\n }\n const res = await fetch(`${this.base}/v1/comments`, this.opts({\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify(comment),\n }));\n if (!res.ok) throw new Error(`save failed: ${res.status}`);\n return (await res.json()) as Comment;\n }\n\n /** Persist one reporter-attached file to object storage and describe it. */\n async upload(projectKey: string, file: File): Promise<Attachment> {\n const data = await fileToDataUrl(file);\n return {\n url: await this.uploadBlob(projectKey, data),\n name: file.name,\n mime: file.type || undefined,\n kind: attachmentKind(file.type),\n size: file.size,\n };\n }\n\n async update(id: string, patch: Partial<Comment>): Promise<void> {\n const res = await fetch(`${this.base}/v1/comments/${encodeURIComponent(id)}`, this.opts({\n method: \"PATCH\",\n headers: this.headers(),\n body: JSON.stringify(patch),\n }));\n if (!res.ok) throw new Error(`update failed: ${res.status}`);\n }\n\n async remove(id: string): Promise<void> {\n const res = await fetch(`${this.base}/v1/comments/${encodeURIComponent(id)}`, this.opts({\n method: \"DELETE\",\n headers: this.headers(),\n }));\n if (!res.ok && res.status !== 404) throw new Error(`remove failed: ${res.status}`);\n }\n}\n","// Canonical types + pure helpers shared across the SDK, server, dashboard, and MCP.\n/** Board order, left to right. */\nexport const COMMENT_STAGES = [\"queue\", \"todo\", \"in_progress\", \"in_review\", \"resolved\"];\n/** Human labels for the board columns. */\nexport const STAGE_LABELS = {\n queue: \"Queue\",\n todo: \"To Do\",\n in_progress: \"In Progress\",\n in_review: \"In Review\",\n resolved: \"Resolved\",\n};\n/**\n * Statuses this project shipped before the five-stage board. Still accepted on\n * input (and on rows written by an older client) so a rolling upgrade never\n * writes a value the board cannot place.\n */\nconst LEGACY_STATUS = {\n open: \"queue\",\n in_progress: \"in_progress\",\n done: \"resolved\",\n};\n/**\n * Coerce any accepted status — current stage or legacy alias — into a stage.\n * Anything unrecognised lands in `queue`, the untriaged inbox, rather than\n * falling off the board entirely.\n */\nexport function normalizeStatus(value) {\n if (typeof value === \"string\") {\n if (COMMENT_STAGES.includes(value))\n return value;\n if (value in LEGACY_STATUS)\n return LEGACY_STATUS[value];\n }\n return \"queue\";\n}\n/** Whether a comment is still open work (everything except `resolved`). */\nexport function isOpenStage(stage) {\n return stage !== \"resolved\";\n}\n/** Classify a viewport width into a device bucket (mobile < 768 ≤ tablet < 1024 ≤ desktop). */\nexport function deviceType(width) {\n if (width < 768)\n return \"mobile\";\n if (width < 1024)\n return \"tablet\";\n return \"desktop\";\n}\nconst DROP_EXACT = new Set([\n \"api\", \"key\", \"fbclid\", \"gclid\", \"gbraid\", \"wbraid\", \"msclkid\",\n \"ref\", \"ref_src\", \"mc_cid\", \"mc_eid\", \"_hsenc\", \"_hsmi\", \"igshid\",\n]);\n/**\n * Normalize a page URL so comments don't fragment across tracking/volatile params.\n * Keeps the path + a filtered, sorted query. Drops utm_*, click ids, and Loupe's\n * own dev params (api/key). Accepts a full URL or a path+search string.\n */\nexport function normalizeUrl(input) {\n try {\n const u = new URL(input, \"http://loupe.local\");\n let path = u.pathname;\n const kept = [];\n for (const [k, v] of u.searchParams) {\n const key = k.toLowerCase();\n if (DROP_EXACT.has(key) || key.startsWith(\"utm_\"))\n continue;\n kept.push([k, v]);\n }\n kept.sort((a, b) => (a[0] === b[0] ? a[1].localeCompare(b[1]) : a[0].localeCompare(b[0])));\n const qs = new URLSearchParams(kept).toString();\n if (path.length > 1 && path.endsWith(\"/\"))\n path = path.slice(0, -1);\n return path + (qs ? `?${qs}` : \"\");\n }\n catch {\n const i = input.indexOf(\"?\");\n return i >= 0 ? input.slice(0, i) : input;\n }\n}\n","import { STYLES } from \"./styles.js\";\nimport { captureAnchor, resolveAnchor } from \"./fingerprint.js\";\nimport { attachmentKind, captureElementContext, captureScreenshot, captureRegionScreenshot, captureRegionRecording } from \"./capture.js\";\nimport { LocalStorageAdapter } from \"./store.js\";\nimport { HttpAdapter } from \"./http-adapter.js\";\nimport { normalizeStatus } from \"./types.js\";\nimport type { Anchor, Attachment, Comment, LoupeConfig, RegionRect, StorageAdapter } from \"./types.js\";\n\ndeclare const __LOUPE_VERSION__: string | undefined;\n/** The build that produced this bundle (baked in by tsup); recorded on every comment. */\nconst SDK_VERSION = typeof __LOUPE_VERSION__ === \"string\" ? __LOUPE_VERSION__ : \"dev\";\n\ntype Mode = \"off\" | \"inspect\" | \"region\" | \"free\" | \"record\";\n/** Where the control panel is anchored. */\ntype DockMode = \"left\" | \"right\" | \"bottom\" | \"float\";\n/** Which sidebar page is showing in the dock. */\ntype Tab = \"comments\" | \"connect\";\n/** What the composer is about to attach a comment to. */\ntype ComposeTarget =\n | { kind: \"element\"; element: Element }\n | { kind: \"region\"; region: RegionRect; element: Element | null; screenshot?: string; recording?: string }\n | { kind: \"free\"; offset: { x: number; y: number }; point: { x: number; y: number }; label?: string };\n\nconst DOCK_MODES: DockMode[] = [\"left\", \"right\", \"bottom\", \"float\"];\n/** How long a single screen recording may run before it auto-stops. */\nconst RECORD_MAX_MS = 20000;\n/** Attachment limits for the composer — small enough to survive a base64 POST. */\nconst MAX_FILES = 10;\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024;\nconst MAX_VIDEO_BYTES = 25 * 1024 * 1024;\n\nconst uid = () =>\n (crypto as any).randomUUID ? crypto.randomUUID() : \"c_\" + Math.abs(hash(String(performance.now()))).toString(36);\nfunction hash(s: string) { let h = 0; for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0; return h; }\n\n/**\n * A phone/tablet. `(pointer: coarse)` is the primary signal, but a phone asking for the\n * **desktop site** reports a FINE pointer, so touch capability is the backstop. Getting\n * this wrong sends a finger user down the mouse path: a composer that grabs the focus\n * (keyboard over the page) and a drag-select that fights the page scroll.\n */\nfunction isTouchDevice(): boolean {\n try {\n if (window.matchMedia(\"(pointer: coarse)\").matches) return true;\n if (window.matchMedia(\"(hover: none)\").matches) return true;\n } catch {\n /* matchMedia unavailable */\n }\n if (typeof navigator !== \"undefined\" && (navigator.maxTouchPoints ?? 0) > 0) return true;\n return typeof window !== \"undefined\" && \"ontouchstart\" in window;\n}\n\n/** Whether the browser says the primary pointer is coarse (diagnostic only). */\nfunction coarsePointer(): boolean {\n try {\n return window.matchMedia(\"(pointer: coarse)\").matches;\n } catch {\n return false;\n }\n}\n\n/** Whether screen recording is possible at all (absent in every iOS browser). */\nfunction canShareScreen(): boolean {\n return typeof (navigator.mediaDevices as MediaDevices | undefined)?.getDisplayMedia === \"function\";\n}\n\n/** A captured data-URL as a File, so a screenshot can ride along as a normal attachment. */\nfunction dataUrlToFile(dataUrl: string, name: string): File | null {\n const m = /^data:([^;,]+)(;base64)?,([\\s\\S]*)$/.exec(dataUrl);\n if (!m) return null;\n const [, type, b64, payload = \"\"] = m;\n try {\n const raw = b64 ? atob(payload) : decodeURIComponent(payload);\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);\n return new File([bytes], name, { type: type || \"image/png\" });\n } catch {\n return null;\n }\n}\n\nexport class LoupeApp {\n private cfg: LoupeConfig;\n private store: StorageAdapter;\n private root!: HTMLElement;\n private shadow!: ShadowRoot;\n private overlay!: HTMLElement;\n private hl!: HTMLElement;\n private selbox!: HTMLElement;\n private regionBox!: HTMLElement;\n private composer!: HTMLElement;\n\n /** The dockable control panel (header + tabs + tools + comment list). */\n private dock!: HTMLElement;\n /**\n * The collapsed FAB cluster shown while the panel is closed: a primary brand\n * button (with the comment count) plus quick actions that expand out of it.\n * `launcher` is the primary button itself (kept as a class for the dock's\n * show/hide logic); `fabMinis` is the row of quick actions.\n */\n private fabCluster!: HTMLElement;\n private fabMinis!: HTMLElement;\n private fabBadge!: HTMLElement;\n /** Whether the quick-action minis are expanded out of the primary FAB. */\n private fabExpanded = false;\n /** Whether pin markers are hidden on the page (a quick-action toggle, persisted). */\n private markersHidden = false;\n private themeBtn!: HTMLButtonElement;\n private listEl!: HTMLElement;\n private countEl!: HTMLElement;\n /** Floating \"recording…\" indicator + stop button, shown only while recording. */\n private recBar!: HTMLElement;\n /** Stops the in-flight screen recording (wired while recording). */\n private stopRecording?: () => void;\n\n private comments: Comment[] = [];\n /** Free-text filter over the list (title / body / author). */\n private search = \"\";\n /** Ids of list items the user expanded — items are collapsed by default. */\n private expanded = new Set<string>();\n /** comment.id → currently resolved element (or null when detached). */\n private resolved = new Map<string, Element | null>();\n /** comment.id → pin element. */\n private pins = new Map<string, HTMLElement>();\n\n private mode: Mode = \"off\";\n private lastUrl = \"\";\n /** In-flight region screenshot, captured in the background while the composer is open. */\n private pendingShot?: Promise<string | undefined>;\n private targetOffset = { x: 0.5, y: 0.5 };\n private pending: ComposeTarget | null = null;\n private dragStart: { x: number; y: number } | null = null;\n /** region comment whose outline is currently highlighted (tracks scroll). */\n private activeRegionId: string | null = null;\n private regionTimer?: number;\n\n // ---- control-panel state (persisted in localStorage `loupe:dock`) ----------\n private dockMode: DockMode = \"right\";\n private open = true;\n private theme: \"dark\" | \"light\" = \"dark\";\n private tab: Tab = \"comments\";\n /** Float-mode window geometry; (x<=0 && y<=0) → placed on first layout. */\n private floatRect = { x: 0, y: 0, w: 380, h: 540 };\n private floatDrag: { px: number; py: number; ox: number; oy: number } | null = null;\n private floatResize: { px: number; py: number; ow: number; oh: number } | null = null;\n\n private raf = 0;\n private mo?: MutationObserver;\n private tick?: number;\n\n constructor(cfg: LoupeConfig) {\n this.cfg = cfg;\n // apiBase set → talk to the backend; otherwise persist locally (prototype).\n this.store = cfg.apiBase\n ? new HttpAdapter(cfg.apiBase, cfg.user, cfg.userHmac, cfg.headers, cfg.credentials)\n : new LocalStorageAdapter();\n }\n\n private get url() { return location.pathname + location.search; }\n\n async start() {\n this.loadState();\n this.buildDom();\n if (this.cfg.autoOpen) this.open = true;\n this.applyDockLayout();\n this.lastUrl = this.url;\n this.comments = await this.store.list(this.cfg.projectKey, this.url);\n this.renderPins();\n this.renderList();\n this.observe();\n this.watchNavigation();\n if (this.cfg.autoOpen) this.setMode(\"inspect\");\n }\n\n /**\n * Reload comments when the page URL changes without a full reload (SPA\n * navigation), so each page only ever shows its own comments.\n */\n private watchNavigation() {\n const onChange = () => {\n if (this.url === this.lastUrl) return;\n this.lastUrl = this.url;\n void this.reloadComments();\n };\n addEventListener(\"popstate\", onChange);\n // history.pushState/replaceState don't emit events — wrap them once.\n for (const key of [\"pushState\", \"replaceState\"] as const) {\n const original = history[key];\n history[key] = function (this: History, ...args: unknown[]) {\n const result = (original as (...a: unknown[]) => unknown).apply(this, args);\n dispatchEvent(new Event(\"loupe:locationchange\"));\n return result;\n } as History[typeof key];\n }\n addEventListener(\"loupe:locationchange\", onChange);\n }\n\n private async reloadComments() {\n try {\n this.comments = await this.store.list(this.cfg.projectKey, this.url);\n this.renderPins();\n this.renderList();\n } catch { /* keep the current view on transient errors */ }\n }\n\n // ---- DOM construction -----------------------------------------------------\n\n private buildDom() {\n this.root = document.createElement(\"div\");\n this.root.id = \"loupe-root\";\n document.body.appendChild(this.root);\n this.shadow = this.root.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n style.textContent = STYLES;\n this.shadow.appendChild(style);\n\n this.overlay = el(\"div\", \"overlay\");\n this.hl = el(\"div\", \"hl\");\n this.hl.appendChild(el(\"span\", \"tip\"));\n this.selbox = el(\"div\", \"selbox\");\n this.regionBox = el(\"div\", \"region-box\");\n this.overlay.append(this.hl, this.selbox, this.regionBox);\n this.shadow.appendChild(this.overlay);\n\n this.composer = el(\"div\", \"composer\");\n this.shadow.appendChild(this.composer);\n\n this.dock = this.buildDock();\n this.fabCluster = this.buildFabCluster();\n this.recBar = this.buildRecBar();\n this.shadow.append(this.dock, this.fabCluster, this.recBar);\n }\n\n /**\n * The dockable control panel:\n * header (brand + dock controls) → tabs → [Comments view: tools + list + integrations]\n * and a [Connect view] with the Claude/MCP onboarding steps.\n */\n private buildDock(): HTMLElement {\n const dock = el(\"div\", \"dock\");\n\n // header ------------------------------------------------------------------\n const head = el(\"div\", \"dhead\");\n const brand = el(\"div\", \"brand\");\n brand.innerHTML = `<span class=\"logo\">◎</span><span class=\"title\"></span>`;\n (brand.querySelector(\".title\") as HTMLElement).textContent = this.cfg.label ?? \"Loupe\";\n head.addEventListener(\"pointerdown\", this.onHeadPointerDown); // drag in float mode\n\n const ctl = el(\"div\", \"dctl\");\n const dockBtn = (mode: DockMode, icon: string, title: string) => {\n const b = el(\"button\") as HTMLButtonElement;\n b.dataset.dock = mode;\n b.title = title;\n b.setAttribute(\"aria-label\", title);\n b.innerHTML = icon;\n b.onclick = () => this.setDock(mode);\n return b;\n };\n // Order mirrors DevTools: dock-left, dock-bottom, dock-right, undock/float.\n ctl.append(\n dockBtn(\"left\", I_DOCK_LEFT, \"Dock to left\"),\n dockBtn(\"bottom\", I_DOCK_BOTTOM, \"Dock to bottom\"),\n dockBtn(\"right\", I_DOCK_RIGHT, \"Dock to right\"),\n dockBtn(\"float\", I_FLOAT, \"Float\"),\n el(\"span\", \"gap\"),\n );\n this.themeBtn = el(\"button\") as HTMLButtonElement;\n this.themeBtn.dataset.role = \"theme\";\n this.themeBtn.onclick = () => this.toggleTheme();\n const closeBtn = el(\"button\") as HTMLButtonElement;\n closeBtn.dataset.role = \"close\";\n closeBtn.title = \"Close\";\n closeBtn.setAttribute(\"aria-label\", \"Close\");\n closeBtn.innerHTML = I_CLOSE;\n closeBtn.onclick = () => this.closeDock();\n ctl.append(this.themeBtn, closeBtn);\n\n head.append(brand, ctl);\n\n // tabs (the two sidebar pages) --------------------------------------------\n const tabs = el(\"div\", \"tabs\");\n const commentsTab = el(\"button\", \"tab\", \"Comments\") as HTMLButtonElement;\n commentsTab.dataset.tab = \"comments\";\n commentsTab.onclick = () => this.setTab(\"comments\");\n const connectTab = el(\"button\", \"tab\", \"Connect Claude\") as HTMLButtonElement;\n connectTab.dataset.tab = \"connect\";\n connectTab.onclick = () => this.setTab(\"connect\");\n tabs.append(commentsTab, connectTab);\n\n // tools -------------------------------------------------------------------\n const tools = el(\"div\", \"tools\");\n const inspectBtn = this.toolBtn(\"✛\", \"Inspect\", \"inspect\");\n inspectBtn.title = \"Inspect an element and comment on it\";\n inspectBtn.onclick = () => this.setMode(this.mode === \"inspect\" ? \"off\" : \"inspect\");\n const freeBtn = this.toolBtn(NOTE_ICON, \"Note\", \"free\");\n freeBtn.title = \"Drop a note anywhere on the page — no element, no screenshot\";\n freeBtn.onclick = () => this.setMode(this.mode === \"free\" ? \"off\" : \"free\");\n const regionBtn = this.toolBtn(REGION_ICON, \"Region\", \"region\");\n regionBtn.title = \"Drag a free-size box, screenshot it, and comment\";\n regionBtn.onclick = () => this.setMode(this.mode === \"region\" ? \"off\" : \"region\");\n const recordBtn = this.toolBtn(RECORD_ICON, \"Record\", \"record\");\n recordBtn.title = isTouchDevice()\n ? \"Record your screen, then describe the issue\"\n : \"Drag a box, record a screen video of it, and comment\";\n recordBtn.onclick = () => this.setMode(this.mode === \"record\" ? \"off\" : \"record\");\n\n // Screen recording is desktop-only: NO mobile browser supports getDisplayMedia\n // (iOS Safari never has; Chrome/Firefox on Android expose it in old versions but every\n // call fails — recorded as unsupported). So on a phone we cannot record the screen\n // from the page at all. What we can do is take the clip the phone already recorded\n // with its own screen recorder — so open the picker for it, and deliberately WITHOUT\n // a `capture` attribute: that would open the camera, and filming the room is not a\n // screen recording.\n if (canShareScreen()) {\n tools.append(inspectBtn, freeBtn, regionBtn, recordBtn);\n } else if (isTouchDevice()) {\n const videoBtn = this.toolBtn(VIDEO_ICON, \"Video\", \"video\");\n videoBtn.title = \"Attach a video — record your screen with your phone, then pick it here\";\n videoBtn.onclick = () => this.pickVideo();\n tools.append(inspectBtn, freeBtn, regionBtn, videoBtn);\n } else {\n tools.append(inspectBtn, freeBtn, regionBtn);\n }\n\n // list --------------------------------------------------------------------\n const listHead = el(\"div\", \"listhead\");\n listHead.append(document.createTextNode(\"Comments\"));\n this.countEl = el(\"span\", \"count\", \"0\");\n listHead.appendChild(this.countEl);\n const search = el(\"input\", \"search\") as HTMLInputElement;\n search.type = \"search\";\n search.placeholder = \"Search…\";\n search.value = this.search;\n search.oninput = () => { this.search = search.value; this.renderList(); };\n listHead.appendChild(search);\n this.listEl = el(\"div\", \"list\");\n\n // Comments view = tools + list + the \"integrates with\" footer.\n const commentsView = el(\"div\", \"view comments-view\");\n commentsView.append(tools, listHead, this.listEl, this.buildIntegrations());\n\n // Connect view = the Claude/MCP onboarding page.\n const connectView = this.buildConnectPanel();\n\n const resize = el(\"div\", \"resize\");\n resize.addEventListener(\"pointerdown\", this.onResizeDown);\n\n dock.append(head, tabs, commentsView, connectView, resize);\n return dock;\n }\n\n /** The \"INTEGRATES WITH\" footer on the Comments page (visual only for now). */\n private buildIntegrations(): HTMLElement {\n const wrap = el(\"div\", \"integrations\");\n wrap.append(el(\"div\", \"ilabel\", \"INTEGRATES WITH\"));\n const row = el(\"div\", \"irow\");\n const icons: [string, string][] = [\n [\"GitHub\", I_GITHUB],\n [\"Slack\", I_SLACK],\n [\"Telegram\", I_TELEGRAM],\n [\"Linear\", I_LINEAR],\n ];\n for (const [name, icon] of icons) {\n const b = el(\"span\", \"ibtn\");\n b.title = `${name} — connect (coming soon)`;\n b.setAttribute(\"aria-label\", name);\n b.innerHTML = icon;\n row.appendChild(b);\n }\n wrap.appendChild(row);\n return wrap;\n }\n\n /** The \"Connect Claude\" onboarding page: how to wire the MCP server to this project. */\n private buildConnectPanel(): HTMLElement {\n const view = el(\"div\", \"view connect-view\");\n const key = this.cfg.projectKey;\n const apiHint = this.cfg.apiBase ?? \"http://localhost:8787\";\n const config = JSON.stringify(\n {\n mcpServers: {\n loupe: {\n command: \"npx\",\n args: [\"-y\", \"@loupekit/mcp\"],\n env: { LOUPE_API: apiHint, LOUPE_PROJECT_KEY: key, LOUPE_ADMIN_KEY: \"<your project secret>\" },\n },\n },\n },\n null,\n 2,\n );\n const steps: [string, string][] = [\n [\"Pin your feedback\", \"Use Inspect, Region, Record, or Note to leave comments right on the live app.\"],\n [\"Add the Loupe MCP server\", \"Drop this into your Claude Code config so Claude can read this project's backlog:\"],\n [\"Let Claude fix it\", \"Claude reads each comment (with the screenshot, HTML & CSS), rewrites the UI, and calls propose_change — the modified HTML/CSS then shows up for your dev team in the dashboard.\"],\n ];\n const hero = el(\"div\", \"connect-hero\");\n hero.innerHTML =\n `<div class=\"chero-logo\">◎</div>` +\n `<div class=\"chero-title\">Hand your feedback to <span class=\"accentink\">Claude</span></div>` +\n `<div class=\"chero-sub\">Every pinned comment becomes an actionable, fully-contextualized task Claude Code can act on.</div>`;\n view.appendChild(hero);\n const list = el(\"ol\", \"connect-steps\");\n steps.forEach(([t, d], i) => {\n const li = el(\"li\");\n li.innerHTML = `<div class=\"cstep-t\">${i + 1}. ${escapeHtml(t)}</div><div class=\"cstep-d\">${escapeHtml(d)}</div>`;\n if (i === 1) {\n const pre = el(\"pre\", \"cstep-code\");\n pre.textContent = config;\n li.appendChild(pre);\n }\n list.appendChild(li);\n });\n view.appendChild(list);\n return view;\n }\n\n /** The floating \"recording…\" pill with a Stop button (shown only while recording). */\n private buildRecBar(): HTMLElement {\n const bar = el(\"button\", \"recbar\") as HTMLButtonElement;\n bar.title = \"Stop recording\";\n bar.setAttribute(\"aria-label\", \"Stop recording\");\n bar.onclick = () => this.stopRecording?.();\n return bar;\n }\n\n /**\n * The collapsed-state FAB cluster. The primary brand button carries the comment\n * count and toggles the quick actions out and back; the actions are the four\n * ways into the product without opening the full panel first:\n * pin a comment, drop a note, hide/show the markers already on the page, and\n * jump straight to the Claude/MCP setup.\n */\n private buildFabCluster(): HTMLElement {\n const cluster = el(\"div\", \"fab-cluster\");\n\n const minis = el(\"div\", \"fab-minis\");\n const mini = (role: string, icon: string, label: string, title: string) => {\n const b = el(\"button\", \"fab-mini\") as HTMLButtonElement;\n b.dataset.fab = role;\n b.title = title;\n b.setAttribute(\"aria-label\", title);\n b.innerHTML = `${icon}<span class=\"fab-tip\">${label}</span>`;\n return b;\n };\n const comment = mini(\"comment\", I_COMMENT, \"Pin comment\", \"Pin feedback on any element\");\n comment.onclick = () => { this.collapseFab(); this.openDock(); this.setMode(\"inspect\"); };\n const note = mini(\"note\", I_NOTE, \"Note\", \"Drop a note anywhere on the page\");\n note.onclick = () => { this.collapseFab(); this.openDock(); this.setMode(\"free\"); };\n const markers = mini(\"markers\", I_EYE, \"Markers\", \"Show or hide the markers on this page\");\n markers.onclick = () => this.toggleMarkers();\n const connect = mini(\"connect\", I_PLUG, \"Connect Claude\", \"Set up the Claude/MCP connection\");\n connect.onclick = () => { this.collapseFab(); this.openDock(); this.setTab(\"connect\"); };\n minis.append(comment, note, markers, connect);\n\n const primary = el(\"button\", \"launcher\") as HTMLButtonElement;\n primary.title = `Open ${this.cfg.label ?? \"Loupe\"}`;\n primary.setAttribute(\"aria-label\", `${this.cfg.label ?? \"Loupe\"} — quick actions`);\n primary.setAttribute(\"aria-expanded\", \"false\");\n primary.innerHTML = `<span class=\"logo\">◎</span>${I_FAB_CHEVRON}<span class=\"lcount\"></span>`;\n this.fabBadge = primary.querySelector(\".lcount\") as HTMLElement;\n primary.onclick = () => this.toggleFab();\n\n cluster.append(minis, primary);\n this.fabMinis = minis;\n return cluster;\n }\n\n /** Expand/collapse the quick actions out of the primary FAB. */\n private toggleFab() {\n this.fabExpanded = !this.fabExpanded;\n this.applyFab();\n }\n\n private collapseFab() {\n if (!this.fabExpanded) return;\n this.fabExpanded = false;\n this.applyFab();\n }\n\n /** Hide/show every pin on the page without losing them (persisted). */\n private toggleMarkers() {\n this.markersHidden = !this.markersHidden;\n this.saveState();\n this.applyFab();\n }\n\n /** Reflect cluster expansion + marker visibility into the DOM. */\n private applyFab() {\n this.fabCluster.classList.toggle(\"expanded\", this.fabExpanded);\n const primary = this.fabCluster.querySelector(\".launcher\") as HTMLElement | null;\n primary?.setAttribute(\"aria-expanded\", String(this.fabExpanded));\n primary?.setAttribute(\"aria-label\", this.fabExpanded ? \"Close quick actions\" : `Open ${this.cfg.label ?? \"Loupe\"} quick actions`);\n const markers = this.fabCluster.querySelector('[data-fab=\"markers\"]') as HTMLElement | null;\n markers?.classList.toggle(\"on\", this.markersHidden);\n markers?.setAttribute(\"aria-pressed\", String(this.markersHidden));\n // !important in CSS so it beats the inline display set by position().\n this.overlay.classList.toggle(\"hide-pins\", this.markersHidden);\n }\n\n /** A tool button with a uniform icon + label layout. `icon` may be an SVG string. */\n private toolBtn(icon: string, label: string, role: string): HTMLButtonElement {\n const b = el(\"button\") as HTMLButtonElement;\n b.dataset.role = role;\n b.setAttribute(\"aria-label\", label);\n b.innerHTML = `<span class=\"ico\">${icon}</span><span class=\"label\">${label}</span>`;\n return b;\n }\n\n // ---- inspector ------------------------------------------------------------\n\n // Pointer Events, not mouse events: a touch drag on a phone never fires\n // mousemove/mouseup, so Region/Record selection was impossible on touch devices.\n // Pointer events cover mouse, touch and pen with one handler each.\n\n private onMove = (e: PointerEvent) => {\n if (this.mode !== \"inspect\") return;\n const target = this.pick(e.clientX, e.clientY);\n if (!target) { this.hl.style.display = \"none\"; return; }\n const r = target.getBoundingClientRect();\n Object.assign(this.hl.style, {\n display: \"block\", left: r.left + \"px\", top: r.top + \"px\",\n width: r.width + \"px\", height: r.height + \"px\",\n });\n (this.hl.firstChild as HTMLElement).textContent =\n target.tagName.toLowerCase() + (target.id ? \"#\" + target.id : \"\");\n };\n\n private onClick = (e: MouseEvent) => {\n if (this.mode !== \"inspect\") return;\n const target = this.pick(e.clientX, e.clientY);\n if (!target) return;\n e.preventDefault();\n e.stopPropagation();\n const r = target.getBoundingClientRect();\n this.targetOffset = {\n x: r.width ? clamp((e.clientX - r.left) / r.width) : 0.5,\n y: r.height ? clamp((e.clientY - r.top) / r.height) : 0.5,\n };\n this.setMode(\"off\");\n this.openComposer({ kind: \"element\", element: target }, e.clientX, e.clientY);\n };\n\n private onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") { this.cancelDrag(); this.setMode(\"off\"); this.closeComposer(); }\n };\n\n // ---- region (\"free-size screenshot\") selection ----------------------------\n\n private onRegionDown = (e: PointerEvent) => {\n if (this.mode !== \"region\" && this.mode !== \"record\") return;\n // A mouse must use the primary button; touch/pen always start with button 0.\n if (e.pointerType !== \"touch\" && e.pointerType !== \"pen\" && e.button !== 0) return;\n // Ignore drags that start on our own UI (the panel overlays the page).\n const t = e.target as Element | null;\n if (t && (t.id === \"loupe-root\" || t.closest?.(\"#loupe-root\"))) return;\n e.preventDefault();\n e.stopPropagation();\n this.dragStart = { x: e.clientX, y: e.clientY };\n document.addEventListener(\"pointermove\", this.onRegionMove, true);\n document.addEventListener(\"pointerup\", this.onRegionUp, true);\n document.addEventListener(\"pointercancel\", this.onRegionCancel, true);\n this.drawSelection(e.clientX, e.clientY);\n };\n\n private onRegionMove = (e: PointerEvent) => {\n if (!this.dragStart) return;\n e.preventDefault();\n this.drawSelection(e.clientX, e.clientY);\n };\n\n private onRegionUp = (e: PointerEvent) => {\n if (!this.dragStart) return;\n e.preventDefault();\n e.stopPropagation();\n const start = this.dragStart;\n const wasRecord = this.mode === \"record\";\n this.cancelDrag();\n const vp: RegionRect = {\n x: Math.min(start.x, e.clientX), y: Math.min(start.y, e.clientY),\n w: Math.abs(e.clientX - start.x), h: Math.abs(e.clientY - start.y),\n };\n if (vp.w < 8 || vp.h < 8) { this.selbox.style.display = \"none\"; return; } // stray tap\n this.setMode(\"off\");\n if (wasRecord) void this.finishRecording(vp);\n else this.finishRegion(vp);\n };\n\n /** The OS took over the gesture (e.g. a system swipe): drop the selection. */\n private onRegionCancel = () => {\n this.cancelDrag();\n this.selbox.style.display = \"none\";\n };\n\n private drawSelection(curX: number, curY: number) {\n const s = this.dragStart!;\n Object.assign(this.selbox.style, {\n display: \"block\",\n left: Math.min(s.x, curX) + \"px\", top: Math.min(s.y, curY) + \"px\",\n width: Math.abs(curX - s.x) + \"px\", height: Math.abs(curY - s.y) + \"px\",\n });\n }\n\n private cancelDrag() {\n this.dragStart = null;\n document.removeEventListener(\"pointermove\", this.onRegionMove, true);\n document.removeEventListener(\"pointerup\", this.onRegionUp, true);\n document.removeEventListener(\"pointercancel\", this.onRegionCancel, true);\n }\n\n /**\n * Anchor a dragged viewport rect to the element under its center so it survives\n * reflow. `rel` (element-relative fractions) is preferred; document coords are the\n * fallback. Shared by both the Region (screenshot) and Record (video) tools.\n */\n private regionFromViewport(vp: RegionRect): { region: RegionRect; element: Element | null } {\n const centerEl = this.pick(vp.x + vp.w / 2, vp.y + vp.h / 2);\n let rel: RegionRect[\"rel\"];\n if (centerEl) {\n const er = centerEl.getBoundingClientRect();\n if (er.width > 0 && er.height > 0) {\n rel = {\n fx: (vp.x - er.left) / er.width, fy: (vp.y - er.top) / er.height,\n fw: vp.w / er.width, fh: vp.h / er.height,\n };\n }\n }\n const region: RegionRect = { x: vp.x + window.scrollX, y: vp.y + window.scrollY, w: vp.w, h: vp.h, rel };\n return { region, element: centerEl };\n }\n\n /**\n * Touch path for the Region tool: capture what is on screen right now and open the\n * composer with it already attached. The reporter scrolls to the part of the page they\n * mean FIRST, then taps Region — no drag, so nothing fights the page scroll.\n */\n private async captureViewportForComposer() {\n const vp: RegionRect = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };\n const capture = this.cfg.captureRegion ?? captureRegionScreenshot;\n let shot: string | undefined;\n try {\n shot = await capture(vp);\n } catch {\n shot = undefined;\n }\n const file = shot ? dataUrlToFile(shot, \"screenshot.png\") : null;\n const docX = window.scrollX + vp.w / 2;\n const docY = window.scrollY + vp.h / 2;\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };\n this.setMode(\"off\");\n this.openComposer(\n { kind: \"free\", offset, point: { x: docX, y: docY }, label: \"Screenshot · attached\" },\n 8,\n window.innerHeight / 2,\n file ? [file] : []\n );\n }\n\n /**\n * Attach a video on a phone, where the page cannot record the screen: the reporter\n * records it with the phone's own screen recorder first, then picks the clip here. No\n * `capture` attribute on purpose — that would force the camera open, and a video of the\n * room is not a screen recording.\n */\n private pickVideo() {\n this.setMode(\"off\");\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"video/*\";\n input.style.display = \"none\";\n input.onchange = () => {\n const file = input.files?.[0];\n input.remove();\n if (!file) return;\n const docX = window.scrollX + window.innerWidth / 2;\n const docY = window.scrollY + window.innerHeight / 2;\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };\n this.openComposer(\n { kind: \"free\", offset, point: { x: docX, y: docY }, label: \"Video · attached\" },\n 8,\n window.innerHeight / 2,\n [file]\n );\n };\n // In the shadow root: keeps the host page's DOM untouched.\n this.shadow.appendChild(input);\n input.click();\n }\n\n /** Capture the selected viewport rect, then open the composer for a region comment. */\n private async finishRegion(vp: RegionRect) {\n this.selbox.style.display = \"none\";\n const { region, element } = this.regionFromViewport(vp);\n const target: ComposeTarget = { kind: \"region\", region, element };\n // Open the composer immediately; capture the screenshot in the background so a\n // slow capture never blocks the UI. It attaches to the comment on submit.\n this.openComposer(target, vp.x + vp.w, vp.y);\n const capture = this.cfg.captureRegion ?? captureRegionScreenshot;\n this.pendingShot = capture(vp);\n void this.pendingShot.then((shot) => {\n if (shot && this.pending === target) target.screenshot = shot;\n }).catch(() => undefined);\n }\n\n /**\n * Record a screen video of the selected rect (same drag-select as Region), then\n * open the composer with the recording attached. Unlike the screenshot flow this\n * is interactive — the browser share prompt and a Stop button drive it — so the\n * composer opens only once recording has finished.\n */\n private async finishRecording(vp: RegionRect) {\n this.selbox.style.display = \"none\";\n const { region, element } = this.regionFromViewport(vp);\n const capture = this.cfg.captureRecording ?? captureRegionRecording;\n this.showRecBar();\n let recording: string | undefined;\n try {\n // Call the capture synchronously (getDisplayMedia needs the click gesture).\n recording = await capture(vp, {\n maxMs: RECORD_MAX_MS,\n register: (stop) => { this.stopRecording = stop; },\n });\n } catch {\n recording = undefined;\n }\n this.hideRecBar();\n if (!recording) return; // user cancelled the share prompt or capture failed\n const target: ComposeTarget = { kind: \"region\", region, element, recording };\n const x = Math.min(vp.x + vp.w, window.innerWidth - 320);\n this.openComposer(target, x, vp.y);\n }\n\n private showRecBar() {\n this.stopRecording = undefined;\n this.recBar.innerHTML = `<span class=\"recdot\"></span><span>Recording… <b>Stop</b></span>`;\n this.recBar.classList.add(\"show\");\n }\n private hideRecBar() {\n this.recBar.classList.remove(\"show\");\n this.stopRecording = undefined;\n }\n\n /** elementFromPoint, ignoring our own UI. */\n private pick(x: number, y: number): Element | null {\n const hitHl = this.hl.style.display;\n this.hl.style.display = \"none\"; // never let the highlight itself be the hit\n const elAt = document.elementFromPoint(x, y);\n this.hl.style.display = hitHl;\n if (!elAt) return null;\n if (elAt.id === \"loupe-root\" || (elAt as Element).closest?.(\"#loupe-root\")) return null;\n return elAt;\n }\n\n private setMode(mode: Mode) {\n // Tools live on the Comments page — entering a mode implies the panel is open there.\n if (mode !== \"off\") {\n if (!this.open) this.open = true;\n if (this.tab !== \"comments\") { this.tab = \"comments\"; this.saveState(); }\n this.applyDockLayout();\n }\n this.mode = mode;\n this.hl.style.display = \"none\";\n this.selbox.style.display = \"none\";\n this.cancelDrag();\n document.body.style.cursor = mode === \"off\" ? \"\" : \"crosshair\";\n (this.dock.querySelector('[data-role=\"inspect\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"inspect\");\n (this.dock.querySelector('[data-role=\"free\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"free\");\n (this.dock.querySelector('[data-role=\"region\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"region\");\n (this.dock.querySelector('[data-role=\"record\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"record\");\n // On mobile this shrinks the bottom sheet to just header + tools (see styles)\n // so most of the page stays visible while picking an element/region.\n this.dock.classList.toggle(\"inspecting\", mode !== \"off\");\n\n document.removeEventListener(\"pointermove\", this.onMove, true);\n document.removeEventListener(\"pointerdown\", this.onMove, true);\n document.removeEventListener(\"click\", this.onClick, true);\n document.removeEventListener(\"click\", this.onFreeClick, true);\n document.removeEventListener(\"pointerdown\", this.onRegionDown, true);\n\n if (mode === \"off\") return;\n document.addEventListener(\"keydown\", this.onKey, true);\n this.closeComposer();\n if (mode === \"inspect\") {\n document.addEventListener(\"pointermove\", this.onMove, true);\n // Touch has no hover: highlight on finger-down so the user can see what a tap\n // will select before lifting (the tap itself still arrives as a click).\n document.addEventListener(\"pointerdown\", this.onMove, true);\n document.addEventListener(\"click\", this.onClick, true);\n } else if (mode === \"free\") {\n document.addEventListener(\"click\", this.onFreeClick, true);\n } else if (mode === \"region\" && isTouchDevice()) {\n // No drag-select on touch — a finger covers the area it is drawing, and the drag\n // fights the page scroll. Grab the visible viewport instead (the reporter scrolls\n // to what they mean first, then taps Region) and hand it to the composer.\n void this.captureViewportForComposer();\n } else if (mode === \"record\" && isTouchDevice()) {\n // Same one-tap idea for video: nothing to drag with a finger, so record the whole\n // screen. Called synchronously from the tap — getDisplayMedia needs that gesture.\n const vp: RegionRect = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };\n this.setMode(\"off\");\n void this.finishRecording(vp);\n } else if (mode === \"region\" || mode === \"record\") {\n document.addEventListener(\"pointerdown\", this.onRegionDown, true);\n }\n }\n\n // ---- free note (drop a comment anywhere, no element / no screenshot) -------\n\n private onFreeClick = (e: MouseEvent) => {\n if (this.mode !== \"free\") return;\n const t = e.target as Element | null;\n if (t && (t.id === \"loupe-root\" || t.closest?.(\"#loupe-root\"))) return; // ignore our own UI\n e.preventDefault();\n e.stopPropagation();\n const docX = e.clientX + window.scrollX;\n const docY = e.clientY + window.scrollY;\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n // Store the drop point as a fraction of the document so it survives reloads\n // and reasonable reflow without needing any element anchor.\n const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };\n this.setMode(\"off\");\n this.openComposer({ kind: \"free\", offset, point: { x: docX, y: docY } }, e.clientX, e.clientY);\n };\n\n // ---- composer -------------------------------------------------------------\n\n private openComposer(target: ComposeTarget, x: number, y: number, seedFiles: File[] = []) {\n this.pending = target;\n const isRecording = target.kind === \"region\" && !!target.recording;\n const c = this.composer;\n c.innerHTML = \"\";\n const label = el(\"div\", \"target\",\n target.kind === \"element\" ? describe(target.element)\n : target.kind === \"region\"\n ? (isRecording\n ? `⏺ Recording · ${Math.round(target.region.w)}×${Math.round(target.region.h)} px`\n : `Region · ${Math.round(target.region.w)}×${Math.round(target.region.h)} px`)\n : target.label ?? \"Free note · anywhere on the page\");\n const title = el(\"input\", \"title\") as HTMLInputElement;\n title.type = \"text\";\n title.placeholder = \"Title — one line: what's wrong, or what you need\";\n\n const ta = el(\"textarea\") as HTMLTextAreaElement;\n ta.placeholder = isRecording ? \"Describe the issue in this recording…\"\n : target.kind === \"region\" ? \"Describe the issue in this area…\"\n : target.kind === \"free\" ? \"Describe this note…\"\n : \"Describe what should change here…\";\n\n // Attachments: images and/or videos, several of each. A touch screenshot capture is\n // seeded here so it needs no extra tap to attach.\n const files: File[] = seedFiles.slice();\n const attach = el(\"div\", \"attach\");\n const pick = el(\"button\", \"pick\", \"+ Attach images / videos\") as HTMLButtonElement;\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/*,video/*\";\n input.multiple = true;\n input.style.display = \"none\";\n const chips = el(\"div\", \"chips\");\n const err = el(\"div\", \"err\");\n const drawChips = () => {\n chips.innerHTML = \"\";\n files.forEach((f, idx) => {\n const chip = el(\"span\", \"chip\", `${attachmentKind(f.type) === \"video\" ? \"🎬\" : \"🖼\"} ${f.name}`);\n const x = el(\"button\", \"x\", \"×\") as HTMLButtonElement;\n x.onclick = () => { files.splice(idx, 1); drawChips(); };\n chip.appendChild(x);\n chips.appendChild(chip);\n });\n };\n input.onchange = () => {\n err.textContent = \"\";\n for (const f of Array.from(input.files ?? [])) {\n if (files.length >= MAX_FILES) { err.textContent = `Up to ${MAX_FILES} files.`; break; }\n const cap = attachmentKind(f.type) === \"video\" ? MAX_VIDEO_BYTES : MAX_IMAGE_BYTES;\n if (f.size > cap) { err.textContent = `${f.name} is too large.`; continue; }\n files.push(f);\n }\n input.value = \"\";\n drawChips();\n };\n pick.onclick = () => input.click();\n attach.append(pick, input, chips, err);\n if (files.length) drawChips();\n\n const row = el(\"div\", \"row\");\n // Free notes carry nothing; recordings always attach the video — both skip the checkbox.\n let box: HTMLInputElement | null = null;\n if (target.kind !== \"free\" && !isRecording) {\n const chk = el(\"label\", \"chk\") as HTMLLabelElement;\n box = document.createElement(\"input\"); box.type = \"checkbox\";\n // Default to attaching. Element shots are captured on submit; region shots are\n // captured in the background and awaited on submit (see pendingShot).\n box.checked = true;\n chk.append(box, document.createTextNode(\"Attach screenshot\"));\n row.append(chk);\n } else {\n row.style.justifyContent = \"flex-end\";\n }\n const btns = el(\"div\", \"btns\");\n const cancel = el(\"button\", \"ghost\", \"Cancel\") as HTMLButtonElement;\n cancel.onclick = () => this.closeComposer();\n const save = el(\"button\", \"primary\", \"Comment\") as HTMLButtonElement;\n save.disabled = true;\n const sync = () => { save.disabled = !title.value.trim() || !ta.value.trim(); };\n title.oninput = sync;\n ta.oninput = sync;\n sync();\n save.onclick = () => this.submit(target, title.value.trim(), ta.value.trim(), box ? box.checked : false, files.slice());\n btns.append(cancel, save);\n row.append(btns);\n c.append(label, title, ta, attach, row);\n\n // Position near the click, clamped to the viewport.\n const w = 320, h = 340;\n const left = Math.min(Math.max(8, x + 12), window.innerWidth - w - 8);\n const top = Math.min(Math.max(8, y + 12), window.innerHeight - h - 8);\n Object.assign(c.style, { display: \"block\", left: left + \"px\", top: top + \"px\" });\n // Do not grab focus on touch: it throws the on-screen keyboard up over the very page\n // the reporter is describing (and over our own form).\n if (!isTouchDevice()) ta.focus();\n }\n\n private closeComposer() {\n this.composer.style.display = \"none\";\n this.pending = null;\n this.pendingShot = undefined;\n }\n\n private async submit(target: ComposeTarget, title: string, body: string, withShot: boolean, files: File[]) {\n if (!title || !body) return;\n const saveBtn = this.composer.querySelector(\".primary\") as HTMLButtonElement;\n if (saveBtn) { saveBtn.disabled = true; saveBtn.textContent = \"Saving…\"; }\n\n let anchor: Anchor, context: Comment[\"context\"], offset: Comment[\"offset\"];\n let screenshot: string | undefined;\n let recording: string | undefined;\n let region: RegionRect | undefined;\n let anchoredEl: Element | null = null;\n\n if (target.kind === \"element\") {\n const capture = this.cfg.captureScreenshot ?? captureScreenshot;\n screenshot = withShot ? await capture(target.element) : undefined;\n anchor = captureAnchor(target.element);\n context = captureElementContext(target.element);\n offset = this.targetOffset;\n anchoredEl = target.element;\n } else if (target.kind === \"free\") {\n // A page-level note: no element, no screenshot. Its position lives in\n // `offset` as a fraction of the document (see onFreeClick + position()).\n screenshot = undefined;\n anchor = pageAnchor(target.point);\n context = { html: \"\", styles: {} };\n offset = target.offset;\n } else {\n // A recording carries its own visuals; a plain region uses the background\n // screenshot (awaited only if it hasn't attached yet).\n recording = target.recording;\n screenshot = !recording && withShot ? (target.screenshot ?? await this.pendingShot) : undefined;\n region = target.region;\n offset = { x: 0, y: 0 };\n // Prefer the real center-element anchor (survives reflow + gives Claude a\n // real element); fall back to a synthetic region anchor when there's none.\n if (target.element) {\n anchor = captureAnchor(target.element);\n context = captureElementContext(target.element);\n anchoredEl = target.element;\n } else {\n anchor = regionAnchor(region);\n context = { html: regionNote(region), styles: {} };\n }\n }\n\n const comment: Comment = {\n id: uid(),\n projectKey: this.cfg.projectKey,\n url: this.url,\n author: this.cfg.user,\n title,\n body,\n status: \"queue\",\n kind: target.kind,\n anchor,\n context,\n offset,\n region,\n screenshot,\n recording,\n attachments: await this.uploadAttachments(files),\n // The screen this was captured on, plus enough to tell a stale bundle from a real\n // bug when someone reports \"it still doesn't work\" (see Comment.viewport).\n viewport: {\n w: window.innerWidth,\n h: window.innerHeight,\n v: SDK_VERSION,\n touch: isTouchDevice(),\n coarse: coarsePointer(),\n gdm: canShareScreen(),\n },\n createdAt: new Date().toISOString(),\n };\n await this.store.save(comment);\n this.comments.push(comment);\n this.resolved.set(comment.id, anchoredEl);\n this.closeComposer();\n this.renderPins();\n this.renderList();\n this.flash(comment.id);\n }\n\n /** Upload the reporter's picked files. A file that fails is skipped, not fatal. */\n private async uploadAttachments(files: File[]): Promise<Attachment[] | undefined> {\n if (!files.length) return undefined;\n const out: Attachment[] = [];\n for (const f of files) {\n try {\n out.push(await this.store.upload(this.cfg.projectKey, f));\n } catch (e) {\n console.warn(\"[loupe] attachment upload failed\", f.name, e);\n }\n }\n return out.length ? out : undefined;\n }\n\n // ---- pins + re-anchoring --------------------------------------------------\n\n private renderPins() {\n // Remove pins for deleted comments.\n for (const [id, pin] of this.pins) {\n if (!this.comments.find((c) => c.id === id)) { pin.remove(); this.pins.delete(id); }\n }\n this.comments.forEach((c, i) => {\n let pin = this.pins.get(c.id);\n if (!pin) {\n pin = el(\"button\", \"pin\") as HTMLButtonElement;\n pin.onclick = () => { this.openDock(); this.flash(c.id); };\n this.overlay.appendChild(pin);\n this.pins.set(c.id, pin);\n }\n pin.textContent = String(i + 1);\n pin.classList.toggle(\"done\", isResolved(c));\n pin.classList.toggle(\"free\", c.kind === \"free\");\n });\n this.updateCount();\n this.position();\n }\n\n private updateCount() {\n const n = this.comments.length;\n this.countEl.textContent = String(n);\n this.fabBadge.textContent = n ? String(n) : \"\";\n }\n\n /** Reposition every pin, re-resolving anchors whose element has gone. */\n private position = () => {\n for (const c of this.comments) {\n const pin = this.pins.get(c.id);\n if (!pin) continue;\n\n if (c.kind === \"free\") {\n // Page-level note: position from the stored document-fraction offset.\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n const px = c.offset.x * docW - window.scrollX;\n const py = c.offset.y * docH - window.scrollY;\n const onScreen = px > -24 && px < window.innerWidth + 24 && py > -24 && py < window.innerHeight + 24;\n Object.assign(pin.style, { left: px + \"px\", top: py + \"px\", display: onScreen ? \"grid\" : \"none\" });\n pin.classList.remove(\"detached\");\n continue;\n }\n\n let elx = this.resolved.get(c.id) ?? null;\n if (!elx || !elx.isConnected) {\n const r = resolveAnchor(c.anchor);\n elx = r?.element ?? null;\n this.resolved.set(c.id, elx);\n }\n\n if (c.kind === \"region\") {\n // Compute the region's live viewport rect from its anchor element; fall\n // back to stored document coords (older data / no anchor found).\n const box = this.regionRect(c, elx);\n if (box) {\n const onScreen = box.x + box.w > 0 && box.x < window.innerWidth && box.y + box.h > 0 && box.y < window.innerHeight;\n Object.assign(pin.style, { left: box.x + \"px\", top: box.y + \"px\", display: onScreen ? \"grid\" : \"none\" });\n pin.classList.toggle(\"detached\", !elx && !c.region?.rel);\n } else {\n pin.style.display = \"none\";\n pin.classList.add(\"detached\");\n }\n continue;\n }\n\n if (elx) {\n const rect = elx.getBoundingClientRect();\n const px = rect.left + c.offset.x * rect.width;\n const py = rect.top + c.offset.y * rect.height;\n const onScreen = rect.bottom > 0 && rect.top < window.innerHeight && rect.width > 0;\n Object.assign(pin.style, { left: px + \"px\", top: py + \"px\", display: onScreen ? \"grid\" : \"none\" });\n pin.classList.remove(\"detached\");\n } else {\n pin.style.display = \"none\";\n pin.classList.add(\"detached\");\n }\n }\n\n // Keep the highlighted region outline glued to its live rect while scrolling.\n if (this.activeRegionId) {\n const c = this.comments.find((x) => x.id === this.activeRegionId);\n const box = c && this.regionRect(c, this.resolved.get(c.id) ?? null);\n if (box) {\n Object.assign(this.regionBox.style, {\n display: \"block\", left: box.x + \"px\", top: box.y + \"px\", width: box.w + \"px\", height: box.h + \"px\",\n });\n }\n }\n };\n\n /**\n * The current viewport rect for a region comment. Prefers the element-relative\n * fractions (so it tracks reflow across viewports); falls back to the stored\n * document coordinates minus scroll. Returns null if neither is available.\n */\n private regionRect(c: Comment, elx: Element | null): { x: number; y: number; w: number; h: number } | null {\n const rel = c.region?.rel;\n if (elx && rel) {\n const r = elx.getBoundingClientRect();\n return { x: r.left + rel.fx * r.width, y: r.top + rel.fy * r.height, w: rel.fw * r.width, h: rel.fh * r.height };\n }\n if (c.region) {\n return { x: c.region.x - window.scrollX, y: c.region.y - window.scrollY, w: c.region.w, h: c.region.h };\n }\n return null;\n }\n\n private observe() {\n const reposition = () => {\n cancelAnimationFrame(this.raf);\n this.raf = requestAnimationFrame(this.position);\n };\n window.addEventListener(\"scroll\", reposition, true);\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"resize\", this.onWinResize);\n let debounce = 0;\n this.mo = new MutationObserver(() => {\n clearTimeout(debounce);\n debounce = window.setTimeout(() => { this.position(); this.renderList(); }, 120);\n });\n this.mo.observe(document.body, { childList: true, subtree: true, attributes: true, characterData: true });\n // Safety net for animated / late-loading layouts.\n this.tick = window.setInterval(this.position, 800);\n }\n\n // ---- dock: open / close / mode / theme ------------------------------------\n\n private openDock() {\n this.open = true;\n this.fabExpanded = false; // the panel replaces the quick actions\n this.saveState();\n this.applyDockLayout();\n this.renderList();\n }\n\n private closeDock() {\n this.open = false;\n this.setMode(\"off\");\n this.closeComposer();\n this.saveState();\n this.applyDockLayout();\n }\n\n private setDock(mode: DockMode) {\n this.dockMode = mode;\n this.open = true;\n this.saveState();\n this.applyDockLayout();\n }\n\n /** Switch the sidebar page (Comments ↔ Connect Claude). */\n private setTab(tab: Tab) {\n if (this.tab === tab) return;\n // Leaving the Comments page cancels any active picking tool.\n if (tab !== \"comments\") this.setMode(\"off\");\n this.tab = tab;\n this.saveState();\n this.applyDockLayout();\n if (tab === \"comments\") this.renderList();\n }\n\n private toggleTheme() {\n this.theme = this.theme === \"dark\" ? \"light\" : \"dark\";\n this.saveState();\n this.applyDockLayout();\n }\n\n private onWinResize = () => this.applyDockLayout();\n\n /** Narrow viewports render the panel as a bottom sheet, not a side/float dock. */\n private isMobile() { return window.innerWidth <= 640; }\n\n private loadState() {\n try {\n const s = localStorage.getItem(\"loupe:dock\");\n if (!s) return;\n const p = JSON.parse(s);\n if (DOCK_MODES.includes(p?.mode)) this.dockMode = p.mode;\n if (typeof p?.open === \"boolean\") this.open = p.open;\n if (p?.theme === \"light\" || p?.theme === \"dark\") this.theme = p.theme;\n if (p?.tab === \"comments\" || p?.tab === \"connect\") this.tab = p.tab;\n if (p?.float && typeof p.float.w === \"number\") this.floatRect = { ...this.floatRect, ...p.float };\n if (typeof p?.markersHidden === \"boolean\") this.markersHidden = p.markersHidden;\n } catch { /* storage unavailable → defaults */ }\n }\n\n private saveState() {\n try {\n localStorage.setItem(\"loupe:dock\", JSON.stringify({\n mode: this.dockMode, open: this.open, theme: this.theme, tab: this.tab, float: this.floatRect,\n markersHidden: this.markersHidden,\n }));\n } catch { /* ignore */ }\n }\n\n /** Reflect all control-panel state (theme, dock mode, geometry, launcher) into the DOM. */\n private applyDockLayout() {\n this.root.classList.toggle(\"theme-light\", this.theme === \"light\");\n this.themeBtn.title = this.theme === \"dark\" ? \"Switch to light theme\" : \"Switch to dark theme\";\n this.themeBtn.innerHTML = this.theme === \"dark\" ? I_SUN : I_MOON;\n\n const d = this.dock;\n d.classList.toggle(\"open\", this.open);\n for (const m of DOCK_MODES) d.classList.toggle(\"mode-\" + m, this.dockMode === m);\n // Which sidebar page is active (Comments vs Connect Claude).\n d.classList.toggle(\"tab-comments\", this.tab === \"comments\");\n d.classList.toggle(\"tab-connect\", this.tab === \"connect\");\n d.querySelectorAll<HTMLElement>(\".tabs .tab\").forEach((b) =>\n b.classList.toggle(\"on\", b.dataset.tab === this.tab));\n\n if (this.dockMode === \"float\") {\n const vw = window.innerWidth, vh = window.innerHeight;\n let { x, y, w, h } = this.floatRect;\n w = clampPx(w, 280, Math.min(760, vw - 24));\n h = clampPx(h, 220, vh - 24);\n if (x <= 0 && y <= 0) { x = Math.max(12, vw - w - 24); y = 64; } // first placement\n x = clampPx(x, 8, Math.max(8, vw - w - 8));\n y = clampPx(y, 8, Math.max(8, vh - h - 8));\n this.floatRect = { x, y, w, h };\n Object.assign(d.style, { left: x + \"px\", top: y + \"px\", width: w + \"px\", height: h + \"px\", right: \"auto\", bottom: \"auto\" });\n } else {\n for (const p of [\"left\", \"top\", \"right\", \"bottom\", \"width\", \"height\"] as const) d.style[p] = \"\";\n }\n\n d.querySelectorAll<HTMLElement>(\".dctl [data-dock]\").forEach((b) =>\n b.classList.toggle(\"on\", b.dataset.dock === this.dockMode));\n\n // FAB cluster: visible only while the panel is closed and always on the same\n // side as the dock edge, so reopening it feels like the panel sliding back in.\n this.fabCluster.classList.toggle(\"show\", !this.open);\n const leftSide = this.dockMode === \"left\";\n this.fabCluster.style.left = leftSide ? \"20px\" : \"auto\";\n this.fabCluster.style.right = leftSide ? \"auto\" : \"20px\";\n this.applyFab();\n\n this.pushPage();\n }\n\n /**\n * Push the host page over so the docked panel never covers content (like real\n * DevTools). We shrink the <html> box with a margin on the docked edge — the\n * panel is `position: fixed` (relative to the viewport), so it sits in the\n * gutter the margin frees up. Float mode and the closed state reserve nothing.\n * Only inline styles are touched, so clearing them restores the host exactly.\n */\n private pushPage() {\n const de = document.documentElement;\n de.style.marginLeft = de.style.marginRight = de.style.marginBottom = \"\";\n // On mobile the panel is a bottom-sheet overlay (see styles) — reserving page\n // space would squeeze content to a sliver, so we never push there.\n if (!this.open || this.dockMode === \"float\" || this.isMobile()) return;\n const r = this.dock.getBoundingClientRect();\n if (this.dockMode === \"left\") de.style.marginLeft = r.width + \"px\";\n else if (this.dockMode === \"right\") de.style.marginRight = r.width + \"px\";\n else if (this.dockMode === \"bottom\") de.style.marginBottom = r.height + \"px\";\n }\n\n // ---- float-mode drag + resize ---------------------------------------------\n\n private onHeadPointerDown = (e: PointerEvent) => {\n if (this.dockMode !== \"float\" || e.button !== 0 || this.isMobile()) return;\n if ((e.target as HTMLElement)?.closest(\".dctl\")) return; // let control buttons work\n this.floatDrag = { px: e.clientX, py: e.clientY, ox: this.floatRect.x, oy: this.floatRect.y };\n this.dock.classList.add(\"dragging\");\n window.addEventListener(\"pointermove\", this.onHeadPointerMove);\n window.addEventListener(\"pointerup\", this.onHeadPointerUp);\n };\n private onHeadPointerMove = (e: PointerEvent) => {\n if (!this.floatDrag) return;\n e.preventDefault();\n this.floatRect.x = this.floatDrag.ox + (e.clientX - this.floatDrag.px);\n this.floatRect.y = this.floatDrag.oy + (e.clientY - this.floatDrag.py);\n this.applyDockLayout();\n };\n private onHeadPointerUp = () => {\n if (!this.floatDrag) return;\n this.floatDrag = null;\n this.dock.classList.remove(\"dragging\");\n window.removeEventListener(\"pointermove\", this.onHeadPointerMove);\n window.removeEventListener(\"pointerup\", this.onHeadPointerUp);\n this.saveState();\n };\n\n private onResizeDown = (e: PointerEvent) => {\n if (this.dockMode !== \"float\") return;\n e.preventDefault(); e.stopPropagation();\n this.floatResize = { px: e.clientX, py: e.clientY, ow: this.floatRect.w, oh: this.floatRect.h };\n window.addEventListener(\"pointermove\", this.onResizeMove);\n window.addEventListener(\"pointerup\", this.onResizeUp);\n };\n private onResizeMove = (e: PointerEvent) => {\n if (!this.floatResize) return;\n e.preventDefault();\n this.floatRect.w = this.floatResize.ow + (e.clientX - this.floatResize.px);\n this.floatRect.h = this.floatResize.oh + (e.clientY - this.floatResize.py);\n this.applyDockLayout();\n };\n private onResizeUp = () => {\n if (!this.floatResize) return;\n this.floatResize = null;\n window.removeEventListener(\"pointermove\", this.onResizeMove);\n window.removeEventListener(\"pointerup\", this.onResizeUp);\n this.saveState();\n };\n\n // ---- comment list ---------------------------------------------------------\n\n private renderList() {\n this.listEl.innerHTML = \"\";\n const q = this.search.trim().toLowerCase();\n const items = q\n ? this.comments.filter((c) => `${c.title ?? \"\"} ${c.body} ${c.author?.name ?? \"\"}`.toLowerCase().includes(q))\n : this.comments;\n if (!items.length) {\n this.listEl.appendChild(el(\"div\", \"empty\",\n q ? \"No comments match your search.\"\n : \"No comments yet. Use Inspect to pick an element, or Note to drop a comment anywhere on the page.\"));\n }\n items.forEach((c, i) => this.listEl.appendChild(this.itemView(c, i)));\n this.updateCount();\n }\n\n private itemView(c: Comment, i: number): HTMLElement {\n const detached = this.pins.get(c.id)?.classList.contains(\"detached\") && !isResolved(c);\n const open = this.expanded.has(c.id);\n const item = el(\"div\", \"item\" + (open ? \"\" : \" collapsed\"));\n const top = el(\"div\", \"top\");\n const num = el(\"span\", \"num\" + (isResolved(c) ? \" done\" : detached ? \" detached\" : \"\"), String(i + 1));\n // No author identity is shown in the widget list (privacy — see the dashboard for triage).\n top.append(num);\n if (c.recording) top.appendChild(el(\"span\", \"rectag\", \"⏺ recording\"));\n const vw = c.viewport?.w;\n if (vw) {\n const kind = vw < 768 ? \"mobile\" : vw < 1024 ? \"tablet\" : \"desktop\";\n const icon = vw < 768 ? \"📱\" : vw < 1024 ? \"▦\" : \"🖥\";\n top.appendChild(el(\"span\", \"device\", `${icon} ${kind}`));\n }\n if (isResolved(c)) top.appendChild(el(\"span\", \"badge done\", \"resolved\"));\n else if (detached) top.appendChild(el(\"span\", \"badge detached\", \"element moved/removed\"));\n top.appendChild(el(\"span\", \"caret\", open ? \"▾\" : \"▸\"));\n item.appendChild(top);\n\n // Collapsed, the item is a single summary line; expanding reveals the detail.\n const summary = c.title || (c.body.split(\"\\n\")[0] ?? \"\").slice(0, 140) || \"(no description)\";\n item.appendChild(el(\"div\", \"summary\", summary));\n\n const detail = el(\"div\", \"detail\");\n // With a title, the body is the full description; without one the first line is\n // already the summary, so only multi-line bodies repeat it here.\n if (c.title || c.body.includes(\"\\n\")) detail.appendChild(el(\"div\", \"body\", c.body));\n detail.appendChild(el(\"div\", \"meta\", describeAnchor(c)));\n\n if (c.recording) {\n const v = el(\"video\", \"shot\") as HTMLVideoElement;\n v.src = c.recording;\n v.controls = true;\n v.playsInline = true;\n if (c.screenshot) v.poster = c.screenshot;\n detail.appendChild(v);\n } else if (c.screenshot) {\n const img = el(\"img\", \"shot\") as HTMLImageElement;\n img.src = c.screenshot;\n detail.appendChild(img);\n }\n\n // Files the reporter attached (images and videos).\n for (const a of c.attachments ?? []) {\n if (a.kind === \"video\") {\n const v = el(\"video\", \"shot\") as HTMLVideoElement;\n v.src = a.url;\n v.controls = true;\n v.playsInline = true;\n detail.appendChild(v);\n } else {\n const img = el(\"img\", \"shot\") as HTMLImageElement;\n img.src = a.url;\n img.alt = a.name ?? \"attachment\";\n detail.appendChild(img);\n }\n }\n\n const actions = el(\"div\", \"actions\");\n const doneBtn = el(\"button\", \"\", isResolved(c) ? \"Reopen\" : \"Resolve\") as HTMLButtonElement;\n doneBtn.onclick = async (e) => {\n e.stopPropagation();\n const status = isResolved(c) ? \"queue\" : \"resolved\";\n c.status = status; await this.store.update(c.id, { status });\n this.renderPins(); this.renderList();\n };\n const del = el(\"button\", \"\", \"Delete\") as HTMLButtonElement;\n del.onclick = async (e) => {\n e.stopPropagation();\n await this.store.remove(c.id);\n this.comments = this.comments.filter((x) => x.id !== c.id);\n this.resolved.delete(c.id);\n this.renderPins(); this.renderList();\n };\n actions.append(doneBtn, del);\n detail.appendChild(actions);\n item.appendChild(detail);\n\n item.onclick = () => {\n if (open) this.expanded.delete(c.id);\n else this.expanded.add(c.id);\n this.renderList();\n };\n return item;\n }\n\n private flash(id: string) {\n const c = this.comments.find((x) => x.id === id);\n const pin = this.pins.get(id);\n\n if (c?.kind === \"free\") {\n for (const p of this.pins.values()) p.classList.remove(\"active\");\n pin?.classList.add(\"active\");\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n window.scrollTo({\n top: Math.max(0, c.offset.y * docH - window.innerHeight / 2),\n left: Math.max(0, c.offset.x * docW - window.innerWidth / 2),\n behavior: \"smooth\",\n });\n this.position();\n return;\n }\n\n if (c?.kind === \"region\" && c.region) {\n for (const p of this.pins.values()) p.classList.remove(\"active\");\n pin?.classList.add(\"active\");\n // Show the outline, keep it tracking scroll, then fade it out.\n this.activeRegionId = id;\n window.clearTimeout(this.regionTimer);\n this.regionTimer = window.setTimeout(() => {\n this.activeRegionId = null;\n this.regionBox.style.display = \"none\";\n }, 2400);\n // Scroll to the anchor element when we have it (correct across reflow),\n // otherwise to the stored document position.\n const elx = this.resolved.get(id);\n if (elx) elx.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n else window.scrollTo({ top: Math.max(0, c.region.y - 120), left: Math.max(0, c.region.x - 120), behavior: \"smooth\" });\n this.position();\n return;\n }\n\n if (!pin || pin.classList.contains(\"detached\")) return;\n for (const p of this.pins.values()) p.classList.remove(\"active\");\n pin.classList.add(\"active\");\n const elx = this.resolved.get(id);\n if (elx) elx.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n\n destroy() {\n this.stopRecording?.();\n this.setMode(\"off\");\n this.mo?.disconnect();\n if (this.tick) clearInterval(this.tick);\n window.clearTimeout(this.regionTimer);\n window.removeEventListener(\"resize\", this.onWinResize);\n window.removeEventListener(\"pointermove\", this.onHeadPointerMove);\n window.removeEventListener(\"pointerup\", this.onHeadPointerUp);\n window.removeEventListener(\"pointermove\", this.onResizeMove);\n window.removeEventListener(\"pointerup\", this.onResizeUp);\n document.removeEventListener(\"keydown\", this.onKey, true);\n // Release the page-push margins we set for docked modes.\n const de = document.documentElement;\n de.style.marginLeft = de.style.marginRight = de.style.marginBottom = \"\";\n this.root?.remove();\n }\n}\n\n// ---- tiny DOM helpers -------------------------------------------------------\n\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, cls = \"\", text = \"\"): HTMLElementTagNameMap[K] {\n const n = document.createElement(tag);\n if (cls) n.className = cls;\n if (text) n.textContent = text;\n return n;\n}\nfunction clamp(n: number) { return Math.max(0, Math.min(1, n)); }\nfunction clampPx(n: number, min: number, max: number) { return Math.max(min, Math.min(max, n)); }\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (m) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" }[m]!));\n}\n\n// ---- inline icons (font-independent, currentColor) --------------------------\n\nconst svg = (inner: string) =>\n `<svg viewBox=\"0 0 16 16\" width=\"15\" height=\"15\" fill=\"none\" aria-hidden=\"true\">${inner}</svg>`;\nconst DOCK_FRAME = `<rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"1.6\" stroke=\"currentColor\" stroke-width=\"1.3\"/>`;\nconst I_DOCK_LEFT = svg(`${DOCK_FRAME}<rect x=\"2.2\" y=\"3.2\" width=\"4\" height=\"9.6\" rx=\"1\" fill=\"currentColor\"/>`);\nconst I_DOCK_RIGHT = svg(`${DOCK_FRAME}<rect x=\"9.8\" y=\"3.2\" width=\"4\" height=\"9.6\" rx=\"1\" fill=\"currentColor\"/>`);\nconst I_DOCK_BOTTOM = svg(`${DOCK_FRAME}<rect x=\"2.2\" y=\"9\" width=\"11.6\" height=\"3.8\" rx=\"1\" fill=\"currentColor\"/>`);\nconst I_FLOAT = svg(\n `<rect x=\"2.5\" y=\"3.5\" width=\"11\" height=\"9\" rx=\"1.6\" stroke=\"currentColor\" stroke-width=\"1.3\"/>` +\n `<path d=\"M2.5 6.1h11\" stroke=\"currentColor\" stroke-width=\"1.3\"/>`);\nconst I_SUN = svg(\n `<circle cx=\"8\" cy=\"8\" r=\"3\" stroke=\"currentColor\" stroke-width=\"1.3\"/>` +\n `<g stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\">` +\n `<path d=\"M8 1.4v1.7\"/><path d=\"M8 12.9v1.7\"/><path d=\"M1.4 8h1.7\"/><path d=\"M12.9 8h1.7\"/>` +\n `<path d=\"M3.3 3.3l1.2 1.2\"/><path d=\"M11.5 11.5l1.2 1.2\"/><path d=\"M12.7 3.3l-1.2 1.2\"/><path d=\"M4.5 11.5l-1.2 1.2\"/></g>`);\nconst I_MOON = svg(\n `<path d=\"M13 9.4A5.3 5.3 0 1 1 6.6 3 4.3 4.3 0 0 0 13 9.4z\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linejoin=\"round\"/>`);\nconst I_CLOSE = svg(\n `<path d=\"M4.2 4.2l7.6 7.6M11.8 4.2l-7.6 7.6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>`);\n\n/** FAB cluster quick-action icons (font-independent, currentColor). */\nconst I_COMMENT = svg(\n `<path d=\"M2 3.1h12v7.4H6.5l-3.3 2.6v-2.6H2z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<path d=\"M8 5.1v3.4M6.3 6.8h3.4\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/>`);\n/** A sticky note for the \"Note\" quick action — deliberately unlike the comment bubble. */\nconst I_NOTE = svg(\n `<path d=\"M2.6 2.6h10.8v7.2l-3.6 3.6H2.6z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<path d=\"M13.4 9.8h-3.6v3.6\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>`);\nconst I_EYE = svg(\n `<path d=\"M1.4 8S3.9 4 8 4s6.6 4 6.6 4-2.5 4-6.6 4S1.4 8 1.4 8z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<circle cx=\"8\" cy=\"8\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.3\"/>`);\nconst I_PLUG = svg(\n `<path d=\"M6 1.8v3.1M10 1.8v3.1\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/>` +\n `<path d=\"M4.4 4.9h7.2v2.3a3.6 3.6 0 0 1-7.2 0z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<path d=\"M8 10.8v3.4\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/>`);\n/** Points up when collapsed, flips down (via CSS) when the actions are out. */\nconst I_FAB_CHEVRON =\n `<span class=\"lchev\">${svg(`<path d=\"M4.4 9.6 8 6l3.6 3.6\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`)}</span>`;\n\n/** Dashed marquee icon for the \"Region\" button — inline SVG so it never depends on a font. */\nconst REGION_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<rect x=\"1.5\" y=\"2.5\" width=\"12\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-dasharray=\"2.4 1.8\"/>` +\n `</svg>`;\n\n/** Speech-bubble icon for the free-\"Note\" button. */\nconst NOTE_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<path d=\"M2 2.5h11v7.5H6l-3 2.5v-2.5H2z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `</svg>`;\n\n/** Camera/record icon for the \"Record\" button — dashed marquee with a record dot. */\nconst RECORD_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<rect x=\"1.5\" y=\"2.5\" width=\"12\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-dasharray=\"2.4 1.8\"/>` +\n `<circle cx=\"7.5\" cy=\"7.5\" r=\"2.4\" fill=\"currentColor\"/>` +\n `</svg>`;\n\n/** Video icon for the \"Video\" button — attach a screen recording made on the phone. */\nconst VIDEO_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<rect x=\"1.5\" y=\"2.5\" width=\"12\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\"/>` +\n `<path d=\"M6.3 5.5l3.9 2.2-3.9 2.2z\" fill=\"currentColor\"/>` +\n `</svg>`;\n\n// ---- integration icons (brand marks for the \"Integrates with\" footer) -------\nconst I_GITHUB =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M8 .2a8 8 0 0 0-2.5 15.6c.4.07.55-.17.55-.38v-1.3c-2.2.48-2.67-1.07-2.67-1.07-.36-.92-.88-1.16-.88-1.16-.72-.5.05-.48.05-.48.8.056 1.22.82 1.22.82.71 1.22 1.87.87 2.33.66.07-.52.28-.87.5-1.07-1.76-.2-3.6-.88-3.6-3.9 0-.86.3-1.57.82-2.12-.08-.2-.36-1 .08-2.1 0 0 .67-.21 2.2.8a7.6 7.6 0 0 1 4 0c1.53-1.02 2.2-.8 2.2-.8.44 1.1.16 1.9.08 2.1.5.55.82 1.26.82 2.12 0 3.03-1.85 3.7-3.61 3.9.28.24.54.72.54 1.46v2.16c0 .21.14.46.55.38A8 8 0 0 0 8 .2z\"/>` +\n `</svg>`;\nconst I_SLACK =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M3.4 10.1a1.6 1.6 0 1 1-1.6-1.6h1.6v1.6zm.8 0a1.6 1.6 0 0 1 3.2 0v4a1.6 1.6 0 1 1-3.2 0v-4zM5.8 3.4a1.6 1.6 0 1 1 1.6-1.6v1.6H5.8zm0 .8a1.6 1.6 0 0 1 0 3.2h-4a1.6 1.6 0 1 1 0-3.2h4zm6.7 1.6a1.6 1.6 0 1 1 1.6 1.6h-1.6V5.8zm-.8 0a1.6 1.6 0 0 1-3.2 0v-4a1.6 1.6 0 1 1 3.2 0v4zm-1.6 6.7a1.6 1.6 0 1 1-1.6 1.6v-1.6h1.6zm0-.8a1.6 1.6 0 0 1 0-3.2h4a1.6 1.6 0 1 1 0 3.2h-4z\"/>` +\n `</svg>`;\nconst I_TELEGRAM =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.7 5.4-1.24 5.85c-.09.41-.34.51-.69.32l-1.9-1.4-.92.88c-.1.1-.19.19-.38.19l.14-1.93 3.5-3.17c.15-.13-.03-.2-.24-.07l-4.32 2.72-1.86-.58c-.4-.13-.41-.4.09-.6l7.26-2.8c.34-.12.63.08.52.6z\"/>` +\n `</svg>`;\nconst I_LINEAR =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M.6 9.2a7.4 7.4 0 0 0 6.2 6.2c.3.04.44-.33.22-.55L1.15 9a.33.33 0 0 0-.55.22zM.5 6.9c-.01.13.04.25.13.34l8.13 8.13c.09.09.21.14.34.13a7.4 7.4 0 0 0 1.3-.26c.28-.08.36-.43.15-.63L1.4 5.45c-.2-.2-.55-.13-.63.15-.12.42-.21.86-.26 1.3zM2.05 4c-.1.13-.09.32.03.44l9.48 9.48c.12.12.31.13.44.03.3-.23.58-.48.85-.75.15-.15.15-.4 0-.55L3.35 3.15a.39.39 0 0 0-.55 0c-.27.27-.52.55-.75.85zM4.5 1.9a.35.35 0 0 0-.04.53l9.11 9.11c.16.16.42.13.53-.04A7.4 7.4 0 1 0 4.5 1.9z\"/>` +\n `</svg>`;\n\n/** Synthesize an Anchor for a free page-level note so downstream (dashboard/MCP) stays happy. */\nfunction pageAnchor(point: { x: number; y: number }): Anchor {\n return {\n tag: \"page\",\n cssPath: \"page\",\n xpath: \"\",\n testid: null,\n text: \"\",\n attrs: {},\n nthOfType: 1,\n rect: { x: Math.round(point.x), y: Math.round(point.y), w: 0, h: 0 },\n viewport: { w: window.innerWidth, h: window.innerHeight },\n };\n}\n\n/** Synthesize an Anchor for a free region so downstream (dashboard/MCP) stays happy. */\nfunction regionAnchor(region: RegionRect): Anchor {\n return {\n tag: \"region\",\n cssPath: `region ${Math.round(region.w)}×${Math.round(region.h)}`,\n xpath: \"\",\n testid: null,\n text: \"\",\n attrs: {},\n nthOfType: 1,\n rect: { x: Math.round(region.x), y: Math.round(region.y), w: Math.round(region.w), h: Math.round(region.h) },\n viewport: { w: window.innerWidth, h: window.innerHeight },\n };\n}\nfunction regionNote(region: RegionRect): string {\n return `<!-- Loupe free-region annotation: ${Math.round(region.w)}×${Math.round(region.h)}px at document (${Math.round(region.x)}, ${Math.round(region.y)}). No single DOM element — see the attached screenshot. -->`;\n}\n\nfunction describe(elx: Element): string {\n const testid = elx.getAttribute(\"data-testid\") || elx.getAttribute(\"data-test\");\n const tag = elx.tagName.toLowerCase();\n if (testid) return `${tag}[data-testid=\"${testid}\"]`;\n if (elx.id) return `${tag}#${elx.id}`;\n const txt = (elx.textContent || \"\").trim().replace(/\\s+/g, \" \").slice(0, 32);\n return txt ? `${tag} · “${txt}”` : tag;\n}\nfunction describeAnchor(c: Comment): string {\n if (c.kind === \"free\") return \"Free note · page-level\";\n return c.anchor.testid ? `[data-testid=\"${c.anchor.testid}\"]` : c.anchor.cssPath;\n}\n\n/**\n * A comment is done only at the last stage. Normalizing first means a row still\n * carrying a legacy status (`done`) reads correctly without a data migration.\n */\nfunction isResolved(c: Comment): boolean {\n return normalizeStatus(c.status) === \"resolved\";\n}\n","import { LoupeApp } from \"./app.js\";\nimport type { LoupeConfig } from \"./types.js\";\n\nexport type { LoupeConfig, LoupeUser, Comment, Anchor, RegionRect } from \"./types.js\";\n\nlet app: LoupeApp | null = null;\n\n/**\n * Initialize Loupe on the current page. Call once, after your app knows who the\n * user is. The toolbar renders only for the identified user.\n *\n * Loupe.init({ projectKey: \"pk_live_…\", user: { id, name, email }, userHmac });\n */\nexport function init(config: LoupeConfig): void {\n if (app) return; // idempotent\n if (!config?.projectKey) { console.error(\"[loupe] init requires a projectKey\"); return; }\n if (!config.user?.id) { console.error(\"[loupe] init requires user.id\"); return; }\n // NOTE: in production the backend verifies config.userHmac before serving data.\n app = new LoupeApp(config);\n const boot = () => app!.start();\n if (document.readyState === \"loading\") document.addEventListener(\"DOMContentLoaded\", boot);\n else boot();\n}\n\n/** Tear down the toolbar and all listeners. */\nexport function destroy(): void {\n app?.destroy();\n app = null;\n}\n"],"mappings":";AACO,IAAM;AAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["el","svg","el","svg","el","blobToDataUrl","init","uid","x","elx"]}
|
|
1
|
+
{"version":3,"sources":["../src/styles.ts","../src/fingerprint.ts","../../../node_modules/modern-screenshot/dist/index.mjs","../src/capture.ts","../src/store.ts","../src/http-adapter.ts","../../shared/dist/index.js","../src/app.ts","../src/index.ts"],"sourcesContent":["// Scoped to the Shadow DOM — none of this leaks to (or is affected by) the host page.\nexport const STYLES = /* css */ `\n:host { all: initial; }\n* { box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif; }\n\n/* Theme tokens live on :host (inside the Shadow DOM :root matches nothing).\n Dark is the default; the host element gets .theme-light to flip to light. */\n:host {\n --accent: #6b73e6;\n --pin: #ff5842;\n --bg: #14161d;\n --bg-2: #1b1e27;\n --bg-3: #262a36;\n --ink: #e7e9f0;\n --muted: #9aa0af;\n --line: #2b2f3b;\n --shadow: 0 12px 48px rgba(0,0,0,.42);\n}\n:host(.theme-light) {\n --accent: #4a55d6;\n --pin: #ff5842;\n --bg: #ffffff;\n --bg-2: #f6f7fb;\n --bg-3: #eceef4;\n --ink: #16181f;\n --muted: #6b7180;\n --line: #e2e5ee;\n --shadow: 0 12px 40px rgba(0,0,0,.22);\n}\n\n.overlay { position: fixed; inset: 0; z-index: 2147483000; pointer-events: none; }\n\n/* inspector highlight */\n.hl {\n position: fixed; pointer-events: none; z-index: 2147483001;\n border: 2px solid var(--accent);\n background: rgba(107, 115, 230, 0.12);\n border-radius: 4px; display: none;\n transition: all 60ms linear;\n}\n.hl .tip {\n position: absolute; top: -24px; left: 0; background: var(--accent); color: #fff;\n font-size: 11px; font-weight: 600; padding: 2px 7px; border-radius: 4px; white-space: nowrap;\n font-family: ui-monospace, Menlo, monospace;\n}\n\n/* region selection (during drag) + active-comment outline */\n.selbox {\n position: fixed; pointer-events: none; z-index: 2147483001; display: none;\n border: 2px dashed var(--accent); background: rgba(107, 115, 230, 0.14); border-radius: 4px;\n}\n.region-box {\n position: fixed; pointer-events: none; z-index: 2147483001; display: none;\n border: 2px solid var(--pin); border-radius: 4px;\n box-shadow: 0 0 0 2px rgba(255, 88, 66, .25), 0 4px 16px rgba(0,0,0,.25);\n}\n\n/* pins */\n.pin {\n position: fixed; pointer-events: auto; z-index: 2147483002;\n width: 26px; height: 26px; border-radius: 50% 50% 50% 2px;\n background: var(--pin); color: #fff; border: 2px solid #fff;\n font-size: 12px; font-weight: 700; cursor: pointer;\n box-shadow: 0 2px 8px rgba(0,0,0,.35);\n display: grid; place-items: center; transform: translate(-4px, -4px);\n transition: transform 80ms ease;\n}\n.pin:hover { transform: translate(-4px, -4px) scale(1.12); }\n.pin.detached { background: #9aa0af; }\n.pin.done { background: #10935a; }\n.pin.free { background: var(--accent); border-radius: 50% 50% 2px 50%; }\n.pin.free.done { background: #10935a; }\n.pin.active { outline: 3px solid rgba(107,115,230,.45); }\n/* The quick-action \"Markers\" toggle hides every pin without discarding it.\n !important beats the inline display the pin positioner sets on each frame. */\n.overlay.hide-pins .pin { display: none !important; }\n\n/* --------------------------------------------------------------- FAB cluster */\n/* The collapsed state: a primary brand button (with the comment count) plus the\n quick actions that expand out of it. Replaces the old single launcher. */\n.fab-cluster {\n position: fixed; z-index: 2147483003; bottom: 20px; right: 20px;\n display: none; flex-direction: column; align-items: flex-end; gap: 10px;\n}\n.fab-cluster.show { display: flex; }\n\n.fab-minis { display: none; flex-direction: column; align-items: flex-end; gap: 10px; }\n.fab-cluster.expanded .fab-minis { display: flex; }\n.fab-cluster.expanded .fab-minis .fab-mini { animation: loupe-fab-in 180ms cubic-bezier(.16, 1, .3, 1) both; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(1) { animation-delay: 0ms; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(2) { animation-delay: 30ms; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(3) { animation-delay: 60ms; }\n.fab-cluster.expanded .fab-minis .fab-mini:nth-child(4) { animation-delay: 90ms; }\n@keyframes loupe-fab-in { from { opacity: 0; transform: translateY(8px) scale(.9); } to { opacity: 1; transform: none; } }\n\n.fab-mini {\n position: relative; width: 40px; height: 40px; border-radius: 50%; padding: 0;\n border: 1px solid var(--line); background: var(--bg); color: var(--ink);\n cursor: pointer; display: inline-flex; align-items: center; justify-content: center;\n box-shadow: var(--shadow);\n}\n.fab-mini:hover { border-color: var(--accent); color: var(--accent); }\n.fab-mini.on { background: var(--accent); border-color: var(--accent); color: #fff; }\n.fab-mini.on:hover { color: #fff; }\n.fab-mini svg { display: block; width: 16px; height: 16px; }\n/* The action's label, revealed on hover so the collapsed cluster stays calm. */\n.fab-mini .fab-tip {\n position: absolute; right: calc(100% + 8px); top: 50%; transform: translateY(-50%);\n background: var(--bg); color: var(--ink); border: 1px solid var(--line);\n border-radius: 7px; padding: 4px 8px; font-size: 11px; font-weight: 600; white-space: nowrap;\n box-shadow: var(--shadow); opacity: 0; pointer-events: none; transition: opacity 120ms ease;\n}\n.fab-mini:hover .fab-tip { opacity: 1; }\n\n.launcher {\n position: relative; width: 46px; height: 46px; border-radius: 50%; padding: 0;\n border: 1px solid var(--line); background: var(--bg-2); color: var(--ink);\n cursor: pointer; display: inline-flex; align-items: center; justify-content: center;\n box-shadow: var(--shadow);\n}\n.launcher:hover { border-color: var(--accent); }\n.launcher .logo { font-size: 24px; line-height: 1; color: var(--accent); }\n/* Chevron pinned to the corner: up = actions are tucked away, down = they are out. */\n.launcher .lchev {\n position: absolute; right: -3px; bottom: -3px; width: 18px; height: 18px; border-radius: 50%;\n background: var(--bg); border: 1px solid var(--line); color: var(--muted);\n display: grid; place-items: center; transition: transform 160ms cubic-bezier(.16, 1, .3, 1);\n}\n.launcher .lchev svg { width: 11px; height: 11px; display: block; }\n.fab-cluster.expanded .launcher .lchev { transform: rotate(180deg); }\n.launcher .lcount {\n position: absolute; top: -5px; right: -5px; background: var(--pin); color: #fff;\n font-size: 10px; font-weight: 700; line-height: 1; border-radius: 999px; padding: 3px 6px;\n border: 2px solid var(--bg);\n}\n.launcher .lcount:empty { display: none; }\n@media (prefers-reduced-motion: reduce) {\n .fab-cluster.expanded .fab-minis .fab-mini { animation: none; }\n .launcher .lchev { transition: none; }\n .fab-mini .fab-tip { transition: none; }\n}\n\n/* --------------------------------------------------------------------- dock */\n/* The control panel. One container, four dock modes (left/right/bottom/float),\n overlaying the host page (never reflows it). */\n.dock {\n position: fixed; z-index: 2147483003; pointer-events: auto;\n display: none; flex-direction: column;\n background: var(--bg); color: var(--ink);\n border: 1px solid var(--line); box-shadow: var(--shadow);\n overflow: hidden; font-size: 13px;\n}\n.dock.open { display: flex; }\n.dock.mode-right { top: 0; right: 0; bottom: 0; width: 360px; border-width: 0 0 0 1px; }\n.dock.mode-left { top: 0; left: 0; bottom: 0; width: 360px; border-width: 0 1px 0 0; }\n.dock.mode-bottom { left: 0; right: 0; bottom: 0; height: 320px; border-width: 1px 0 0 0; }\n.dock.mode-float { border-radius: 14px; /* left/top/width/height set inline */ }\n\n/* header: brand + dock controls */\n.dhead {\n display: flex; align-items: center; gap: 8px; flex: none;\n padding: 8px 10px; border-bottom: 1px solid var(--line); background: var(--bg-2);\n}\n.dock.mode-float .dhead { cursor: grab; }\n.dock.mode-float.dragging .dhead { cursor: grabbing; }\n.dock.dragging { user-select: none; }\n.brand { display: flex; align-items: center; gap: 8px; font-weight: 700; letter-spacing: -.01em; }\n.brand .logo { font-size: 16px; line-height: 1; color: var(--accent); flex: none; }\n.brand .title { font-size: 13px; }\n.dctl { display: flex; align-items: center; gap: 2px; margin-left: auto; }\n.dctl button {\n display: inline-flex; align-items: center; justify-content: center;\n width: 26px; height: 26px; padding: 0; border: 0; border-radius: 6px;\n background: transparent; color: var(--muted); cursor: pointer;\n}\n.dctl button:hover { background: var(--bg-3); color: var(--ink); }\n.dctl button.on { background: var(--bg-3); color: var(--accent); }\n.dctl svg { display: block; }\n.dctl .gap { width: 1px; height: 16px; background: var(--line); margin: 0 4px; flex: none; }\n\n/* tools row */\n.tools { display: flex; gap: 6px; flex: none; padding: 10px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }\n.tools button {\n display: flex; align-items: center; gap: 6px; padding: 7px 10px; line-height: 1;\n border: 1px solid var(--line); border-radius: 8px; background: var(--bg-2); color: var(--ink);\n font-size: 12px; font-weight: 600; cursor: pointer;\n}\n.tools button:hover { background: var(--bg-3); }\n.tools button.on { background: var(--accent); border-color: var(--accent); color: #fff; }\n.tools .ico { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; }\n.tools .ico svg { width: 15px; height: 15px; display: block; }\n\n/* list */\n.listhead {\n display: flex; align-items: center; gap: 8px; flex: none; padding: 12px 12px 6px;\n font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700;\n}\n.count { background: var(--pin); color: #fff; font-size: 11px; font-weight: 700; line-height: 1; border-radius: 999px; padding: 3px 7px; }\n.list { flex: 1; overflow-y: auto; padding: 6px 10px 12px; display: flex; flex-direction: column; gap: 8px; }\n.empty { color: var(--muted); font-size: 13px; padding: 24px 12px; text-align: center; line-height: 1.5; }\n/* bottom dock lays the list out in flowing columns so it isn't a tall single strip */\n.dock.mode-bottom .list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); align-content: start; }\n\n.item { border: 1px solid var(--line); border-radius: 10px; padding: 10px; cursor: pointer; background: var(--bg-2); }\n.item:hover { border-color: var(--accent); }\n.item .top { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }\n.item .num { background: var(--pin); color: #fff; width: 20px; height: 20px; border-radius: 50%; font-size: 11px; font-weight: 700; display: grid; place-items: center; flex: none; }\n.item .num.detached { background: #9aa0af; }\n.item .num.done { background: #10935a; }\n.item .who { font-size: 12px; font-weight: 600; }\n.item .device { font-size: 10px; color: var(--muted); background: var(--bg-3); border-radius: 999px; padding: 1px 7px; white-space: nowrap; }\n.item .body { font-size: 13px; line-height: 1.4; }\n.item .meta { font-size: 11px; color: var(--muted); margin-top: 6px; font-family: ui-monospace, Menlo, monospace; word-break: break-all; }\n.item .badge { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 1px 6px; border-radius: 5px; margin-left: auto; white-space: nowrap; }\n.badge.detached { background: var(--bg-3); color: var(--muted); }\n.badge.done { background: #d8f0e4; color: #10935a; }\n.item .actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }\n.item .actions button { font-size: 11px; border: 1px solid var(--line); background: var(--bg-3); border-radius: 6px; padding: 4px 8px; cursor: pointer; color: var(--ink); }\n.item .actions button:hover { border-color: var(--accent); }\n.item img.shot { width: 100%; border-radius: 6px; margin-top: 8px; border: 1px solid var(--line); }\n.item video.shot { width: 100%; border-radius: 6px; margin-top: 8px; border: 1px solid var(--line); }\n.item .caret { margin-left: auto; color: var(--muted); font-size: 11px; }\n.item .summary { font-size: 13px; font-weight: 600; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.item .detail { margin-top: 6px; }\n.item.collapsed .detail { display: none; }\n.listhead .search {\n margin-left: auto; flex: 1; max-width: 170px; font-size: 12px; text-transform: none; letter-spacing: 0;\n padding: 4px 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg-2); color: var(--ink); outline: none;\n}\n.listhead .search:focus { border-color: var(--accent); }\n\n/* float resize grip (bottom-right corner) */\n.resize { display: none; position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 1; }\n.dock.mode-float .resize { display: block; }\n.resize::after {\n content: \"\"; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px;\n border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); opacity: .7;\n}\n\n/* composer popover */\n.composer {\n position: fixed; z-index: 2147483004; pointer-events: auto; width: 320px;\n background: var(--bg); color: var(--ink); border: 1px solid var(--line);\n border-radius: 12px; box-shadow: var(--shadow); padding: 12px; display: none;\n}\n.composer .target {\n font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--accent);\n background: var(--bg-2); border-radius: 6px; padding: 5px 8px; margin-bottom: 8px;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n}\n.composer textarea {\n width: 100%; min-height: 68px; resize: vertical; border: 1px solid var(--line);\n border-radius: 8px; padding: 8px; font-size: 13px; color: var(--ink); background: var(--bg-2); outline: none;\n}\n.composer textarea:focus { border-color: var(--accent); }\n.composer .row { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; gap: 8px; }\n.composer label.chk { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 6px; cursor: pointer; }\n.composer .btns { display: flex; gap: 6px; }\n.composer button { border: 0; border-radius: 8px; font-size: 13px; font-weight: 600; padding: 7px 12px; cursor: pointer; }\n.composer .primary { background: var(--accent); color: #fff; }\n.composer .primary:disabled { opacity: .5; cursor: default; }\n.composer .ghost { background: var(--bg-3); color: var(--ink); }\n.composer input.title {\n width: 100%; border: 1px solid var(--line); border-radius: 8px; padding: 8px; margin-bottom: 8px;\n font-size: 13px; font-weight: 600; color: var(--ink); background: var(--bg-2); outline: none;\n}\n.composer input.title:focus { border-color: var(--accent); }\n.composer .attach { margin-top: 8px; }\n.composer .pick {\n width: 100%; border: 1px dashed var(--line); background: transparent; color: var(--muted);\n border-radius: 8px; padding: 7px; font-size: 12px; font-weight: 600; cursor: pointer;\n}\n.composer .pick:hover { border-color: var(--accent); color: var(--accent); }\n.composer .chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }\n.composer .chip {\n display: inline-flex; align-items: center; gap: 4px; max-width: 100%;\n background: var(--bg-3); border-radius: 6px; padding: 2px 4px 2px 7px; font-size: 11px; color: var(--ink);\n}\n.composer .chip .x { border: 0; background: transparent; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 0 2px; }\n.composer .err { color: var(--pin); font-size: 11px; margin-top: 4px; }\n.composer .err:empty { display: none; }\n\n/* Priority + change-type pickers, side by side under the attachments. */\n.composer .meta2 { display: flex; gap: 6px; margin-top: 8px; }\n.composer select.mini {\n flex: 1; min-width: 0; font-size: 12px; padding: 6px 7px; border-radius: 7px;\n border: 1px solid var(--line); background: var(--bg-2); color: var(--ink); outline: none;\n}\n.composer select.mini:focus { border-color: var(--accent); }\n\n/* ------------------------------------------------------------ sidebar tabs */\n.tabs { display: flex; gap: 4px; flex: none; padding: 8px 10px 0; border-bottom: 1px solid var(--line); }\n.tabs .tab {\n flex: 1; padding: 8px 10px; border: 0; border-bottom: 2px solid transparent;\n background: transparent; color: var(--muted); font-size: 12px; font-weight: 700; cursor: pointer;\n border-radius: 6px 6px 0 0;\n}\n.tabs .tab:hover { color: var(--ink); background: var(--bg-2); }\n.tabs .tab.on { color: var(--accent); border-bottom-color: var(--accent); }\n\n/* Two sidebar pages: only the active one shows. */\n.view { display: none; }\n.dock.tab-comments .comments-view { display: flex; flex-direction: column; flex: 1; min-height: 0; }\n.dock.tab-connect .connect-view { display: block; flex: 1; overflow-y: auto; }\n\n/* recording marker + video in the list */\n.item .rectag { font-size: 10px; font-weight: 700; color: var(--pin); background: var(--bg-3); border-radius: 999px; padding: 1px 7px; white-space: nowrap; }\n.item video.shot { width: 100%; border-radius: 6px; margin-top: 8px; border: 1px solid var(--line); background: #000; display: block; }\n\n/* ------------------------------------------------ \"integrates with\" footer */\n.integrations { flex: none; padding: 12px 12px 14px; border-top: 1px solid var(--line); text-align: center; }\n.integrations .ilabel { font-size: 10px; letter-spacing: .12em; color: var(--muted); font-weight: 700; margin-bottom: 8px; }\n.integrations .irow { display: flex; align-items: center; justify-content: center; gap: 14px; }\n.integrations .ibtn { color: var(--muted); display: inline-flex; opacity: .8; cursor: default; }\n.integrations .ibtn:hover { color: var(--accent); opacity: 1; }\n.integrations .ibtn svg { display: block; }\n\n/* ------------------------------------------------------- Connect Claude page */\n.connect-view { padding: 16px 14px 20px; }\n.connect-hero { text-align: center; margin-bottom: 18px; }\n.connect-hero .chero-logo { font-size: 34px; line-height: 1; color: var(--accent); }\n.connect-hero .chero-title { font-size: 18px; font-weight: 800; letter-spacing: -.02em; margin-top: 8px; }\n.connect-hero .chero-sub { font-size: 12.5px; color: var(--muted); line-height: 1.45; margin-top: 6px; }\n.accentink { color: var(--accent); }\n.connect-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }\n.connect-steps .cstep-t { font-size: 13px; font-weight: 700; }\n.connect-steps .cstep-d { font-size: 12px; color: var(--muted); line-height: 1.45; margin-top: 3px; }\n.connect-steps .cstep-code {\n margin: 8px 0 0; padding: 10px; background: var(--bg-2); border: 1px solid var(--line);\n border-radius: 8px; font-family: ui-monospace, Menlo, monospace; font-size: 11px; line-height: 1.4;\n color: var(--ink); white-space: pre; overflow-x: auto;\n}\n\n/* ------------------------------------------------------- recording indicator */\n.recbar {\n position: fixed; z-index: 2147483005; top: 16px; left: 50%; transform: translateX(-50%);\n display: none; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px;\n background: var(--bg); color: var(--ink); border: 1px solid var(--pin);\n box-shadow: var(--shadow); font-size: 12px; font-weight: 600; cursor: pointer;\n}\n.recbar.show { display: inline-flex; }\n.recbar b { color: var(--pin); }\n.recbar .recdot { width: 9px; height: 9px; border-radius: 50%; background: var(--pin); animation: loupe-recpulse 1.1s infinite; }\n@keyframes loupe-recpulse { 0%,100% { opacity: 1; } 50% { opacity: .25; } }\n@media (prefers-reduced-motion: reduce) { .recbar .recdot { animation: none; } }\n\n/* Mobile: left/right/float docking is a desktop affordance. On small screens the\n panel collapses to a bottom sheet that OVERLAYS the page (pushing a side dock\n here would squeeze the page to a useless sliver), regardless of the chosen dock\n mode. !important overrides the inline geometry JS applies for float mode. */\n@media (max-width: 640px) {\n .dock.open {\n top: auto !important; left: 0 !important; right: 0 !important; bottom: 0 !important;\n width: auto !important; height: 76vh !important;\n border-width: 1px 0 0 0 !important; border-radius: 16px 16px 0 0 !important;\n }\n .dctl [data-dock], .dctl .gap { display: none; } /* dock positions don't apply on mobile */\n .resize { display: none !important; }\n .tools button { flex: 1; justify-content: center; } /* full-width tap targets */\n .dock.mode-bottom .list { grid-template-columns: 1fr; }\n .fab-cluster { bottom: 16px; right: 16px; }\n /* While a tool is active, shrink the sheet to just header + tools so most of the\n page stays visible and tappable; the list returns when the tool closes. */\n .dock.inspecting { height: auto !important; }\n .dock.inspecting .listhead, .dock.inspecting .list { display: none; }\n /* The composer is a bottom sheet on a phone: full width, thumb-reachable, and it\n scrolls when the on-screen keyboard is up. JS sets its position inline (hence the\n !important) — on small screens the sheet wins. */\n .composer {\n top: auto !important; left: 0 !important; right: 0 !important; bottom: 0 !important;\n width: auto !important; max-height: 80vh; overflow-y: auto;\n border-radius: 16px 16px 0 0; padding-bottom: 16px;\n }\n}\n`;\n","import type { Anchor, ResolveResult } from \"./types.js\";\n\n// ---- config ----------------------------------------------------------------\n\nconst TEXT_MAX = 120;\nconst ATTR_KEYS = [\"role\", \"aria-label\", \"name\", \"type\", \"alt\", \"href\", \"placeholder\", \"title\"];\n/** Minimum composite score to accept a scan match. Below this we treat the element as gone. */\nconst ACCEPT_THRESHOLD = 0.5;\n/** Weights for the composite similarity score (sum need not be 1; we normalize). */\nconst W = { tag: 0.12, text: 0.34, attrs: 0.22, testid: 0.22, cssPath: 0.2, position: 0.1 };\n\n// ---- capture ----------------------------------------------------------------\n\nexport function captureAnchor(el: Element): Anchor {\n const rect = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n cssPath: cssPath(el),\n xpath: xPath(el),\n testid: stableId(el),\n text: normText(el.textContent),\n attrs: readAttrs(el),\n nthOfType: nthOfType(el),\n rect: {\n x: Math.round(rect.left + window.scrollX),\n y: Math.round(rect.top + window.scrollY),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n viewport: { w: window.innerWidth, h: window.innerHeight },\n };\n}\n\n// ---- resolve ----------------------------------------------------------------\n\n/**\n * Try to re-locate the element described by `anchor` on the current page.\n * Returns the best candidate above threshold, or null (→ caller falls back to\n * a coordinate pin on the screenshot). Never returns an element inside our own UI.\n */\nexport function resolveAnchor(anchor: Anchor, root: ParentNode = document): ResolveResult | null {\n // 1. Stable id / testid — the strongest signal. Accept immediately if unique.\n if (anchor.testid) {\n const byTestid = safeQueryAll(root, `[data-testid=\"${cssStr(anchor.testid)}\"], [data-test=\"${cssStr(anchor.testid)}\"]`);\n const byId = document.getElementById(anchor.testid);\n const hits = dedupe([...byTestid, ...(byId ? [byId] : [])]).filter(usable);\n if (hits.length === 1) return { element: hits[0]!, score: 0.98, via: \"testid\" };\n // Multiple matches → fall through to scoring to disambiguate.\n }\n\n // 1.5. A cssPath rooted at a stable id/testid + structural position is\n // high-confidence even when the element's own text/content has changed\n // (e.g. a value that updates on redeploy). Require the tag to still match.\n if (/^(\\[data-testid=|#)/.test(anchor.cssPath)) {\n const hits = safeQueryAll(root, anchor.cssPath).filter(usable);\n if (hits.length === 1 && hits[0]!.tagName.toLowerCase() === anchor.tag) {\n return { element: hits[0]!, score: 0.9, via: \"cssPath\" };\n }\n }\n\n const candidates = new Map<Element, ResolveResult[\"via\"]>();\n const consider = (el: Element | null, via: ResolveResult[\"via\"]) => {\n if (el && usable(el) && !candidates.has(el)) candidates.set(el, via);\n };\n\n // 2. Exact locators.\n consider(safeQuery(root, anchor.cssPath), \"cssPath\");\n consider(byXPath(anchor.xpath), \"xpath\");\n for (const el of safeQueryAll(root, anchor.tag)) consider(el, \"scan\");\n\n // 3. Broaden by text when the tag scan is too narrow (e.g. wrapper changed tag).\n if (anchor.text) {\n for (const el of safeQueryAll(root, \"*\")) {\n if (candidates.size > 4000) break; // safety cap on huge pages\n if (normText(el.textContent) === anchor.text) consider(el, \"scan\");\n }\n }\n\n let best: ResolveResult | null = null;\n for (const [el, via] of candidates) {\n const score = similarity(anchor, el, via);\n if (!best || score > best.score) best = { element: el, score, via };\n }\n return best && best.score >= ACCEPT_THRESHOLD ? best : null;\n}\n\nfunction similarity(a: Anchor, el: Element, via: ResolveResult[\"via\"]): number {\n let sum = 0;\n let total = 0;\n\n const add = (w: number, v: number) => { sum += w * v; total += w; };\n\n add(W.tag, el.tagName.toLowerCase() === a.tag ? 1 : 0);\n\n if (a.text) {\n const t = normText(el.textContent);\n add(W.text, t === a.text ? 1 : t && (t.includes(a.text) || a.text.includes(t)) ? 0.5 : 0);\n }\n\n const attrKeys = Object.keys(a.attrs);\n if (attrKeys.length) {\n let matched = 0;\n for (const k of attrKeys) if (el.getAttribute(k) === a.attrs[k]) matched++;\n add(W.attrs, matched / attrKeys.length);\n }\n\n if (a.testid) add(W.testid, stableId(el) === a.testid ? 1 : 0);\n\n add(W.cssPath, via === \"cssPath\" ? 1 : 0);\n\n // Positional proximity — normalized by the (possibly changed) viewport diagonal.\n const r = el.getBoundingClientRect();\n const cx = r.left + window.scrollX + r.width / 2;\n const cy = r.top + window.scrollY + r.height / 2;\n const ax = a.rect.x + a.rect.w / 2;\n const ay = a.rect.y + a.rect.h / 2;\n const diag = Math.hypot(a.viewport.w, a.viewport.h) || 1;\n const dist = Math.hypot(cx - ax, cy - ay);\n add(W.position, Math.max(0, 1 - dist / diag));\n\n return total ? sum / total : 0;\n}\n\n// ---- locator builders -------------------------------------------------------\n\nfunction cssPath(el: Element): string {\n const segs: string[] = [];\n let node: Element | null = el;\n while (node && node.nodeType === 1 && node !== document.documentElement) {\n const id = node.getAttribute(\"id\");\n const testid = node.getAttribute(\"data-testid\") || node.getAttribute(\"data-test\");\n if (id && isStable(id)) { segs.unshift(`#${cssEsc(id)}`); break; }\n if (testid) { segs.unshift(`[data-testid=\"${cssStr(testid)}\"]`); break; }\n segs.unshift(`${node.tagName.toLowerCase()}:nth-of-type(${nthOfType(node)})`);\n node = node.parentElement;\n if (node === document.body) { segs.unshift(\"body\"); break; }\n }\n return segs.join(\" > \");\n}\n\nfunction xPath(el: Element): string {\n const segs: string[] = [];\n let node: Element | null = el;\n while (node && node.nodeType === 1 && node !== document.documentElement) {\n segs.unshift(`${node.tagName.toLowerCase()}[${nthOfType(node)}]`);\n node = node.parentElement;\n }\n return \"/html/\" + segs.join(\"/\");\n}\n\n// ---- small helpers ----------------------------------------------------------\n\nfunction nthOfType(el: Element): number {\n let i = 1;\n let sib = el.previousElementSibling;\n while (sib) {\n if (sib.tagName === el.tagName) i++;\n sib = sib.previousElementSibling;\n }\n return i;\n}\n\nfunction stableId(el: Element): string | null {\n const testid = el.getAttribute(\"data-testid\") || el.getAttribute(\"data-test\");\n if (testid) return testid;\n const id = el.getAttribute(\"id\");\n return id && isStable(id) ? id : null;\n}\n\n/** Reject framework-generated ids (e.g. \":r3:\", \"ember42\", long hashes). */\nfunction isStable(id: string): boolean {\n if (id.length > 40) return false;\n if (/^(ember|react|radix|headlessui|:r)/i.test(id)) return false;\n if (/[:]/.test(id)) return false;\n return true;\n}\n\nfunction readAttrs(el: Element): Record<string, string> {\n const out: Record<string, string> = {};\n for (const k of ATTR_KEYS) {\n const v = el.getAttribute(k);\n if (v != null && v !== \"\") out[k] = v.length > 200 ? v.slice(0, 200) : v;\n }\n return out;\n}\n\nfunction normText(t: string | null): string {\n return (t || \"\").replace(/\\s+/g, \" \").trim().slice(0, TEXT_MAX);\n}\n\n/** Exclude anything inside our own Shadow-DOM host and non-visible nodes. */\nfunction usable(el: Element): boolean {\n if (el.id === \"loupe-root\" || el.closest(\"#loupe-root\")) return false;\n if (el === document.body || el === document.documentElement) return false;\n return true;\n}\n\nfunction byXPath(xp: string): Element | null {\n try {\n const r = document.evaluate(xp, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n return r.singleNodeValue instanceof Element ? r.singleNodeValue : null;\n } catch {\n return null;\n }\n}\n\nfunction safeQuery(root: ParentNode, sel: string): Element | null {\n try { return sel ? root.querySelector(sel) : null; } catch { return null; }\n}\nfunction safeQueryAll(root: ParentNode, sel: string): Element[] {\n try { return sel ? Array.from(root.querySelectorAll(sel)) : []; } catch { return []; }\n}\nfunction dedupe(els: Element[]): Element[] {\n return Array.from(new Set(els));\n}\nfunction cssEsc(s: string): string {\n return (window.CSS && CSS.escape) ? CSS.escape(s) : s.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n/** Escape a value for use inside a double-quoted attribute selector. */\nfunction cssStr(s: string): string {\n return s.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n","function changeJpegDpi(uint8Array, dpi) {\n uint8Array[13] = 1;\n uint8Array[14] = dpi >> 8;\n uint8Array[15] = dpi & 255;\n uint8Array[16] = dpi >> 8;\n uint8Array[17] = dpi & 255;\n return uint8Array;\n}\n\nconst _P = \"p\".charCodeAt(0);\nconst _H = \"H\".charCodeAt(0);\nconst _Y = \"Y\".charCodeAt(0);\nconst _S = \"s\".charCodeAt(0);\nlet pngDataTable;\nfunction createPngDataTable() {\n const crcTable = new Int32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;\n }\n crcTable[n] = c;\n }\n return crcTable;\n}\nfunction calcCrc(uint8Array) {\n let c = -1;\n if (!pngDataTable)\n pngDataTable = createPngDataTable();\n for (let n = 0; n < uint8Array.length; n++) {\n c = pngDataTable[(c ^ uint8Array[n]) & 255] ^ c >>> 8;\n }\n return c ^ -1;\n}\nfunction searchStartOfPhys(uint8Array) {\n const length = uint8Array.length - 1;\n for (let i = length; i >= 4; i--) {\n if (uint8Array[i - 4] === 9 && uint8Array[i - 3] === _P && uint8Array[i - 2] === _H && uint8Array[i - 1] === _Y && uint8Array[i] === _S) {\n return i - 3;\n }\n }\n return 0;\n}\nfunction changePngDpi(uint8Array, dpi, overwritepHYs = false) {\n const physChunk = new Uint8Array(13);\n dpi *= 39.3701;\n physChunk[0] = _P;\n physChunk[1] = _H;\n physChunk[2] = _Y;\n physChunk[3] = _S;\n physChunk[4] = dpi >>> 24;\n physChunk[5] = dpi >>> 16;\n physChunk[6] = dpi >>> 8;\n physChunk[7] = dpi & 255;\n physChunk[8] = physChunk[4];\n physChunk[9] = physChunk[5];\n physChunk[10] = physChunk[6];\n physChunk[11] = physChunk[7];\n physChunk[12] = 1;\n const crc = calcCrc(physChunk);\n const crcChunk = new Uint8Array(4);\n crcChunk[0] = crc >>> 24;\n crcChunk[1] = crc >>> 16;\n crcChunk[2] = crc >>> 8;\n crcChunk[3] = crc & 255;\n if (overwritepHYs) {\n const startingIndex = searchStartOfPhys(uint8Array);\n uint8Array.set(physChunk, startingIndex);\n uint8Array.set(crcChunk, startingIndex + 13);\n return uint8Array;\n } else {\n const chunkLength = new Uint8Array(4);\n chunkLength[0] = 0;\n chunkLength[1] = 0;\n chunkLength[2] = 0;\n chunkLength[3] = 9;\n const finalHeader = new Uint8Array(54);\n finalHeader.set(uint8Array, 0);\n finalHeader.set(chunkLength, 33);\n finalHeader.set(physChunk, 37);\n finalHeader.set(crcChunk, 50);\n return finalHeader;\n }\n}\nconst b64PhysSignature1 = \"AAlwSFlz\";\nconst b64PhysSignature2 = \"AAAJcEhZ\";\nconst b64PhysSignature3 = \"AAAACXBI\";\nfunction detectPhysChunkFromDataUrl(dataUrl) {\n let b64index = dataUrl.indexOf(b64PhysSignature1);\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature2);\n }\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature3);\n }\n return b64index;\n}\n\nconst PREFIX = \"[modern-screenshot]\";\nconst IN_BROWSER = typeof window !== \"undefined\";\nconst SUPPORT_WEB_WORKER = IN_BROWSER && \"Worker\" in window;\nconst SUPPORT_ATOB = IN_BROWSER && \"atob\" in window;\nconst SUPPORT_BTOA = IN_BROWSER && \"btoa\" in window;\nconst USER_AGENT = IN_BROWSER ? window.navigator?.userAgent : \"\";\nconst IN_CHROME = USER_AGENT.includes(\"Chrome\");\nconst IN_SAFARI = USER_AGENT.includes(\"AppleWebKit\") && !IN_CHROME;\nconst IN_FIREFOX = USER_AGENT.includes(\"Firefox\");\nconst isContext = (value) => value && \"__CONTEXT__\" in value;\nconst isCssFontFaceRule = (rule) => rule.constructor.name === \"CSSFontFaceRule\";\nconst isCSSImportRule = (rule) => rule.constructor.name === \"CSSImportRule\";\nconst isLayerBlockRule = (rule) => rule.constructor.name === \"CSSLayerBlockRule\";\nconst isElementNode = (node) => node.nodeType === 1;\nconst isSVGElementNode = (node) => typeof node.className === \"object\";\nconst isSVGImageElementNode = (node) => node.tagName === \"image\";\nconst isSVGUseElementNode = (node) => node.tagName === \"use\";\nconst isHTMLElementNode = (node) => isElementNode(node) && typeof node.style !== \"undefined\" && !isSVGElementNode(node);\nconst isCommentNode = (node) => node.nodeType === 8;\nconst isTextNode = (node) => node.nodeType === 3;\nconst isImageElement = (node) => node.tagName === \"IMG\";\nconst isVideoElement = (node) => node.tagName === \"VIDEO\";\nconst isCanvasElement = (node) => node.tagName === \"CANVAS\";\nconst isTextareaElement = (node) => node.tagName === \"TEXTAREA\";\nconst isInputElement = (node) => node.tagName === \"INPUT\";\nconst isStyleElement = (node) => node.tagName === \"STYLE\";\nconst isScriptElement = (node) => node.tagName === \"SCRIPT\";\nconst isSelectElement = (node) => node.tagName === \"SELECT\";\nconst isSlotElement = (node) => node.tagName === \"SLOT\";\nconst isIFrameElement = (node) => node.tagName === \"IFRAME\";\nconst consoleWarn = (...args) => console.warn(PREFIX, ...args);\nfunction supportWebp(ownerDocument) {\n const canvas = ownerDocument?.createElement?.(\"canvas\");\n if (canvas) {\n canvas.height = canvas.width = 1;\n }\n return Boolean(canvas) && \"toDataURL\" in canvas && Boolean(canvas.toDataURL(\"image/webp\").includes(\"image/webp\"));\n}\nconst isDataUrl = (url) => url.startsWith(\"data:\");\nfunction resolveUrl(url, baseUrl) {\n if (url.match(/^[a-z]+:\\/\\//i))\n return url;\n if (IN_BROWSER && url.match(/^\\/\\//))\n return window.location.protocol + url;\n if (url.match(/^[a-z]+:/i))\n return url;\n if (!IN_BROWSER)\n return url;\n const doc = getDocument().implementation.createHTMLDocument();\n const base = doc.createElement(\"base\");\n const a = doc.createElement(\"a\");\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl)\n base.href = baseUrl;\n a.href = url;\n return a.href;\n}\nfunction getDocument(target) {\n return (target && isElementNode(target) ? target?.ownerDocument : target) ?? window.document;\n}\nconst XMLNS = \"http://www.w3.org/2000/svg\";\nfunction createSvg(width, height, ownerDocument) {\n const svg = getDocument(ownerDocument).createElementNS(XMLNS, \"svg\");\n svg.setAttributeNS(null, \"width\", width.toString());\n svg.setAttributeNS(null, \"height\", height.toString());\n svg.setAttributeNS(null, \"viewBox\", `0 0 ${width} ${height}`);\n return svg;\n}\nfunction svgToDataUrl(svg, removeControlCharacter) {\n let xhtml = new XMLSerializer().serializeToString(svg);\n if (removeControlCharacter) {\n xhtml = xhtml.replace(/[\\u0000-\\u0008\\v\\f\\u000E-\\u001F\\uD800-\\uDFFF\\uFFFE\\uFFFF]/gu, \"\");\n }\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(xhtml)}`;\n}\nasync function canvasToBlob(canvas, type = \"image/png\", quality = 1) {\n try {\n return await new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error(\"Blob is null\"));\n }\n }, type, quality);\n });\n } catch (error) {\n if (SUPPORT_ATOB) {\n return dataUrlToBlob(canvas.toDataURL(type, quality));\n }\n throw error;\n }\n}\nfunction dataUrlToBlob(dataUrl) {\n const [header, base64] = dataUrl.split(\",\");\n const type = header.match(/data:(.+);/)?.[1] ?? void 0;\n const decoded = window.atob(base64);\n const length = decoded.length;\n const buffer = new Uint8Array(length);\n for (let i = 0; i < length; i += 1) {\n buffer[i] = decoded.charCodeAt(i);\n }\n return new Blob([buffer], { type });\n}\nfunction readBlob(blob, type) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.onabort = () => reject(new Error(`Failed read blob to ${type}`));\n if (type === \"dataUrl\") {\n reader.readAsDataURL(blob);\n } else if (type === \"arrayBuffer\") {\n reader.readAsArrayBuffer(blob);\n }\n });\n}\nconst blobToDataUrl = (blob) => readBlob(blob, \"dataUrl\");\nconst blobToArrayBuffer = (blob) => readBlob(blob, \"arrayBuffer\");\nfunction createImage(url, ownerDocument) {\n const img = getDocument(ownerDocument).createElement(\"img\");\n img.decoding = \"sync\";\n img.loading = \"eager\";\n img.src = url;\n return img;\n}\nfunction loadMedia(media, options) {\n return new Promise((resolve) => {\n const { timeout, ownerDocument, onError: userOnError, onWarn } = options ?? {};\n const node = typeof media === \"string\" ? createImage(media, getDocument(ownerDocument)) : media;\n let timer = null;\n let removeEventListeners = null;\n function onResolve() {\n resolve(node);\n timer && clearTimeout(timer);\n removeEventListeners?.();\n }\n if (timeout) {\n timer = setTimeout(onResolve, timeout);\n }\n if (isVideoElement(node)) {\n const currentSrc = node.currentSrc || node.src;\n if (!currentSrc) {\n if (node.poster) {\n return loadMedia(node.poster, options).then(resolve);\n }\n return onResolve();\n }\n if (node.readyState >= 2) {\n return onResolve();\n }\n const onLoadeddata = onResolve;\n const onError = (error) => {\n onWarn?.(\n \"Failed video load\",\n currentSrc,\n error\n );\n userOnError?.(error);\n onResolve();\n };\n removeEventListeners = () => {\n node.removeEventListener(\"loadeddata\", onLoadeddata);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"loadeddata\", onLoadeddata, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n } else {\n const currentSrc = isSVGImageElementNode(node) ? node.href.baseVal : node.currentSrc || node.src;\n if (!currentSrc) {\n return onResolve();\n }\n const onLoad = async () => {\n if (isImageElement(node) && \"decode\" in node) {\n try {\n await node.decode();\n } catch (error) {\n onWarn?.(\n \"Failed to decode image, trying to render anyway\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n }\n }\n onResolve();\n };\n const onError = (error) => {\n onWarn?.(\n \"Failed image load\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n onResolve();\n };\n if (isImageElement(node) && node.complete) {\n return onLoad();\n }\n removeEventListeners = () => {\n node.removeEventListener(\"load\", onLoad);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"load\", onLoad, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n }\n });\n}\nasync function waitUntilLoad(node, options) {\n if (isHTMLElementNode(node)) {\n if (isImageElement(node) || isVideoElement(node)) {\n await loadMedia(node, options);\n } else {\n await Promise.all(\n [\"img\", \"video\"].flatMap((selectors) => {\n return Array.from(node.querySelectorAll(selectors)).map((el) => loadMedia(el, options));\n })\n );\n }\n }\n}\nconst uuid = /* @__PURE__ */ function uuid2() {\n let counter = 0;\n const random = () => `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n}();\nfunction splitFontFamily(fontFamily) {\n return fontFamily?.split(\",\").map((val) => val.trim().replace(/\"|'/g, \"\").toLowerCase()).filter(Boolean);\n}\n\nlet uid = 0;\nfunction createLogger(debug) {\n const prefix = `${PREFIX}[#${uid}]`;\n uid++;\n return {\n // eslint-disable-next-line no-console\n time: (label) => debug && console.time(`${prefix} ${label}`),\n // eslint-disable-next-line no-console\n timeEnd: (label) => debug && console.timeEnd(`${prefix} ${label}`),\n warn: (...args) => debug && consoleWarn(...args)\n };\n}\n\nfunction getDefaultRequestInit(bypassingCache) {\n return {\n cache: bypassingCache ? \"no-cache\" : \"force-cache\"\n };\n}\n\nasync function orCreateContext(node, options) {\n return isContext(node) ? node : createContext(node, { ...options, autoDestruct: true });\n}\nasync function createContext(node, options) {\n const { scale = 1, workerUrl, workerNumber = 1 } = options || {};\n const debug = Boolean(options?.debug);\n const features = options?.features ?? true;\n const ownerDocument = node.ownerDocument ?? (IN_BROWSER ? window.document : void 0);\n const ownerWindow = node.ownerDocument?.defaultView ?? (IN_BROWSER ? window : void 0);\n const requests = /* @__PURE__ */ new Map();\n const context = {\n // Options\n width: 0,\n height: 0,\n quality: 1,\n type: \"image/png\",\n scale,\n backgroundColor: null,\n style: null,\n filter: null,\n maximumCanvasSize: 0,\n timeout: 3e4,\n progress: null,\n debug,\n fetch: {\n requestInit: getDefaultRequestInit(options?.fetch?.bypassingCache),\n placeholderImage: \"data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\",\n bypassingCache: false,\n ...options?.fetch\n },\n fetchFn: null,\n font: {},\n drawImageInterval: 100,\n workerUrl: null,\n workerNumber,\n onCloneEachNode: null,\n onCloneNode: null,\n onEmbedNode: null,\n onCreateForeignObjectSvg: null,\n includeStyleProperties: null,\n autoDestruct: false,\n ...options,\n // InternalContext\n __CONTEXT__: true,\n log: createLogger(debug),\n node,\n ownerDocument,\n ownerWindow,\n dpi: scale === 1 ? null : 96 * scale,\n svgStyleElement: createStyleElement(ownerDocument),\n svgDefsElement: ownerDocument?.createElementNS(XMLNS, \"defs\"),\n svgStyles: /* @__PURE__ */ new Map(),\n defaultComputedStyles: /* @__PURE__ */ new Map(),\n workers: [\n ...Array.from({\n length: SUPPORT_WEB_WORKER && workerUrl && workerNumber ? workerNumber : 0\n })\n ].map(() => {\n try {\n const worker = new Worker(workerUrl);\n worker.onmessage = async (event) => {\n const { url, result } = event.data;\n if (result) {\n requests.get(url)?.resolve?.(result);\n } else {\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n }\n };\n worker.onmessageerror = (event) => {\n const { url } = event.data;\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n };\n return worker;\n } catch (error) {\n context.log.warn(\"Failed to new Worker\", error);\n return null;\n }\n }).filter(Boolean),\n fontFamilies: /* @__PURE__ */ new Map(),\n fontCssTexts: /* @__PURE__ */ new Map(),\n acceptOfImage: `${[\n supportWebp(ownerDocument) && \"image/webp\",\n \"image/svg+xml\",\n \"image/*\",\n \"*/*\"\n ].filter(Boolean).join(\",\")};q=0.8`,\n requests,\n drawImageCount: 0,\n tasks: [],\n features,\n isEnable: (key) => {\n if (key === \"restoreScrollPosition\") {\n return typeof features === \"boolean\" ? false : features[key] ?? false;\n }\n if (typeof features === \"boolean\") {\n return features;\n }\n return features[key] ?? true;\n },\n shadowRoots: []\n };\n context.log.time(\"wait until load\");\n await waitUntilLoad(node, { timeout: context.timeout, onWarn: context.log.warn });\n context.log.timeEnd(\"wait until load\");\n const { width, height } = resolveBoundingBox(node, context);\n context.width = width;\n context.height = height;\n return context;\n}\nfunction createStyleElement(ownerDocument) {\n if (!ownerDocument)\n return void 0;\n const style = ownerDocument.createElement(\"style\");\n const cssText = style.ownerDocument.createTextNode(`\n.______background-clip--text {\n background-clip: text;\n -webkit-background-clip: text;\n}\n`);\n style.appendChild(cssText);\n return style;\n}\nfunction resolveBoundingBox(node, context) {\n let { width, height } = context;\n if (isElementNode(node) && (!width || !height)) {\n const box = node.getBoundingClientRect();\n width = width || box.width || Number(node.getAttribute(\"width\")) || 0;\n height = height || box.height || Number(node.getAttribute(\"height\")) || 0;\n }\n return { width, height };\n}\n\nasync function imageToCanvas(image, context) {\n const {\n log,\n timeout,\n drawImageCount,\n drawImageInterval\n } = context;\n log.time(\"image to canvas\");\n const loaded = await loadMedia(image, { timeout, onWarn: context.log.warn });\n const { canvas, context2d } = createCanvas(image.ownerDocument, context);\n const drawImage = () => {\n try {\n context2d?.drawImage(loaded, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to drawImage\", error);\n }\n };\n drawImage();\n if (context.isEnable(\"fixSvgXmlDecode\")) {\n for (let i = 0; i < drawImageCount; i++) {\n await new Promise((resolve) => {\n setTimeout(() => {\n context2d?.clearRect(0, 0, canvas.width, canvas.height);\n drawImage();\n resolve();\n }, i + drawImageInterval);\n });\n }\n }\n context.drawImageCount = 0;\n log.timeEnd(\"image to canvas\");\n return canvas;\n}\nfunction createCanvas(ownerDocument, context) {\n const { width, height, scale, backgroundColor, maximumCanvasSize: max } = context;\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = Math.floor(width * scale);\n canvas.height = Math.floor(height * scale);\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n if (max) {\n if (canvas.width > max || canvas.height > max) {\n if (canvas.width > max && canvas.height > max) {\n if (canvas.width > canvas.height) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n } else if (canvas.width > max) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n }\n }\n const context2d = canvas.getContext(\"2d\");\n if (context2d && backgroundColor) {\n context2d.fillStyle = backgroundColor;\n context2d.fillRect(0, 0, canvas.width, canvas.height);\n }\n return { canvas, context2d };\n}\n\nfunction cloneCanvas(canvas, context) {\n if (canvas.ownerDocument) {\n try {\n const dataURL = canvas.toDataURL();\n if (dataURL !== \"data:,\") {\n return createImage(dataURL, canvas.ownerDocument);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n }\n const cloned = canvas.cloneNode(false);\n const ctx = canvas.getContext(\"2d\");\n const clonedCtx = cloned.getContext(\"2d\");\n try {\n if (ctx && clonedCtx) {\n clonedCtx.putImageData(\n ctx.getImageData(0, 0, canvas.width, canvas.height),\n 0,\n 0\n );\n }\n return cloned;\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n return cloned;\n}\n\nfunction cloneIframe(iframe, context) {\n try {\n if (iframe?.contentDocument?.documentElement) {\n return cloneNode(iframe.contentDocument.documentElement, context);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone iframe\", error);\n }\n return iframe.cloneNode(false);\n}\n\nfunction cloneImage(image) {\n const cloned = image.cloneNode(false);\n if (image.currentSrc && image.currentSrc !== image.src) {\n cloned.src = image.currentSrc;\n cloned.srcset = \"\";\n }\n if (cloned.loading === \"lazy\") {\n cloned.loading = \"eager\";\n }\n return cloned;\n}\n\nasync function cloneVideo(video, context) {\n if (video.ownerDocument && !video.currentSrc && video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n const cloned = video.cloneNode(false);\n cloned.crossOrigin = \"anonymous\";\n if (video.currentSrc && video.currentSrc !== video.src) {\n cloned.src = video.currentSrc;\n }\n const ownerDocument = cloned.ownerDocument;\n if (ownerDocument) {\n let canPlay = true;\n await loadMedia(cloned, { onError: () => canPlay = false, onWarn: context.log.warn });\n if (!canPlay) {\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n cloned.currentTime = video.currentTime;\n await new Promise((resolve) => {\n cloned.addEventListener(\"seeked\", resolve, { once: true });\n });\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = video.offsetWidth;\n canvas.height = video.offsetHeight;\n try {\n const ctx = canvas.getContext(\"2d\");\n if (ctx)\n ctx.drawImage(cloned, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to clone video\", error);\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n return cloneCanvas(canvas, context);\n }\n return cloned;\n}\n\nfunction cloneElement(node, context) {\n if (isCanvasElement(node)) {\n return cloneCanvas(node, context);\n }\n if (isIFrameElement(node)) {\n return cloneIframe(node, context);\n }\n if (isImageElement(node)) {\n return cloneImage(node);\n }\n if (isVideoElement(node)) {\n return cloneVideo(node, context);\n }\n return node.cloneNode(false);\n}\n\nfunction getSandBox(context) {\n let sandbox = context.sandbox;\n if (!sandbox) {\n const { ownerDocument } = context;\n try {\n if (ownerDocument) {\n sandbox = ownerDocument.createElement(\"iframe\");\n sandbox.id = `__SANDBOX__${uuid()}`;\n sandbox.width = \"0\";\n sandbox.height = \"0\";\n sandbox.style.visibility = \"hidden\";\n sandbox.style.position = \"fixed\";\n ownerDocument.body.appendChild(sandbox);\n sandbox.srcdoc = '<!DOCTYPE html><meta charset=\"UTF-8\"><title></title><body>';\n context.sandbox = sandbox;\n }\n } catch (error) {\n context.log.warn(\"Failed to getSandBox\", error);\n }\n }\n return sandbox;\n}\n\nconst ignoredStyles = [\n \"width\",\n \"height\",\n \"-webkit-text-fill-color\"\n];\nconst includedAttributes = [\n \"stroke\",\n \"fill\"\n];\nfunction getDefaultStyle(node, pseudoElement, context) {\n const { defaultComputedStyles } = context;\n const nodeName = node.nodeName.toLowerCase();\n const isSvgNode = isSVGElementNode(node) && nodeName !== \"svg\";\n const attributes = isSvgNode ? includedAttributes.map((name) => [name, node.getAttribute(name)]).filter(([, value]) => value !== null) : [];\n const key = [\n isSvgNode && \"svg\",\n nodeName,\n attributes.map((name, value) => `${name}=${value}`).join(\",\"),\n pseudoElement\n ].filter(Boolean).join(\":\");\n if (defaultComputedStyles.has(key))\n return defaultComputedStyles.get(key);\n const sandbox = getSandBox(context);\n const sandboxWindow = sandbox?.contentWindow;\n if (!sandboxWindow)\n return /* @__PURE__ */ new Map();\n const sandboxDocument = sandboxWindow?.document;\n let root;\n let el;\n if (isSvgNode) {\n root = sandboxDocument.createElementNS(XMLNS, \"svg\");\n el = root.ownerDocument.createElementNS(root.namespaceURI, nodeName);\n attributes.forEach(([name, value]) => {\n el.setAttributeNS(null, name, value);\n });\n root.appendChild(el);\n } else {\n root = el = sandboxDocument.createElement(nodeName);\n }\n el.textContent = \" \";\n sandboxDocument.body.appendChild(root);\n const computedStyle = sandboxWindow.getComputedStyle(el, pseudoElement);\n const styles = /* @__PURE__ */ new Map();\n for (let len = computedStyle.length, i = 0; i < len; i++) {\n const name = computedStyle.item(i);\n if (ignoredStyles.includes(name))\n continue;\n styles.set(name, computedStyle.getPropertyValue(name));\n }\n sandboxDocument.body.removeChild(root);\n defaultComputedStyles.set(key, styles);\n return styles;\n}\n\nfunction getDiffStyle(style, defaultStyle, includeStyleProperties) {\n const diffStyle = /* @__PURE__ */ new Map();\n const prefixs = [];\n const prefixTree = /* @__PURE__ */ new Map();\n if (includeStyleProperties) {\n for (const name of includeStyleProperties) {\n applyTo(name);\n }\n } else {\n for (let len = style.length, i = 0; i < len; i++) {\n const name = style.item(i);\n applyTo(name);\n }\n }\n for (let len = prefixs.length, i = 0; i < len; i++) {\n prefixTree.get(prefixs[i])?.forEach((value, name) => diffStyle.set(name, value));\n }\n function applyTo(name) {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n const subIndex = name.lastIndexOf(\"-\");\n const prefix = subIndex > -1 ? name.substring(0, subIndex) : void 0;\n if (prefix) {\n let map = prefixTree.get(prefix);\n if (!map) {\n map = /* @__PURE__ */ new Map();\n prefixTree.set(prefix, map);\n }\n map.set(name, [value, priority]);\n }\n if (defaultStyle.get(name) === value && !priority)\n return;\n if (prefix) {\n prefixs.push(prefix);\n } else {\n diffStyle.set(name, [value, priority]);\n }\n }\n return diffStyle;\n}\n\nfunction copyCssStyles(node, cloned, isRoot, context) {\n const { ownerWindow, includeStyleProperties, currentParentNodeStyle } = context;\n const clonedStyle = cloned.style;\n const computedStyle = ownerWindow.getComputedStyle(node);\n const defaultStyle = getDefaultStyle(node, null, context);\n currentParentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, includeStyleProperties);\n style.delete(\"transition-property\");\n style.delete(\"all\");\n style.delete(\"d\");\n style.delete(\"content\");\n if (isRoot) {\n style.delete(\"position\");\n style.delete(\"margin-top\");\n style.delete(\"margin-right\");\n style.delete(\"margin-bottom\");\n style.delete(\"margin-left\");\n style.delete(\"margin-block-start\");\n style.delete(\"margin-block-end\");\n style.delete(\"margin-inline-start\");\n style.delete(\"margin-inline-end\");\n style.set(\"box-sizing\", [\"border-box\", \"\"]);\n }\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n if (IN_CHROME) {\n if (!style.has(\"font-kerning\"))\n style.set(\"font-kerning\", [\"normal\", \"\"]);\n if ((style.get(\"overflow-x\")?.[0] === \"hidden\" || style.get(\"overflow-y\")?.[0] === \"hidden\") && style.get(\"text-overflow\")?.[0] === \"ellipsis\" && node.scrollWidth === node.clientWidth) {\n style.set(\"text-overflow\", [\"clip\", \"\"]);\n }\n }\n for (let len = clonedStyle.length, i = 0; i < len; i++) {\n clonedStyle.removeProperty(clonedStyle.item(i));\n }\n style.forEach(([value, priority], name) => {\n clonedStyle.setProperty(name, value, priority);\n });\n return style;\n}\n\nfunction copyInputValue(node, cloned) {\n if (isTextareaElement(node) || isInputElement(node) || isSelectElement(node)) {\n cloned.setAttribute(\"value\", node.value);\n }\n}\n\nconst pseudoClasses = [\n \"::before\",\n \"::after\"\n // '::placeholder', TODO\n];\nconst scrollbarPseudoClasses = [\n \"::-webkit-scrollbar\",\n \"::-webkit-scrollbar-button\",\n // '::-webkit-scrollbar:horizontal', TODO\n \"::-webkit-scrollbar-thumb\",\n \"::-webkit-scrollbar-track\",\n \"::-webkit-scrollbar-track-piece\",\n // '::-webkit-scrollbar:vertical', TODO\n \"::-webkit-scrollbar-corner\",\n \"::-webkit-resizer\"\n];\nfunction copyPseudoClass(node, cloned, copyScrollbar, context, addWordToFontFamilies) {\n const { ownerWindow, svgStyleElement, svgStyles, currentNodeStyle } = context;\n if (!svgStyleElement || !ownerWindow)\n return;\n function copyBy(pseudoClass) {\n const computedStyle = ownerWindow.getComputedStyle(node, pseudoClass);\n let content = computedStyle.getPropertyValue(\"content\");\n if (!content || content === \"none\")\n return;\n addWordToFontFamilies?.(content);\n content = content.replace(/(')|(\")|(counter\\(.+\\))/g, \"\");\n const klasses = [uuid()];\n const defaultStyle = getDefaultStyle(node, pseudoClass, context);\n currentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, context.includeStyleProperties);\n style.delete(\"content\");\n style.delete(\"-webkit-locale\");\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n const cloneStyle = [\n `content: '${content}';`\n ];\n style.forEach(([value, priority], name) => {\n cloneStyle.push(`${name}: ${value}${priority ? \" !important\" : \"\"};`);\n });\n if (cloneStyle.length === 1)\n return;\n try {\n cloned.className = [cloned.className, ...klasses].join(\" \");\n } catch (err) {\n context.log.warn(\"Failed to copyPseudoClass\", err);\n return;\n }\n const cssText = cloneStyle.join(\"\\n \");\n let allClasses = svgStyles.get(cssText);\n if (!allClasses) {\n allClasses = [];\n svgStyles.set(cssText, allClasses);\n }\n allClasses.push(`.${klasses[0]}${pseudoClass}`);\n }\n pseudoClasses.forEach(copyBy);\n if (copyScrollbar)\n scrollbarPseudoClasses.forEach(copyBy);\n}\n\nconst excludeParentNodes = /* @__PURE__ */ new Set([\n \"symbol\"\n // test/fixtures/svg.symbol.html\n]);\nasync function appendChildNode(node, cloned, child, context, addWordToFontFamilies) {\n if (isElementNode(child) && (isStyleElement(child) || isScriptElement(child)))\n return;\n if (context.filter && !context.filter(child))\n return;\n if (excludeParentNodes.has(cloned.nodeName) || excludeParentNodes.has(child.nodeName)) {\n context.currentParentNodeStyle = void 0;\n } else {\n context.currentParentNodeStyle = context.currentNodeStyle;\n }\n const childCloned = await cloneNode(child, context, false, addWordToFontFamilies);\n if (context.isEnable(\"restoreScrollPosition\")) {\n restoreScrollPosition(node, childCloned);\n }\n cloned.appendChild(childCloned);\n}\nasync function cloneChildNodes(node, cloned, context, addWordToFontFamilies) {\n let firstChild = node.firstChild;\n if (isElementNode(node)) {\n if (node.shadowRoot) {\n firstChild = node.shadowRoot?.firstChild;\n context.shadowRoots.push(node.shadowRoot);\n }\n }\n for (let child = firstChild; child; child = child.nextSibling) {\n if (isCommentNode(child))\n continue;\n if (isElementNode(child) && isSlotElement(child) && typeof child.assignedNodes === \"function\") {\n const nodes = child.assignedNodes();\n for (let i = 0; i < nodes.length; i++) {\n await appendChildNode(node, cloned, nodes[i], context, addWordToFontFamilies);\n }\n } else {\n await appendChildNode(node, cloned, child, context, addWordToFontFamilies);\n }\n }\n}\nfunction restoreScrollPosition(node, chlidCloned) {\n if (!isHTMLElementNode(node) || !isHTMLElementNode(chlidCloned))\n return;\n const { scrollTop, scrollLeft } = node;\n if (!scrollTop && !scrollLeft) {\n return;\n }\n const { transform } = chlidCloned.style;\n const matrix = new DOMMatrix(transform);\n const { a, b, c, d } = matrix;\n matrix.a = 1;\n matrix.b = 0;\n matrix.c = 0;\n matrix.d = 1;\n matrix.translateSelf(-scrollLeft, -scrollTop);\n matrix.a = a;\n matrix.b = b;\n matrix.c = c;\n matrix.d = d;\n chlidCloned.style.transform = matrix.toString();\n}\nfunction applyCssStyleWithOptions(cloned, context) {\n const { backgroundColor, width, height, style: styles } = context;\n const clonedStyle = cloned.style;\n if (backgroundColor)\n clonedStyle.setProperty(\"background-color\", backgroundColor, \"important\");\n if (width)\n clonedStyle.setProperty(\"width\", `${width}px`, \"important\");\n if (height)\n clonedStyle.setProperty(\"height\", `${height}px`, \"important\");\n if (styles) {\n for (const name in styles) clonedStyle[name] = styles[name];\n }\n}\nconst NORMAL_ATTRIBUTE_RE = /^[\\w-:]+$/;\nasync function cloneNode(node, context, isRoot = false, addWordToFontFamilies) {\n const { ownerDocument, ownerWindow, fontFamilies, onCloneEachNode } = context;\n if (ownerDocument && isTextNode(node)) {\n if (addWordToFontFamilies && /\\S/.test(node.data)) {\n addWordToFontFamilies(node.data);\n }\n return ownerDocument.createTextNode(node.data);\n }\n if (ownerDocument && ownerWindow && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {\n const cloned2 = await cloneElement(node, context);\n if (context.isEnable(\"removeAbnormalAttributes\")) {\n const names = cloned2.getAttributeNames();\n for (let len = names.length, i = 0; i < len; i++) {\n const name = names[i];\n if (!NORMAL_ATTRIBUTE_RE.test(name)) {\n cloned2.removeAttribute(name);\n }\n }\n }\n const style = context.currentNodeStyle = copyCssStyles(node, cloned2, isRoot, context);\n if (isRoot)\n applyCssStyleWithOptions(cloned2, context);\n let copyScrollbar = false;\n if (context.isEnable(\"copyScrollbar\")) {\n const overflow = [\n style.get(\"overflow-x\")?.[0],\n style.get(\"overflow-y\")?.[0]\n ];\n copyScrollbar = overflow.includes(\"scroll\") || (overflow.includes(\"auto\") || overflow.includes(\"overlay\")) && (node.scrollHeight > node.clientHeight || node.scrollWidth > node.clientWidth);\n }\n const textTransform = style.get(\"text-transform\")?.[0];\n const families = splitFontFamily(style.get(\"font-family\")?.[0]);\n const addWordToFontFamilies2 = families ? (word) => {\n if (textTransform === \"uppercase\") {\n word = word.toUpperCase();\n } else if (textTransform === \"lowercase\") {\n word = word.toLowerCase();\n } else if (textTransform === \"capitalize\") {\n word = word[0].toUpperCase() + word.substring(1);\n }\n families.forEach((family) => {\n let fontFamily = fontFamilies.get(family);\n if (!fontFamily) {\n fontFamilies.set(family, fontFamily = /* @__PURE__ */ new Set());\n }\n word.split(\"\").forEach((text) => fontFamily.add(text));\n });\n } : void 0;\n copyPseudoClass(\n node,\n cloned2,\n copyScrollbar,\n context,\n addWordToFontFamilies2\n );\n copyInputValue(node, cloned2);\n if (!isVideoElement(node)) {\n await cloneChildNodes(\n node,\n cloned2,\n context,\n addWordToFontFamilies2\n );\n }\n await onCloneEachNode?.(cloned2);\n return cloned2;\n }\n const cloned = node.cloneNode(false);\n await cloneChildNodes(node, cloned, context);\n await onCloneEachNode?.(cloned);\n return cloned;\n}\n\nfunction destroyContext(context) {\n context.ownerDocument = void 0;\n context.ownerWindow = void 0;\n context.svgStyleElement = void 0;\n context.svgDefsElement = void 0;\n context.svgStyles.clear();\n context.defaultComputedStyles.clear();\n if (context.sandbox) {\n try {\n context.sandbox.remove();\n } catch (err) {\n context.log.warn(\"Failed to destroyContext\", err);\n }\n context.sandbox = void 0;\n }\n context.workers = [];\n context.fontFamilies.clear();\n context.fontCssTexts.clear();\n context.requests.clear();\n context.tasks = [];\n context.shadowRoots = [];\n}\n\nfunction baseFetch(options) {\n const { url, timeout, responseType, ...requestInit } = options;\n const controller = new AbortController();\n const timer = timeout ? setTimeout(() => controller.abort(), timeout) : void 0;\n return fetch(url, { signal: controller.signal, ...requestInit }).then((response) => {\n if (!response.ok) {\n throw new Error(\"Failed fetch, not 2xx response\", { cause: response });\n }\n switch (responseType) {\n case \"arrayBuffer\":\n return response.arrayBuffer();\n case \"dataUrl\":\n return response.blob().then(blobToDataUrl);\n case \"text\":\n default:\n return response.text();\n }\n }).finally(() => clearTimeout(timer));\n}\nfunction contextFetch(context, options) {\n const { url: rawUrl, requestType = \"text\", responseType = \"text\", imageDom } = options;\n let url = rawUrl;\n const {\n timeout,\n acceptOfImage,\n requests,\n fetchFn,\n fetch: {\n requestInit,\n bypassingCache,\n placeholderImage\n },\n font,\n workers,\n fontFamilies\n } = context;\n if (requestType === \"image\" && (IN_SAFARI || IN_FIREFOX)) {\n context.drawImageCount++;\n }\n let request = requests.get(rawUrl);\n if (!request) {\n if (bypassingCache) {\n if (bypassingCache instanceof RegExp && bypassingCache.test(url)) {\n url += (/\\?/.test(url) ? \"&\" : \"?\") + (/* @__PURE__ */ new Date()).getTime();\n }\n }\n const canFontMinify = requestType.startsWith(\"font\") && font && font.minify;\n const fontTexts = /* @__PURE__ */ new Set();\n if (canFontMinify) {\n const families = requestType.split(\";\")[1].split(\",\");\n families.forEach((family) => {\n if (!fontFamilies.has(family))\n return;\n fontFamilies.get(family).forEach((text) => fontTexts.add(text));\n });\n }\n const needFontMinify = canFontMinify && fontTexts.size;\n const baseFetchOptions = {\n url,\n timeout,\n responseType: needFontMinify ? \"arrayBuffer\" : responseType,\n headers: requestType === \"image\" ? { accept: acceptOfImage } : void 0,\n ...requestInit\n };\n request = {\n type: requestType,\n resolve: void 0,\n reject: void 0,\n response: null\n };\n request.response = (async () => {\n if (fetchFn && requestType === \"image\") {\n const result = await fetchFn(rawUrl);\n if (result)\n return result;\n }\n if (!IN_SAFARI && rawUrl.startsWith(\"http\") && workers.length) {\n return new Promise((resolve, reject) => {\n const worker = workers[requests.size & workers.length - 1];\n worker.postMessage({ rawUrl, ...baseFetchOptions });\n request.resolve = resolve;\n request.reject = reject;\n });\n }\n return baseFetch(baseFetchOptions);\n })().catch((error) => {\n requests.delete(rawUrl);\n if (requestType === \"image\" && placeholderImage) {\n context.log.warn(\"Failed to fetch image base64, trying to use placeholder image\", url);\n return typeof placeholderImage === \"string\" ? placeholderImage : placeholderImage(imageDom);\n }\n throw error;\n });\n requests.set(rawUrl, request);\n }\n return request.response;\n}\n\nasync function replaceCssUrlToDataUrl(cssText, baseUrl, context, isImage) {\n if (!hasCssUrl(cssText))\n return cssText;\n for (const [rawUrl, url] of parseCssUrls(cssText, baseUrl)) {\n try {\n const dataUrl = await contextFetch(\n context,\n {\n url,\n requestType: isImage ? \"image\" : \"text\",\n responseType: \"dataUrl\"\n }\n );\n cssText = cssText.replace(toRE(rawUrl), `$1${dataUrl}$3`);\n } catch (error) {\n context.log.warn(\"Failed to fetch css data url\", rawUrl, error);\n }\n }\n return cssText;\n}\nfunction hasCssUrl(cssText) {\n return /url\\((['\"]?)([^'\"]+?)\\1\\)/.test(cssText);\n}\nconst URL_RE = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nfunction parseCssUrls(cssText, baseUrl) {\n const result = [];\n cssText.replace(URL_RE, (raw, quotation, url) => {\n result.push([url, resolveUrl(url, baseUrl)]);\n return raw;\n });\n return result.filter(([url]) => !isDataUrl(url));\n}\nfunction toRE(url) {\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, \"\\\\$1\");\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, \"g\");\n}\n\nconst properties = [\n \"background-image\",\n \"border-image-source\",\n \"-webkit-border-image\",\n \"-webkit-mask-image\",\n \"list-style-image\"\n];\nfunction embedCssStyleImage(style, context) {\n return properties.map((property) => {\n const value = style.getPropertyValue(property);\n if (!value || value === \"none\") {\n return null;\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n return replaceCssUrlToDataUrl(value, null, context, true).then((newValue) => {\n if (!newValue || value === newValue)\n return;\n style.setProperty(\n property,\n newValue,\n style.getPropertyPriority(property)\n );\n });\n }).filter(Boolean);\n}\n\nfunction embedImageElement(cloned, context) {\n if (isImageElement(cloned)) {\n const originalSrc = cloned.currentSrc || cloned.src;\n if (!isDataUrl(originalSrc)) {\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.srcset = \"\";\n cloned.dataset.originalSrc = originalSrc;\n cloned.src = url || \"\";\n })\n ];\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n } else if (isSVGElementNode(cloned) && !isDataUrl(cloned.href.baseVal)) {\n const originalSrc = cloned.href.baseVal;\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.dataset.originalSrc = originalSrc;\n cloned.href.baseVal = url || \"\";\n })\n ];\n }\n return [];\n}\n\nfunction embedSvgUse(cloned, context) {\n const { ownerDocument, svgDefsElement } = context;\n const href = cloned.getAttribute(\"href\") ?? cloned.getAttribute(\"xlink:href\");\n if (!href)\n return [];\n const [svgUrl, id] = href.split(\"#\");\n if (id) {\n const query = `#${id}`;\n const definition = context.shadowRoots.reduce(\n (res, root) => {\n return res ?? root.querySelector(`svg ${query}`);\n },\n ownerDocument?.querySelector(`svg ${query}`)\n );\n if (svgUrl) {\n cloned.setAttribute(\"href\", query);\n }\n if (svgDefsElement?.querySelector(query))\n return [];\n if (definition) {\n svgDefsElement?.appendChild(definition.cloneNode(true));\n return [];\n } else if (svgUrl) {\n return [\n contextFetch(context, {\n url: svgUrl,\n responseType: \"text\"\n }).then((svgData) => {\n svgDefsElement?.insertAdjacentHTML(\"beforeend\", svgData);\n })\n ];\n }\n }\n return [];\n}\n\nfunction embedNode(cloned, context) {\n const { tasks } = context;\n if (isElementNode(cloned)) {\n if (isImageElement(cloned) || isSVGImageElementNode(cloned)) {\n tasks.push(...embedImageElement(cloned, context));\n }\n if (isSVGUseElementNode(cloned)) {\n tasks.push(...embedSvgUse(cloned, context));\n }\n }\n if (isHTMLElementNode(cloned)) {\n tasks.push(...embedCssStyleImage(cloned.style, context));\n }\n cloned.childNodes.forEach((child) => {\n embedNode(child, context);\n });\n}\n\nasync function embedWebFont(clone, context) {\n const {\n ownerDocument,\n svgStyleElement,\n fontFamilies,\n fontCssTexts,\n tasks,\n font\n } = context;\n if (!ownerDocument || !svgStyleElement || !fontFamilies.size) {\n return;\n }\n if (font && font.cssText) {\n const cssText = filterPreferredFormat(font.cssText, context);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n const styleSheets = Array.from(ownerDocument.styleSheets).filter((styleSheet) => {\n try {\n return \"cssRules\" in styleSheet && Boolean(styleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(`Error while reading CSS rules from ${styleSheet.href}`, error);\n return false;\n }\n });\n const tempDoc = ownerDocument.implementation.createHTMLDocument(\"\");\n const tempStyleEl = tempDoc.createElement(\"style\");\n tempDoc.head.appendChild(tempStyleEl);\n const tempStyleSheet = tempStyleEl.sheet;\n await Promise.all(\n styleSheets.flatMap((styleSheet) => {\n return Array.from(styleSheet.cssRules).map(async (cssRule) => {\n if (isCSSImportRule(cssRule)) {\n const baseUrl = cssRule.href;\n let cssText = \"\";\n try {\n cssText = await contextFetch(context, {\n url: baseUrl,\n requestType: \"text\",\n responseType: \"text\"\n });\n } catch (error) {\n context.log.warn(`Error fetch remote css import from ${baseUrl}`, error);\n }\n const replacedCssText = cssText.replace(\n URL_RE,\n (raw, quotation, url) => raw.replace(url, resolveUrl(url, baseUrl))\n );\n for (const rule of parseCss(replacedCssText)) {\n try {\n tempStyleSheet.insertRule(rule, tempStyleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(\"Error inserting rule from remote css import\", { rule, error });\n }\n }\n }\n });\n })\n );\n if (tempStyleSheet.cssRules.length)\n styleSheets.push(tempStyleSheet);\n const cssRules = [];\n styleSheets.forEach((sheet) => {\n unwrapCssLayers(sheet.cssRules, cssRules);\n });\n cssRules.filter((cssRule) => isCssFontFaceRule(cssRule) && hasCssUrl(cssRule.style.getPropertyValue(\"src\")) && splitFontFamily(cssRule.style.getPropertyValue(\"font-family\"))?.some((val) => fontFamilies.has(val))).forEach((value) => {\n const rule = value;\n const cssText = fontCssTexts.get(rule.cssText);\n if (cssText) {\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n tasks.push(\n replaceCssUrlToDataUrl(\n rule.cssText,\n rule.parentStyleSheet ? rule.parentStyleSheet.href : null,\n context\n ).then((cssText2) => {\n cssText2 = filterPreferredFormat(cssText2, context);\n fontCssTexts.set(rule.cssText, cssText2);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText2}\n`));\n })\n );\n }\n });\n }\n}\nconst COMMENTS_RE = /(\\/\\*[\\s\\S]*?\\*\\/)/g;\nconst KEYFRAMES_RE = /((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})/gi;\nfunction parseCss(source) {\n if (source == null)\n return [];\n const result = [];\n let cssText = source.replace(COMMENTS_RE, \"\");\n while (true) {\n const matches = KEYFRAMES_RE.exec(cssText);\n if (!matches)\n break;\n result.push(matches[0]);\n }\n cssText = cssText.replace(KEYFRAMES_RE, \"\");\n const IMPORT_RE = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n const UNIFIED_RE = new RegExp(\n // eslint-disable-next-line\n \"((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})\",\n \"gi\"\n );\n while (true) {\n let matches = IMPORT_RE.exec(cssText);\n if (!matches) {\n matches = UNIFIED_RE.exec(cssText);\n if (!matches) {\n break;\n } else {\n IMPORT_RE.lastIndex = UNIFIED_RE.lastIndex;\n }\n } else {\n UNIFIED_RE.lastIndex = IMPORT_RE.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nconst URL_WITH_FORMAT_RE = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_RE = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction filterPreferredFormat(str, context) {\n const { font } = context;\n const preferredFormat = font ? font?.preferredFormat : void 0;\n return preferredFormat ? str.replace(FONT_SRC_RE, (match) => {\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_RE.exec(match) || [];\n if (!format)\n return \"\";\n if (format === preferredFormat)\n return `src: ${src};`;\n }\n }) : str;\n}\nfunction unwrapCssLayers(rules, out = []) {\n for (const rule of Array.from(rules)) {\n if (isLayerBlockRule(rule)) {\n out.push(...unwrapCssLayers(rule.cssRules));\n } else if (\"cssRules\" in rule) {\n unwrapCssLayers(rule.cssRules, out);\n } else {\n out.push(rule);\n }\n }\n return out;\n}\n\nconst SVG_EXTERNAL_RESOURCE_REGEX = /\\bx?link:?href\\s*=\\s*[\"'](?!data:)[^\"']+[\"']/i;\nfunction svgHasExternalResources(svg) {\n return SVG_EXTERNAL_RESOURCE_REGEX.test(svg.innerHTML);\n}\nasync function domToForeignObjectSvg(node, options) {\n const context = await orCreateContext(node, options);\n if (isElementNode(context.node) && isSVGElementNode(context.node) && !svgHasExternalResources(context.node))\n return context.node;\n const {\n ownerDocument,\n log,\n tasks,\n svgStyleElement,\n svgDefsElement,\n svgStyles,\n font,\n progress,\n autoDestruct,\n onCloneNode,\n onEmbedNode,\n onCreateForeignObjectSvg\n } = context;\n log.time(\"clone node\");\n const clone = await cloneNode(context.node, context, true);\n if (svgStyleElement && ownerDocument) {\n let allCssText = \"\";\n svgStyles.forEach((klasses, cssText) => {\n allCssText += `${klasses.join(\",\\n\")} {\n ${cssText}\n}\n`;\n });\n svgStyleElement.appendChild(ownerDocument.createTextNode(allCssText));\n }\n log.timeEnd(\"clone node\");\n await onCloneNode?.(clone);\n if (font !== false && isElementNode(clone)) {\n log.time(\"embed web font\");\n await embedWebFont(clone, context);\n log.timeEnd(\"embed web font\");\n }\n log.time(\"embed node\");\n embedNode(clone, context);\n const count = tasks.length;\n let current = 0;\n const runTask = async () => {\n while (true) {\n const task = tasks.pop();\n if (!task)\n break;\n try {\n await task;\n } catch (error) {\n context.log.warn(\"Failed to run task\", error);\n }\n progress?.(++current, count);\n }\n };\n progress?.(current, count);\n await Promise.all([...Array.from({ length: 4 })].map(runTask));\n log.timeEnd(\"embed node\");\n await onEmbedNode?.(clone);\n const svg = createForeignObjectSvg(clone, context);\n svgDefsElement && svg.insertBefore(svgDefsElement, svg.children[0]);\n svgStyleElement && svg.insertBefore(svgStyleElement, svg.children[0]);\n autoDestruct && destroyContext(context);\n await onCreateForeignObjectSvg?.(svg);\n return svg;\n}\nfunction createForeignObjectSvg(clone, context) {\n const { width, height } = context;\n const svg = createSvg(width, height, clone.ownerDocument);\n const foreignObject = svg.ownerDocument.createElementNS(svg.namespaceURI, \"foreignObject\");\n foreignObject.setAttributeNS(null, \"x\", \"0%\");\n foreignObject.setAttributeNS(null, \"y\", \"0%\");\n foreignObject.setAttributeNS(null, \"width\", \"100%\");\n foreignObject.setAttributeNS(null, \"height\", \"100%\");\n foreignObject.append(clone);\n svg.appendChild(foreignObject);\n return svg;\n}\n\nasync function domToCanvas(node, options) {\n const context = await orCreateContext(node, options);\n const svg = await domToForeignObjectSvg(context);\n const dataUrl = svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n if (!context.autoDestruct) {\n context.svgStyleElement = createStyleElement(context.ownerDocument);\n context.svgDefsElement = context.ownerDocument?.createElementNS(XMLNS, \"defs\");\n context.svgStyles.clear();\n }\n const image = createImage(dataUrl, svg.ownerDocument);\n return await imageToCanvas(image, context);\n}\n\nasync function domToBlob(node, options) {\n const context = await orCreateContext(node, options);\n const { log, type, quality, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to blob\");\n const blob = await canvasToBlob(canvas, type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi) {\n const arrayBuffer = await blobToArrayBuffer(blob.slice(0, 33));\n let uint8Array = new Uint8Array(arrayBuffer);\n if (type === \"image/png\") {\n uint8Array = changePngDpi(uint8Array, dpi);\n } else if (type === \"image/jpeg\") {\n uint8Array = changeJpegDpi(uint8Array, dpi);\n }\n log.timeEnd(\"canvas to blob\");\n return new Blob([uint8Array, blob.slice(33)], { type });\n }\n log.timeEnd(\"canvas to blob\");\n return blob;\n}\n\nasync function domToDataUrl(node, options) {\n const context = await orCreateContext(node, options);\n const { log, quality, type, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to data url\");\n let dataUrl = canvas.toDataURL(type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi && SUPPORT_ATOB && SUPPORT_BTOA) {\n const [format, body] = dataUrl.split(\",\");\n let headerLength = 0;\n let overwritepHYs = false;\n if (type === \"image/png\") {\n const b64Index = detectPhysChunkFromDataUrl(body);\n if (b64Index >= 0) {\n headerLength = Math.ceil((b64Index + 28) / 3) * 4;\n overwritepHYs = true;\n } else {\n headerLength = 33 / 3 * 4;\n }\n } else if (type === \"image/jpeg\") {\n headerLength = 18 / 3 * 4;\n }\n const stringHeader = body.substring(0, headerLength);\n const restOfData = body.substring(headerLength);\n const headerBytes = window.atob(stringHeader);\n const uint8Array = new Uint8Array(headerBytes.length);\n for (let i = 0; i < uint8Array.length; i++) {\n uint8Array[i] = headerBytes.charCodeAt(i);\n }\n const finalArray = type === \"image/png\" ? changePngDpi(uint8Array, dpi, overwritepHYs) : changeJpegDpi(uint8Array, dpi);\n const base64Header = window.btoa(String.fromCharCode(...finalArray));\n dataUrl = [format, \",\", base64Header, restOfData].join(\"\");\n }\n log.timeEnd(\"canvas to data url\");\n return dataUrl;\n}\n\nasync function domToSvg(node, options) {\n const context = await orCreateContext(node, options);\n const { width, height, ownerDocument } = context;\n const dataUrl = await domToDataUrl(context);\n const svg = createSvg(width, height, ownerDocument);\n const svgImage = svg.ownerDocument.createElementNS(svg.namespaceURI, \"image\");\n svgImage.setAttributeNS(null, \"href\", dataUrl);\n svgImage.setAttributeNS(null, \"height\", \"100%\");\n svgImage.setAttributeNS(null, \"width\", \"100%\");\n svg.appendChild(svgImage);\n return svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n}\n\nasync function domToImage(node, options) {\n const context = await orCreateContext(node, options);\n const { ownerDocument, width, height, scale, type } = context;\n const url = type === \"image/svg+xml\" ? await domToSvg(context) : await domToDataUrl(context);\n const image = createImage(url, ownerDocument);\n image.width = Math.floor(width * scale);\n image.height = Math.floor(height * scale);\n image.style.width = `${width}px`;\n image.style.height = `${height}px`;\n return image;\n}\n\nasync function domToJpeg(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/jpeg\" })\n );\n}\n\nasync function domToPixel(node, options) {\n const context = await orCreateContext(node, options);\n const canvas = await domToCanvas(context);\n return canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height).data;\n}\n\nasync function domToPng(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/png\" })\n );\n}\n\nasync function domToWebp(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/webp\" })\n );\n}\n\nexport { createContext, destroyContext, domToBlob, domToCanvas, domToDataUrl, domToForeignObjectSvg, domToImage, domToJpeg, domToPixel, domToPng, domToSvg, domToWebp, loadMedia, waitUntilLoad };\n","import { domToPng } from \"modern-screenshot\";\nimport type { ElementContext, RegionRect } from \"./types.js\";\n\nconst STYLE_KEYS = [\n \"display\", \"position\", \"width\", \"height\", \"margin\", \"padding\",\n \"color\", \"background-color\", \"font-size\", \"font-weight\", \"font-family\",\n \"border\", \"border-radius\", \"box-shadow\", \"flex\", \"grid-template-columns\",\n \"text-align\", \"line-height\", \"opacity\",\n];\n\n/** outerHTML + a curated slice of computed styles — the context handed to Claude. */\nexport function captureElementContext(el: Element): ElementContext {\n const html = el.outerHTML.length > 6000 ? el.outerHTML.slice(0, 6000) + \"…\" : el.outerHTML;\n const cs = getComputedStyle(el);\n const styles: Record<string, string> = {};\n for (const k of STYLE_KEYS) {\n const v = cs.getPropertyValue(k);\n if (v) styles[k] = v.trim();\n }\n return { html, styles };\n}\n\n/** Max time (ms) any single capture may spend fetching/embedding assets. */\nconst CAPTURE_TIMEOUT = 6000;\n\n/** Resolve `undefined` if `p` doesn't settle within `ms` — so a capture can never hang the UI. */\nfunction withTimeout<T>(p: Promise<T>, ms: number): Promise<T | undefined> {\n return Promise.race([p, new Promise<undefined>((resolve) => setTimeout(() => resolve(undefined), ms))]);\n}\n\n/**\n * Give web fonts a brief chance to finish loading so they embed instead of\n * falling back — but NEVER block on it. On some SPAs `document.fonts.ready`\n * settles slowly (or keeps loading), which would otherwise hang the capture,\n * so we race it against a short cap.\n */\nasync function fontsReady(): Promise<void> {\n try {\n const fonts = (document as Document & { fonts?: FontFaceSet }).fonts;\n if (!fonts?.ready) return;\n await Promise.race([\n fonts.ready,\n new Promise<void>((resolve) => setTimeout(resolve, 800)),\n ]);\n } catch {\n /* FontFaceSet unsupported — carry on */\n }\n}\n\n/** Skip Loupe's own UI and redacted elements in any capture. */\nfunction captureFilter(node: Node): boolean {\n if (!(node instanceof Element)) return true;\n if (node.id === \"loupe-root\") return false;\n if (node.hasAttribute(\"data-loupe-redact\")) return false;\n return true;\n}\n\n/**\n * Screenshot the target element. Elements marked [data-loupe-redact] are\n * excluded before anything leaves the browser, and our own UI is never captured.\n */\nexport async function captureScreenshot(el: Element): Promise<string | undefined> {\n try {\n await fontsReady();\n return await withTimeout(\n domToPng(el as HTMLElement, {\n scale: Math.min(window.devicePixelRatio || 1, 2),\n backgroundColor: getComputedStyle(document.body).backgroundColor || \"#ffffff\",\n timeout: CAPTURE_TIMEOUT,\n filter: captureFilter,\n }),\n CAPTURE_TIMEOUT + 2000,\n );\n } catch (err) {\n console.warn(\"[loupe] screenshot capture failed\", err);\n return undefined;\n }\n}\n\n/**\n * Screenshot a free-form rectangle (the \"region shot\"). `rect` is in **viewport**\n * coordinates (what's on screen now). The default renders the whole page and crops;\n * the extension overrides this with a real captureVisibleTab crop. Redacted regions\n * are painted over before the pixels leave the browser.\n */\nexport async function captureRegionScreenshot(rect: RegionRect): Promise<string | undefined> {\n try {\n await fontsReady();\n const scale = Math.min(window.devicePixelRatio || 1, 2);\n // Render the SMALLEST element that fully covers the selection, not the whole\n // page. Rendering document.body is heavy and its cross-origin font embedding\n // often times out (→ fallback fonts, reflow); a scoped subtree behaves like\n // the reliable element capture.\n const container = regionContainer(rect);\n const origin = container.getBoundingClientRect();\n const full = await withTimeout(\n domToPng(container, {\n scale,\n backgroundColor: getComputedStyle(document.body).backgroundColor || \"#ffffff\",\n timeout: CAPTURE_TIMEOUT,\n filter: captureFilter,\n }),\n CAPTURE_TIMEOUT + 2000,\n );\n if (!full) return undefined;\n const redact = Array.from(document.querySelectorAll(\"[data-loupe-redact]\")).map((n) =>\n (n as Element).getBoundingClientRect(),\n );\n return await cropRegion(full, rect, origin.left, origin.top, scale, redact);\n } catch (err) {\n console.warn(\"[loupe] region capture failed\", err);\n return undefined;\n }\n}\n\n/** The smallest on-page element whose box fully covers the selection rectangle. */\nfunction regionContainer(rect: RegionRect): HTMLElement {\n const cx = rect.x + rect.w / 2;\n const cy = rect.y + rect.h / 2;\n let node = document.elementFromPoint(cx, cy) as HTMLElement | null;\n if (node && node.closest(\"#loupe-root\")) node = null; // never our own UI\n const covers = (r: DOMRect) =>\n r.left <= rect.x && r.top <= rect.y && r.right >= rect.x + rect.w && r.bottom >= rect.y + rect.h;\n while (node && node !== document.body && node !== document.documentElement) {\n if (covers(node.getBoundingClientRect())) return node;\n node = node.parentElement;\n }\n return document.body;\n}\n\n/** Options for a screen recording. */\nexport interface RecordOptions {\n /** Auto-stop after this many ms (a safety cap so recordings never run forever). */\n maxMs?: number;\n /** Called once with a `stop()` fn so the caller can wire a Stop button to it. */\n register?: (stop: () => void) => void;\n}\n\n/** Best available webm MIME the browser can record, or \"\" to let MediaRecorder pick. */\nfunction pickRecordingMime(): string {\n const MR: any = (window as any).MediaRecorder;\n if (!MR?.isTypeSupported) return \"\";\n for (const t of [\"video/webm;codecs=vp9\", \"video/webm;codecs=vp8\", \"video/webm\"]) {\n if (MR.isTypeSupported(t)) return t;\n }\n return \"\";\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const r = new FileReader();\n r.onload = () => resolve(String(r.result));\n r.onerror = () => reject(r.error);\n r.readAsDataURL(blob);\n });\n}\n\n/** Read a file the reporter picked into a data URL (for upload, or offline storage). */\nexport function fileToDataUrl(file: File): Promise<string> {\n return blobToDataUrl(file);\n}\n\n/** Classify an attachment by MIME type — videos play inline, images render as thumbs. */\nexport function attachmentKind(mime: string | undefined): \"image\" | \"video\" {\n return (mime ?? \"\").startsWith(\"video/\") ? \"video\" : \"image\";\n}\n\n/**\n * Record a screen video cropped to `rect` (viewport coords), mirroring the region\n * screenshot flow. Uses getDisplayMedia (real pixels) — the browser shows a share\n * prompt; picking the current tab keeps the crop aligned. Each frame is drawn to a\n * canvas cropped to the selection, then re-encoded to webm. Returns a data URL, or\n * undefined if the user cancels the prompt or recording isn't supported. The default\n * is overridable via LoupeConfig.captureRecording (e.g. the extension).\n */\nexport async function captureRegionRecording(rect: RegionRect, opts?: RecordOptions): Promise<string | undefined> {\n const md = navigator.mediaDevices as MediaDevices & {\n getDisplayMedia?: (c?: any) => Promise<MediaStream>;\n };\n if (!md?.getDisplayMedia || !(window as any).MediaRecorder) return undefined;\n\n let stream: MediaStream;\n try {\n stream = await md.getDisplayMedia({ video: { frameRate: 30 }, audio: false, preferCurrentTab: true } as any);\n } catch {\n return undefined; // user dismissed the picker\n }\n\n try {\n return await recordCropped(stream, rect, opts);\n } catch (err) {\n console.warn(\"[loupe] screen recording failed\", err);\n return undefined;\n } finally {\n stream.getTracks().forEach((t) => t.stop());\n }\n}\n\nasync function recordCropped(stream: MediaStream, rect: RegionRect, opts?: RecordOptions): Promise<string | undefined> {\n const maxMs = opts?.maxMs ?? 20000;\n const video = document.createElement(\"video\");\n video.srcObject = stream;\n video.muted = true;\n (video as any).playsInline = true;\n await video.play().catch(() => undefined);\n\n const track = stream.getVideoTracks()[0];\n const s = track?.getSettings?.() ?? {};\n const vw = (s.width as number) || video.videoWidth || window.innerWidth;\n const vh = (s.height as number) || video.videoHeight || window.innerHeight;\n // The shared surface (ideally the current tab) maps to the page viewport by scale.\n const sx = vw / window.innerWidth;\n const sy = vh / window.innerHeight;\n const cw = Math.max(2, Math.round(rect.w * sx));\n const ch = Math.max(2, Math.round(rect.h * sy));\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = cw;\n canvas.height = ch;\n const ctx = canvas.getContext(\"2d\")!;\n let raf = 0;\n const draw = () => {\n try { ctx.drawImage(video, rect.x * sx, rect.y * sy, cw, ch, 0, 0, cw, ch); } catch { /* not ready yet */ }\n raf = requestAnimationFrame(draw);\n };\n draw();\n\n const out = (canvas as HTMLCanvasElement & { captureStream(fps?: number): MediaStream }).captureStream(30);\n const mime = pickRecordingMime();\n const rec = new MediaRecorder(out, mime ? { mimeType: mime } : undefined);\n const chunks: BlobPart[] = [];\n rec.ondataavailable = (e) => { if (e.data && e.data.size) chunks.push(e.data); };\n\n const stop = () => { if (rec.state !== \"inactive\") rec.stop(); };\n opts?.register?.(stop);\n // Auto-stop on the cap, or when the user ends the share via the browser UI.\n const timer = window.setTimeout(stop, maxMs);\n track?.addEventListener(\"ended\", stop);\n\n const done = new Promise<void>((resolve) => { rec.onstop = () => resolve(); });\n rec.start();\n await done;\n\n window.clearTimeout(timer);\n cancelAnimationFrame(raf);\n if (!chunks.length) return undefined;\n return blobToDataUrl(new Blob(chunks, { type: mime || \"video/webm\" }));\n}\n\n/** Crop `rect` (viewport coords) out of a full-page data URL whose origin sits at (ox, oy). */\nfunction cropRegion(\n dataUrl: string,\n rect: RegionRect,\n ox: number,\n oy: number,\n scale: number,\n redact: DOMRect[],\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n const sw = Math.max(1, Math.round(rect.w * scale));\n const sh = Math.max(1, Math.round(rect.h * scale));\n const canvas = document.createElement(\"canvas\");\n canvas.width = sw;\n canvas.height = sh;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.drawImage(img, (rect.x - ox) * scale, (rect.y - oy) * scale, sw, sh, 0, 0, sw, sh);\n ctx.fillStyle = \"#0f0f14\";\n for (const r of redact) {\n ctx.fillRect((r.left - rect.x) * scale, (r.top - rect.y) * scale, r.width * scale, r.height * scale);\n }\n resolve(canvas.toDataURL(\"image/png\"));\n };\n img.onerror = reject;\n img.src = dataUrl;\n });\n}\n","import type { Attachment, Comment, StorageAdapter } from \"./types.js\";\nimport { attachmentKind, fileToDataUrl } from \"./capture.js\";\n\n/**\n * Prototype storage: everything lives in localStorage, keyed by project + path.\n * The production adapter swaps this for HTTP calls to the backend — the SDK\n * only depends on the StorageAdapter interface, so nothing else changes.\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n private key(projectKey: string, url: string) {\n return `loupe:${projectKey}:${url}`;\n }\n\n private readAll(projectKey: string, url: string): Comment[] {\n try {\n const raw = localStorage.getItem(this.key(projectKey, url));\n return raw ? (JSON.parse(raw) as Comment[]) : [];\n } catch {\n return [];\n }\n }\n\n private writeAll(projectKey: string, url: string, comments: Comment[]) {\n localStorage.setItem(this.key(projectKey, url), JSON.stringify(comments));\n }\n\n async list(projectKey: string, url: string): Promise<Comment[]> {\n return this.readAll(projectKey, url);\n }\n\n async save(comment: Comment): Promise<Comment> {\n const all = this.readAll(comment.projectKey, comment.url);\n all.push(comment);\n this.writeAll(comment.projectKey, comment.url, all);\n return comment;\n }\n\n /**\n * Offline mode: keep the file inline. localStorage is only a few MB, so refuse\n * anything that would blow the quota rather than silently dropping it.\n */\n async upload(_projectKey: string, file: File): Promise<Attachment> {\n if (file.size > 3_000_000) throw new Error(\"attachment too large for offline mode\");\n return {\n url: await fileToDataUrl(file),\n name: file.name,\n mime: file.type || undefined,\n kind: attachmentKind(file.type),\n size: file.size,\n };\n }\n\n async update(id: string, patch: Partial<Comment>): Promise<void> {\n // We don't know the url here, so scan the loupe:* keys for the id.\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (!k || !k.startsWith(\"loupe:\")) continue;\n const list = JSON.parse(localStorage.getItem(k) || \"[]\") as Comment[];\n const idx = list.findIndex((c) => c.id === id);\n if (idx >= 0) {\n list[idx] = { ...list[idx]!, ...patch };\n localStorage.setItem(k, JSON.stringify(list));\n return;\n }\n }\n }\n\n async remove(id: string): Promise<void> {\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (!k || !k.startsWith(\"loupe:\")) continue;\n const list = JSON.parse(localStorage.getItem(k) || \"[]\") as Comment[];\n const next = list.filter((c) => c.id !== id);\n if (next.length !== list.length) {\n localStorage.setItem(k, JSON.stringify(next));\n return;\n }\n }\n }\n}\n","import type { Attachment, Comment, LoupeUser, StorageAdapter } from \"./types.js\";\nimport { attachmentKind, fileToDataUrl } from \"./capture.js\";\n\n/**\n * Talks to the Loupe backend. Selected automatically when `apiBase` is set in\n * init(). Sends the identity headers the backend verifies (HMAC in production).\n */\nexport class HttpAdapter implements StorageAdapter {\n constructor(\n private base: string,\n private user: LoupeUser,\n private userHmac?: string,\n private extraHeaders?: Record<string, string>,\n private credentials?: RequestCredentials,\n ) {\n this.base = base.replace(/\\/$/, \"\");\n }\n\n private headers(): HeadersInit {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\", \"X-Loupe-User\": this.user.id };\n if (this.userHmac) h[\"X-Loupe-Hmac\"] = this.userHmac;\n if (this.extraHeaders) Object.assign(h, this.extraHeaders);\n return h;\n }\n\n /** Base fetch options shared by every request (credentials mode, if set). */\n private opts(init?: RequestInit): RequestInit {\n return this.credentials ? { credentials: this.credentials, ...init } : { ...init };\n }\n\n async list(projectKey: string, url: string): Promise<Comment[]> {\n const q = new URLSearchParams({ projectKey, url });\n const res = await fetch(`${this.base}/v1/comments?${q}`, this.opts({ headers: this.headers() }));\n if (!res.ok) throw new Error(`list failed: ${res.status}`);\n return (await res.json()) as Comment[];\n }\n\n /** Upload an inline data-URL asset to object storage; return its URL (or the data URL on failure). */\n private async uploadBlob(projectKey: string, data: string): Promise<string> {\n try {\n const up = await fetch(`${this.base}/v1/blobs`, this.opts({\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify({ projectKey, data }),\n }));\n if (up.ok) return (await up.json()).url as string;\n } catch {\n /* fall back to inlining below */\n }\n return data;\n }\n\n async save(comment: Comment): Promise<Comment> {\n // Upload media to object storage first, then store only the URL — keeps the\n // comment row (and every later list/read) small.\n if (comment.screenshot?.startsWith(\"data:\")) {\n comment = { ...comment, screenshot: await this.uploadBlob(comment.projectKey, comment.screenshot) };\n }\n if (comment.recording?.startsWith(\"data:\")) {\n comment = { ...comment, recording: await this.uploadBlob(comment.projectKey, comment.recording) };\n }\n const res = await fetch(`${this.base}/v1/comments`, this.opts({\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify(comment),\n }));\n if (!res.ok) throw new Error(`save failed: ${res.status}`);\n return (await res.json()) as Comment;\n }\n\n /** Persist one reporter-attached file to object storage and describe it. */\n async upload(projectKey: string, file: File): Promise<Attachment> {\n const data = await fileToDataUrl(file);\n return {\n url: await this.uploadBlob(projectKey, data),\n name: file.name,\n mime: file.type || undefined,\n kind: attachmentKind(file.type),\n size: file.size,\n };\n }\n\n async update(id: string, patch: Partial<Comment>): Promise<void> {\n const res = await fetch(`${this.base}/v1/comments/${encodeURIComponent(id)}`, this.opts({\n method: \"PATCH\",\n headers: this.headers(),\n body: JSON.stringify(patch),\n }));\n if (!res.ok) throw new Error(`update failed: ${res.status}`);\n }\n\n async remove(id: string): Promise<void> {\n const res = await fetch(`${this.base}/v1/comments/${encodeURIComponent(id)}`, this.opts({\n method: \"DELETE\",\n headers: this.headers(),\n }));\n if (!res.ok && res.status !== 404) throw new Error(`remove failed: ${res.status}`);\n }\n}\n","// Canonical types + pure helpers shared across the SDK, server, dashboard, and MCP.\n/** Board order, left to right. */\nexport const COMMENT_STAGES = [\"queue\", \"todo\", \"in_progress\", \"in_review\", \"resolved\"];\n/** Human labels for the board columns. */\nexport const STAGE_LABELS = {\n queue: \"Queue\",\n todo: \"To Do\",\n in_progress: \"In Progress\",\n in_review: \"In Review\",\n resolved: \"Resolved\",\n};\n/**\n * Statuses this project shipped before the five-stage board. Still accepted on\n * input (and on rows written by an older client) so a rolling upgrade never\n * writes a value the board cannot place.\n */\nconst LEGACY_STATUS = {\n open: \"queue\",\n in_progress: \"in_progress\",\n done: \"resolved\",\n};\n/**\n * Coerce any accepted status — current stage or legacy alias — into a stage.\n * Anything unrecognised lands in `queue`, the untriaged inbox, rather than\n * falling off the board entirely.\n */\nexport function normalizeStatus(value) {\n if (typeof value === \"string\") {\n if (COMMENT_STAGES.includes(value))\n return value;\n if (value in LEGACY_STATUS)\n return LEGACY_STATUS[value];\n }\n return \"queue\";\n}\n/** Whether a comment is still open work (everything except `resolved`). */\nexport function isOpenStage(stage) {\n return stage !== \"resolved\";\n}\n/** Priorities, most urgent first. */\nexport const COMMENT_PRIORITIES = [\"critical\", \"high\", \"medium\", \"low\"];\n/** Human labels for the priority chips. */\nexport const PRIORITY_LABELS = {\n critical: \"Critical\",\n high: \"High\",\n medium: \"Medium\",\n low: \"Low\",\n};\n/** Sort key: 0 is the most urgent, so `a - b` sorts correctly. */\nexport const PRIORITY_RANK = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n};\n/** Change types. */\nexport const CHANGE_TYPES = [\"frontend\", \"backend\", \"api\", \"other\"];\n/** Human labels for the change-type chips. */\nexport const CHANGE_TYPE_LABELS = {\n frontend: \"Frontend\",\n backend: \"Backend\",\n api: \"API\",\n other: \"Other\",\n};\n/** Defaults applied when a comment does not say. */\nexport const DEFAULT_PRIORITY = \"medium\";\nexport const DEFAULT_CHANGE_TYPE = \"other\";\n/** Coerce any value into a priority, falling back to the default. */\nexport function normalizePriority(value) {\n if (typeof value === \"string\" && COMMENT_PRIORITIES.includes(value)) {\n return value;\n }\n return DEFAULT_PRIORITY;\n}\n/** Coerce any value into a change type, falling back to the default. */\nexport function normalizeChangeType(value) {\n if (typeof value === \"string\" && CHANGE_TYPES.includes(value)) {\n return value;\n }\n return DEFAULT_CHANGE_TYPE;\n}\n/** Classify a viewport width into a device bucket (mobile < 768 ≤ tablet < 1024 ≤ desktop). */\nexport function deviceType(width) {\n if (width < 768)\n return \"mobile\";\n if (width < 1024)\n return \"tablet\";\n return \"desktop\";\n}\nconst DROP_EXACT = new Set([\n \"api\", \"key\", \"fbclid\", \"gclid\", \"gbraid\", \"wbraid\", \"msclkid\",\n \"ref\", \"ref_src\", \"mc_cid\", \"mc_eid\", \"_hsenc\", \"_hsmi\", \"igshid\",\n]);\n/**\n * Normalize a page URL so comments don't fragment across tracking/volatile params.\n * Keeps the path + a filtered, sorted query. Drops utm_*, click ids, and Loupe's\n * own dev params (api/key). Accepts a full URL or a path+search string.\n */\nexport function normalizeUrl(input) {\n try {\n const u = new URL(input, \"http://loupe.local\");\n let path = u.pathname;\n const kept = [];\n for (const [k, v] of u.searchParams) {\n const key = k.toLowerCase();\n if (DROP_EXACT.has(key) || key.startsWith(\"utm_\"))\n continue;\n kept.push([k, v]);\n }\n kept.sort((a, b) => (a[0] === b[0] ? a[1].localeCompare(b[1]) : a[0].localeCompare(b[0])));\n const qs = new URLSearchParams(kept).toString();\n if (path.length > 1 && path.endsWith(\"/\"))\n path = path.slice(0, -1);\n return path + (qs ? `?${qs}` : \"\");\n }\n catch {\n const i = input.indexOf(\"?\");\n return i >= 0 ? input.slice(0, i) : input;\n }\n}\n","import { STYLES } from \"./styles.js\";\nimport { captureAnchor, resolveAnchor } from \"./fingerprint.js\";\nimport { attachmentKind, captureElementContext, captureScreenshot, captureRegionScreenshot, captureRegionRecording } from \"./capture.js\";\nimport { LocalStorageAdapter } from \"./store.js\";\nimport { HttpAdapter } from \"./http-adapter.js\";\nimport {\n CHANGE_TYPES,\n CHANGE_TYPE_LABELS,\n COMMENT_PRIORITIES,\n DEFAULT_CHANGE_TYPE,\n DEFAULT_PRIORITY,\n normalizeStatus,\n PRIORITY_LABELS,\n} from \"./types.js\";\nimport type {\n Anchor, Attachment, ChangeType, Comment, CommentPriority, LoupeConfig, RegionRect, StorageAdapter,\n} from \"./types.js\";\n\ndeclare const __LOUPE_VERSION__: string | undefined;\n/** The build that produced this bundle (baked in by tsup); recorded on every comment. */\nconst SDK_VERSION = typeof __LOUPE_VERSION__ === \"string\" ? __LOUPE_VERSION__ : \"dev\";\n\ntype Mode = \"off\" | \"inspect\" | \"region\" | \"free\" | \"record\";\n/** Where the control panel is anchored. */\ntype DockMode = \"left\" | \"right\" | \"bottom\" | \"float\";\n/** Which sidebar page is showing in the dock. */\ntype Tab = \"comments\" | \"connect\";\n/** What the composer is about to attach a comment to. */\ntype ComposeTarget =\n | { kind: \"element\"; element: Element }\n | { kind: \"region\"; region: RegionRect; element: Element | null; screenshot?: string; recording?: string }\n | { kind: \"free\"; offset: { x: number; y: number }; point: { x: number; y: number }; label?: string };\n\nconst DOCK_MODES: DockMode[] = [\"left\", \"right\", \"bottom\", \"float\"];\n/** How long a single screen recording may run before it auto-stops. */\nconst RECORD_MAX_MS = 20000;\n/** Attachment limits for the composer — small enough to survive a base64 POST. */\nconst MAX_FILES = 10;\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024;\nconst MAX_VIDEO_BYTES = 25 * 1024 * 1024;\n\nconst uid = () =>\n (crypto as any).randomUUID ? crypto.randomUUID() : \"c_\" + Math.abs(hash(String(performance.now()))).toString(36);\nfunction hash(s: string) { let h = 0; for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0; return h; }\n\n/**\n * A phone/tablet. `(pointer: coarse)` is the primary signal, but a phone asking for the\n * **desktop site** reports a FINE pointer, so touch capability is the backstop. Getting\n * this wrong sends a finger user down the mouse path: a composer that grabs the focus\n * (keyboard over the page) and a drag-select that fights the page scroll.\n */\nfunction isTouchDevice(): boolean {\n try {\n if (window.matchMedia(\"(pointer: coarse)\").matches) return true;\n if (window.matchMedia(\"(hover: none)\").matches) return true;\n } catch {\n /* matchMedia unavailable */\n }\n if (typeof navigator !== \"undefined\" && (navigator.maxTouchPoints ?? 0) > 0) return true;\n return typeof window !== \"undefined\" && \"ontouchstart\" in window;\n}\n\n/** Whether the browser says the primary pointer is coarse (diagnostic only). */\nfunction coarsePointer(): boolean {\n try {\n return window.matchMedia(\"(pointer: coarse)\").matches;\n } catch {\n return false;\n }\n}\n\n/** Whether screen recording is possible at all (absent in every iOS browser). */\nfunction canShareScreen(): boolean {\n return typeof (navigator.mediaDevices as MediaDevices | undefined)?.getDisplayMedia === \"function\";\n}\n\n/** A captured data-URL as a File, so a screenshot can ride along as a normal attachment. */\nfunction dataUrlToFile(dataUrl: string, name: string): File | null {\n const m = /^data:([^;,]+)(;base64)?,([\\s\\S]*)$/.exec(dataUrl);\n if (!m) return null;\n const [, type, b64, payload = \"\"] = m;\n try {\n const raw = b64 ? atob(payload) : decodeURIComponent(payload);\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);\n return new File([bytes], name, { type: type || \"image/png\" });\n } catch {\n return null;\n }\n}\n\nexport class LoupeApp {\n private cfg: LoupeConfig;\n private store: StorageAdapter;\n private root!: HTMLElement;\n private shadow!: ShadowRoot;\n private overlay!: HTMLElement;\n private hl!: HTMLElement;\n private selbox!: HTMLElement;\n private regionBox!: HTMLElement;\n private composer!: HTMLElement;\n\n /** The dockable control panel (header + tabs + tools + comment list). */\n private dock!: HTMLElement;\n /**\n * The collapsed FAB cluster shown while the panel is closed: a primary brand\n * button (with the comment count) plus quick actions that expand out of it.\n * `launcher` is the primary button itself (kept as a class for the dock's\n * show/hide logic); `fabMinis` is the row of quick actions.\n */\n private fabCluster!: HTMLElement;\n private fabMinis!: HTMLElement;\n private fabBadge!: HTMLElement;\n /** Whether the quick-action minis are expanded out of the primary FAB. */\n private fabExpanded = false;\n /** Whether pin markers are hidden on the page (a quick-action toggle, persisted). */\n private markersHidden = false;\n private themeBtn!: HTMLButtonElement;\n private listEl!: HTMLElement;\n private countEl!: HTMLElement;\n /** Floating \"recording…\" indicator + stop button, shown only while recording. */\n private recBar!: HTMLElement;\n /** Stops the in-flight screen recording (wired while recording). */\n private stopRecording?: () => void;\n\n private comments: Comment[] = [];\n /** Free-text filter over the list (title / body / author). */\n private search = \"\";\n /** Ids of list items the user expanded — items are collapsed by default. */\n private expanded = new Set<string>();\n /** comment.id → currently resolved element (or null when detached). */\n private resolved = new Map<string, Element | null>();\n /** comment.id → pin element. */\n private pins = new Map<string, HTMLElement>();\n\n private mode: Mode = \"off\";\n private lastUrl = \"\";\n /** In-flight region screenshot, captured in the background while the composer is open. */\n private pendingShot?: Promise<string | undefined>;\n private targetOffset = { x: 0.5, y: 0.5 };\n private pending: ComposeTarget | null = null;\n private dragStart: { x: number; y: number } | null = null;\n /** region comment whose outline is currently highlighted (tracks scroll). */\n private activeRegionId: string | null = null;\n private regionTimer?: number;\n\n // ---- control-panel state (persisted in localStorage `loupe:dock`) ----------\n private dockMode: DockMode = \"right\";\n private open = true;\n private theme: \"dark\" | \"light\" = \"dark\";\n private tab: Tab = \"comments\";\n /** Float-mode window geometry; (x<=0 && y<=0) → placed on first layout. */\n private floatRect = { x: 0, y: 0, w: 380, h: 540 };\n private floatDrag: { px: number; py: number; ox: number; oy: number } | null = null;\n private floatResize: { px: number; py: number; ow: number; oh: number } | null = null;\n\n private raf = 0;\n private mo?: MutationObserver;\n private tick?: number;\n\n constructor(cfg: LoupeConfig) {\n this.cfg = cfg;\n // apiBase set → talk to the backend; otherwise persist locally (prototype).\n this.store = cfg.apiBase\n ? new HttpAdapter(cfg.apiBase, cfg.user, cfg.userHmac, cfg.headers, cfg.credentials)\n : new LocalStorageAdapter();\n }\n\n private get url() { return location.pathname + location.search; }\n\n async start() {\n this.loadState();\n this.buildDom();\n if (this.cfg.autoOpen) this.open = true;\n this.applyDockLayout();\n this.lastUrl = this.url;\n this.comments = await this.store.list(this.cfg.projectKey, this.url);\n this.renderPins();\n this.renderList();\n this.observe();\n this.watchNavigation();\n if (this.cfg.autoOpen) this.setMode(\"inspect\");\n }\n\n /**\n * Reload comments when the page URL changes without a full reload (SPA\n * navigation), so each page only ever shows its own comments.\n */\n private watchNavigation() {\n const onChange = () => {\n if (this.url === this.lastUrl) return;\n this.lastUrl = this.url;\n void this.reloadComments();\n };\n addEventListener(\"popstate\", onChange);\n // history.pushState/replaceState don't emit events — wrap them once.\n for (const key of [\"pushState\", \"replaceState\"] as const) {\n const original = history[key];\n history[key] = function (this: History, ...args: unknown[]) {\n const result = (original as (...a: unknown[]) => unknown).apply(this, args);\n dispatchEvent(new Event(\"loupe:locationchange\"));\n return result;\n } as History[typeof key];\n }\n addEventListener(\"loupe:locationchange\", onChange);\n }\n\n private async reloadComments() {\n try {\n this.comments = await this.store.list(this.cfg.projectKey, this.url);\n this.renderPins();\n this.renderList();\n } catch { /* keep the current view on transient errors */ }\n }\n\n // ---- DOM construction -----------------------------------------------------\n\n private buildDom() {\n this.root = document.createElement(\"div\");\n this.root.id = \"loupe-root\";\n document.body.appendChild(this.root);\n this.shadow = this.root.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n style.textContent = STYLES;\n this.shadow.appendChild(style);\n\n this.overlay = el(\"div\", \"overlay\");\n this.hl = el(\"div\", \"hl\");\n this.hl.appendChild(el(\"span\", \"tip\"));\n this.selbox = el(\"div\", \"selbox\");\n this.regionBox = el(\"div\", \"region-box\");\n this.overlay.append(this.hl, this.selbox, this.regionBox);\n this.shadow.appendChild(this.overlay);\n\n this.composer = el(\"div\", \"composer\");\n this.shadow.appendChild(this.composer);\n\n this.dock = this.buildDock();\n this.fabCluster = this.buildFabCluster();\n this.recBar = this.buildRecBar();\n this.shadow.append(this.dock, this.fabCluster, this.recBar);\n }\n\n /**\n * The dockable control panel:\n * header (brand + dock controls) → tabs → [Comments view: tools + list + integrations]\n * and a [Connect view] with the Claude/MCP onboarding steps.\n */\n private buildDock(): HTMLElement {\n const dock = el(\"div\", \"dock\");\n\n // header ------------------------------------------------------------------\n const head = el(\"div\", \"dhead\");\n const brand = el(\"div\", \"brand\");\n brand.innerHTML = `<span class=\"logo\">◎</span><span class=\"title\"></span>`;\n (brand.querySelector(\".title\") as HTMLElement).textContent = this.cfg.label ?? \"Loupe\";\n head.addEventListener(\"pointerdown\", this.onHeadPointerDown); // drag in float mode\n\n const ctl = el(\"div\", \"dctl\");\n const dockBtn = (mode: DockMode, icon: string, title: string) => {\n const b = el(\"button\") as HTMLButtonElement;\n b.dataset.dock = mode;\n b.title = title;\n b.setAttribute(\"aria-label\", title);\n b.innerHTML = icon;\n b.onclick = () => this.setDock(mode);\n return b;\n };\n // Order mirrors DevTools: dock-left, dock-bottom, dock-right, undock/float.\n ctl.append(\n dockBtn(\"left\", I_DOCK_LEFT, \"Dock to left\"),\n dockBtn(\"bottom\", I_DOCK_BOTTOM, \"Dock to bottom\"),\n dockBtn(\"right\", I_DOCK_RIGHT, \"Dock to right\"),\n dockBtn(\"float\", I_FLOAT, \"Float\"),\n el(\"span\", \"gap\"),\n );\n this.themeBtn = el(\"button\") as HTMLButtonElement;\n this.themeBtn.dataset.role = \"theme\";\n this.themeBtn.onclick = () => this.toggleTheme();\n const closeBtn = el(\"button\") as HTMLButtonElement;\n closeBtn.dataset.role = \"close\";\n closeBtn.title = \"Close\";\n closeBtn.setAttribute(\"aria-label\", \"Close\");\n closeBtn.innerHTML = I_CLOSE;\n closeBtn.onclick = () => this.closeDock();\n ctl.append(this.themeBtn, closeBtn);\n\n head.append(brand, ctl);\n\n // tabs (the two sidebar pages) --------------------------------------------\n const tabs = el(\"div\", \"tabs\");\n const commentsTab = el(\"button\", \"tab\", \"Comments\") as HTMLButtonElement;\n commentsTab.dataset.tab = \"comments\";\n commentsTab.onclick = () => this.setTab(\"comments\");\n const connectTab = el(\"button\", \"tab\", \"Connect Claude\") as HTMLButtonElement;\n connectTab.dataset.tab = \"connect\";\n connectTab.onclick = () => this.setTab(\"connect\");\n tabs.append(commentsTab, connectTab);\n\n // tools -------------------------------------------------------------------\n const tools = el(\"div\", \"tools\");\n const inspectBtn = this.toolBtn(\"✛\", \"Inspect\", \"inspect\");\n inspectBtn.title = \"Inspect an element and comment on it\";\n inspectBtn.onclick = () => this.setMode(this.mode === \"inspect\" ? \"off\" : \"inspect\");\n const freeBtn = this.toolBtn(NOTE_ICON, \"Note\", \"free\");\n freeBtn.title = \"Drop a note anywhere on the page — no element, no screenshot\";\n freeBtn.onclick = () => this.setMode(this.mode === \"free\" ? \"off\" : \"free\");\n const regionBtn = this.toolBtn(REGION_ICON, \"Region\", \"region\");\n regionBtn.title = \"Drag a free-size box, screenshot it, and comment\";\n regionBtn.onclick = () => this.setMode(this.mode === \"region\" ? \"off\" : \"region\");\n const recordBtn = this.toolBtn(RECORD_ICON, \"Record\", \"record\");\n recordBtn.title = isTouchDevice()\n ? \"Record your screen, then describe the issue\"\n : \"Drag a box, record a screen video of it, and comment\";\n recordBtn.onclick = () => this.setMode(this.mode === \"record\" ? \"off\" : \"record\");\n\n // Screen recording is desktop-only: NO mobile browser supports getDisplayMedia\n // (iOS Safari never has; Chrome/Firefox on Android expose it in old versions but every\n // call fails — recorded as unsupported). So on a phone we cannot record the screen\n // from the page at all. What we can do is take the clip the phone already recorded\n // with its own screen recorder — so open the picker for it, and deliberately WITHOUT\n // a `capture` attribute: that would open the camera, and filming the room is not a\n // screen recording.\n if (canShareScreen()) {\n tools.append(inspectBtn, freeBtn, regionBtn, recordBtn);\n } else if (isTouchDevice()) {\n const videoBtn = this.toolBtn(VIDEO_ICON, \"Video\", \"video\");\n videoBtn.title = \"Attach a video — record your screen with your phone, then pick it here\";\n videoBtn.onclick = () => this.pickVideo();\n tools.append(inspectBtn, freeBtn, regionBtn, videoBtn);\n } else {\n tools.append(inspectBtn, freeBtn, regionBtn);\n }\n\n // list --------------------------------------------------------------------\n const listHead = el(\"div\", \"listhead\");\n listHead.append(document.createTextNode(\"Comments\"));\n this.countEl = el(\"span\", \"count\", \"0\");\n listHead.appendChild(this.countEl);\n const search = el(\"input\", \"search\") as HTMLInputElement;\n search.type = \"search\";\n search.placeholder = \"Search…\";\n search.value = this.search;\n search.oninput = () => { this.search = search.value; this.renderList(); };\n listHead.appendChild(search);\n this.listEl = el(\"div\", \"list\");\n\n // Comments view = tools + list + the \"integrates with\" footer.\n const commentsView = el(\"div\", \"view comments-view\");\n commentsView.append(tools, listHead, this.listEl, this.buildIntegrations());\n\n // Connect view = the Claude/MCP onboarding page.\n const connectView = this.buildConnectPanel();\n\n const resize = el(\"div\", \"resize\");\n resize.addEventListener(\"pointerdown\", this.onResizeDown);\n\n dock.append(head, tabs, commentsView, connectView, resize);\n return dock;\n }\n\n /** The \"INTEGRATES WITH\" footer on the Comments page (visual only for now). */\n private buildIntegrations(): HTMLElement {\n const wrap = el(\"div\", \"integrations\");\n wrap.append(el(\"div\", \"ilabel\", \"INTEGRATES WITH\"));\n const row = el(\"div\", \"irow\");\n const icons: [string, string][] = [\n [\"GitHub\", I_GITHUB],\n [\"Slack\", I_SLACK],\n [\"Telegram\", I_TELEGRAM],\n [\"Linear\", I_LINEAR],\n ];\n for (const [name, icon] of icons) {\n const b = el(\"span\", \"ibtn\");\n b.title = `${name} — connect (coming soon)`;\n b.setAttribute(\"aria-label\", name);\n b.innerHTML = icon;\n row.appendChild(b);\n }\n wrap.appendChild(row);\n return wrap;\n }\n\n /** The \"Connect Claude\" onboarding page: how to wire the MCP server to this project. */\n private buildConnectPanel(): HTMLElement {\n const view = el(\"div\", \"view connect-view\");\n const key = this.cfg.projectKey;\n const apiHint = this.cfg.apiBase ?? \"http://localhost:8787\";\n const config = JSON.stringify(\n {\n mcpServers: {\n loupe: {\n command: \"npx\",\n args: [\"-y\", \"@loupekit/mcp\"],\n env: { LOUPE_API: apiHint, LOUPE_PROJECT_KEY: key, LOUPE_ADMIN_KEY: \"<your project secret>\" },\n },\n },\n },\n null,\n 2,\n );\n const steps: [string, string][] = [\n [\"Pin your feedback\", \"Use Inspect, Region, Record, or Note to leave comments right on the live app.\"],\n [\"Add the Loupe MCP server\", \"Drop this into your Claude Code config so Claude can read this project's backlog:\"],\n [\"Let Claude fix it\", \"Claude reads each comment (with the screenshot, HTML & CSS), rewrites the UI, and calls propose_change — the modified HTML/CSS then shows up for your dev team in the dashboard.\"],\n ];\n const hero = el(\"div\", \"connect-hero\");\n hero.innerHTML =\n `<div class=\"chero-logo\">◎</div>` +\n `<div class=\"chero-title\">Hand your feedback to <span class=\"accentink\">Claude</span></div>` +\n `<div class=\"chero-sub\">Every pinned comment becomes an actionable, fully-contextualized task Claude Code can act on.</div>`;\n view.appendChild(hero);\n const list = el(\"ol\", \"connect-steps\");\n steps.forEach(([t, d], i) => {\n const li = el(\"li\");\n li.innerHTML = `<div class=\"cstep-t\">${i + 1}. ${escapeHtml(t)}</div><div class=\"cstep-d\">${escapeHtml(d)}</div>`;\n if (i === 1) {\n const pre = el(\"pre\", \"cstep-code\");\n pre.textContent = config;\n li.appendChild(pre);\n }\n list.appendChild(li);\n });\n view.appendChild(list);\n return view;\n }\n\n /** The floating \"recording…\" pill with a Stop button (shown only while recording). */\n private buildRecBar(): HTMLElement {\n const bar = el(\"button\", \"recbar\") as HTMLButtonElement;\n bar.title = \"Stop recording\";\n bar.setAttribute(\"aria-label\", \"Stop recording\");\n bar.onclick = () => this.stopRecording?.();\n return bar;\n }\n\n /**\n * The collapsed-state FAB cluster. The primary brand button carries the comment\n * count and toggles the quick actions out and back; the actions are the four\n * ways into the product without opening the full panel first:\n * pin a comment, drop a note, hide/show the markers already on the page, and\n * jump straight to the Claude/MCP setup.\n */\n private buildFabCluster(): HTMLElement {\n const cluster = el(\"div\", \"fab-cluster\");\n\n const minis = el(\"div\", \"fab-minis\");\n const mini = (role: string, icon: string, label: string, title: string) => {\n const b = el(\"button\", \"fab-mini\") as HTMLButtonElement;\n b.dataset.fab = role;\n b.title = title;\n b.setAttribute(\"aria-label\", title);\n b.innerHTML = `${icon}<span class=\"fab-tip\">${label}</span>`;\n return b;\n };\n const comment = mini(\"comment\", I_COMMENT, \"Pin comment\", \"Pin feedback on any element\");\n comment.onclick = () => { this.collapseFab(); this.openDock(); this.setMode(\"inspect\"); };\n const note = mini(\"note\", I_NOTE, \"Note\", \"Drop a note anywhere on the page\");\n note.onclick = () => { this.collapseFab(); this.openDock(); this.setMode(\"free\"); };\n const markers = mini(\"markers\", I_EYE, \"Markers\", \"Show or hide the markers on this page\");\n markers.onclick = () => this.toggleMarkers();\n const connect = mini(\"connect\", I_PLUG, \"Connect Claude\", \"Set up the Claude/MCP connection\");\n connect.onclick = () => { this.collapseFab(); this.openDock(); this.setTab(\"connect\"); };\n minis.append(comment, note, markers, connect);\n\n const primary = el(\"button\", \"launcher\") as HTMLButtonElement;\n primary.title = `Open ${this.cfg.label ?? \"Loupe\"}`;\n primary.setAttribute(\"aria-label\", `${this.cfg.label ?? \"Loupe\"} — quick actions`);\n primary.setAttribute(\"aria-expanded\", \"false\");\n primary.innerHTML = `<span class=\"logo\">◎</span>${I_FAB_CHEVRON}<span class=\"lcount\"></span>`;\n this.fabBadge = primary.querySelector(\".lcount\") as HTMLElement;\n primary.onclick = () => this.toggleFab();\n\n cluster.append(minis, primary);\n this.fabMinis = minis;\n return cluster;\n }\n\n /** Expand/collapse the quick actions out of the primary FAB. */\n private toggleFab() {\n this.fabExpanded = !this.fabExpanded;\n this.applyFab();\n }\n\n private collapseFab() {\n if (!this.fabExpanded) return;\n this.fabExpanded = false;\n this.applyFab();\n }\n\n /** Hide/show every pin on the page without losing them (persisted). */\n private toggleMarkers() {\n this.markersHidden = !this.markersHidden;\n this.saveState();\n this.applyFab();\n }\n\n /** Reflect cluster expansion + marker visibility into the DOM. */\n private applyFab() {\n this.fabCluster.classList.toggle(\"expanded\", this.fabExpanded);\n const primary = this.fabCluster.querySelector(\".launcher\") as HTMLElement | null;\n primary?.setAttribute(\"aria-expanded\", String(this.fabExpanded));\n primary?.setAttribute(\"aria-label\", this.fabExpanded ? \"Close quick actions\" : `Open ${this.cfg.label ?? \"Loupe\"} quick actions`);\n const markers = this.fabCluster.querySelector('[data-fab=\"markers\"]') as HTMLElement | null;\n markers?.classList.toggle(\"on\", this.markersHidden);\n markers?.setAttribute(\"aria-pressed\", String(this.markersHidden));\n // !important in CSS so it beats the inline display set by position().\n this.overlay.classList.toggle(\"hide-pins\", this.markersHidden);\n }\n\n /** A tool button with a uniform icon + label layout. `icon` may be an SVG string. */\n private toolBtn(icon: string, label: string, role: string): HTMLButtonElement {\n const b = el(\"button\") as HTMLButtonElement;\n b.dataset.role = role;\n b.setAttribute(\"aria-label\", label);\n b.innerHTML = `<span class=\"ico\">${icon}</span><span class=\"label\">${label}</span>`;\n return b;\n }\n\n // ---- inspector ------------------------------------------------------------\n\n // Pointer Events, not mouse events: a touch drag on a phone never fires\n // mousemove/mouseup, so Region/Record selection was impossible on touch devices.\n // Pointer events cover mouse, touch and pen with one handler each.\n\n private onMove = (e: PointerEvent) => {\n if (this.mode !== \"inspect\") return;\n const target = this.pick(e.clientX, e.clientY);\n if (!target) { this.hl.style.display = \"none\"; return; }\n const r = target.getBoundingClientRect();\n Object.assign(this.hl.style, {\n display: \"block\", left: r.left + \"px\", top: r.top + \"px\",\n width: r.width + \"px\", height: r.height + \"px\",\n });\n (this.hl.firstChild as HTMLElement).textContent =\n target.tagName.toLowerCase() + (target.id ? \"#\" + target.id : \"\");\n };\n\n private onClick = (e: MouseEvent) => {\n if (this.mode !== \"inspect\") return;\n const target = this.pick(e.clientX, e.clientY);\n if (!target) return;\n e.preventDefault();\n e.stopPropagation();\n const r = target.getBoundingClientRect();\n this.targetOffset = {\n x: r.width ? clamp((e.clientX - r.left) / r.width) : 0.5,\n y: r.height ? clamp((e.clientY - r.top) / r.height) : 0.5,\n };\n this.setMode(\"off\");\n this.openComposer({ kind: \"element\", element: target }, e.clientX, e.clientY);\n };\n\n private onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") { this.cancelDrag(); this.setMode(\"off\"); this.closeComposer(); }\n };\n\n // ---- region (\"free-size screenshot\") selection ----------------------------\n\n private onRegionDown = (e: PointerEvent) => {\n if (this.mode !== \"region\" && this.mode !== \"record\") return;\n // A mouse must use the primary button; touch/pen always start with button 0.\n if (e.pointerType !== \"touch\" && e.pointerType !== \"pen\" && e.button !== 0) return;\n // Ignore drags that start on our own UI (the panel overlays the page).\n const t = e.target as Element | null;\n if (t && (t.id === \"loupe-root\" || t.closest?.(\"#loupe-root\"))) return;\n e.preventDefault();\n e.stopPropagation();\n this.dragStart = { x: e.clientX, y: e.clientY };\n document.addEventListener(\"pointermove\", this.onRegionMove, true);\n document.addEventListener(\"pointerup\", this.onRegionUp, true);\n document.addEventListener(\"pointercancel\", this.onRegionCancel, true);\n this.drawSelection(e.clientX, e.clientY);\n };\n\n private onRegionMove = (e: PointerEvent) => {\n if (!this.dragStart) return;\n e.preventDefault();\n this.drawSelection(e.clientX, e.clientY);\n };\n\n private onRegionUp = (e: PointerEvent) => {\n if (!this.dragStart) return;\n e.preventDefault();\n e.stopPropagation();\n const start = this.dragStart;\n const wasRecord = this.mode === \"record\";\n this.cancelDrag();\n const vp: RegionRect = {\n x: Math.min(start.x, e.clientX), y: Math.min(start.y, e.clientY),\n w: Math.abs(e.clientX - start.x), h: Math.abs(e.clientY - start.y),\n };\n if (vp.w < 8 || vp.h < 8) { this.selbox.style.display = \"none\"; return; } // stray tap\n this.setMode(\"off\");\n if (wasRecord) void this.finishRecording(vp);\n else this.finishRegion(vp);\n };\n\n /** The OS took over the gesture (e.g. a system swipe): drop the selection. */\n private onRegionCancel = () => {\n this.cancelDrag();\n this.selbox.style.display = \"none\";\n };\n\n private drawSelection(curX: number, curY: number) {\n const s = this.dragStart!;\n Object.assign(this.selbox.style, {\n display: \"block\",\n left: Math.min(s.x, curX) + \"px\", top: Math.min(s.y, curY) + \"px\",\n width: Math.abs(curX - s.x) + \"px\", height: Math.abs(curY - s.y) + \"px\",\n });\n }\n\n private cancelDrag() {\n this.dragStart = null;\n document.removeEventListener(\"pointermove\", this.onRegionMove, true);\n document.removeEventListener(\"pointerup\", this.onRegionUp, true);\n document.removeEventListener(\"pointercancel\", this.onRegionCancel, true);\n }\n\n /**\n * Anchor a dragged viewport rect to the element under its center so it survives\n * reflow. `rel` (element-relative fractions) is preferred; document coords are the\n * fallback. Shared by both the Region (screenshot) and Record (video) tools.\n */\n private regionFromViewport(vp: RegionRect): { region: RegionRect; element: Element | null } {\n const centerEl = this.pick(vp.x + vp.w / 2, vp.y + vp.h / 2);\n let rel: RegionRect[\"rel\"];\n if (centerEl) {\n const er = centerEl.getBoundingClientRect();\n if (er.width > 0 && er.height > 0) {\n rel = {\n fx: (vp.x - er.left) / er.width, fy: (vp.y - er.top) / er.height,\n fw: vp.w / er.width, fh: vp.h / er.height,\n };\n }\n }\n const region: RegionRect = { x: vp.x + window.scrollX, y: vp.y + window.scrollY, w: vp.w, h: vp.h, rel };\n return { region, element: centerEl };\n }\n\n /**\n * Touch path for the Region tool: capture what is on screen right now and open the\n * composer with it already attached. The reporter scrolls to the part of the page they\n * mean FIRST, then taps Region — no drag, so nothing fights the page scroll.\n */\n private async captureViewportForComposer() {\n const vp: RegionRect = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };\n const capture = this.cfg.captureRegion ?? captureRegionScreenshot;\n let shot: string | undefined;\n try {\n shot = await capture(vp);\n } catch {\n shot = undefined;\n }\n const file = shot ? dataUrlToFile(shot, \"screenshot.png\") : null;\n const docX = window.scrollX + vp.w / 2;\n const docY = window.scrollY + vp.h / 2;\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };\n this.setMode(\"off\");\n this.openComposer(\n { kind: \"free\", offset, point: { x: docX, y: docY }, label: \"Screenshot · attached\" },\n 8,\n window.innerHeight / 2,\n file ? [file] : []\n );\n }\n\n /**\n * Attach a video on a phone, where the page cannot record the screen: the reporter\n * records it with the phone's own screen recorder first, then picks the clip here. No\n * `capture` attribute on purpose — that would force the camera open, and a video of the\n * room is not a screen recording.\n */\n private pickVideo() {\n this.setMode(\"off\");\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"video/*\";\n input.style.display = \"none\";\n input.onchange = () => {\n const file = input.files?.[0];\n input.remove();\n if (!file) return;\n const docX = window.scrollX + window.innerWidth / 2;\n const docY = window.scrollY + window.innerHeight / 2;\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };\n this.openComposer(\n { kind: \"free\", offset, point: { x: docX, y: docY }, label: \"Video · attached\" },\n 8,\n window.innerHeight / 2,\n [file]\n );\n };\n // In the shadow root: keeps the host page's DOM untouched.\n this.shadow.appendChild(input);\n input.click();\n }\n\n /** Capture the selected viewport rect, then open the composer for a region comment. */\n private async finishRegion(vp: RegionRect) {\n this.selbox.style.display = \"none\";\n const { region, element } = this.regionFromViewport(vp);\n const target: ComposeTarget = { kind: \"region\", region, element };\n // Open the composer immediately; capture the screenshot in the background so a\n // slow capture never blocks the UI. It attaches to the comment on submit.\n this.openComposer(target, vp.x + vp.w, vp.y);\n const capture = this.cfg.captureRegion ?? captureRegionScreenshot;\n this.pendingShot = capture(vp);\n void this.pendingShot.then((shot) => {\n if (shot && this.pending === target) target.screenshot = shot;\n }).catch(() => undefined);\n }\n\n /**\n * Record a screen video of the selected rect (same drag-select as Region), then\n * open the composer with the recording attached. Unlike the screenshot flow this\n * is interactive — the browser share prompt and a Stop button drive it — so the\n * composer opens only once recording has finished.\n */\n private async finishRecording(vp: RegionRect) {\n this.selbox.style.display = \"none\";\n const { region, element } = this.regionFromViewport(vp);\n const capture = this.cfg.captureRecording ?? captureRegionRecording;\n this.showRecBar();\n let recording: string | undefined;\n try {\n // Call the capture synchronously (getDisplayMedia needs the click gesture).\n recording = await capture(vp, {\n maxMs: RECORD_MAX_MS,\n register: (stop) => { this.stopRecording = stop; },\n });\n } catch {\n recording = undefined;\n }\n this.hideRecBar();\n if (!recording) return; // user cancelled the share prompt or capture failed\n const target: ComposeTarget = { kind: \"region\", region, element, recording };\n const x = Math.min(vp.x + vp.w, window.innerWidth - 320);\n this.openComposer(target, x, vp.y);\n }\n\n private showRecBar() {\n this.stopRecording = undefined;\n this.recBar.innerHTML = `<span class=\"recdot\"></span><span>Recording… <b>Stop</b></span>`;\n this.recBar.classList.add(\"show\");\n }\n private hideRecBar() {\n this.recBar.classList.remove(\"show\");\n this.stopRecording = undefined;\n }\n\n /** elementFromPoint, ignoring our own UI. */\n private pick(x: number, y: number): Element | null {\n const hitHl = this.hl.style.display;\n this.hl.style.display = \"none\"; // never let the highlight itself be the hit\n const elAt = document.elementFromPoint(x, y);\n this.hl.style.display = hitHl;\n if (!elAt) return null;\n if (elAt.id === \"loupe-root\" || (elAt as Element).closest?.(\"#loupe-root\")) return null;\n return elAt;\n }\n\n private setMode(mode: Mode) {\n // Tools live on the Comments page — entering a mode implies the panel is open there.\n if (mode !== \"off\") {\n if (!this.open) this.open = true;\n if (this.tab !== \"comments\") { this.tab = \"comments\"; this.saveState(); }\n this.applyDockLayout();\n }\n this.mode = mode;\n this.hl.style.display = \"none\";\n this.selbox.style.display = \"none\";\n this.cancelDrag();\n document.body.style.cursor = mode === \"off\" ? \"\" : \"crosshair\";\n (this.dock.querySelector('[data-role=\"inspect\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"inspect\");\n (this.dock.querySelector('[data-role=\"free\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"free\");\n (this.dock.querySelector('[data-role=\"region\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"region\");\n (this.dock.querySelector('[data-role=\"record\"]') as HTMLElement)?.classList.toggle(\"on\", mode === \"record\");\n // On mobile this shrinks the bottom sheet to just header + tools (see styles)\n // so most of the page stays visible while picking an element/region.\n this.dock.classList.toggle(\"inspecting\", mode !== \"off\");\n\n document.removeEventListener(\"pointermove\", this.onMove, true);\n document.removeEventListener(\"pointerdown\", this.onMove, true);\n document.removeEventListener(\"click\", this.onClick, true);\n document.removeEventListener(\"click\", this.onFreeClick, true);\n document.removeEventListener(\"pointerdown\", this.onRegionDown, true);\n\n if (mode === \"off\") return;\n document.addEventListener(\"keydown\", this.onKey, true);\n this.closeComposer();\n if (mode === \"inspect\") {\n document.addEventListener(\"pointermove\", this.onMove, true);\n // Touch has no hover: highlight on finger-down so the user can see what a tap\n // will select before lifting (the tap itself still arrives as a click).\n document.addEventListener(\"pointerdown\", this.onMove, true);\n document.addEventListener(\"click\", this.onClick, true);\n } else if (mode === \"free\") {\n document.addEventListener(\"click\", this.onFreeClick, true);\n } else if (mode === \"region\" && isTouchDevice()) {\n // No drag-select on touch — a finger covers the area it is drawing, and the drag\n // fights the page scroll. Grab the visible viewport instead (the reporter scrolls\n // to what they mean first, then taps Region) and hand it to the composer.\n void this.captureViewportForComposer();\n } else if (mode === \"record\" && isTouchDevice()) {\n // Same one-tap idea for video: nothing to drag with a finger, so record the whole\n // screen. Called synchronously from the tap — getDisplayMedia needs that gesture.\n const vp: RegionRect = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };\n this.setMode(\"off\");\n void this.finishRecording(vp);\n } else if (mode === \"region\" || mode === \"record\") {\n document.addEventListener(\"pointerdown\", this.onRegionDown, true);\n }\n }\n\n // ---- free note (drop a comment anywhere, no element / no screenshot) -------\n\n private onFreeClick = (e: MouseEvent) => {\n if (this.mode !== \"free\") return;\n const t = e.target as Element | null;\n if (t && (t.id === \"loupe-root\" || t.closest?.(\"#loupe-root\"))) return; // ignore our own UI\n e.preventDefault();\n e.stopPropagation();\n const docX = e.clientX + window.scrollX;\n const docY = e.clientY + window.scrollY;\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n // Store the drop point as a fraction of the document so it survives reloads\n // and reasonable reflow without needing any element anchor.\n const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };\n this.setMode(\"off\");\n this.openComposer({ kind: \"free\", offset, point: { x: docX, y: docY } }, e.clientX, e.clientY);\n };\n\n // ---- composer -------------------------------------------------------------\n\n private openComposer(target: ComposeTarget, x: number, y: number, seedFiles: File[] = []) {\n this.pending = target;\n const isRecording = target.kind === \"region\" && !!target.recording;\n const c = this.composer;\n c.innerHTML = \"\";\n const label = el(\"div\", \"target\",\n target.kind === \"element\" ? describe(target.element)\n : target.kind === \"region\"\n ? (isRecording\n ? `⏺ Recording · ${Math.round(target.region.w)}×${Math.round(target.region.h)} px`\n : `Region · ${Math.round(target.region.w)}×${Math.round(target.region.h)} px`)\n : target.label ?? \"Free note · anywhere on the page\");\n const title = el(\"input\", \"title\") as HTMLInputElement;\n title.type = \"text\";\n title.placeholder = \"Title — one line: what's wrong, or what you need\";\n\n const ta = el(\"textarea\") as HTMLTextAreaElement;\n ta.placeholder = isRecording ? \"Describe the issue in this recording…\"\n : target.kind === \"region\" ? \"Describe the issue in this area…\"\n : target.kind === \"free\" ? \"Describe this note…\"\n : \"Describe what should change here…\";\n\n // Attachments: images and/or videos, several of each. A touch screenshot capture is\n // seeded here so it needs no extra tap to attach.\n const files: File[] = seedFiles.slice();\n const attach = el(\"div\", \"attach\");\n const pick = el(\"button\", \"pick\", \"+ Attach images / videos\") as HTMLButtonElement;\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/*,video/*\";\n input.multiple = true;\n input.style.display = \"none\";\n const chips = el(\"div\", \"chips\");\n const err = el(\"div\", \"err\");\n const drawChips = () => {\n chips.innerHTML = \"\";\n files.forEach((f, idx) => {\n const chip = el(\"span\", \"chip\", `${attachmentKind(f.type) === \"video\" ? \"🎬\" : \"🖼\"} ${f.name}`);\n const x = el(\"button\", \"x\", \"×\") as HTMLButtonElement;\n x.onclick = () => { files.splice(idx, 1); drawChips(); };\n chip.appendChild(x);\n chips.appendChild(chip);\n });\n };\n input.onchange = () => {\n err.textContent = \"\";\n for (const f of Array.from(input.files ?? [])) {\n if (files.length >= MAX_FILES) { err.textContent = `Up to ${MAX_FILES} files.`; break; }\n const cap = attachmentKind(f.type) === \"video\" ? MAX_VIDEO_BYTES : MAX_IMAGE_BYTES;\n if (f.size > cap) { err.textContent = `${f.name} is too large.`; continue; }\n files.push(f);\n }\n input.value = \"\";\n drawChips();\n };\n pick.onclick = () => input.click();\n attach.append(pick, input, chips, err);\n if (files.length) drawChips();\n\n const row = el(\"div\", \"row\");\n // Triage metadata. Both default sensibly so a reporter can ignore them and\n // still file something the team can find and rank.\n const meta = el(\"div\", \"meta2\");\n const prioSel = document.createElement(\"select\");\n prioSel.className = \"mini\";\n prioSel.title = \"Priority\";\n prioSel.setAttribute(\"aria-label\", \"Priority\");\n for (const p of COMMENT_PRIORITIES) {\n prioSel.append(optionEl(PRIORITY_LABELS[p], p, p === DEFAULT_PRIORITY));\n }\n const typeSel = document.createElement(\"select\");\n typeSel.className = \"mini\";\n typeSel.title = \"Change type\";\n typeSel.setAttribute(\"aria-label\", \"Change type\");\n for (const t of CHANGE_TYPES) {\n typeSel.append(optionEl(CHANGE_TYPE_LABELS[t], t, t === DEFAULT_CHANGE_TYPE));\n }\n meta.append(prioSel, typeSel);\n // Free notes carry nothing; recordings always attach the video — both skip the checkbox.\n let box: HTMLInputElement | null = null;\n if (target.kind !== \"free\" && !isRecording) {\n const chk = el(\"label\", \"chk\") as HTMLLabelElement;\n box = document.createElement(\"input\"); box.type = \"checkbox\";\n // Default to attaching. Element shots are captured on submit; region shots are\n // captured in the background and awaited on submit (see pendingShot).\n box.checked = true;\n chk.append(box, document.createTextNode(\"Attach screenshot\"));\n row.append(chk);\n } else {\n row.style.justifyContent = \"flex-end\";\n }\n const btns = el(\"div\", \"btns\");\n const cancel = el(\"button\", \"ghost\", \"Cancel\") as HTMLButtonElement;\n cancel.onclick = () => this.closeComposer();\n const save = el(\"button\", \"primary\", \"Comment\") as HTMLButtonElement;\n save.disabled = true;\n const sync = () => { save.disabled = !title.value.trim() || !ta.value.trim(); };\n title.oninput = sync;\n ta.oninput = sync;\n sync();\n save.onclick = () => this.submit(\n target, title.value.trim(), ta.value.trim(), box ? box.checked : false, files.slice(),\n prioSel.value as CommentPriority, typeSel.value as ChangeType,\n );\n btns.append(cancel, save);\n row.append(btns);\n c.append(label, title, ta, attach, meta, row);\n\n // Position near the click, clamped to the viewport.\n const w = 320, h = 380;\n const left = Math.min(Math.max(8, x + 12), window.innerWidth - w - 8);\n const top = Math.min(Math.max(8, y + 12), window.innerHeight - h - 8);\n Object.assign(c.style, { display: \"block\", left: left + \"px\", top: top + \"px\" });\n // Do not grab focus on touch: it throws the on-screen keyboard up over the very page\n // the reporter is describing (and over our own form).\n if (!isTouchDevice()) ta.focus();\n }\n\n private closeComposer() {\n this.composer.style.display = \"none\";\n this.pending = null;\n this.pendingShot = undefined;\n }\n\n private async submit(\n target: ComposeTarget,\n title: string,\n body: string,\n withShot: boolean,\n files: File[],\n priority: CommentPriority = DEFAULT_PRIORITY,\n changeType: ChangeType = DEFAULT_CHANGE_TYPE,\n ) {\n if (!title || !body) return;\n const saveBtn = this.composer.querySelector(\".primary\") as HTMLButtonElement;\n if (saveBtn) { saveBtn.disabled = true; saveBtn.textContent = \"Saving…\"; }\n\n let anchor: Anchor, context: Comment[\"context\"], offset: Comment[\"offset\"];\n let screenshot: string | undefined;\n let recording: string | undefined;\n let region: RegionRect | undefined;\n let anchoredEl: Element | null = null;\n\n if (target.kind === \"element\") {\n const capture = this.cfg.captureScreenshot ?? captureScreenshot;\n screenshot = withShot ? await capture(target.element) : undefined;\n anchor = captureAnchor(target.element);\n context = captureElementContext(target.element);\n offset = this.targetOffset;\n anchoredEl = target.element;\n } else if (target.kind === \"free\") {\n // A page-level note: no element, no screenshot. Its position lives in\n // `offset` as a fraction of the document (see onFreeClick + position()).\n screenshot = undefined;\n anchor = pageAnchor(target.point);\n context = { html: \"\", styles: {} };\n offset = target.offset;\n } else {\n // A recording carries its own visuals; a plain region uses the background\n // screenshot (awaited only if it hasn't attached yet).\n recording = target.recording;\n screenshot = !recording && withShot ? (target.screenshot ?? await this.pendingShot) : undefined;\n region = target.region;\n offset = { x: 0, y: 0 };\n // Prefer the real center-element anchor (survives reflow + gives Claude a\n // real element); fall back to a synthetic region anchor when there's none.\n if (target.element) {\n anchor = captureAnchor(target.element);\n context = captureElementContext(target.element);\n anchoredEl = target.element;\n } else {\n anchor = regionAnchor(region);\n context = { html: regionNote(region), styles: {} };\n }\n }\n\n const comment: Comment = {\n id: uid(),\n projectKey: this.cfg.projectKey,\n url: this.url,\n author: this.cfg.user,\n title,\n body,\n status: \"queue\",\n priority,\n changeType,\n kind: target.kind,\n anchor,\n context,\n offset,\n region,\n screenshot,\n recording,\n attachments: await this.uploadAttachments(files),\n // The screen this was captured on, plus enough to tell a stale bundle from a real\n // bug when someone reports \"it still doesn't work\" (see Comment.viewport).\n viewport: {\n w: window.innerWidth,\n h: window.innerHeight,\n v: SDK_VERSION,\n touch: isTouchDevice(),\n coarse: coarsePointer(),\n gdm: canShareScreen(),\n },\n createdAt: new Date().toISOString(),\n };\n await this.store.save(comment);\n this.comments.push(comment);\n this.resolved.set(comment.id, anchoredEl);\n this.closeComposer();\n this.renderPins();\n this.renderList();\n this.flash(comment.id);\n }\n\n /** Upload the reporter's picked files. A file that fails is skipped, not fatal. */\n private async uploadAttachments(files: File[]): Promise<Attachment[] | undefined> {\n if (!files.length) return undefined;\n const out: Attachment[] = [];\n for (const f of files) {\n try {\n out.push(await this.store.upload(this.cfg.projectKey, f));\n } catch (e) {\n console.warn(\"[loupe] attachment upload failed\", f.name, e);\n }\n }\n return out.length ? out : undefined;\n }\n\n // ---- pins + re-anchoring --------------------------------------------------\n\n private renderPins() {\n // Remove pins for deleted comments.\n for (const [id, pin] of this.pins) {\n if (!this.comments.find((c) => c.id === id)) { pin.remove(); this.pins.delete(id); }\n }\n this.comments.forEach((c, i) => {\n let pin = this.pins.get(c.id);\n if (!pin) {\n pin = el(\"button\", \"pin\") as HTMLButtonElement;\n pin.onclick = () => { this.openDock(); this.flash(c.id); };\n this.overlay.appendChild(pin);\n this.pins.set(c.id, pin);\n }\n pin.textContent = String(i + 1);\n pin.classList.toggle(\"done\", isResolved(c));\n pin.classList.toggle(\"free\", c.kind === \"free\");\n });\n this.updateCount();\n this.position();\n }\n\n private updateCount() {\n const n = this.comments.length;\n this.countEl.textContent = String(n);\n this.fabBadge.textContent = n ? String(n) : \"\";\n }\n\n /** Reposition every pin, re-resolving anchors whose element has gone. */\n private position = () => {\n for (const c of this.comments) {\n const pin = this.pins.get(c.id);\n if (!pin) continue;\n\n if (c.kind === \"free\") {\n // Page-level note: position from the stored document-fraction offset.\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n const px = c.offset.x * docW - window.scrollX;\n const py = c.offset.y * docH - window.scrollY;\n const onScreen = px > -24 && px < window.innerWidth + 24 && py > -24 && py < window.innerHeight + 24;\n Object.assign(pin.style, { left: px + \"px\", top: py + \"px\", display: onScreen ? \"grid\" : \"none\" });\n pin.classList.remove(\"detached\");\n continue;\n }\n\n let elx = this.resolved.get(c.id) ?? null;\n if (!elx || !elx.isConnected) {\n const r = resolveAnchor(c.anchor);\n elx = r?.element ?? null;\n this.resolved.set(c.id, elx);\n }\n\n if (c.kind === \"region\") {\n // Compute the region's live viewport rect from its anchor element; fall\n // back to stored document coords (older data / no anchor found).\n const box = this.regionRect(c, elx);\n if (box) {\n const onScreen = box.x + box.w > 0 && box.x < window.innerWidth && box.y + box.h > 0 && box.y < window.innerHeight;\n Object.assign(pin.style, { left: box.x + \"px\", top: box.y + \"px\", display: onScreen ? \"grid\" : \"none\" });\n pin.classList.toggle(\"detached\", !elx && !c.region?.rel);\n } else {\n pin.style.display = \"none\";\n pin.classList.add(\"detached\");\n }\n continue;\n }\n\n if (elx) {\n const rect = elx.getBoundingClientRect();\n const px = rect.left + c.offset.x * rect.width;\n const py = rect.top + c.offset.y * rect.height;\n const onScreen = rect.bottom > 0 && rect.top < window.innerHeight && rect.width > 0;\n Object.assign(pin.style, { left: px + \"px\", top: py + \"px\", display: onScreen ? \"grid\" : \"none\" });\n pin.classList.remove(\"detached\");\n } else {\n pin.style.display = \"none\";\n pin.classList.add(\"detached\");\n }\n }\n\n // Keep the highlighted region outline glued to its live rect while scrolling.\n if (this.activeRegionId) {\n const c = this.comments.find((x) => x.id === this.activeRegionId);\n const box = c && this.regionRect(c, this.resolved.get(c.id) ?? null);\n if (box) {\n Object.assign(this.regionBox.style, {\n display: \"block\", left: box.x + \"px\", top: box.y + \"px\", width: box.w + \"px\", height: box.h + \"px\",\n });\n }\n }\n };\n\n /**\n * The current viewport rect for a region comment. Prefers the element-relative\n * fractions (so it tracks reflow across viewports); falls back to the stored\n * document coordinates minus scroll. Returns null if neither is available.\n */\n private regionRect(c: Comment, elx: Element | null): { x: number; y: number; w: number; h: number } | null {\n const rel = c.region?.rel;\n if (elx && rel) {\n const r = elx.getBoundingClientRect();\n return { x: r.left + rel.fx * r.width, y: r.top + rel.fy * r.height, w: rel.fw * r.width, h: rel.fh * r.height };\n }\n if (c.region) {\n return { x: c.region.x - window.scrollX, y: c.region.y - window.scrollY, w: c.region.w, h: c.region.h };\n }\n return null;\n }\n\n private observe() {\n const reposition = () => {\n cancelAnimationFrame(this.raf);\n this.raf = requestAnimationFrame(this.position);\n };\n window.addEventListener(\"scroll\", reposition, true);\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"resize\", this.onWinResize);\n let debounce = 0;\n this.mo = new MutationObserver(() => {\n clearTimeout(debounce);\n debounce = window.setTimeout(() => { this.position(); this.renderList(); }, 120);\n });\n this.mo.observe(document.body, { childList: true, subtree: true, attributes: true, characterData: true });\n // Safety net for animated / late-loading layouts.\n this.tick = window.setInterval(this.position, 800);\n }\n\n // ---- dock: open / close / mode / theme ------------------------------------\n\n private openDock() {\n this.open = true;\n this.fabExpanded = false; // the panel replaces the quick actions\n this.saveState();\n this.applyDockLayout();\n this.renderList();\n }\n\n private closeDock() {\n this.open = false;\n this.setMode(\"off\");\n this.closeComposer();\n this.saveState();\n this.applyDockLayout();\n }\n\n private setDock(mode: DockMode) {\n this.dockMode = mode;\n this.open = true;\n this.saveState();\n this.applyDockLayout();\n }\n\n /** Switch the sidebar page (Comments ↔ Connect Claude). */\n private setTab(tab: Tab) {\n if (this.tab === tab) return;\n // Leaving the Comments page cancels any active picking tool.\n if (tab !== \"comments\") this.setMode(\"off\");\n this.tab = tab;\n this.saveState();\n this.applyDockLayout();\n if (tab === \"comments\") this.renderList();\n }\n\n private toggleTheme() {\n this.theme = this.theme === \"dark\" ? \"light\" : \"dark\";\n this.saveState();\n this.applyDockLayout();\n }\n\n private onWinResize = () => this.applyDockLayout();\n\n /** Narrow viewports render the panel as a bottom sheet, not a side/float dock. */\n private isMobile() { return window.innerWidth <= 640; }\n\n private loadState() {\n try {\n const s = localStorage.getItem(\"loupe:dock\");\n if (!s) return;\n const p = JSON.parse(s);\n if (DOCK_MODES.includes(p?.mode)) this.dockMode = p.mode;\n if (typeof p?.open === \"boolean\") this.open = p.open;\n if (p?.theme === \"light\" || p?.theme === \"dark\") this.theme = p.theme;\n if (p?.tab === \"comments\" || p?.tab === \"connect\") this.tab = p.tab;\n if (p?.float && typeof p.float.w === \"number\") this.floatRect = { ...this.floatRect, ...p.float };\n if (typeof p?.markersHidden === \"boolean\") this.markersHidden = p.markersHidden;\n } catch { /* storage unavailable → defaults */ }\n }\n\n private saveState() {\n try {\n localStorage.setItem(\"loupe:dock\", JSON.stringify({\n mode: this.dockMode, open: this.open, theme: this.theme, tab: this.tab, float: this.floatRect,\n markersHidden: this.markersHidden,\n }));\n } catch { /* ignore */ }\n }\n\n /** Reflect all control-panel state (theme, dock mode, geometry, launcher) into the DOM. */\n private applyDockLayout() {\n this.root.classList.toggle(\"theme-light\", this.theme === \"light\");\n this.themeBtn.title = this.theme === \"dark\" ? \"Switch to light theme\" : \"Switch to dark theme\";\n this.themeBtn.innerHTML = this.theme === \"dark\" ? I_SUN : I_MOON;\n\n const d = this.dock;\n d.classList.toggle(\"open\", this.open);\n for (const m of DOCK_MODES) d.classList.toggle(\"mode-\" + m, this.dockMode === m);\n // Which sidebar page is active (Comments vs Connect Claude).\n d.classList.toggle(\"tab-comments\", this.tab === \"comments\");\n d.classList.toggle(\"tab-connect\", this.tab === \"connect\");\n d.querySelectorAll<HTMLElement>(\".tabs .tab\").forEach((b) =>\n b.classList.toggle(\"on\", b.dataset.tab === this.tab));\n\n if (this.dockMode === \"float\") {\n const vw = window.innerWidth, vh = window.innerHeight;\n let { x, y, w, h } = this.floatRect;\n w = clampPx(w, 280, Math.min(760, vw - 24));\n h = clampPx(h, 220, vh - 24);\n if (x <= 0 && y <= 0) { x = Math.max(12, vw - w - 24); y = 64; } // first placement\n x = clampPx(x, 8, Math.max(8, vw - w - 8));\n y = clampPx(y, 8, Math.max(8, vh - h - 8));\n this.floatRect = { x, y, w, h };\n Object.assign(d.style, { left: x + \"px\", top: y + \"px\", width: w + \"px\", height: h + \"px\", right: \"auto\", bottom: \"auto\" });\n } else {\n for (const p of [\"left\", \"top\", \"right\", \"bottom\", \"width\", \"height\"] as const) d.style[p] = \"\";\n }\n\n d.querySelectorAll<HTMLElement>(\".dctl [data-dock]\").forEach((b) =>\n b.classList.toggle(\"on\", b.dataset.dock === this.dockMode));\n\n // FAB cluster: visible only while the panel is closed and always on the same\n // side as the dock edge, so reopening it feels like the panel sliding back in.\n this.fabCluster.classList.toggle(\"show\", !this.open);\n const leftSide = this.dockMode === \"left\";\n this.fabCluster.style.left = leftSide ? \"20px\" : \"auto\";\n this.fabCluster.style.right = leftSide ? \"auto\" : \"20px\";\n this.applyFab();\n\n this.pushPage();\n }\n\n /**\n * Push the host page over so the docked panel never covers content (like real\n * DevTools). We shrink the <html> box with a margin on the docked edge — the\n * panel is `position: fixed` (relative to the viewport), so it sits in the\n * gutter the margin frees up. Float mode and the closed state reserve nothing.\n * Only inline styles are touched, so clearing them restores the host exactly.\n */\n private pushPage() {\n const de = document.documentElement;\n de.style.marginLeft = de.style.marginRight = de.style.marginBottom = \"\";\n // On mobile the panel is a bottom-sheet overlay (see styles) — reserving page\n // space would squeeze content to a sliver, so we never push there.\n if (!this.open || this.dockMode === \"float\" || this.isMobile()) return;\n const r = this.dock.getBoundingClientRect();\n if (this.dockMode === \"left\") de.style.marginLeft = r.width + \"px\";\n else if (this.dockMode === \"right\") de.style.marginRight = r.width + \"px\";\n else if (this.dockMode === \"bottom\") de.style.marginBottom = r.height + \"px\";\n }\n\n // ---- float-mode drag + resize ---------------------------------------------\n\n private onHeadPointerDown = (e: PointerEvent) => {\n if (this.dockMode !== \"float\" || e.button !== 0 || this.isMobile()) return;\n if ((e.target as HTMLElement)?.closest(\".dctl\")) return; // let control buttons work\n this.floatDrag = { px: e.clientX, py: e.clientY, ox: this.floatRect.x, oy: this.floatRect.y };\n this.dock.classList.add(\"dragging\");\n window.addEventListener(\"pointermove\", this.onHeadPointerMove);\n window.addEventListener(\"pointerup\", this.onHeadPointerUp);\n };\n private onHeadPointerMove = (e: PointerEvent) => {\n if (!this.floatDrag) return;\n e.preventDefault();\n this.floatRect.x = this.floatDrag.ox + (e.clientX - this.floatDrag.px);\n this.floatRect.y = this.floatDrag.oy + (e.clientY - this.floatDrag.py);\n this.applyDockLayout();\n };\n private onHeadPointerUp = () => {\n if (!this.floatDrag) return;\n this.floatDrag = null;\n this.dock.classList.remove(\"dragging\");\n window.removeEventListener(\"pointermove\", this.onHeadPointerMove);\n window.removeEventListener(\"pointerup\", this.onHeadPointerUp);\n this.saveState();\n };\n\n private onResizeDown = (e: PointerEvent) => {\n if (this.dockMode !== \"float\") return;\n e.preventDefault(); e.stopPropagation();\n this.floatResize = { px: e.clientX, py: e.clientY, ow: this.floatRect.w, oh: this.floatRect.h };\n window.addEventListener(\"pointermove\", this.onResizeMove);\n window.addEventListener(\"pointerup\", this.onResizeUp);\n };\n private onResizeMove = (e: PointerEvent) => {\n if (!this.floatResize) return;\n e.preventDefault();\n this.floatRect.w = this.floatResize.ow + (e.clientX - this.floatResize.px);\n this.floatRect.h = this.floatResize.oh + (e.clientY - this.floatResize.py);\n this.applyDockLayout();\n };\n private onResizeUp = () => {\n if (!this.floatResize) return;\n this.floatResize = null;\n window.removeEventListener(\"pointermove\", this.onResizeMove);\n window.removeEventListener(\"pointerup\", this.onResizeUp);\n this.saveState();\n };\n\n // ---- comment list ---------------------------------------------------------\n\n private renderList() {\n this.listEl.innerHTML = \"\";\n const q = this.search.trim().toLowerCase();\n const items = q\n ? this.comments.filter((c) => `${c.title ?? \"\"} ${c.body} ${c.author?.name ?? \"\"}`.toLowerCase().includes(q))\n : this.comments;\n if (!items.length) {\n this.listEl.appendChild(el(\"div\", \"empty\",\n q ? \"No comments match your search.\"\n : \"No comments yet. Use Inspect to pick an element, or Note to drop a comment anywhere on the page.\"));\n }\n items.forEach((c, i) => this.listEl.appendChild(this.itemView(c, i)));\n this.updateCount();\n }\n\n private itemView(c: Comment, i: number): HTMLElement {\n const detached = this.pins.get(c.id)?.classList.contains(\"detached\") && !isResolved(c);\n const open = this.expanded.has(c.id);\n const item = el(\"div\", \"item\" + (open ? \"\" : \" collapsed\"));\n const top = el(\"div\", \"top\");\n const num = el(\"span\", \"num\" + (isResolved(c) ? \" done\" : detached ? \" detached\" : \"\"), String(i + 1));\n // No author identity is shown in the widget list (privacy — see the dashboard for triage).\n top.append(num);\n if (c.recording) top.appendChild(el(\"span\", \"rectag\", \"⏺ recording\"));\n const vw = c.viewport?.w;\n if (vw) {\n const kind = vw < 768 ? \"mobile\" : vw < 1024 ? \"tablet\" : \"desktop\";\n const icon = vw < 768 ? \"📱\" : vw < 1024 ? \"▦\" : \"🖥\";\n top.appendChild(el(\"span\", \"device\", `${icon} ${kind}`));\n }\n if (isResolved(c)) top.appendChild(el(\"span\", \"badge done\", \"resolved\"));\n else if (detached) top.appendChild(el(\"span\", \"badge detached\", \"element moved/removed\"));\n top.appendChild(el(\"span\", \"caret\", open ? \"▾\" : \"▸\"));\n item.appendChild(top);\n\n // Collapsed, the item is a single summary line; expanding reveals the detail.\n const summary = c.title || (c.body.split(\"\\n\")[0] ?? \"\").slice(0, 140) || \"(no description)\";\n item.appendChild(el(\"div\", \"summary\", summary));\n\n const detail = el(\"div\", \"detail\");\n // With a title, the body is the full description; without one the first line is\n // already the summary, so only multi-line bodies repeat it here.\n if (c.title || c.body.includes(\"\\n\")) detail.appendChild(el(\"div\", \"body\", c.body));\n detail.appendChild(el(\"div\", \"meta\", describeAnchor(c)));\n\n if (c.recording) {\n const v = el(\"video\", \"shot\") as HTMLVideoElement;\n v.src = c.recording;\n v.controls = true;\n v.playsInline = true;\n if (c.screenshot) v.poster = c.screenshot;\n detail.appendChild(v);\n } else if (c.screenshot) {\n const img = el(\"img\", \"shot\") as HTMLImageElement;\n img.src = c.screenshot;\n detail.appendChild(img);\n }\n\n // Files the reporter attached (images and videos).\n for (const a of c.attachments ?? []) {\n if (a.kind === \"video\") {\n const v = el(\"video\", \"shot\") as HTMLVideoElement;\n v.src = a.url;\n v.controls = true;\n v.playsInline = true;\n detail.appendChild(v);\n } else {\n const img = el(\"img\", \"shot\") as HTMLImageElement;\n img.src = a.url;\n img.alt = a.name ?? \"attachment\";\n detail.appendChild(img);\n }\n }\n\n const actions = el(\"div\", \"actions\");\n const doneBtn = el(\"button\", \"\", isResolved(c) ? \"Reopen\" : \"Resolve\") as HTMLButtonElement;\n doneBtn.onclick = async (e) => {\n e.stopPropagation();\n const status = isResolved(c) ? \"queue\" : \"resolved\";\n c.status = status; await this.store.update(c.id, { status });\n this.renderPins(); this.renderList();\n };\n const del = el(\"button\", \"\", \"Delete\") as HTMLButtonElement;\n del.onclick = async (e) => {\n e.stopPropagation();\n await this.store.remove(c.id);\n this.comments = this.comments.filter((x) => x.id !== c.id);\n this.resolved.delete(c.id);\n this.renderPins(); this.renderList();\n };\n actions.append(doneBtn, del);\n detail.appendChild(actions);\n item.appendChild(detail);\n\n item.onclick = () => {\n if (open) this.expanded.delete(c.id);\n else this.expanded.add(c.id);\n this.renderList();\n };\n return item;\n }\n\n private flash(id: string) {\n const c = this.comments.find((x) => x.id === id);\n const pin = this.pins.get(id);\n\n if (c?.kind === \"free\") {\n for (const p of this.pins.values()) p.classList.remove(\"active\");\n pin?.classList.add(\"active\");\n const docW = Math.max(1, document.documentElement.scrollWidth);\n const docH = Math.max(1, document.documentElement.scrollHeight);\n window.scrollTo({\n top: Math.max(0, c.offset.y * docH - window.innerHeight / 2),\n left: Math.max(0, c.offset.x * docW - window.innerWidth / 2),\n behavior: \"smooth\",\n });\n this.position();\n return;\n }\n\n if (c?.kind === \"region\" && c.region) {\n for (const p of this.pins.values()) p.classList.remove(\"active\");\n pin?.classList.add(\"active\");\n // Show the outline, keep it tracking scroll, then fade it out.\n this.activeRegionId = id;\n window.clearTimeout(this.regionTimer);\n this.regionTimer = window.setTimeout(() => {\n this.activeRegionId = null;\n this.regionBox.style.display = \"none\";\n }, 2400);\n // Scroll to the anchor element when we have it (correct across reflow),\n // otherwise to the stored document position.\n const elx = this.resolved.get(id);\n if (elx) elx.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n else window.scrollTo({ top: Math.max(0, c.region.y - 120), left: Math.max(0, c.region.x - 120), behavior: \"smooth\" });\n this.position();\n return;\n }\n\n if (!pin || pin.classList.contains(\"detached\")) return;\n for (const p of this.pins.values()) p.classList.remove(\"active\");\n pin.classList.add(\"active\");\n const elx = this.resolved.get(id);\n if (elx) elx.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n\n destroy() {\n this.stopRecording?.();\n this.setMode(\"off\");\n this.mo?.disconnect();\n if (this.tick) clearInterval(this.tick);\n window.clearTimeout(this.regionTimer);\n window.removeEventListener(\"resize\", this.onWinResize);\n window.removeEventListener(\"pointermove\", this.onHeadPointerMove);\n window.removeEventListener(\"pointerup\", this.onHeadPointerUp);\n window.removeEventListener(\"pointermove\", this.onResizeMove);\n window.removeEventListener(\"pointerup\", this.onResizeUp);\n document.removeEventListener(\"keydown\", this.onKey, true);\n // Release the page-push margins we set for docked modes.\n const de = document.documentElement;\n de.style.marginLeft = de.style.marginRight = de.style.marginBottom = \"\";\n this.root?.remove();\n }\n}\n\n// ---- tiny DOM helpers -------------------------------------------------------\n\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, cls = \"\", text = \"\"): HTMLElementTagNameMap[K] {\n const n = document.createElement(tag);\n if (cls) n.className = cls;\n if (text) n.textContent = text;\n return n;\n}\nfunction clamp(n: number) { return Math.max(0, Math.min(1, n)); }\nfunction clampPx(n: number, min: number, max: number) { return Math.max(min, Math.min(max, n)); }\n/** An `<option>`. Built as an element rather than `new Option(...)`, which some\n * DOM implementations (and the test environment) do not provide. */\nfunction optionEl(text: string, value: string, selected: boolean): HTMLOptionElement {\n const o = document.createElement(\"option\");\n o.value = value;\n o.textContent = text;\n o.selected = selected;\n return o;\n}\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (m) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" }[m]!));\n}\n\n// ---- inline icons (font-independent, currentColor) --------------------------\n\nconst svg = (inner: string) =>\n `<svg viewBox=\"0 0 16 16\" width=\"15\" height=\"15\" fill=\"none\" aria-hidden=\"true\">${inner}</svg>`;\nconst DOCK_FRAME = `<rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"1.6\" stroke=\"currentColor\" stroke-width=\"1.3\"/>`;\nconst I_DOCK_LEFT = svg(`${DOCK_FRAME}<rect x=\"2.2\" y=\"3.2\" width=\"4\" height=\"9.6\" rx=\"1\" fill=\"currentColor\"/>`);\nconst I_DOCK_RIGHT = svg(`${DOCK_FRAME}<rect x=\"9.8\" y=\"3.2\" width=\"4\" height=\"9.6\" rx=\"1\" fill=\"currentColor\"/>`);\nconst I_DOCK_BOTTOM = svg(`${DOCK_FRAME}<rect x=\"2.2\" y=\"9\" width=\"11.6\" height=\"3.8\" rx=\"1\" fill=\"currentColor\"/>`);\nconst I_FLOAT = svg(\n `<rect x=\"2.5\" y=\"3.5\" width=\"11\" height=\"9\" rx=\"1.6\" stroke=\"currentColor\" stroke-width=\"1.3\"/>` +\n `<path d=\"M2.5 6.1h11\" stroke=\"currentColor\" stroke-width=\"1.3\"/>`);\nconst I_SUN = svg(\n `<circle cx=\"8\" cy=\"8\" r=\"3\" stroke=\"currentColor\" stroke-width=\"1.3\"/>` +\n `<g stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\">` +\n `<path d=\"M8 1.4v1.7\"/><path d=\"M8 12.9v1.7\"/><path d=\"M1.4 8h1.7\"/><path d=\"M12.9 8h1.7\"/>` +\n `<path d=\"M3.3 3.3l1.2 1.2\"/><path d=\"M11.5 11.5l1.2 1.2\"/><path d=\"M12.7 3.3l-1.2 1.2\"/><path d=\"M4.5 11.5l-1.2 1.2\"/></g>`);\nconst I_MOON = svg(\n `<path d=\"M13 9.4A5.3 5.3 0 1 1 6.6 3 4.3 4.3 0 0 0 13 9.4z\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linejoin=\"round\"/>`);\nconst I_CLOSE = svg(\n `<path d=\"M4.2 4.2l7.6 7.6M11.8 4.2l-7.6 7.6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>`);\n\n/** FAB cluster quick-action icons (font-independent, currentColor). */\nconst I_COMMENT = svg(\n `<path d=\"M2 3.1h12v7.4H6.5l-3.3 2.6v-2.6H2z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<path d=\"M8 5.1v3.4M6.3 6.8h3.4\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/>`);\n/** A sticky note for the \"Note\" quick action — deliberately unlike the comment bubble. */\nconst I_NOTE = svg(\n `<path d=\"M2.6 2.6h10.8v7.2l-3.6 3.6H2.6z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<path d=\"M13.4 9.8h-3.6v3.6\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>`);\nconst I_EYE = svg(\n `<path d=\"M1.4 8S3.9 4 8 4s6.6 4 6.6 4-2.5 4-6.6 4S1.4 8 1.4 8z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<circle cx=\"8\" cy=\"8\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.3\"/>`);\nconst I_PLUG = svg(\n `<path d=\"M6 1.8v3.1M10 1.8v3.1\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/>` +\n `<path d=\"M4.4 4.9h7.2v2.3a3.6 3.6 0 0 1-7.2 0z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `<path d=\"M8 10.8v3.4\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/>`);\n/** Points up when collapsed, flips down (via CSS) when the actions are out. */\nconst I_FAB_CHEVRON =\n `<span class=\"lchev\">${svg(`<path d=\"M4.4 9.6 8 6l3.6 3.6\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`)}</span>`;\n\n/** Dashed marquee icon for the \"Region\" button — inline SVG so it never depends on a font. */\nconst REGION_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<rect x=\"1.5\" y=\"2.5\" width=\"12\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-dasharray=\"2.4 1.8\"/>` +\n `</svg>`;\n\n/** Speech-bubble icon for the free-\"Note\" button. */\nconst NOTE_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<path d=\"M2 2.5h11v7.5H6l-3 2.5v-2.5H2z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>` +\n `</svg>`;\n\n/** Camera/record icon for the \"Record\" button — dashed marquee with a record dot. */\nconst RECORD_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<rect x=\"1.5\" y=\"2.5\" width=\"12\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-dasharray=\"2.4 1.8\"/>` +\n `<circle cx=\"7.5\" cy=\"7.5\" r=\"2.4\" fill=\"currentColor\"/>` +\n `</svg>`;\n\n/** Video icon for the \"Video\" button — attach a screen recording made on the phone. */\nconst VIDEO_ICON =\n `<svg width=\"15\" height=\"15\" viewBox=\"0 0 15 15\" fill=\"none\" aria-hidden=\"true\">` +\n `<rect x=\"1.5\" y=\"2.5\" width=\"12\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\"/>` +\n `<path d=\"M6.3 5.5l3.9 2.2-3.9 2.2z\" fill=\"currentColor\"/>` +\n `</svg>`;\n\n// ---- integration icons (brand marks for the \"Integrates with\" footer) -------\nconst I_GITHUB =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M8 .2a8 8 0 0 0-2.5 15.6c.4.07.55-.17.55-.38v-1.3c-2.2.48-2.67-1.07-2.67-1.07-.36-.92-.88-1.16-.88-1.16-.72-.5.05-.48.05-.48.8.056 1.22.82 1.22.82.71 1.22 1.87.87 2.33.66.07-.52.28-.87.5-1.07-1.76-.2-3.6-.88-3.6-3.9 0-.86.3-1.57.82-2.12-.08-.2-.36-1 .08-2.1 0 0 .67-.21 2.2.8a7.6 7.6 0 0 1 4 0c1.53-1.02 2.2-.8 2.2-.8.44 1.1.16 1.9.08 2.1.5.55.82 1.26.82 2.12 0 3.03-1.85 3.7-3.61 3.9.28.24.54.72.54 1.46v2.16c0 .21.14.46.55.38A8 8 0 0 0 8 .2z\"/>` +\n `</svg>`;\nconst I_SLACK =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M3.4 10.1a1.6 1.6 0 1 1-1.6-1.6h1.6v1.6zm.8 0a1.6 1.6 0 0 1 3.2 0v4a1.6 1.6 0 1 1-3.2 0v-4zM5.8 3.4a1.6 1.6 0 1 1 1.6-1.6v1.6H5.8zm0 .8a1.6 1.6 0 0 1 0 3.2h-4a1.6 1.6 0 1 1 0-3.2h4zm6.7 1.6a1.6 1.6 0 1 1 1.6 1.6h-1.6V5.8zm-.8 0a1.6 1.6 0 0 1-3.2 0v-4a1.6 1.6 0 1 1 3.2 0v4zm-1.6 6.7a1.6 1.6 0 1 1-1.6 1.6v-1.6h1.6zm0-.8a1.6 1.6 0 0 1 0-3.2h4a1.6 1.6 0 1 1 0 3.2h-4z\"/>` +\n `</svg>`;\nconst I_TELEGRAM =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.7 5.4-1.24 5.85c-.09.41-.34.51-.69.32l-1.9-1.4-.92.88c-.1.1-.19.19-.38.19l.14-1.93 3.5-3.17c.15-.13-.03-.2-.24-.07l-4.32 2.72-1.86-.58c-.4-.13-.41-.4.09-.6l7.26-2.8c.34-.12.63.08.52.6z\"/>` +\n `</svg>`;\nconst I_LINEAR =\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">` +\n `<path d=\"M.6 9.2a7.4 7.4 0 0 0 6.2 6.2c.3.04.44-.33.22-.55L1.15 9a.33.33 0 0 0-.55.22zM.5 6.9c-.01.13.04.25.13.34l8.13 8.13c.09.09.21.14.34.13a7.4 7.4 0 0 0 1.3-.26c.28-.08.36-.43.15-.63L1.4 5.45c-.2-.2-.55-.13-.63.15-.12.42-.21.86-.26 1.3zM2.05 4c-.1.13-.09.32.03.44l9.48 9.48c.12.12.31.13.44.03.3-.23.58-.48.85-.75.15-.15.15-.4 0-.55L3.35 3.15a.39.39 0 0 0-.55 0c-.27.27-.52.55-.75.85zM4.5 1.9a.35.35 0 0 0-.04.53l9.11 9.11c.16.16.42.13.53-.04A7.4 7.4 0 1 0 4.5 1.9z\"/>` +\n `</svg>`;\n\n/** Synthesize an Anchor for a free page-level note so downstream (dashboard/MCP) stays happy. */\nfunction pageAnchor(point: { x: number; y: number }): Anchor {\n return {\n tag: \"page\",\n cssPath: \"page\",\n xpath: \"\",\n testid: null,\n text: \"\",\n attrs: {},\n nthOfType: 1,\n rect: { x: Math.round(point.x), y: Math.round(point.y), w: 0, h: 0 },\n viewport: { w: window.innerWidth, h: window.innerHeight },\n };\n}\n\n/** Synthesize an Anchor for a free region so downstream (dashboard/MCP) stays happy. */\nfunction regionAnchor(region: RegionRect): Anchor {\n return {\n tag: \"region\",\n cssPath: `region ${Math.round(region.w)}×${Math.round(region.h)}`,\n xpath: \"\",\n testid: null,\n text: \"\",\n attrs: {},\n nthOfType: 1,\n rect: { x: Math.round(region.x), y: Math.round(region.y), w: Math.round(region.w), h: Math.round(region.h) },\n viewport: { w: window.innerWidth, h: window.innerHeight },\n };\n}\nfunction regionNote(region: RegionRect): string {\n return `<!-- Loupe free-region annotation: ${Math.round(region.w)}×${Math.round(region.h)}px at document (${Math.round(region.x)}, ${Math.round(region.y)}). No single DOM element — see the attached screenshot. -->`;\n}\n\nfunction describe(elx: Element): string {\n const testid = elx.getAttribute(\"data-testid\") || elx.getAttribute(\"data-test\");\n const tag = elx.tagName.toLowerCase();\n if (testid) return `${tag}[data-testid=\"${testid}\"]`;\n if (elx.id) return `${tag}#${elx.id}`;\n const txt = (elx.textContent || \"\").trim().replace(/\\s+/g, \" \").slice(0, 32);\n return txt ? `${tag} · “${txt}”` : tag;\n}\nfunction describeAnchor(c: Comment): string {\n if (c.kind === \"free\") return \"Free note · page-level\";\n return c.anchor.testid ? `[data-testid=\"${c.anchor.testid}\"]` : c.anchor.cssPath;\n}\n\n/**\n * A comment is done only at the last stage. Normalizing first means a row still\n * carrying a legacy status (`done`) reads correctly without a data migration.\n */\nfunction isResolved(c: Comment): boolean {\n return normalizeStatus(c.status) === \"resolved\";\n}\n","import { LoupeApp } from \"./app.js\";\nimport type { LoupeConfig } from \"./types.js\";\n\nexport type { LoupeConfig, LoupeUser, Comment, Anchor, RegionRect } from \"./types.js\";\n\nlet app: LoupeApp | null = null;\n\n/**\n * Initialize Loupe on the current page. Call once, after your app knows who the\n * user is. The toolbar renders only for the identified user.\n *\n * Loupe.init({ projectKey: \"pk_live_…\", user: { id, name, email }, userHmac });\n */\nexport function init(config: LoupeConfig): void {\n if (app) return; // idempotent\n if (!config?.projectKey) { console.error(\"[loupe] init requires a projectKey\"); return; }\n if (!config.user?.id) { console.error(\"[loupe] init requires user.id\"); return; }\n // NOTE: in production the backend verifies config.userHmac before serving data.\n app = new LoupeApp(config);\n const boot = () => app!.start();\n if (document.readyState === \"loading\") document.addEventListener(\"DOMContentLoaded\", boot);\n else boot();\n}\n\n/** Tear down the toolbar and all listeners. */\nexport function destroy(): void {\n app?.destroy();\n app = null;\n}\n"],"mappings":";AACO,IAAM;AAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["el","svg","el","svg","el","blobToDataUrl","init","uid","x","elx"]}
|