@launchsecure/launch-kit 0.0.27 → 0.0.29

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.
Files changed (48) hide show
  1. package/dist/beacon/beacon.mjs +1003 -440
  2. package/dist/beacon/beacon.mjs.map +1 -1
  3. package/dist/beacon/beacon.umd.js +45 -24
  4. package/dist/beacon/beacon.umd.js.map +1 -1
  5. package/dist/beacon/types/capture/events.d.ts +20 -0
  6. package/dist/beacon/types/capture/events.d.ts.map +1 -0
  7. package/dist/beacon/types/element.d.ts +1 -0
  8. package/dist/beacon/types/element.d.ts.map +1 -1
  9. package/dist/beacon/types/index.d.ts +2 -1
  10. package/dist/beacon/types/index.d.ts.map +1 -1
  11. package/dist/beacon/types/monitor/dom.d.ts +13 -0
  12. package/dist/beacon/types/monitor/dom.d.ts.map +1 -0
  13. package/dist/beacon/types/monitor/index.d.ts +19 -0
  14. package/dist/beacon/types/monitor/index.d.ts.map +1 -0
  15. package/dist/beacon/types/monitor/network.d.ts +12 -0
  16. package/dist/beacon/types/monitor/network.d.ts.map +1 -0
  17. package/dist/beacon/types/monitor/transport.d.ts +27 -0
  18. package/dist/beacon/types/monitor/transport.d.ts.map +1 -0
  19. package/dist/beacon/types/monitor/types.d.ts +117 -0
  20. package/dist/beacon/types/monitor/types.d.ts.map +1 -0
  21. package/dist/beacon/types/types.d.ts +10 -0
  22. package/dist/beacon/types/types.d.ts.map +1 -1
  23. package/dist/beacon/types/ui/drawer.d.ts +3 -1
  24. package/dist/beacon/types/ui/drawer.d.ts.map +1 -1
  25. package/dist/beacon/types/ui/monitor-panel.d.ts +19 -0
  26. package/dist/beacon/types/ui/monitor-panel.d.ts.map +1 -0
  27. package/dist/server/beacon-monitor-entry.js +353 -0
  28. package/dist/server/chart-serve.js +3 -1
  29. package/dist/server/cli.js +276 -218
  30. package/dist/server/course-entry.js +246 -0
  31. package/dist/server/graph-mcp-entry.js +35 -72
  32. package/dist/server/init-entry.js +1051 -122
  33. package/dist/server/orbit-entry.js +187 -24
  34. package/package.json +5 -3
  35. package/scaffolds/ls-marketplace/.claude-plugin/marketplace.json +15 -0
  36. package/scaffolds/ls-marketplace/plugins/kit/.claude-plugin/plugin.json +19 -0
  37. package/scaffolds/ls-marketplace/plugins/kit/commands/activate-beacon.md +216 -0
  38. package/scaffolds/ls-marketplace/plugins/kit/commands/activate-statusline.md +46 -0
  39. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-array.md +92 -0
  40. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-clear.md +68 -0
  41. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-pulse.md +80 -0
  42. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-scan.md +62 -0
  43. package/scaffolds/ls-marketplace/plugins/kit/commands/deactivate-statusline.md +34 -0
  44. package/scaffolds/ls-marketplace/plugins/kit/commands/show-mcp-status.md +109 -0
  45. package/scaffolds/ls-marketplace/plugins/kit/commands/standup.md +191 -0
  46. package/scaffolds/recall-hook/scripts/ensure-recall.sh +69 -0
  47. package/scaffolds/statusline/statusline-mcp.sh +192 -0
  48. package/scaffolds/statusline/statusline-wrapper.sh +50 -0
@@ -1 +1 @@
1
- {"version":3,"file":"beacon.mjs","sources":["../../src/beacon-client/ui/icons.ts","../../src/beacon-client/ui/button.ts","../../src/beacon-client/ui/drawer.ts","../../src/beacon-client/ui/pin-popover.ts","../../src/beacon-client/ui/pick-mode-overlay.ts","../../src/beacon-client/capture/picker.ts","../../src/beacon-client/capture/selector.ts","../../src/beacon-client/capture/framework.ts","../../src/beacon-client/capture/element.ts","../../src/beacon-client/capture/metadata.ts","../../src/beacon-client/capture/screenshot.ts","../../src/beacon-client/capture/overlay.ts","../../src/beacon-client/transport/submit.ts","../../src/beacon-client/element.ts","../../src/beacon-client/index.ts"],"sourcesContent":["// Inline SVGs to avoid an icon library dep. Returns innerHTML strings (caller assigns).\n\nexport const ICONS = {\n feedback: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>`,\n pin: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 17v5\"/><path d=\"M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z\"/></svg>`,\n close: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>`,\n trash: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 6h18\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"/><path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`,\n send: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m22 2-7 20-4-9-9-4Z\"/><path d=\"M22 2 11 13\"/></svg>`,\n check: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"/></svg>`,\n} as const;\n","// Default floating trigger button. Rendered into the Shadow DOM unless a slot=\"trigger\"\n// child is provided by the consumer.\n\nimport { ICONS } from './icons';\n\nexport function createTriggerButton(label = 'Feedback'): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'beacon-default-trigger';\n btn.setAttribute('aria-label', label);\n btn.innerHTML = `${ICONS.feedback}<span>${label}</span>`;\n return btn;\n}\n","// The form drawer: description textarea + severity picker + pin list + actions.\n// Built imperatively (no JSX). The element class is the controller; this module\n// handles markup + small DOM helpers.\n\nimport { ICONS } from './icons';\nimport type { Pin, Severity } from '../types';\n\nconst DEFAULT_SEVERITIES: Severity[] = ['bug', 'idea', 'ux', 'a11y'];\n\nexport interface DrawerCallbacks {\n onClose: () => void;\n onAnnotate: () => void;\n onSubmit: () => void;\n onPinNoteChange: (pinNumber: number, note: string) => void;\n onPinDelete: (pinNumber: number) => void;\n onDescriptionChange: (value: string) => void;\n onSeverityChange: (sev: Severity) => void;\n}\n\nexport class DrawerView {\n readonly root: HTMLDivElement;\n readonly bodyEl: HTMLDivElement;\n private severities: Severity[];\n private callbacks: DrawerCallbacks;\n private state = {\n description: '',\n severity: 'bug' as Severity,\n pins: [] as Pin[],\n annotatedScreenshot: undefined as string | undefined,\n submitting: false,\n status: '' as string,\n statusKind: '' as '' | 'error' | 'success',\n };\n\n constructor(severities: Severity[], callbacks: DrawerCallbacks) {\n this.severities = severities.length > 0 ? severities : DEFAULT_SEVERITIES;\n this.callbacks = callbacks;\n this.root = document.createElement('div');\n this.root.className = 'beacon-drawer';\n this.root.innerHTML = `\n <div class=\"beacon-drawer-header\">\n <div class=\"beacon-drawer-title\">Send feedback</div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-action=\"close\" aria-label=\"Close\">${ICONS.close}</button>\n </div>\n <div class=\"beacon-drawer-body\"></div>\n `;\n this.bodyEl = this.root.querySelector('.beacon-drawer-body') as HTMLDivElement;\n this.root.querySelector('[data-action=\"close\"]')!.addEventListener('click', () => this.callbacks.onClose());\n this.render();\n }\n\n open() {\n this.root.classList.remove('minimized');\n this.root.classList.add('open');\n }\n\n close() {\n this.root.classList.remove('open');\n }\n\n minimize() {\n this.root.classList.add('minimized');\n this.root.classList.remove('open');\n }\n\n setPins(pins: Pin[], annotatedScreenshot?: string) {\n this.state.pins = pins;\n if (annotatedScreenshot !== undefined) this.state.annotatedScreenshot = annotatedScreenshot;\n this.render();\n }\n\n getAnnotatedScreenshot(): string | undefined {\n return this.state.annotatedScreenshot;\n }\n\n setAnnotatedScreenshot(value: string | undefined) {\n this.state.annotatedScreenshot = value;\n this.render();\n }\n\n setSubmitting(submitting: boolean) {\n this.state.submitting = submitting;\n this.render();\n }\n\n setStatus(status: string, kind: '' | 'error' | 'success' = '') {\n this.state.status = status;\n this.state.statusKind = kind;\n this.render();\n }\n\n reset() {\n this.state = {\n description: '',\n severity: 'bug',\n pins: [],\n annotatedScreenshot: undefined,\n submitting: false,\n status: '',\n statusKind: '',\n };\n this.render();\n }\n\n getDescription() { return this.state.description; }\n getSeverity() { return this.state.severity; }\n\n private render() {\n const canSubmit = this.state.description.trim().length > 0 && !this.state.submitting;\n\n this.bodyEl.innerHTML = `\n <div class=\"beacon-field\">\n <label class=\"beacon-label\" for=\"beacon-desc\">What's the issue?</label>\n <textarea id=\"beacon-desc\" class=\"beacon-textarea\" placeholder=\"Describe what you saw, what you expected, anything that helps reproduce…\">${escapeHtml(this.state.description)}</textarea>\n </div>\n\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Severity</span>\n <div class=\"beacon-severity\" role=\"radiogroup\">\n ${this.severities.map((sev) => `\n <label class=\"beacon-severity-opt ${sev === this.state.severity ? 'selected' : ''}\" data-sev=\"${sev}\">\n <input type=\"radio\" name=\"beacon-severity\" value=\"${sev}\" ${sev === this.state.severity ? 'checked' : ''}>\n ${sev}\n </label>\n `).join('')}\n </div>\n </div>\n\n ${this.state.annotatedScreenshot ? `\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Annotated screenshot</span>\n <img src=\"${this.state.annotatedScreenshot}\" class=\"beacon-thumb\" alt=\"Annotated screenshot preview\">\n </div>\n ` : ''}\n\n ${this.state.pins.length > 0 ? `\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Pins (${this.state.pins.length})</span>\n <div class=\"beacon-pin-list\">\n ${this.state.pins.map((p) => `\n <div class=\"beacon-pin-item\" data-pin=\"${p.number}\">\n <span class=\"beacon-pin-num\">${p.number}</span>\n <div class=\"beacon-pin-meta\">\n <div class=\"beacon-pin-selector\" title=\"${escapeHtml(p.selector)}\">${escapeHtml(p.selector)}</div>\n <input type=\"text\" class=\"beacon-pin-note-input\" placeholder=\"Add a note (optional)\" value=\"${escapeHtml(p.note ?? '')}\">\n </div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-pin-delete=\"${p.number}\" aria-label=\"Remove pin ${p.number}\">${ICONS.trash}</button>\n </div>\n `).join('')}\n </div>\n </div>\n ` : ''}\n\n <div class=\"beacon-actions\">\n <button type=\"button\" class=\"beacon-btn secondary\" data-action=\"annotate\" ${this.state.submitting ? 'disabled' : ''}>\n ${ICONS.pin} ${this.state.pins.length > 0 ? 'Add another pin' : 'Annotate elements'}\n </button>\n <span style=\"flex:1\"></span>\n <button type=\"button\" class=\"beacon-btn primary\" data-action=\"submit\" ${canSubmit ? '' : 'disabled'}>\n ${ICONS.send} ${this.state.submitting ? 'Sending…' : 'Send'}\n </button>\n </div>\n\n ${this.state.status ? `<div class=\"beacon-status ${this.state.statusKind}\">${escapeHtml(this.state.status)}</div>` : ''}\n `;\n\n // Wire events.\n const desc = this.bodyEl.querySelector('#beacon-desc') as HTMLTextAreaElement;\n desc.addEventListener('input', () => {\n this.state.description = desc.value;\n this.callbacks.onDescriptionChange(desc.value);\n // Re-render only the submit button's disabled state — full re-render kills focus, so skip it here.\n const submitBtn = this.bodyEl.querySelector('[data-action=\"submit\"]') as HTMLButtonElement | null;\n if (submitBtn) {\n submitBtn.disabled = !(desc.value.trim().length > 0) || this.state.submitting;\n }\n });\n\n this.bodyEl.querySelectorAll<HTMLInputElement>('input[name=\"beacon-severity\"]').forEach((input) => {\n input.addEventListener('change', () => {\n if (input.checked) {\n this.state.severity = input.value as Severity;\n this.callbacks.onSeverityChange(this.state.severity);\n this.render();\n }\n });\n });\n\n this.bodyEl.querySelector('[data-action=\"annotate\"]')?.addEventListener('click', () => this.callbacks.onAnnotate());\n this.bodyEl.querySelector('[data-action=\"submit\"]')?.addEventListener('click', () => this.callbacks.onSubmit());\n\n this.bodyEl.querySelectorAll<HTMLButtonElement>('[data-pin-delete]').forEach((btn) => {\n btn.addEventListener('click', () => {\n const num = Number(btn.getAttribute('data-pin-delete'));\n this.callbacks.onPinDelete(num);\n });\n });\n\n this.bodyEl.querySelectorAll<HTMLInputElement>('.beacon-pin-note-input').forEach((input) => {\n const item = input.closest('[data-pin]');\n const num = Number(item?.getAttribute('data-pin') ?? 0);\n input.addEventListener('input', () => this.callbacks.onPinNoteChange(num, input.value));\n });\n }\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n","// Small contextual popover that opens next to a picked element so the user can\n// optionally type a note. The cross icon discards this pin and lets the user keep\n// picking; Save attaches the (optional) note. Escape ends annotation entirely.\n\nimport { ICONS } from './icons';\n\nexport type PinPopoverCancel = 'pin' | 'all' | false;\n\nexport interface PinPopoverResult {\n note?: string;\n // 'pin' = discard this pin, keep picking. 'all' = end annotation. false = save.\n cancelled: PinPopoverCancel;\n}\n\nexport function showPinPopover(opts: {\n shadowRoot: ShadowRoot;\n anchor: { x: number; y: number }; // viewport coords\n pinNumber: number;\n}): Promise<PinPopoverResult> {\n return new Promise((resolve) => {\n const popover = document.createElement('div');\n // Mount on body (not shadow root) so we escape transformed-ancestor stacking\n // contexts. beacon-no-capture keeps it out of the screenshot. theme-auto follows\n // OS preference; if a future caller needs explicit theme, add an opts.theme.\n popover.className = 'beacon-pin-popover open beacon-no-capture beacon-theme-auto';\n popover.innerHTML = `\n <div class=\"beacon-pin-popover-header\">\n <div style=\"display:flex;align-items:center;gap:6px;font-weight:600;font-size:13px;\">\n <span class=\"beacon-pin-num\">${opts.pinNumber}</span>\n <span>Note for this pin</span>\n </div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-action=\"cancel\" aria-label=\"Discard this pin\">${ICONS.close}</button>\n </div>\n <textarea class=\"beacon-textarea\" rows=\"2\" placeholder=\"Optional — describe what's wrong here…\" style=\"min-height:48px;\"></textarea>\n <div class=\"beacon-pin-popover-actions\">\n <button type=\"button\" class=\"beacon-btn primary\" data-action=\"save\">${ICONS.check} Save</button>\n </div>\n `;\n\n // Position below the picked point, clamped to viewport.\n const POPOVER_W = 240;\n const POPOVER_H = 160;\n const left = Math.min(Math.max(8, opts.anchor.x), window.innerWidth - POPOVER_W - 8);\n const top = Math.min(Math.max(8, opts.anchor.y + 12), window.innerHeight - POPOVER_H - 8);\n popover.style.left = `${left}px`;\n popover.style.top = `${top}px`;\n\n document.body.appendChild(popover);\n\n const textarea = popover.querySelector('textarea')!;\n textarea.focus();\n\n function close(result: PinPopoverResult) {\n document.removeEventListener('keydown', handleGlobalKey, true);\n popover.remove();\n resolve(result);\n }\n\n // Document-level Escape handler so it works regardless of focus location\n // (textarea, popover background, anywhere on the page). Escape ends the whole\n // annotation session — use the cross icon to drop just this pin.\n function handleGlobalKey(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n close({ cancelled: 'all' });\n }\n }\n document.addEventListener('keydown', handleGlobalKey, true);\n\n popover.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n const action = target.closest('[data-action]')?.getAttribute('data-action');\n if (action === 'cancel') close({ cancelled: 'pin' });\n if (action === 'save') {\n const note = textarea.value.trim();\n close({ ...(note ? { note } : {}), cancelled: false });\n }\n });\n\n // Cmd/Ctrl+Enter inside the textarea = save (Enter alone inserts newlines).\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n const note = textarea.value.trim();\n close({ ...(note ? { note } : {}), cancelled: false });\n }\n });\n });\n}\n","// Visual overlay shown during pin-mode. Three layers:\n// 1. Subtle dotted viewport border + soft inset glow → \"you're in pin mode\"\n// 2. Top-center hint pill → \"press Esc to finish\"\n// 3. Numbered markers → over each already-pinned\n// element so the user can\n// see what they pinned\n//\n// Mounted on document.body (NOT the beacon Shadow DOM) because position:fixed\n// children of transformed/filtered/contained ancestors get anchored to that\n// ancestor instead of the viewport — and many host pages put a transform on\n// sticky headers, which is exactly where the slotted trigger lives.\n//\n// Each element carries the `beacon-no-capture` class so the screenshot filter\n// in capture/screenshot.ts skips them. All use pointer-events: none so they\n// don't block elementsFromPoint during picking.\n\nconst NO_CAPTURE_CLASS = 'beacon-no-capture';\nconst DEFAULT_ACCENT = '#0ea5e9';\nconst DEFAULT_HINT = 'Click any element to pin it · Press Esc to finish';\n\nexport interface PinAnchor {\n target: Element;\n /** Selector to re-query if `target` is detached from DOM (React re-render, conditional unmount). */\n selector?: string;\n /** Last-known viewport rect from pin time. Used as a faded \"anchor lost\" marker if both\n * the live ref and the selector lookup fail. */\n fallbackRect?: { x: number; y: number; w: number; h: number };\n}\n\nexport interface PickModeOverlay {\n addPin(pinNumber: number, anchor: PinAnchor): void;\n /** Swap the hint pill into a loading state (with spinner). Pass undefined to restore the default hint. */\n setLoading(message?: string): void;\n destroy(): void;\n}\n\nexport interface PickModeOverlayOptions {\n /** Accent color for border, hint pill, markers, and outlines. Defaults to sky-blue. */\n accent?: string;\n}\n\n/** Append a hex alpha suffix only when the color is a 7-char hex. Other formats\n * (`rgb(...)`, named colors) pass through unchanged — the alpha effect is lost\n * but the value stays valid. */\nfunction withAlpha(color: string, alphaHex: string): string {\n return /^#[0-9a-fA-F]{6}$/.test(color) ? `${color}${alphaHex}` : color;\n}\n\nexport function createPickModeOverlay(opts: PickModeOverlayOptions = {}): PickModeOverlay {\n const ACCENT = opts.accent ?? DEFAULT_ACCENT;\n const ACCENT_BORDER = withAlpha(ACCENT, 'b3'); // ~70% alpha for dashed viewport border\n const ACCENT_GLOW = withAlpha(ACCENT, '2e'); // ~18% alpha for inset glow\n // One-time keyframes for the loading spinner. Kept in <head> with the\n // beacon-no-capture class — <style> tags don't render so they don't affect\n // the screenshot, but we mark them anyway for filter consistency.\n const styleTag = document.createElement('style');\n styleTag.className = NO_CAPTURE_CLASS;\n styleTag.textContent = '@keyframes beacon-spin { to { transform: rotate(360deg); } }';\n document.head.appendChild(styleTag);\n\n const frame = document.createElement('div');\n frame.className = NO_CAPTURE_CLASS;\n frame.setAttribute('aria-hidden', 'true');\n frame.style.cssText = [\n 'position: fixed',\n 'inset: 0',\n 'pointer-events: none',\n 'z-index: 2147483646',\n `border: 2px dashed ${ACCENT_BORDER}`,\n 'border-radius: 4px',\n `box-shadow: inset 0 0 56px ${ACCENT_GLOW}`,\n 'box-sizing: border-box',\n ].join('; ');\n\n const hint = document.createElement('div');\n hint.className = NO_CAPTURE_CLASS;\n hint.setAttribute('role', 'status');\n hint.style.cssText = [\n 'position: fixed',\n 'top: 16px',\n 'left: 50%',\n 'transform: translateX(-50%)',\n `background: ${ACCENT}`,\n 'color: #fff',\n 'padding: 6px 14px',\n 'border-radius: 999px',\n 'font: 500 12px/1.4 system-ui, -apple-system, sans-serif',\n 'letter-spacing: 0.01em',\n 'box-shadow: 0 4px 12px #0000004d',\n 'pointer-events: none',\n 'white-space: nowrap',\n 'z-index: 2147483646',\n ].join('; ');\n hint.textContent = DEFAULT_HINT;\n\n const SPINNER_HTML = `<span style=\"\n display: inline-block;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-top-color: transparent;\n border-radius: 50%;\n animation: beacon-spin 800ms linear infinite;\n vertical-align: middle;\n margin-right: 8px;\n \"></span>`;\n\n function escapeHtml(s: string): string {\n return s.replace(/[<>&]/g, (c) => ({ '<': '&lt;', '>': '&gt;', '&': '&amp;' }[c] as string));\n }\n\n document.body.appendChild(frame);\n document.body.appendChild(hint);\n\n const tracked = new Map<number, { anchor: PinAnchor; marker: HTMLDivElement; outline: HTMLDivElement }>();\n\n function makeMarker(num: number): HTMLDivElement {\n const m = document.createElement('div');\n m.className = NO_CAPTURE_CLASS;\n m.setAttribute('aria-hidden', 'true');\n m.style.cssText = [\n 'position: fixed',\n 'width: 24px',\n 'height: 24px',\n 'border-radius: 999px',\n `background: ${ACCENT}`,\n 'color: #fff',\n 'display: flex',\n 'align-items: center',\n 'justify-content: center',\n 'font: 700 12px/1 system-ui, -apple-system, sans-serif',\n 'border: 2px solid #fff',\n 'box-shadow: 0 2px 8px #00000066',\n 'pointer-events: none',\n 'z-index: 2147483646',\n ].join('; ');\n m.textContent = String(num);\n document.body.appendChild(m);\n return m;\n }\n\n function makeOutline(): HTMLDivElement {\n const o = document.createElement('div');\n o.className = NO_CAPTURE_CLASS;\n o.setAttribute('aria-hidden', 'true');\n o.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n `border: 2px solid ${ACCENT}`,\n 'border-radius: 2px',\n 'box-sizing: border-box',\n // Slightly below marker z so the marker visually \"sits on\" the outline corner.\n 'z-index: 2147483645',\n ].join('; ');\n document.body.appendChild(o);\n return o;\n }\n\n function placeAt(\n entry: { marker: HTMLDivElement; outline: HTMLDivElement },\n rect: { x: number; y: number; w: number; h: number },\n isStale: boolean,\n ) {\n const opacity = isStale ? '0.5' : '1';\n\n entry.outline.style.display = 'block';\n entry.outline.style.opacity = opacity;\n entry.outline.style.left = `${rect.x}px`;\n entry.outline.style.top = `${rect.y}px`;\n entry.outline.style.width = `${rect.w}px`;\n entry.outline.style.height = `${rect.h}px`;\n\n entry.marker.style.display = 'flex';\n entry.marker.style.opacity = opacity;\n entry.marker.style.left = `${rect.x + rect.w - 12}px`;\n entry.marker.style.top = `${Math.max(2, rect.y - 12)}px`;\n }\n\n function hide(entry: { marker: HTMLDivElement; outline: HTMLDivElement }) {\n entry.marker.style.display = 'none';\n entry.outline.style.display = 'none';\n }\n\n function reposition() {\n tracked.forEach((entry) => {\n // Tier 1: live element ref still in DOM\n let liveTarget: Element | null = entry.anchor.target;\n if (!document.contains(liveTarget)) liveTarget = null;\n\n // Tier 2: re-query by selector (handles React re-renders that swap the node)\n if (!liveTarget && entry.anchor.selector) {\n liveTarget = document.querySelector(entry.anchor.selector);\n if (liveTarget) entry.anchor.target = liveTarget; // refresh for next reposition\n }\n\n if (liveTarget) {\n const r = liveTarget.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n placeAt(entry, { x: r.left, y: r.top, w: r.width, h: r.height }, false);\n return;\n }\n }\n\n // Tier 3: fallback to the rect captured at pin time. Honest \"anchor lost\"\n // signal — half opacity so the user can see this isn't tracking anymore.\n const fr = entry.anchor.fallbackRect;\n if (fr && (fr.w > 0 || fr.h > 0)) {\n placeAt(entry, fr, true);\n return;\n }\n\n hide(entry);\n });\n }\n\n let raf: number | null = null;\n function schedule() {\n if (raf !== null) return;\n raf = requestAnimationFrame(() => {\n raf = null;\n reposition();\n });\n }\n\n window.addEventListener('scroll', schedule, true);\n window.addEventListener('resize', schedule);\n\n return {\n addPin(num, anchor) {\n const marker = makeMarker(num);\n const outline = makeOutline();\n tracked.set(num, { anchor, marker, outline });\n reposition();\n },\n setLoading(message) {\n if (message) {\n hint.innerHTML = SPINNER_HTML + escapeHtml(message);\n } else {\n hint.textContent = DEFAULT_HINT;\n }\n },\n destroy() {\n window.removeEventListener('scroll', schedule, true);\n window.removeEventListener('resize', schedule);\n if (raf !== null) cancelAnimationFrame(raf);\n frame.remove();\n hint.remove();\n styleTag.remove();\n tracked.forEach(({ marker, outline }) => {\n marker.remove();\n outline.remove();\n });\n tracked.clear();\n },\n };\n}\n","// Hover/click element picker. Draws an outline overlay over the hovered element\n// and resolves with the clicked element. Skips the widget's own elements via\n// composedPath check against the provided shadow root.\n\nexport interface PickerOptions {\n shadowRoot: ShadowRoot;\n onHover?: (el: Element | null) => void;\n /** Outline color for the hovered-element highlight. Defaults to sky-blue. */\n accent?: string;\n}\n\nconst DEFAULT_ACCENT = '#0ea5e9';\n\n/** Append hex alpha suffix only for 7-char hex; other color formats pass through unchanged. */\nfunction withAlpha(color: string, alphaHex: string): string {\n return /^#[0-9a-fA-F]{6}$/.test(color) ? `${color}${alphaHex}` : color;\n}\n\nexport interface PickerHandle {\n cancel: () => void;\n promise: Promise<Element | null>; // resolves with picked element, or null on Escape\n}\n\nexport function startPicker(opts: PickerOptions): PickerHandle {\n const { shadowRoot, onHover } = opts;\n const accent = opts.accent ?? DEFAULT_ACCENT;\n const accentFill = withAlpha(accent, '14'); // ~8% alpha hover-fill tint\n\n // Outline overlay — appended to body, position: fixed, pointer-events: none.\n const outline = document.createElement('div');\n outline.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n 'z-index: 2147483646',\n `border: 2px solid ${accent}`,\n `background: ${accentFill}`,\n 'transition: all 60ms ease-out',\n 'box-sizing: border-box',\n 'border-radius: 2px',\n ].join('; ');\n document.body.appendChild(outline);\n\n const tooltip = document.createElement('div');\n tooltip.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n 'z-index: 2147483647',\n 'background: #0f172a',\n 'color: #fff',\n 'font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace',\n 'padding: 3px 6px',\n 'border-radius: 3px',\n 'max-width: 280px',\n 'overflow: hidden',\n 'text-overflow: ellipsis',\n 'white-space: nowrap',\n ].join('; ');\n document.body.appendChild(tooltip);\n\n const previousCursor = document.body.style.cursor;\n document.body.style.cursor = 'crosshair';\n\n let resolved = false;\n let resolvePromise: (v: Element | null) => void = () => {};\n const promise = new Promise<Element | null>((res) => { resolvePromise = res; });\n\n function isWidgetElement(el: EventTarget | null): boolean {\n if (!el || !(el instanceof Node)) return false;\n // composedPath gives us shadow boundaries.\n let node: Node | null = el;\n while (node) {\n if (node === shadowRoot || node === shadowRoot.host) return true;\n node = node.parentNode ?? (node as ShadowRoot).host ?? null;\n }\n return false;\n }\n\n function findTarget(x: number, y: number): Element | null {\n // Hide overlay so it doesn't appear in elementsFromPoint, then use elementsFromPoint\n // and pick the first non-widget element.\n outline.style.display = 'none';\n tooltip.style.display = 'none';\n const candidates = document.elementsFromPoint(x, y);\n outline.style.display = 'block';\n tooltip.style.display = 'block';\n for (const c of candidates) {\n if (!isWidgetElement(c)) return c;\n }\n return null;\n }\n\n function positionOutline(el: Element) {\n const rect = el.getBoundingClientRect();\n outline.style.left = `${rect.left}px`;\n outline.style.top = `${rect.top}px`;\n outline.style.width = `${rect.width}px`;\n outline.style.height = `${rect.height}px`;\n\n const tag = el.tagName.toLowerCase();\n const cls = el.classList.length > 0 ? '.' + Array.from(el.classList).slice(0, 2).join('.') : '';\n tooltip.textContent = tag + cls;\n // Place tooltip just above the element, or below if it would clip the top.\n const above = rect.top - 22;\n tooltip.style.left = `${rect.left}px`;\n tooltip.style.top = `${above >= 0 ? above : rect.bottom + 4}px`;\n }\n\n function handleMove(e: MouseEvent) {\n const el = findTarget(e.clientX, e.clientY);\n if (el) {\n positionOutline(el);\n onHover?.(el);\n } else {\n outline.style.display = 'none';\n tooltip.style.display = 'none';\n onHover?.(null);\n }\n }\n\n // Listen on pointerdown (NOT click) so we intercept the press BEFORE the host\n // page reacts. Radix Select / Popover / Dialog open on pointerdown — by the\n // time `click` fires, the page state has changed (dropdown open, focus moved,\n // layout shifted) and elementsFromPoint at click coords returns the wrong thing.\n // pointerdown + capture phase + preventDefault + stopPropagation gives us the\n // element under the cursor exactly as the user saw it, before any host handlers run.\n function handlePointerDown(e: PointerEvent) {\n if (e.button !== 0) return; // ignore right/middle clicks\n e.preventDefault();\n e.stopPropagation();\n const el = findTarget(e.clientX, e.clientY);\n if (el) finish(el);\n }\n\n // Also swallow the trailing click/mouseup so a host-page handler doesn't fire\n // anyway. We've already finished by this point but keep listeners briefly.\n function swallow(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n function handleKey(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n finish(null);\n }\n }\n\n function finish(el: Element | null) {\n if (resolved) return;\n resolved = true;\n document.removeEventListener('mousemove', handleMove, true);\n document.removeEventListener('pointerdown', handlePointerDown, true);\n document.removeEventListener('click', swallow, true);\n document.removeEventListener('mouseup', swallow, true);\n document.removeEventListener('keydown', handleKey, true);\n outline.remove();\n tooltip.remove();\n document.body.style.cursor = previousCursor;\n resolvePromise(el);\n }\n\n document.addEventListener('mousemove', handleMove, true);\n document.addEventListener('pointerdown', handlePointerDown, true);\n document.addEventListener('click', swallow, true);\n document.addEventListener('mouseup', swallow, true);\n document.addEventListener('keydown', handleKey, true);\n\n return {\n cancel: () => finish(null),\n promise,\n };\n}\n","// Build a unique-ish CSS selector path for an element by walking up the parent chain.\n// Strategy per ancestor: id (if unique) → tag.classes (if unique among siblings) → tag:nth-of-type(n).\n// Stops at <body> or after a depth limit.\n\nconst MAX_DEPTH = 8;\n\nfunction isUniqueId(id: string, root: Document | ShadowRoot = document): boolean {\n if (!id) return false;\n try {\n return root.querySelectorAll(`#${CSS.escape(id)}`).length === 1;\n } catch {\n return false;\n }\n}\n\nfunction tagWithClasses(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const classes = Array.from(el.classList)\n // Drop classes that look like generated atomic / hashed names (heuristic — keep stable-looking ones).\n .filter((c) => c.length > 0 && c.length < 40)\n .slice(0, 3)\n .map((c) => `.${CSS.escape(c)}`)\n .join('');\n return tag + classes;\n}\n\nfunction nthOfTypeIndex(el: Element): number {\n const parent = el.parentElement;\n if (!parent) return 1;\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === el.tagName);\n return sameTag.indexOf(el) + 1;\n}\n\nexport function buildSelector(target: Element): string {\n if (!target || target.nodeType !== Node.ELEMENT_NODE) return '';\n\n // Fast path: unique id on the target itself.\n if (target.id && isUniqueId(target.id)) {\n return `#${CSS.escape(target.id)}`;\n }\n\n const parts: string[] = [];\n let el: Element | null = target;\n let depth = 0;\n\n while (el && el.tagName.toLowerCase() !== 'body' && depth < MAX_DEPTH) {\n const current: Element = el;\n\n if (current.id && isUniqueId(current.id)) {\n parts.unshift(`#${CSS.escape(current.id)}`);\n break;\n }\n\n const base = tagWithClasses(current);\n const parent: HTMLElement | null = current.parentElement;\n\n // If this base matches multiple siblings, disambiguate with :nth-of-type.\n let part = base;\n if (parent) {\n try {\n const currentClasses = Array.from(current.classList).join(' ');\n const siblings: Element[] = Array.from(parent.children).filter(\n (c: Element) => c.tagName === current.tagName && Array.from(c.classList).join(' ') === currentClasses,\n );\n if (siblings.length > 1) {\n part = `${current.tagName.toLowerCase()}:nth-of-type(${nthOfTypeIndex(current)})`;\n }\n } catch {\n // ignore — fall back to base\n }\n }\n\n parts.unshift(part);\n el = parent;\n depth++;\n }\n\n return parts.join(' > ');\n}\n","// Best-effort framework component name detection.\n// Production builds usually minify component names — return null quietly when unavailable.\n\nimport type { Pin } from '../types';\n\ntype FW = NonNullable<Pin['framework']>;\n\nfunction detectReact(el: Element): FW | null {\n // React stores fiber refs on properties like __reactFiber$<hash> / __reactInternalInstance$<hash>.\n const keys = Object.keys(el).filter((k) => k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$'));\n if (keys.length === 0) return null;\n\n let fiber: unknown = (el as unknown as Record<string, unknown>)[keys[0]!];\n // Walk up the fiber chain to find the nearest function/class component (skip host elements).\n for (let i = 0; i < 10 && fiber; i++) {\n const f = fiber as { type?: unknown; return?: unknown };\n const type = f.type;\n if (typeof type === 'function') {\n const name = (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name;\n if (name && name !== '_default') return { lib: 'react', name };\n }\n if (typeof type === 'object' && type !== null) {\n const name = (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name;\n if (name) return { lib: 'react', name };\n }\n fiber = f.return;\n }\n return { lib: 'react' };\n}\n\nfunction detectVue(el: Element): FW | null {\n const anyEl = el as unknown as Record<string, unknown>;\n const vueParent = anyEl.__vueParentComponent as { type?: { name?: string; __name?: string } } | undefined;\n if (vueParent) {\n const name = vueParent.type?.name ?? vueParent.type?.__name;\n return { lib: 'vue', ...(name ? { name } : {}) };\n }\n if (anyEl.__vue__) return { lib: 'vue' };\n return null;\n}\n\nfunction detectAngular(el: Element): FW | null {\n // Angular dev mode exposes window.ng.getComponent(el).\n const ng = (window as unknown as { ng?: { getComponent?: (el: Element) => unknown } }).ng;\n if (!ng?.getComponent) return null;\n try {\n const cmp = ng.getComponent(el);\n if (!cmp) return null;\n const ctor = (cmp as { constructor?: { name?: string } }).constructor;\n return { lib: 'angular', ...(ctor?.name ? { name: ctor.name } : {}) };\n } catch {\n return null;\n }\n}\n\nfunction detectSvelte(el: Element): FW | null {\n // Svelte exposes very little at runtime. Look for $$ properties on the host.\n const anyEl = el as unknown as Record<string, unknown>;\n if ('__svelte_meta' in anyEl) return { lib: 'svelte' };\n return null;\n}\n\nexport function detectFramework(el: Element): Pin['framework'] | undefined {\n const result = detectReact(el) ?? detectVue(el) ?? detectAngular(el) ?? detectSvelte(el);\n return result ?? undefined;\n}\n","// Capture per-pin element data: outerHTML (truncated), selector, computed styles, bounding rect, framework hint.\n\nimport type { RawPinCapture } from '../types';\nimport { buildSelector } from './selector';\nimport { detectFramework } from './framework';\n\n// Limits matched to the /api/feedback zod schema. The route caps each list / string\n// length defensively — exceed any of these and the entire payload 400s with no\n// useful detail surfaced in the beacon UI, so we mirror the caps here.\nconst OUTER_HTML_LIMIT = 5000; // schema: outerHTML max 8000\nconst PARENT_OUTER_HTML_LIMIT = 1000; // schema: parentOuterHTML max 2000\nconst SELECTOR_LIMIT = 1000; // schema: selector max 1000\nconst ID_LIMIT = 200; // schema: id max 200\nconst CLASSLIST_MAX_ENTRIES = 50; // schema: classList array max 50\nconst CLASS_NAME_LIMIT = 200; // schema: each class max 200\nconst STYLE_VALUE_LIMIT = 500; // schema: computedStyles value max 500\n\n// A focused, useful subset of computed style properties. Dumping all 400+ resolved\n// properties is noise; this list covers layout, typography, color, and key visual hints.\nconst USEFUL_STYLE_PROPS = [\n 'display', 'position', 'top', 'right', 'bottom', 'left',\n 'width', 'height', 'min-width', 'min-height', 'max-width', 'max-height',\n 'margin', 'padding',\n 'font-family', 'font-size', 'font-weight', 'line-height', 'text-align',\n 'color', 'background-color', 'background-image',\n 'border', 'border-radius',\n 'opacity', 'visibility', 'overflow',\n 'z-index', 'transform', 'transition',\n 'flex', 'flex-direction', 'justify-content', 'align-items', 'gap',\n 'grid-template-columns', 'grid-template-rows',\n] as const;\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max) + `\\n\\n/* … truncated, original was ${s.length} chars */`;\n}\n\nfunction pickStyles(el: Element): Record<string, string> {\n const computed = getComputedStyle(el);\n const out: Record<string, string> = {};\n for (const prop of USEFUL_STYLE_PROPS) {\n const value = computed.getPropertyValue(prop);\n if (value && value !== 'normal' && value !== 'none' && value !== 'auto' && value !== '0px') {\n out[prop] = value.trim().slice(0, STYLE_VALUE_LIMIT);\n }\n }\n return out;\n}\n\nfunction capClassList(el: Element): string[] {\n const all = Array.from(el.classList);\n // First slice to the entry cap, then truncate each class name. Order matters:\n // truncating first and then slicing would still produce >50 entries.\n return all\n .slice(0, CLASSLIST_MAX_ENTRIES)\n .map((c) => (c.length > CLASS_NAME_LIMIT ? c.slice(0, CLASS_NAME_LIMIT) : c));\n}\n\nexport function capturePin(el: Element): RawPinCapture {\n const rect = el.getBoundingClientRect();\n const rawSelector = buildSelector(el);\n const rawId = el.id || null;\n return {\n selector: rawSelector.length > SELECTOR_LIMIT ? rawSelector.slice(0, SELECTOR_LIMIT) : rawSelector,\n tagName: el.tagName.toLowerCase(),\n id: rawId && rawId.length > ID_LIMIT ? rawId.slice(0, ID_LIMIT) : rawId,\n classList: capClassList(el),\n outerHTML: truncate(el.outerHTML, OUTER_HTML_LIMIT),\n ...(el.parentElement\n ? { parentOuterHTML: truncate(el.parentElement.outerHTML, PARENT_OUTER_HTML_LIMIT) }\n : {}),\n computedStyles: pickStyles(el),\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n ...(detectFramework(el) ? { framework: detectFramework(el)! } : {}),\n };\n}\n","// Capture browser / viewport / locale metadata. Pure read-only — no instrumentation.\n\nimport type { Metadata } from '../types';\n\ninterface UADataLike {\n brands: Array<{ brand: string; version: string }>;\n mobile: boolean;\n platform: string;\n}\n\nfunction getUaData(): Metadata['uaData'] {\n const nav = navigator as Navigator & { userAgentData?: UADataLike };\n if (!nav.userAgentData) return undefined;\n // Pick the first non-\"Not.A/Brand\" brand for legibility.\n const brand = nav.userAgentData.brands.find((b) => !/Not[.\\-]?A.?Brand/i.test(b.brand))?.brand\n ?? nav.userAgentData.brands[0]?.brand\n ?? 'unknown';\n return {\n brand,\n mobile: nav.userAgentData.mobile,\n platform: nav.userAgentData.platform,\n };\n}\n\nfunction getTheme(): Metadata['theme'] {\n if (window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark';\n if (window.matchMedia('(prefers-color-scheme: light)').matches) return 'light';\n return undefined;\n}\n\nexport function captureMetadata(): Metadata {\n return {\n url: window.location.href,\n ...(document.referrer ? { referrer: document.referrer } : {}),\n userAgent: navigator.userAgent,\n ...(getUaData() ? { uaData: getUaData()! } : {}),\n viewport: {\n w: window.innerWidth,\n h: window.innerHeight,\n dpr: window.devicePixelRatio || 1,\n },\n screen: {\n w: window.screen.width,\n h: window.screen.height,\n },\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n locale: navigator.language,\n ...(getTheme() ? { theme: getTheme()! } : {}),\n capturedAt: new Date().toISOString(),\n };\n}\n","// Lazy-loaded screenshot capture via html-to-image.\n// Captures the viewport (document.documentElement) as a JPEG data URL.\n//\n// Cross-origin images that don't return CORS headers (e.g., GitHub avatar redirects\n// from github.com → avatars.githubusercontent.com) cause html-to-image to taint\n// the canvas → toJpeg throws SecurityError. Filter alone wasn't reliable because\n// html-to-image fetches some images outside the filter's reach. Belt-and-suspenders:\n// physically swap cross-origin <img>.src to a transparent pixel before capture,\n// restore after. The user sees a brief blank where the avatar was during capture\n// (~hundreds of ms); the page never sees a screenshot failure.\n\nlet htmlToImage: typeof import('html-to-image') | null = null;\n\nasync function load() {\n if (!htmlToImage) {\n htmlToImage = await import('html-to-image');\n }\n return htmlToImage;\n}\n\nexport interface ScreenshotOptions {\n quality?: number; // 0..1, default 0.7\n pixelRatio?: number; // default min(devicePixelRatio, 2) — capping to keep file size sane\n excludeShadowRoot?: ShadowRoot; // skip our own widget elements\n}\n\nconst TRANSPARENT_PIXEL =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=';\n\nfunction isUrlSafeForCanvas(rawUrl: string, crossOriginAttr?: string | null): boolean {\n if (!rawUrl) return true;\n if (rawUrl.startsWith('data:') || rawUrl.startsWith('blob:')) return true;\n if (rawUrl.startsWith('/') || rawUrl.startsWith('#')) return true;\n try {\n const u = new URL(rawUrl, window.location.href);\n if (u.origin === window.location.origin) return true;\n } catch {\n return false;\n }\n return crossOriginAttr === 'anonymous' || crossOriginAttr === 'use-credentials';\n}\n\n/**\n * Replace cross-origin image sources with a transparent pixel for the duration of\n * the capture so html-to-image can't even attempt to fetch them. Returns a restore\n * function that puts the originals back.\n *\n * Covers two element types:\n * - HTML <img> (uses .src)\n * - SVG <image> (uses href / xlink:href) — used by AstronautAvatar for GitHub avatars\n */\nfunction neutralizeCrossOriginImages(): () => void {\n const stashedImg: Array<{ el: HTMLImageElement; src: string }> = [];\n const stashedSvg: Array<{ el: SVGImageElement; href: string | null; xlink: string | null }> = [];\n\n document.querySelectorAll('img').forEach((img) => {\n if (!isUrlSafeForCanvas(img.src, img.crossOrigin)) {\n stashedImg.push({ el: img, src: img.src });\n img.src = TRANSPARENT_PIXEL;\n }\n });\n\n document.querySelectorAll('image').forEach((img) => {\n const svgImg = img as unknown as SVGImageElement;\n const href = svgImg.getAttribute('href');\n const xlink = svgImg.getAttributeNS('http://www.w3.org/1999/xlink', 'href');\n const url = href || xlink || '';\n if (url && !isUrlSafeForCanvas(url)) {\n stashedSvg.push({ el: svgImg, href, xlink });\n if (href !== null) svgImg.setAttribute('href', TRANSPARENT_PIXEL);\n if (xlink !== null) svgImg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', TRANSPARENT_PIXEL);\n }\n });\n\n return () => {\n for (const { el, src } of stashedImg) {\n el.src = src;\n }\n for (const { el, href, xlink } of stashedSvg) {\n if (href !== null) el.setAttribute('href', href);\n if (xlink !== null) el.setAttributeNS('http://www.w3.org/1999/xlink', 'href', xlink);\n }\n };\n}\n\nexport async function captureScreenshot(opts: ScreenshotOptions = {}): Promise<string> {\n const { quality = 0.7, pixelRatio = Math.min(window.devicePixelRatio || 1, 2), excludeShadowRoot } = opts;\n const lib = await load();\n\n // Skip:\n // - the widget's host element (drawer / floating trigger)\n // - any element marked .beacon-no-capture (overlays mounted to document.body\n // because shadow-DOM children get trapped inside transformed ancestors)\n const filter = excludeShadowRoot\n ? (node: Node) => {\n let cur: Node | null = node;\n while (cur) {\n if (cur === excludeShadowRoot.host) return false;\n if (cur instanceof Element && cur.classList.contains('beacon-no-capture')) return false;\n cur = cur.parentNode;\n }\n return true;\n }\n : undefined;\n\n const restore = neutralizeCrossOriginImages();\n\n try {\n return await lib.toJpeg(document.documentElement, {\n quality,\n pixelRatio,\n cacheBust: true,\n ...(filter ? { filter } : {}),\n imagePlaceholder: TRANSPARENT_PIXEL,\n // Cap dimensions to viewport so we don't accidentally capture full document height.\n width: window.innerWidth,\n height: window.innerHeight,\n style: {\n // Avoid scrolling artifacts.\n transform: 'none',\n },\n });\n } finally {\n restore();\n }\n}\n","// Draw the captured pins onto a screenshot. Takes the viewport screenshot data\n// URL and the pin list, returns a new data URL with two things baked per pin:\n//\n// 1. An outline rectangle around the pinned element (so triagers can tell\n// WHICH element was pinned without clicking into the pin data).\n// 2. A numbered circle at the outline's top-right corner.\n//\n// Rect freshness: pin.boundingRect is captured at pin time. If the user scrolls\n// between pinning and screenshot capture, that rect is in stale viewport coords.\n// We recompute via the same fallback chain the live overlay uses:\n// live element ref → selector lookup → captured rect\n// This keeps outlines and markers correctly anchored to what was pinned.\n\nimport type { Pin } from '../types';\n\nconst MARKER_RADIUS = 14;\nconst MARKER_STROKE = '#ffffff';\nconst MARKER_TEXT = '#ffffff';\nconst OUTLINE_WIDTH = 3;\nconst DEFAULT_ACCENT = '#0ea5e9';\n\nexport async function drawMarkers(\n screenshotDataUrl: string,\n pins: Pin[],\n viewportSize: { w: number; h: number; dpr: number },\n pinElements?: WeakMap<Pin, Element>,\n accent: string = DEFAULT_ACCENT,\n): Promise<string> {\n const MARKER_FILL = accent;\n const OUTLINE_COLOR = accent;\n const img = await loadImage(screenshotDataUrl);\n\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('Could not get 2D canvas context');\n\n ctx.drawImage(img, 0, 0);\n\n // Map viewport coords → screenshot pixel coords using the ratio between image\n // size and the captured viewport dimensions.\n const scaleX = canvas.width / viewportSize.w;\n const scaleY = canvas.height / viewportSize.h;\n\n for (const pin of pins) {\n const rect = getFreshRect(pin, pinElements);\n if (!rect) continue;\n\n const x = rect.x * scaleX;\n const y = rect.y * scaleY;\n const w = rect.w * scaleX;\n const h = rect.h * scaleY;\n\n // ── Outline rectangle ──\n ctx.lineWidth = OUTLINE_WIDTH;\n ctx.strokeStyle = OUTLINE_COLOR;\n ctx.strokeRect(x, y, w, h);\n\n // ── Numbered marker at top-right corner (matches the live overlay placement\n // so what users saw during pin mode looks like what triagers see later). ──\n const cx = x + w;\n const cy = y;\n\n // Filled circle.\n ctx.beginPath();\n ctx.fillStyle = MARKER_FILL;\n ctx.arc(cx, cy, MARKER_RADIUS, 0, Math.PI * 2);\n ctx.fill();\n\n // White outer stroke for contrast.\n ctx.lineWidth = 3;\n ctx.strokeStyle = MARKER_STROKE;\n ctx.stroke();\n\n // Number text.\n ctx.fillStyle = MARKER_TEXT;\n ctx.font = 'bold 16px system-ui, -apple-system, sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(String(pin.number), cx, cy + 1);\n }\n\n return canvas.toDataURL('image/jpeg', 0.85);\n}\n\n/**\n * Three-tier fallback for \"where is this pinned element NOW\":\n * 1. Live element ref via WeakMap (most accurate — handles scroll, layout shift)\n * 2. Selector re-query (handles React re-render swapping the node identity)\n * 3. Original captured rect (last resort — may be stale relative to current viewport)\n */\nfunction getFreshRect(\n pin: Pin,\n pinElements?: WeakMap<Pin, Element>,\n): { x: number; y: number; w: number; h: number } | null {\n const target = pinElements?.get(pin);\n if (target && document.contains(target)) {\n const r = target.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n return { x: r.left, y: r.top, w: r.width, h: r.height };\n }\n }\n\n if (pin.selector) {\n try {\n const found = document.querySelector(pin.selector);\n if (found) {\n const r = found.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n return { x: r.left, y: r.top, w: r.width, h: r.height };\n }\n }\n } catch {\n // Invalid selector — fall through to captured rect.\n }\n }\n\n return pin.boundingRect;\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (err) => reject(err);\n img.src = src;\n });\n}\n","// POST the feedback payload to the configured endpoint.\n\nimport type { FeedbackPayload, SubmitResponse } from '../types';\n\nexport async function submitFeedback(\n endpoint: string,\n payload: FeedbackPayload,\n headers?: Record<string, string>,\n): Promise<SubmitResponse> {\n const res = await fetch(endpoint, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...(headers ?? {}),\n },\n body: JSON.stringify(payload),\n });\n\n let body: unknown = null;\n const contentType = res.headers.get('Content-Type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n body = await res.json();\n } catch {\n body = null;\n }\n } else {\n try {\n body = await res.text();\n } catch {\n body = null;\n }\n }\n\n return {\n ok: res.ok,\n status: res.status,\n body,\n };\n}\n","// <launch-kit-beacon> custom element. Orchestrates the capture pipeline + UI.\n\nimport stylesCss from './styles.css?inline';\n\nimport type { BeaconConfig, FeedbackPayload, Pin, RawPinCapture, Severity } from './types';\nimport { createTriggerButton } from './ui/button';\nimport { DrawerView } from './ui/drawer';\nimport { showPinPopover } from './ui/pin-popover';\nimport { createPickModeOverlay } from './ui/pick-mode-overlay';\nimport { startPicker } from './capture/picker';\nimport { capturePin } from './capture/element';\nimport { captureMetadata } from './capture/metadata';\nimport { captureScreenshot } from './capture/screenshot';\nimport { drawMarkers } from './capture/overlay';\nimport { submitFeedback } from './transport/submit';\n\nconst ATTRS = ['endpoint', 'position', 'theme', 'severities'] as const;\n\n// Inject the beacon stylesheet into <head> once, idempotently. Needed because the\n// drawer + pin popover are appended to document.body to escape transformed-ancestor\n// stacking contexts (sticky headers, etc.) — they're outside the shadow root, so the\n// shadow-scoped <style> doesn't reach them.\nconst GLOBAL_STYLE_ID = 'launch-kit-beacon-portal-styles';\nfunction ensureGlobalStyles(stylesText: string): void {\n if (document.getElementById(GLOBAL_STYLE_ID)) return;\n const tag = document.createElement('style');\n tag.id = GLOBAL_STYLE_ID;\n tag.textContent = stylesText;\n document.head.appendChild(tag);\n}\n\n// CSS custom properties consumers can override. The drawer's stylesheet uses\n// var(--beacon-*); after the body-mount refactor we copy the host's resolved\n// values onto the body-mounted drawer/popover (CSS inheritance no longer reaches\n// across the body boundary).\nconst CUSTOMIZABLE_VARS = [\n '--beacon-accent',\n '--beacon-bg',\n '--beacon-fg',\n '--beacon-muted',\n '--beacon-border',\n '--beacon-radius',\n '--beacon-shadow',\n '--beacon-z-index',\n '--beacon-bug',\n '--beacon-idea',\n '--beacon-ux',\n '--beacon-a11y',\n] as const;\n\nconst DEFAULT_ACCENT = '#0ea5e9';\n\nexport class LaunchKitBeacon extends HTMLElement {\n static get observedAttributes() { return ATTRS as unknown as string[]; }\n\n private shadow!: ShadowRoot;\n private trigger?: HTMLElement;\n private drawer?: DrawerView;\n private slotEl?: HTMLSlotElement;\n\n private _config: BeaconConfig | null = null;\n private pins: Pin[] = [];\n // Tracks the live DOM element each pin came from so re-entering annotate mode\n // can restore visual markers for previously pinned items. Off-payload by design.\n private pinElements = new WeakMap<Pin, Element>();\n private description = '';\n private severity: Severity = 'bug';\n // While drawer is open, block clicks on the host page so users can't accidentally\n // navigate away mid-feedback (and lose their pins). Same approach as a modal.\n private documentClickBlocker?: (e: MouseEvent) => void;\n // Set when submit succeeds so the close() warn skips during the 1.5s delay before\n // auto-close — without this, users who click the X during that window would see\n // \"Discard your feedback?\" right after they just sent it.\n private submitSucceeded = false;\n\n /** Public — wrappers can set `widget.config = {...}` for dynamic endpoint/headers/context. */\n set config(value: BeaconConfig) {\n this._config = value;\n }\n get config(): BeaconConfig | null {\n if (this._config) return this._config;\n const endpoint = this.getAttribute('endpoint');\n return endpoint ? { endpoint } : null;\n }\n\n connectedCallback() {\n if (!this.shadow) {\n this.shadow = this.attachShadow({ mode: 'open' });\n const style = document.createElement('style');\n style.textContent = stylesCss;\n this.shadow.appendChild(style);\n\n // Slot for custom trigger override.\n this.slotEl = document.createElement('slot');\n this.slotEl.name = 'trigger';\n this.shadow.appendChild(this.slotEl);\n\n // Default trigger (shown unless slot is filled or position=\"hidden\").\n this.trigger = createTriggerButton();\n this.shadow.appendChild(this.trigger);\n this.trigger.addEventListener('click', () => this.open());\n\n // If consumer provided a slot=\"trigger\" child, hook clicks on it.\n this.slotEl.addEventListener('slotchange', () => {\n const assigned = this.slotEl!.assignedElements();\n if (assigned.length > 0) {\n // Hide the default; wire all assigned elements to open the drawer.\n if (this.trigger) (this.trigger as HTMLElement).style.display = 'none';\n assigned.forEach((el) => el.addEventListener('click', () => this.open()));\n }\n });\n\n this.drawer = new DrawerView(this.parseSeverities(), {\n onClose: () => this.close(),\n onAnnotate: () => this.startAnnotate(),\n onSubmit: () => this.handleSubmit(),\n onPinNoteChange: (n, note) => this.updatePinNote(n, note),\n onPinDelete: (n) => this.deletePin(n),\n onDescriptionChange: (v) => { this.description = v; },\n onSeverityChange: (s) => { this.severity = s; },\n });\n // Mount the drawer at document.body so it escapes any transformed ancestor\n // (sticky headers, blurred toolbars) that would otherwise trap it in a sub-\n // stacking-context and put it underneath other floating UI like a Command\n // Center / PDA shell. The trigger stays in shadow DOM (slotted from the\n // header is fine; that's where the user expects to see it).\n ensureGlobalStyles(stylesCss);\n this.drawer.root.classList.add('beacon-no-capture');\n this.drawer.root.classList.add(`beacon-theme-${this.getAttribute('theme') ?? 'auto'}`);\n document.body.appendChild(this.drawer.root);\n }\n\n // Default attributes if not set.\n if (!this.hasAttribute('position')) this.setAttribute('position', 'bottom-right');\n if (!this.hasAttribute('theme')) this.setAttribute('theme', 'auto');\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (name === 'severities' && this.drawer) {\n // Re-create drawer with new severities. Keep current state.\n // Cheapest path: instruct drawer to refresh — but our drawer captures severities at construction.\n // Acceptable simplification: log a warning if attribute changes mid-life.\n // Production wrappers should set severities at construction via initial attribute.\n console.warn('[launch-kit-beacon] severities attribute changed after mount; not yet hot-reloaded.');\n }\n if (name === 'theme' && this.drawer && oldValue !== newValue) {\n this.drawer.root.classList.remove(`beacon-theme-${oldValue ?? 'auto'}`);\n this.drawer.root.classList.add(`beacon-theme-${newValue ?? 'auto'}`);\n }\n }\n\n // ── Public API ──────────────────────────────────────────\n\n open() {\n if (!this.drawer) return;\n // Edge-aware positioning when consumer is using a slotted trigger\n // (typical pattern when position=\"hidden\" — e.g., the trigger lives in a header).\n // Otherwise fall back to CSS-driven default position (bottom-right / bottom-left).\n if (this.getAttribute('position') === 'hidden') {\n const triggerEl = this.slotEl?.assignedElements()[0] as HTMLElement | undefined;\n if (triggerEl) {\n positionDrawerRelativeTo(this.drawer.root, triggerEl);\n }\n }\n this.submitSucceeded = false;\n this.syncCustomProperties();\n this.installClickBlocker();\n this.drawer.open();\n }\n\n close() {\n if (!this.drawer) return;\n if (!this.submitSucceeded && this.hasUnsavedData()) {\n // eslint-disable-next-line no-alert\n const ok = window.confirm('You have unsaved feedback. Close and discard it?');\n if (!ok) return;\n }\n this.forceClose();\n }\n\n disconnectedCallback() {\n // Custom element being removed from DOM (e.g., HMR or framework teardown).\n // Make sure we don't leak the document-level click listener.\n this.uninstallClickBlocker();\n // Drawer is mounted at body level — pull it out so we don't leave orphans\n // behind on HMR or framework teardown.\n if (this.drawer && this.drawer.root.parentNode) {\n this.drawer.root.parentNode.removeChild(this.drawer.root);\n }\n }\n\n async openWithPicker() {\n this.open();\n // Defer to next tick so the drawer is in DOM before we minimize it.\n setTimeout(() => this.startAnnotate(), 0);\n }\n\n // ── Annotate flow ──────────────────────────────────────────\n\n private async startAnnotate() {\n if (!this.drawer) return;\n this.drawer.minimize();\n\n const accent = this.getAccentColor();\n const overlay = createPickModeOverlay({ accent });\n\n // Restore markers for pins from prior annotate sessions. Use the WeakMap'd\n // element ref if it's still in the DOM; the overlay's reposition logic also\n // falls back to selector and captured rect if this ref is stale.\n for (const pin of this.pins) {\n const target = this.pinElements.get(pin);\n if (target) {\n overlay.addPin(pin.number, {\n target,\n selector: pin.selector,\n fallbackRect: pin.boundingRect,\n });\n }\n }\n\n try {\n let next = true;\n while (next) {\n const handle = startPicker({ shadowRoot: this.shadow, accent });\n const el = await handle.promise;\n if (!el) break; // user pressed Escape\n\n const rect = el.getBoundingClientRect();\n const popoverResult = await showPinPopover({\n shadowRoot: this.shadow,\n anchor: { x: rect.left, y: rect.bottom },\n pinNumber: this.pins.length + 1,\n });\n // 'all' (Escape) ends annotation; 'pin' (cross icon) drops this one and\n // re-enters pick mode for the next element. false falls through to capture.\n if (popoverResult.cancelled === 'all') break;\n if (popoverResult.cancelled === 'pin') continue;\n\n const raw = capturePin(el);\n const pin: Pin = {\n number: this.pins.length + 1,\n ...raw,\n ...(popoverResult.note ? { note: popoverResult.note } : {}),\n };\n this.pins.push(pin);\n this.pinElements.set(pin, el);\n overlay.addPin(pin.number, {\n target: el,\n selector: raw.selector,\n fallbackRect: raw.boundingRect,\n });\n\n // Loop continues — user picks another element OR presses Escape to finish.\n }\n\n // Capture final screenshot + draw markers + reopen drawer with preview.\n if (this.pins.length > 0) {\n // Swap the hint pill into a spinner BEFORE the capture so the user has\n // visible feedback during the 500ms-2s html-to-image walks the DOM.\n // Yield one frame so the swap actually paints before the main thread\n // gets busy with capture work.\n overlay.setLoading('Capturing screenshot…');\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n\n try {\n const meta = captureMetadata();\n const raw = await captureScreenshot({ excludeShadowRoot: this.shadow });\n const annotated = await drawMarkers(raw, this.pins, meta.viewport, this.pinElements, accent);\n this.drawer.setPins(this.pins, annotated);\n } catch (err) {\n // Don't drop the report — pins still post. But surface the failure so users\n // know why their preview is missing instead of guessing.\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[launch-kit-beacon] screenshot capture failed:', err);\n this.drawer.setPins(this.pins);\n this.drawer.setStatus(`Screenshot capture failed: ${msg}`, 'error');\n }\n }\n } finally {\n overlay.destroy();\n }\n\n this.drawer.open();\n }\n\n private updatePinNote(num: number, note: string) {\n const pin = this.pins.find((p) => p.number === num);\n if (!pin) return;\n if (note.trim()) {\n pin.note = note;\n } else {\n delete pin.note;\n }\n // Don't re-render — the input is already up to date; rerender would lose focus.\n }\n\n private deletePin(num: number) {\n this.pins = this.pins.filter((p) => p.number !== num);\n // Renumber.\n this.pins.forEach((p, i) => { p.number = i + 1; });\n // Invalidate the cached annotated screenshot — it bakes the deleted pin's\n // marker into the JPEG. handleSubmit will recapture if needed.\n this.drawer?.setAnnotatedScreenshot(undefined);\n this.drawer?.setPins(this.pins);\n }\n\n // ── Submit flow ──────────────────────────────────────────\n\n private async handleSubmit() {\n if (!this.drawer) return;\n const cfg = this.config;\n if (!cfg?.endpoint) {\n this.drawer.setStatus('Missing endpoint configuration', 'error');\n return;\n }\n\n const description = this.drawer.getDescription().trim();\n const severity = this.drawer.getSeverity();\n if (!description) {\n this.drawer.setStatus('Description is required', 'error');\n return;\n }\n\n // Show the loading state IMMEDIATELY after validation, before any expensive\n // async work. Without this, the user clicks Save and sees nothing change for\n // 500ms-2s while captureScreenshot walks the DOM. Yield one frame so the\n // disabled state actually paints before the main thread gets busy.\n this.drawer.setSubmitting(true);\n\n // Reuse the screenshot already produced at end of annotate. Only recapture\n // if missing — invalidated by deletePin or never produced (e.g., user typed\n // a description and clicked Save without annotating).\n let screenshotDataUrl = this.drawer.getAnnotatedScreenshot();\n const needsCapture = !screenshotDataUrl && this.pins.length > 0;\n\n this.drawer.setStatus(needsCapture ? 'Capturing screenshot…' : 'Sending…');\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n\n const meta = captureMetadata();\n\n if (needsCapture) {\n try {\n const raw = await captureScreenshot({ excludeShadowRoot: this.shadow });\n screenshotDataUrl = await drawMarkers(raw, this.pins, meta.viewport, this.pinElements, this.getAccentColor());\n } catch (err) {\n console.error('[launch-kit-beacon] screenshot capture failed at submit:', err);\n }\n }\n\n const payload: FeedbackPayload = {\n description,\n severity,\n ...(screenshotDataUrl ? { screenshot: { dataUrl: screenshotDataUrl, mime: 'image/jpeg' } } : {}),\n metadata: meta,\n pins: this.pins,\n ...(this.resolveContext() ? { context: this.resolveContext() } : {}),\n };\n\n // Pre-submit hook (cancellable).\n const beforeEvent = new CustomEvent('beacon-before-submit', {\n detail: { payload },\n cancelable: true,\n bubbles: true,\n composed: true,\n });\n const proceed = this.dispatchEvent(beforeEvent);\n if (!proceed) {\n this.drawer.setSubmitting(false);\n this.drawer.setStatus('Submission cancelled', 'error');\n return;\n }\n\n this.drawer.setStatus('Sending…');\n\n try {\n const headers = this.resolveHeaders();\n const response = await submitFeedback(cfg.endpoint, payload, headers);\n this.drawer.setSubmitting(false);\n\n if (response.ok) {\n this.submitSucceeded = true;\n this.drawer.setStatus('Sent — thanks!', 'success');\n this.dispatchEvent(new CustomEvent('beacon-after-submit', {\n detail: { response },\n bubbles: true,\n composed: true,\n }));\n // Reset state and close after a moment. forceClose skips the \"discard?\"\n // warn (because submitSucceeded is true) and tears down the click blocker.\n setTimeout(() => {\n this.forceClose();\n }, 1500);\n } else {\n this.drawer.setStatus(`Failed: ${response.status}`, 'error');\n }\n } catch (err) {\n this.drawer.setSubmitting(false);\n const msg = err instanceof Error ? err.message : 'Network error';\n this.drawer.setStatus(`Failed: ${msg}`, 'error');\n }\n }\n\n // ── Helpers ──────────────────────────────────────────\n\n /**\n * Resolved accent color — reads --beacon-accent from the host's computed style\n * (which picks up any inline `style=\"--beacon-accent: …\"` or stylesheet override\n * targeting the host). Falls back to the default sky-blue if unset.\n */\n private getAccentColor(): string {\n if (typeof window === 'undefined') return DEFAULT_ACCENT;\n const v = getComputedStyle(this).getPropertyValue('--beacon-accent').trim();\n return v || DEFAULT_ACCENT;\n }\n\n /**\n * Mirror every customizable --beacon-* var from the host onto the body-mounted\n * drawer. CSS inheritance stops at the body boundary, so we copy the host's\n * resolved values forward. Called on open() so changes mid-session are picked up.\n */\n private syncCustomProperties(): void {\n if (!this.drawer) return;\n const cs = getComputedStyle(this);\n for (const name of CUSTOMIZABLE_VARS) {\n const val = cs.getPropertyValue(name).trim();\n if (val) this.drawer.root.style.setProperty(name, val);\n }\n }\n\n private hasUnsavedData(): boolean {\n if (this.pins.length > 0) return true;\n const desc = this.drawer?.getDescription() ?? '';\n return desc.trim().length > 0;\n }\n\n private resetState(): void {\n this.pins = [];\n this.description = '';\n this.severity = 'bug';\n this.pinElements = new WeakMap();\n this.drawer?.reset();\n }\n\n private forceClose(): void {\n this.uninstallClickBlocker();\n this.resetState();\n this.submitSucceeded = false;\n this.drawer?.close();\n }\n\n private installClickBlocker(): void {\n if (this.documentClickBlocker) return;\n this.documentClickBlocker = (e: MouseEvent) => {\n const path = e.composedPath();\n // Allow:\n // 1. Clicks inside the shadow root or on the slotted trigger — both go\n // through the host element on their composed path.\n // 2. Clicks on body-mounted beacon UI — drawer, popover, and any future\n // body-mounted UI carry the `beacon-no-capture` class, so we allowlist\n // anything whose path crosses such an element.\n // Pick-mode border/hint/markers are pointer-events:none and never appear in\n // an event path, so they don't need to be allowlisted explicitly.\n if (path.includes(this.shadow.host)) return;\n for (const node of path) {\n if (node instanceof Element && node.classList.contains('beacon-no-capture')) return;\n }\n e.preventDefault();\n e.stopPropagation();\n };\n document.addEventListener('click', this.documentClickBlocker, true);\n }\n\n private uninstallClickBlocker(): void {\n if (!this.documentClickBlocker) return;\n document.removeEventListener('click', this.documentClickBlocker, true);\n this.documentClickBlocker = undefined;\n }\n\n private resolveHeaders(): Record<string, string> | undefined {\n const h = this.config?.headers;\n if (!h) return undefined;\n return typeof h === 'function' ? h() : h;\n }\n\n private resolveContext(): Record<string, unknown> | undefined {\n const c = this.config?.context;\n if (!c) return undefined;\n return typeof c === 'function' ? c() : c;\n }\n\n private parseSeverities(): Severity[] {\n const attr = this.getAttribute('severities');\n if (!attr) return ['bug', 'idea', 'ux', 'a11y'];\n return attr.split(',').map((s) => s.trim()).filter(Boolean) as Severity[];\n }\n}\n\nexport function defineBeacon(tagName = 'launch-kit-beacon'): void {\n if (typeof window === 'undefined') return;\n if (!customElements.get(tagName)) {\n customElements.define(tagName, LaunchKitBeacon);\n }\n}\n\n// ── Helpers ──────────────────────────────────────────\n\nconst DRAWER_WIDTH = 380;\nconst VIEWPORT_MARGIN = 8;\nconst ESTIMATED_DRAWER_HEIGHT = 520;\n\n/**\n * Position the drawer relative to a trigger element, edge-aware.\n *\n * Default placement: directly below the trigger, with the drawer's right edge\n * aligned to the trigger's right edge. Falls back to opening above the trigger\n * if there isn't enough space below. Always clamps within the viewport so the\n * drawer never overflows off-screen.\n */\nfunction positionDrawerRelativeTo(drawer: HTMLElement, trigger: HTMLElement): void {\n const rect = trigger.getBoundingClientRect();\n const viewportW = window.innerWidth;\n const viewportH = window.innerHeight;\n\n // ── Horizontal: align drawer's right edge to trigger's right edge ─────────\n // Compute desired right offset; clamp so drawer never overflows past either edge.\n let rightOffset = Math.max(VIEWPORT_MARGIN, viewportW - rect.right);\n // If aligning right would push the drawer's left edge past the viewport, shift it.\n const leftEdgeIfApplied = viewportW - rightOffset - DRAWER_WIDTH;\n if (leftEdgeIfApplied < VIEWPORT_MARGIN) {\n rightOffset = Math.max(VIEWPORT_MARGIN, viewportW - DRAWER_WIDTH - VIEWPORT_MARGIN);\n }\n\n // ── Vertical: prefer below trigger, fall back to above ────────────────────\n const spaceBelow = viewportH - rect.bottom - VIEWPORT_MARGIN;\n const spaceAbove = rect.top - VIEWPORT_MARGIN;\n\n // Set ALL four anchors explicitly. Use 'auto' (not '') to override CSS defaults\n // (the drawer's CSS has `bottom: 20px` for the floating-trigger case — empty\n // string falls back to that; 'auto' is the only way to truly clear it).\n drawer.style.left = 'auto';\n drawer.style.right = `${rightOffset}px`;\n\n if (spaceBelow >= ESTIMATED_DRAWER_HEIGHT || spaceBelow >= spaceAbove) {\n drawer.style.top = `${rect.bottom + VIEWPORT_MARGIN}px`;\n drawer.style.bottom = 'auto';\n } else {\n drawer.style.top = 'auto';\n drawer.style.bottom = `${viewportH - rect.top + VIEWPORT_MARGIN}px`;\n }\n}\n","// Entry point for the launch-kit beacon Web Component.\n// Importing this module auto-registers the <launch-kit-beacon> custom element.\n// Exposed via the @launchsecure/launch-kit/beacon subpath export.\n\nimport { defineBeacon, LaunchKitBeacon } from './element';\n\nexport { LaunchKitBeacon, defineBeacon };\nexport type {\n BeaconConfig,\n FeedbackPayload,\n Pin,\n Metadata,\n Severity,\n HeaderProvider,\n ContextProvider,\n SubmitResponse,\n} from './types';\n\n// Auto-register on import. Consumers who want to control the tag name can call\n// defineBeacon('my-tag') themselves before any <launch-kit-beacon> elements are parsed.\ndefineBeacon();\n"],"names":["ICONS","createTriggerButton","label","btn","DEFAULT_SEVERITIES","DrawerView","severities","callbacks","pins","annotatedScreenshot","value","submitting","status","kind","canSubmit","escapeHtml","sev","p","desc","submitBtn","input","_a","_b","num","item","s","showPinPopover","opts","resolve","popover","POPOVER_W","POPOVER_H","left","top","textarea","close","result","handleGlobalKey","e","action","note","NO_CAPTURE_CLASS","DEFAULT_ACCENT","DEFAULT_HINT","withAlpha","color","alphaHex","createPickModeOverlay","ACCENT","ACCENT_BORDER","ACCENT_GLOW","styleTag","frame","hint","SPINNER_HTML","c","tracked","makeMarker","m","makeOutline","o","placeAt","entry","rect","isStale","opacity","hide","reposition","liveTarget","r","fr","raf","schedule","anchor","marker","outline","message","startPicker","shadowRoot","onHover","accent","accentFill","tooltip","previousCursor","resolved","resolvePromise","promise","res","isWidgetElement","el","node","findTarget","x","y","candidates","positionOutline","tag","cls","above","handleMove","handlePointerDown","swallow","handleKey","finish","MAX_DEPTH","isUniqueId","id","root","tagWithClasses","classes","nthOfTypeIndex","parent","buildSelector","target","parts","depth","current","base","part","currentClasses","detectReact","keys","k","fiber","i","f","type","name","detectVue","anyEl","vueParent","detectAngular","ng","cmp","ctor","detectSvelte","detectFramework","OUTER_HTML_LIMIT","PARENT_OUTER_HTML_LIMIT","SELECTOR_LIMIT","ID_LIMIT","CLASSLIST_MAX_ENTRIES","CLASS_NAME_LIMIT","STYLE_VALUE_LIMIT","USEFUL_STYLE_PROPS","truncate","max","pickStyles","computed","out","prop","capClassList","capturePin","rawSelector","rawId","getUaData","nav","b","getTheme","captureMetadata","htmlToImage","load","TRANSPARENT_PIXEL","isUrlSafeForCanvas","rawUrl","crossOriginAttr","neutralizeCrossOriginImages","stashedImg","stashedSvg","img","svgImg","href","xlink","url","src","captureScreenshot","quality","pixelRatio","excludeShadowRoot","lib","filter","cur","restore","MARKER_RADIUS","MARKER_STROKE","MARKER_TEXT","OUTLINE_WIDTH","drawMarkers","screenshotDataUrl","viewportSize","pinElements","MARKER_FILL","OUTLINE_COLOR","loadImage","canvas","ctx","scaleX","scaleY","pin","getFreshRect","w","h","cx","cy","found","reject","err","submitFeedback","endpoint","payload","headers","body","ATTRS","GLOBAL_STYLE_ID","ensureGlobalStyles","stylesText","CUSTOMIZABLE_VARS","LaunchKitBeacon","style","stylesCss","assigned","n","v","oldValue","newValue","triggerEl","positionDrawerRelativeTo","overlay","next","popoverResult","raw","meta","annotated","msg","cfg","description","severity","needsCapture","beforeEvent","response","cs","val","path","attr","defineBeacon","tagName","DRAWER_WIDTH","VIEWPORT_MARGIN","ESTIMATED_DRAWER_HEIGHT","drawer","trigger","viewportW","viewportH","rightOffset","spaceBelow","spaceAbove"],"mappings":"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"}
1
+ {"version":3,"file":"beacon.mjs","sources":["../../src/beacon-client/ui/icons.ts","../../src/beacon-client/ui/button.ts","../../src/beacon-client/ui/drawer.ts","../../src/beacon-client/ui/pin-popover.ts","../../src/beacon-client/ui/pick-mode-overlay.ts","../../src/beacon-client/capture/picker.ts","../../src/beacon-client/capture/selector.ts","../../src/beacon-client/capture/framework.ts","../../src/beacon-client/capture/element.ts","../../src/beacon-client/capture/metadata.ts","../../src/beacon-client/capture/screenshot.ts","../../src/beacon-client/capture/overlay.ts","../../src/beacon-client/capture/events.ts","../../src/beacon-client/transport/submit.ts","../../src/beacon-client/element.ts","../../src/beacon-client/monitor/dom.ts","../../src/beacon-client/monitor/network.ts","../../src/beacon-client/monitor/transport.ts","../../src/beacon-client/monitor/index.ts","../../src/beacon-client/index.ts"],"sourcesContent":["// Inline SVGs to avoid an icon library dep. Returns innerHTML strings (caller assigns).\n\nexport const ICONS = {\n feedback: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>`,\n pin: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 17v5\"/><path d=\"M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z\"/></svg>`,\n close: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>`,\n trash: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 6h18\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"/><path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`,\n send: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m22 2-7 20-4-9-9-4Z\"/><path d=\"M22 2 11 13\"/></svg>`,\n check: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"/></svg>`,\n} as const;\n","// Default floating trigger button. Rendered into the Shadow DOM unless a slot=\"trigger\"\n// child is provided by the consumer.\n\nimport { ICONS } from './icons';\n\nexport function createTriggerButton(label = 'Feedback'): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'beacon-default-trigger';\n btn.setAttribute('aria-label', label);\n btn.innerHTML = `${ICONS.feedback}<span>${label}</span>`;\n return btn;\n}\n","// The form drawer: description textarea + severity picker + pin list + actions.\n// Built imperatively (no JSX). The element class is the controller; this module\n// handles markup + small DOM helpers.\n\nimport { ICONS } from './icons';\nimport type { CapturedEvent, Pin, Severity } from '../types';\n\nconst DEFAULT_SEVERITIES: Severity[] = ['bug', 'idea', 'ux', 'a11y'];\n\nexport interface DrawerCallbacks {\n onClose: () => void;\n onAnnotate: () => void;\n onSubmit: () => void;\n onPinNoteChange: (pinNumber: number, note: string) => void;\n onPinDelete: (pinNumber: number) => void;\n onDescriptionChange: (value: string) => void;\n onSeverityChange: (sev: Severity) => void;\n}\n\nexport class DrawerView {\n readonly root: HTMLDivElement;\n readonly bodyEl: HTMLDivElement;\n private severities: Severity[];\n private callbacks: DrawerCallbacks;\n private state = {\n description: '',\n severity: 'bug' as Severity,\n pins: [] as Pin[],\n events: [] as CapturedEvent[],\n annotatedScreenshot: undefined as string | undefined,\n submitting: false,\n status: '' as string,\n statusKind: '' as '' | 'error' | 'success',\n };\n\n constructor(severities: Severity[], callbacks: DrawerCallbacks) {\n this.severities = severities.length > 0 ? severities : DEFAULT_SEVERITIES;\n this.callbacks = callbacks;\n this.root = document.createElement('div');\n this.root.className = 'beacon-drawer';\n this.root.innerHTML = `\n <div class=\"beacon-drawer-header\">\n <div class=\"beacon-drawer-title\">Send feedback</div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-action=\"close\" aria-label=\"Close\">${ICONS.close}</button>\n </div>\n <div class=\"beacon-drawer-body\"></div>\n `;\n this.bodyEl = this.root.querySelector('.beacon-drawer-body') as HTMLDivElement;\n this.root.querySelector('[data-action=\"close\"]')!.addEventListener('click', () => this.callbacks.onClose());\n this.render();\n }\n\n open() {\n this.root.classList.remove('minimized');\n this.root.classList.add('open');\n }\n\n close() {\n this.root.classList.remove('open');\n }\n\n minimize() {\n this.root.classList.add('minimized');\n this.root.classList.remove('open');\n }\n\n setPins(pins: Pin[], annotatedScreenshot?: string) {\n this.state.pins = pins;\n if (annotatedScreenshot !== undefined) this.state.annotatedScreenshot = annotatedScreenshot;\n this.render();\n }\n\n // Push the latest events buffer into the drawer. element.ts calls this both\n // on open() (initial snapshot) AND from a subscriber so the chip ticks up\n // live as errors fire. We partial-update the chip element only — a full\n // re-render of bodyEl would blow away the textarea's focus + cursor while\n // the user is typing, which is much worse than the chip never animating.\n setEvents(events: CapturedEvent[]) {\n this.state.events = events;\n this.updateEventsChip();\n }\n\n private updateEventsChip() {\n const chip = this.bodyEl.querySelector<HTMLDetailsElement>('.beacon-events');\n if (!chip) {\n // First setEvents before any render — fall back to full render so the\n // chip element is created in the DOM. Subsequent updates will partial.\n this.render();\n return;\n }\n const count = this.state.events.length;\n if (count === 0) {\n chip.hidden = true;\n return;\n }\n chip.hidden = false;\n chip.dataset.count = String(count);\n\n const summaryLabel = chip.querySelector<HTMLElement>('.beacon-events-label');\n if (summaryLabel) {\n summaryLabel.textContent = `${count} runtime ${count === 1 ? 'error' : 'errors'} will be included`;\n }\n\n const list = chip.querySelector<HTMLUListElement>('.beacon-events-list');\n if (list) {\n list.innerHTML = this.state.events.map((ev) => `\n <li class=\"beacon-events-item\">\n <span class=\"beacon-events-kind ${ev.kind === 'unhandledrejection' ? 'rejection' : 'error'}\">${ev.kind === 'unhandledrejection' ? 'rejection' : 'error'}</span>\n <span class=\"beacon-events-msg\">${escapeHtml(ev.message)}</span>\n </li>\n `).join('');\n }\n }\n\n getAnnotatedScreenshot(): string | undefined {\n return this.state.annotatedScreenshot;\n }\n\n setAnnotatedScreenshot(value: string | undefined) {\n this.state.annotatedScreenshot = value;\n this.render();\n }\n\n setSubmitting(submitting: boolean) {\n this.state.submitting = submitting;\n this.render();\n }\n\n setStatus(status: string, kind: '' | 'error' | 'success' = '') {\n this.state.status = status;\n this.state.statusKind = kind;\n this.render();\n }\n\n reset() {\n this.state = {\n description: '',\n severity: 'bug',\n pins: [],\n events: [],\n annotatedScreenshot: undefined,\n submitting: false,\n status: '',\n statusKind: '',\n };\n this.render();\n }\n\n getDescription() { return this.state.description; }\n getSeverity() { return this.state.severity; }\n\n private render() {\n const canSubmit = this.state.description.trim().length > 0 && !this.state.submitting;\n\n this.bodyEl.innerHTML = `\n <div class=\"beacon-field\">\n <label class=\"beacon-label\" for=\"beacon-desc\">What's the issue?</label>\n <textarea id=\"beacon-desc\" class=\"beacon-textarea\" placeholder=\"Describe what you saw, what you expected, anything that helps reproduce…\">${escapeHtml(this.state.description)}</textarea>\n </div>\n\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Severity</span>\n <div class=\"beacon-severity\" role=\"radiogroup\">\n ${this.severities.map((sev) => `\n <label class=\"beacon-severity-opt ${sev === this.state.severity ? 'selected' : ''}\" data-sev=\"${sev}\">\n <input type=\"radio\" name=\"beacon-severity\" value=\"${sev}\" ${sev === this.state.severity ? 'checked' : ''}>\n ${sev}\n </label>\n `).join('')}\n </div>\n </div>\n\n ${this.state.annotatedScreenshot ? `\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Annotated screenshot</span>\n <img src=\"${this.state.annotatedScreenshot}\" class=\"beacon-thumb\" alt=\"Annotated screenshot preview\">\n </div>\n ` : ''}\n\n ${this.state.pins.length > 0 ? `\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Pins (${this.state.pins.length})</span>\n <div class=\"beacon-pin-list\">\n ${this.state.pins.map((p) => `\n <div class=\"beacon-pin-item\" data-pin=\"${p.number}\">\n <span class=\"beacon-pin-num\">${p.number}</span>\n <div class=\"beacon-pin-meta\">\n <div class=\"beacon-pin-selector\" title=\"${escapeHtml(p.selector)}\">${escapeHtml(p.selector)}</div>\n <input type=\"text\" class=\"beacon-pin-note-input\" placeholder=\"Add a note (optional)\" value=\"${escapeHtml(p.note ?? '')}\">\n </div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-pin-delete=\"${p.number}\" aria-label=\"Remove pin ${p.number}\">${ICONS.trash}</button>\n </div>\n `).join('')}\n </div>\n </div>\n ` : ''}\n\n <details class=\"beacon-events\" data-count=\"${this.state.events.length}\" ${this.state.events.length === 0 ? 'hidden' : ''}>\n <summary class=\"beacon-events-summary\">\n <span class=\"beacon-events-dot\" aria-hidden=\"true\">●</span>\n <span class=\"beacon-events-label\">${this.state.events.length} runtime ${this.state.events.length === 1 ? 'error' : 'errors'} will be included</span>\n </summary>\n <ul class=\"beacon-events-list\">\n ${this.state.events.map((ev) => `\n <li class=\"beacon-events-item\">\n <span class=\"beacon-events-kind ${ev.kind === 'unhandledrejection' ? 'rejection' : 'error'}\">${ev.kind === 'unhandledrejection' ? 'rejection' : 'error'}</span>\n <span class=\"beacon-events-msg\">${escapeHtml(ev.message)}</span>\n </li>\n `).join('')}\n </ul>\n </details>\n\n <div class=\"beacon-actions\">\n <button type=\"button\" class=\"beacon-btn secondary\" data-action=\"annotate\" ${this.state.submitting ? 'disabled' : ''}>\n ${ICONS.pin} ${this.state.pins.length > 0 ? 'Add another pin' : 'Annotate elements'}\n </button>\n <span style=\"flex:1\"></span>\n <button type=\"button\" class=\"beacon-btn primary\" data-action=\"submit\" ${canSubmit ? '' : 'disabled'}>\n ${ICONS.send} ${this.state.submitting ? 'Sending…' : 'Send'}\n </button>\n </div>\n\n ${this.state.status ? `<div class=\"beacon-status ${this.state.statusKind}\">${escapeHtml(this.state.status)}</div>` : ''}\n `;\n\n // Wire events.\n const desc = this.bodyEl.querySelector('#beacon-desc') as HTMLTextAreaElement;\n desc.addEventListener('input', () => {\n this.state.description = desc.value;\n this.callbacks.onDescriptionChange(desc.value);\n // Re-render only the submit button's disabled state — full re-render kills focus, so skip it here.\n const submitBtn = this.bodyEl.querySelector('[data-action=\"submit\"]') as HTMLButtonElement | null;\n if (submitBtn) {\n submitBtn.disabled = !(desc.value.trim().length > 0) || this.state.submitting;\n }\n });\n\n this.bodyEl.querySelectorAll<HTMLInputElement>('input[name=\"beacon-severity\"]').forEach((input) => {\n input.addEventListener('change', () => {\n if (input.checked) {\n this.state.severity = input.value as Severity;\n this.callbacks.onSeverityChange(this.state.severity);\n this.render();\n }\n });\n });\n\n this.bodyEl.querySelector('[data-action=\"annotate\"]')?.addEventListener('click', () => this.callbacks.onAnnotate());\n this.bodyEl.querySelector('[data-action=\"submit\"]')?.addEventListener('click', () => this.callbacks.onSubmit());\n\n this.bodyEl.querySelectorAll<HTMLButtonElement>('[data-pin-delete]').forEach((btn) => {\n btn.addEventListener('click', () => {\n const num = Number(btn.getAttribute('data-pin-delete'));\n this.callbacks.onPinDelete(num);\n });\n });\n\n this.bodyEl.querySelectorAll<HTMLInputElement>('.beacon-pin-note-input').forEach((input) => {\n const item = input.closest('[data-pin]');\n const num = Number(item?.getAttribute('data-pin') ?? 0);\n input.addEventListener('input', () => this.callbacks.onPinNoteChange(num, input.value));\n });\n }\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n","// Small contextual popover that opens next to a picked element so the user can\n// optionally type a note. The cross icon discards this pin and lets the user keep\n// picking; Save attaches the (optional) note. Escape ends annotation entirely.\n\nimport { ICONS } from './icons';\n\nexport type PinPopoverCancel = 'pin' | 'all' | false;\n\nexport interface PinPopoverResult {\n note?: string;\n // 'pin' = discard this pin, keep picking. 'all' = end annotation. false = save.\n cancelled: PinPopoverCancel;\n}\n\nexport function showPinPopover(opts: {\n shadowRoot: ShadowRoot;\n anchor: { x: number; y: number }; // viewport coords\n pinNumber: number;\n}): Promise<PinPopoverResult> {\n return new Promise((resolve) => {\n const popover = document.createElement('div');\n // Mount on body (not shadow root) so we escape transformed-ancestor stacking\n // contexts. beacon-no-capture keeps it out of the screenshot. theme-auto follows\n // OS preference; if a future caller needs explicit theme, add an opts.theme.\n popover.className = 'beacon-pin-popover open beacon-no-capture beacon-theme-auto';\n popover.innerHTML = `\n <div class=\"beacon-pin-popover-header\">\n <div style=\"display:flex;align-items:center;gap:6px;font-weight:600;font-size:13px;\">\n <span class=\"beacon-pin-num\">${opts.pinNumber}</span>\n <span>Note for this pin</span>\n </div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-action=\"cancel\" aria-label=\"Discard this pin\">${ICONS.close}</button>\n </div>\n <textarea class=\"beacon-textarea\" rows=\"2\" placeholder=\"Optional — describe what's wrong here…\" style=\"min-height:48px;\"></textarea>\n <div class=\"beacon-pin-popover-actions\">\n <button type=\"button\" class=\"beacon-btn primary\" data-action=\"save\">${ICONS.check} Save</button>\n </div>\n `;\n\n // Position below the picked point, clamped to viewport.\n const POPOVER_W = 240;\n const POPOVER_H = 160;\n const left = Math.min(Math.max(8, opts.anchor.x), window.innerWidth - POPOVER_W - 8);\n const top = Math.min(Math.max(8, opts.anchor.y + 12), window.innerHeight - POPOVER_H - 8);\n popover.style.left = `${left}px`;\n popover.style.top = `${top}px`;\n\n document.body.appendChild(popover);\n\n const textarea = popover.querySelector('textarea')!;\n textarea.focus();\n\n function close(result: PinPopoverResult) {\n document.removeEventListener('keydown', handleGlobalKey, true);\n popover.remove();\n resolve(result);\n }\n\n // Document-level Escape handler so it works regardless of focus location\n // (textarea, popover background, anywhere on the page). Escape ends the whole\n // annotation session — use the cross icon to drop just this pin.\n function handleGlobalKey(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n close({ cancelled: 'all' });\n }\n }\n document.addEventListener('keydown', handleGlobalKey, true);\n\n popover.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n const action = target.closest('[data-action]')?.getAttribute('data-action');\n if (action === 'cancel') close({ cancelled: 'pin' });\n if (action === 'save') {\n const note = textarea.value.trim();\n close({ ...(note ? { note } : {}), cancelled: false });\n }\n });\n\n // Cmd/Ctrl+Enter inside the textarea = save (Enter alone inserts newlines).\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n const note = textarea.value.trim();\n close({ ...(note ? { note } : {}), cancelled: false });\n }\n });\n });\n}\n","// Visual overlay shown during pin-mode. Three layers:\n// 1. Subtle dotted viewport border + soft inset glow → \"you're in pin mode\"\n// 2. Top-center hint pill → \"press Esc to finish\"\n// 3. Numbered markers → over each already-pinned\n// element so the user can\n// see what they pinned\n//\n// Mounted on document.body (NOT the beacon Shadow DOM) because position:fixed\n// children of transformed/filtered/contained ancestors get anchored to that\n// ancestor instead of the viewport — and many host pages put a transform on\n// sticky headers, which is exactly where the slotted trigger lives.\n//\n// Each element carries the `beacon-no-capture` class so the screenshot filter\n// in capture/screenshot.ts skips them. All use pointer-events: none so they\n// don't block elementsFromPoint during picking.\n\nconst NO_CAPTURE_CLASS = 'beacon-no-capture';\nconst DEFAULT_ACCENT = '#0ea5e9';\nconst DEFAULT_HINT = 'Click any element to pin it · Press Esc to finish';\n\nexport interface PinAnchor {\n target: Element;\n /** Selector to re-query if `target` is detached from DOM (React re-render, conditional unmount). */\n selector?: string;\n /** Last-known viewport rect from pin time. Used as a faded \"anchor lost\" marker if both\n * the live ref and the selector lookup fail. */\n fallbackRect?: { x: number; y: number; w: number; h: number };\n}\n\nexport interface PickModeOverlay {\n addPin(pinNumber: number, anchor: PinAnchor): void;\n /** Swap the hint pill into a loading state (with spinner). Pass undefined to restore the default hint. */\n setLoading(message?: string): void;\n destroy(): void;\n}\n\nexport interface PickModeOverlayOptions {\n /** Accent color for border, hint pill, markers, and outlines. Defaults to sky-blue. */\n accent?: string;\n}\n\n/** Append a hex alpha suffix only when the color is a 7-char hex. Other formats\n * (`rgb(...)`, named colors) pass through unchanged — the alpha effect is lost\n * but the value stays valid. */\nfunction withAlpha(color: string, alphaHex: string): string {\n return /^#[0-9a-fA-F]{6}$/.test(color) ? `${color}${alphaHex}` : color;\n}\n\nexport function createPickModeOverlay(opts: PickModeOverlayOptions = {}): PickModeOverlay {\n const ACCENT = opts.accent ?? DEFAULT_ACCENT;\n const ACCENT_BORDER = withAlpha(ACCENT, 'b3'); // ~70% alpha for dashed viewport border\n const ACCENT_GLOW = withAlpha(ACCENT, '2e'); // ~18% alpha for inset glow\n // One-time keyframes for the loading spinner. Kept in <head> with the\n // beacon-no-capture class — <style> tags don't render so they don't affect\n // the screenshot, but we mark them anyway for filter consistency.\n const styleTag = document.createElement('style');\n styleTag.className = NO_CAPTURE_CLASS;\n styleTag.textContent = '@keyframes beacon-spin { to { transform: rotate(360deg); } }';\n document.head.appendChild(styleTag);\n\n const frame = document.createElement('div');\n frame.className = NO_CAPTURE_CLASS;\n frame.setAttribute('aria-hidden', 'true');\n frame.style.cssText = [\n 'position: fixed',\n 'inset: 0',\n 'pointer-events: none',\n 'z-index: 2147483646',\n `border: 2px dashed ${ACCENT_BORDER}`,\n 'border-radius: 4px',\n `box-shadow: inset 0 0 56px ${ACCENT_GLOW}`,\n 'box-sizing: border-box',\n ].join('; ');\n\n const hint = document.createElement('div');\n hint.className = NO_CAPTURE_CLASS;\n hint.setAttribute('role', 'status');\n hint.style.cssText = [\n 'position: fixed',\n 'top: 16px',\n 'left: 50%',\n 'transform: translateX(-50%)',\n `background: ${ACCENT}`,\n 'color: #fff',\n 'padding: 6px 14px',\n 'border-radius: 999px',\n 'font: 500 12px/1.4 system-ui, -apple-system, sans-serif',\n 'letter-spacing: 0.01em',\n 'box-shadow: 0 4px 12px #0000004d',\n 'pointer-events: none',\n 'white-space: nowrap',\n 'z-index: 2147483646',\n ].join('; ');\n hint.textContent = DEFAULT_HINT;\n\n const SPINNER_HTML = `<span style=\"\n display: inline-block;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-top-color: transparent;\n border-radius: 50%;\n animation: beacon-spin 800ms linear infinite;\n vertical-align: middle;\n margin-right: 8px;\n \"></span>`;\n\n function escapeHtml(s: string): string {\n return s.replace(/[<>&]/g, (c) => ({ '<': '&lt;', '>': '&gt;', '&': '&amp;' }[c] as string));\n }\n\n document.body.appendChild(frame);\n document.body.appendChild(hint);\n\n const tracked = new Map<number, { anchor: PinAnchor; marker: HTMLDivElement; outline: HTMLDivElement }>();\n\n function makeMarker(num: number): HTMLDivElement {\n const m = document.createElement('div');\n m.className = NO_CAPTURE_CLASS;\n m.setAttribute('aria-hidden', 'true');\n m.style.cssText = [\n 'position: fixed',\n 'width: 24px',\n 'height: 24px',\n 'border-radius: 999px',\n `background: ${ACCENT}`,\n 'color: #fff',\n 'display: flex',\n 'align-items: center',\n 'justify-content: center',\n 'font: 700 12px/1 system-ui, -apple-system, sans-serif',\n 'border: 2px solid #fff',\n 'box-shadow: 0 2px 8px #00000066',\n 'pointer-events: none',\n 'z-index: 2147483646',\n ].join('; ');\n m.textContent = String(num);\n document.body.appendChild(m);\n return m;\n }\n\n function makeOutline(): HTMLDivElement {\n const o = document.createElement('div');\n o.className = NO_CAPTURE_CLASS;\n o.setAttribute('aria-hidden', 'true');\n o.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n `border: 2px solid ${ACCENT}`,\n 'border-radius: 2px',\n 'box-sizing: border-box',\n // Slightly below marker z so the marker visually \"sits on\" the outline corner.\n 'z-index: 2147483645',\n ].join('; ');\n document.body.appendChild(o);\n return o;\n }\n\n function placeAt(\n entry: { marker: HTMLDivElement; outline: HTMLDivElement },\n rect: { x: number; y: number; w: number; h: number },\n isStale: boolean,\n ) {\n const opacity = isStale ? '0.5' : '1';\n\n entry.outline.style.display = 'block';\n entry.outline.style.opacity = opacity;\n entry.outline.style.left = `${rect.x}px`;\n entry.outline.style.top = `${rect.y}px`;\n entry.outline.style.width = `${rect.w}px`;\n entry.outline.style.height = `${rect.h}px`;\n\n entry.marker.style.display = 'flex';\n entry.marker.style.opacity = opacity;\n entry.marker.style.left = `${rect.x + rect.w - 12}px`;\n entry.marker.style.top = `${Math.max(2, rect.y - 12)}px`;\n }\n\n function hide(entry: { marker: HTMLDivElement; outline: HTMLDivElement }) {\n entry.marker.style.display = 'none';\n entry.outline.style.display = 'none';\n }\n\n function reposition() {\n tracked.forEach((entry) => {\n // Tier 1: live element ref still in DOM\n let liveTarget: Element | null = entry.anchor.target;\n if (!document.contains(liveTarget)) liveTarget = null;\n\n // Tier 2: re-query by selector (handles React re-renders that swap the node)\n if (!liveTarget && entry.anchor.selector) {\n liveTarget = document.querySelector(entry.anchor.selector);\n if (liveTarget) entry.anchor.target = liveTarget; // refresh for next reposition\n }\n\n if (liveTarget) {\n const r = liveTarget.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n placeAt(entry, { x: r.left, y: r.top, w: r.width, h: r.height }, false);\n return;\n }\n }\n\n // Tier 3: fallback to the rect captured at pin time. Honest \"anchor lost\"\n // signal — half opacity so the user can see this isn't tracking anymore.\n const fr = entry.anchor.fallbackRect;\n if (fr && (fr.w > 0 || fr.h > 0)) {\n placeAt(entry, fr, true);\n return;\n }\n\n hide(entry);\n });\n }\n\n let raf: number | null = null;\n function schedule() {\n if (raf !== null) return;\n raf = requestAnimationFrame(() => {\n raf = null;\n reposition();\n });\n }\n\n window.addEventListener('scroll', schedule, true);\n window.addEventListener('resize', schedule);\n\n return {\n addPin(num, anchor) {\n const marker = makeMarker(num);\n const outline = makeOutline();\n tracked.set(num, { anchor, marker, outline });\n reposition();\n },\n setLoading(message) {\n if (message) {\n hint.innerHTML = SPINNER_HTML + escapeHtml(message);\n } else {\n hint.textContent = DEFAULT_HINT;\n }\n },\n destroy() {\n window.removeEventListener('scroll', schedule, true);\n window.removeEventListener('resize', schedule);\n if (raf !== null) cancelAnimationFrame(raf);\n frame.remove();\n hint.remove();\n styleTag.remove();\n tracked.forEach(({ marker, outline }) => {\n marker.remove();\n outline.remove();\n });\n tracked.clear();\n },\n };\n}\n","// Hover/click element picker. Draws an outline overlay over the hovered element\n// and resolves with the clicked element. Skips the widget's own elements via\n// composedPath check against the provided shadow root.\n\nexport interface PickerOptions {\n shadowRoot: ShadowRoot;\n onHover?: (el: Element | null) => void;\n /** Outline color for the hovered-element highlight. Defaults to sky-blue. */\n accent?: string;\n}\n\nconst DEFAULT_ACCENT = '#0ea5e9';\n\n/** Append hex alpha suffix only for 7-char hex; other color formats pass through unchanged. */\nfunction withAlpha(color: string, alphaHex: string): string {\n return /^#[0-9a-fA-F]{6}$/.test(color) ? `${color}${alphaHex}` : color;\n}\n\nexport interface PickerHandle {\n cancel: () => void;\n promise: Promise<Element | null>; // resolves with picked element, or null on Escape\n}\n\nexport function startPicker(opts: PickerOptions): PickerHandle {\n const { shadowRoot, onHover } = opts;\n const accent = opts.accent ?? DEFAULT_ACCENT;\n const accentFill = withAlpha(accent, '14'); // ~8% alpha hover-fill tint\n\n // Outline overlay — appended to body, position: fixed, pointer-events: none.\n const outline = document.createElement('div');\n outline.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n 'z-index: 2147483646',\n `border: 2px solid ${accent}`,\n `background: ${accentFill}`,\n 'transition: all 60ms ease-out',\n 'box-sizing: border-box',\n 'border-radius: 2px',\n ].join('; ');\n document.body.appendChild(outline);\n\n const tooltip = document.createElement('div');\n tooltip.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n 'z-index: 2147483647',\n 'background: #0f172a',\n 'color: #fff',\n 'font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace',\n 'padding: 3px 6px',\n 'border-radius: 3px',\n 'max-width: 280px',\n 'overflow: hidden',\n 'text-overflow: ellipsis',\n 'white-space: nowrap',\n ].join('; ');\n document.body.appendChild(tooltip);\n\n const previousCursor = document.body.style.cursor;\n document.body.style.cursor = 'crosshair';\n\n let resolved = false;\n let resolvePromise: (v: Element | null) => void = () => {};\n const promise = new Promise<Element | null>((res) => { resolvePromise = res; });\n\n function isWidgetElement(el: EventTarget | null): boolean {\n if (!el || !(el instanceof Node)) return false;\n // composedPath gives us shadow boundaries.\n let node: Node | null = el;\n while (node) {\n if (node === shadowRoot || node === shadowRoot.host) return true;\n node = node.parentNode ?? (node as ShadowRoot).host ?? null;\n }\n return false;\n }\n\n function findTarget(x: number, y: number): Element | null {\n // Hide overlay so it doesn't appear in elementsFromPoint, then use elementsFromPoint\n // and pick the first non-widget element.\n outline.style.display = 'none';\n tooltip.style.display = 'none';\n const candidates = document.elementsFromPoint(x, y);\n outline.style.display = 'block';\n tooltip.style.display = 'block';\n for (const c of candidates) {\n if (!isWidgetElement(c)) return c;\n }\n return null;\n }\n\n function positionOutline(el: Element) {\n const rect = el.getBoundingClientRect();\n outline.style.left = `${rect.left}px`;\n outline.style.top = `${rect.top}px`;\n outline.style.width = `${rect.width}px`;\n outline.style.height = `${rect.height}px`;\n\n const tag = el.tagName.toLowerCase();\n const cls = el.classList.length > 0 ? '.' + Array.from(el.classList).slice(0, 2).join('.') : '';\n tooltip.textContent = tag + cls;\n // Place tooltip just above the element, or below if it would clip the top.\n const above = rect.top - 22;\n tooltip.style.left = `${rect.left}px`;\n tooltip.style.top = `${above >= 0 ? above : rect.bottom + 4}px`;\n }\n\n function handleMove(e: MouseEvent) {\n const el = findTarget(e.clientX, e.clientY);\n if (el) {\n positionOutline(el);\n onHover?.(el);\n } else {\n outline.style.display = 'none';\n tooltip.style.display = 'none';\n onHover?.(null);\n }\n }\n\n // Listen on pointerdown (NOT click) so we intercept the press BEFORE the host\n // page reacts. Radix Select / Popover / Dialog open on pointerdown — by the\n // time `click` fires, the page state has changed (dropdown open, focus moved,\n // layout shifted) and elementsFromPoint at click coords returns the wrong thing.\n // pointerdown + capture phase + preventDefault + stopPropagation gives us the\n // element under the cursor exactly as the user saw it, before any host handlers run.\n function handlePointerDown(e: PointerEvent) {\n if (e.button !== 0) return; // ignore right/middle clicks\n e.preventDefault();\n e.stopPropagation();\n const el = findTarget(e.clientX, e.clientY);\n if (el) finish(el);\n }\n\n // Also swallow the trailing click/mouseup so a host-page handler doesn't fire\n // anyway. We've already finished by this point but keep listeners briefly.\n function swallow(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n function handleKey(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n finish(null);\n }\n }\n\n function finish(el: Element | null) {\n if (resolved) return;\n resolved = true;\n document.removeEventListener('mousemove', handleMove, true);\n document.removeEventListener('pointerdown', handlePointerDown, true);\n document.removeEventListener('click', swallow, true);\n document.removeEventListener('mouseup', swallow, true);\n document.removeEventListener('keydown', handleKey, true);\n outline.remove();\n tooltip.remove();\n document.body.style.cursor = previousCursor;\n resolvePromise(el);\n }\n\n document.addEventListener('mousemove', handleMove, true);\n document.addEventListener('pointerdown', handlePointerDown, true);\n document.addEventListener('click', swallow, true);\n document.addEventListener('mouseup', swallow, true);\n document.addEventListener('keydown', handleKey, true);\n\n return {\n cancel: () => finish(null),\n promise,\n };\n}\n","// Build a unique-ish CSS selector path for an element by walking up the parent chain.\n// Strategy per ancestor: id (if unique) → tag.classes (if unique among siblings) → tag:nth-of-type(n).\n// Stops at <body> or after a depth limit.\n\nconst MAX_DEPTH = 8;\n\nfunction isUniqueId(id: string, root: Document | ShadowRoot = document): boolean {\n if (!id) return false;\n try {\n return root.querySelectorAll(`#${CSS.escape(id)}`).length === 1;\n } catch {\n return false;\n }\n}\n\nfunction tagWithClasses(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const classes = Array.from(el.classList)\n // Drop classes that look like generated atomic / hashed names (heuristic — keep stable-looking ones).\n .filter((c) => c.length > 0 && c.length < 40)\n .slice(0, 3)\n .map((c) => `.${CSS.escape(c)}`)\n .join('');\n return tag + classes;\n}\n\nfunction nthOfTypeIndex(el: Element): number {\n const parent = el.parentElement;\n if (!parent) return 1;\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === el.tagName);\n return sameTag.indexOf(el) + 1;\n}\n\nexport function buildSelector(target: Element): string {\n if (!target || target.nodeType !== Node.ELEMENT_NODE) return '';\n\n // Fast path: unique id on the target itself.\n if (target.id && isUniqueId(target.id)) {\n return `#${CSS.escape(target.id)}`;\n }\n\n const parts: string[] = [];\n let el: Element | null = target;\n let depth = 0;\n\n while (el && el.tagName.toLowerCase() !== 'body' && depth < MAX_DEPTH) {\n const current: Element = el;\n\n if (current.id && isUniqueId(current.id)) {\n parts.unshift(`#${CSS.escape(current.id)}`);\n break;\n }\n\n const base = tagWithClasses(current);\n const parent: HTMLElement | null = current.parentElement;\n\n // If this base matches multiple siblings, disambiguate with :nth-of-type.\n let part = base;\n if (parent) {\n try {\n const currentClasses = Array.from(current.classList).join(' ');\n const siblings: Element[] = Array.from(parent.children).filter(\n (c: Element) => c.tagName === current.tagName && Array.from(c.classList).join(' ') === currentClasses,\n );\n if (siblings.length > 1) {\n part = `${current.tagName.toLowerCase()}:nth-of-type(${nthOfTypeIndex(current)})`;\n }\n } catch {\n // ignore — fall back to base\n }\n }\n\n parts.unshift(part);\n el = parent;\n depth++;\n }\n\n return parts.join(' > ');\n}\n","// Best-effort framework component name detection.\n// Production builds usually minify component names — return null quietly when unavailable.\n\nimport type { Pin } from '../types';\n\ntype FW = NonNullable<Pin['framework']>;\n\nfunction detectReact(el: Element): FW | null {\n // React stores fiber refs on properties like __reactFiber$<hash> / __reactInternalInstance$<hash>.\n const keys = Object.keys(el).filter((k) => k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$'));\n if (keys.length === 0) return null;\n\n let fiber: unknown = (el as unknown as Record<string, unknown>)[keys[0]!];\n // Walk up the fiber chain to find the nearest function/class component (skip host elements).\n for (let i = 0; i < 10 && fiber; i++) {\n const f = fiber as { type?: unknown; return?: unknown };\n const type = f.type;\n if (typeof type === 'function') {\n const name = (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name;\n if (name && name !== '_default') return { lib: 'react', name };\n }\n if (typeof type === 'object' && type !== null) {\n const name = (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name;\n if (name) return { lib: 'react', name };\n }\n fiber = f.return;\n }\n return { lib: 'react' };\n}\n\nfunction detectVue(el: Element): FW | null {\n const anyEl = el as unknown as Record<string, unknown>;\n const vueParent = anyEl.__vueParentComponent as { type?: { name?: string; __name?: string } } | undefined;\n if (vueParent) {\n const name = vueParent.type?.name ?? vueParent.type?.__name;\n return { lib: 'vue', ...(name ? { name } : {}) };\n }\n if (anyEl.__vue__) return { lib: 'vue' };\n return null;\n}\n\nfunction detectAngular(el: Element): FW | null {\n // Angular dev mode exposes window.ng.getComponent(el).\n const ng = (window as unknown as { ng?: { getComponent?: (el: Element) => unknown } }).ng;\n if (!ng?.getComponent) return null;\n try {\n const cmp = ng.getComponent(el);\n if (!cmp) return null;\n const ctor = (cmp as { constructor?: { name?: string } }).constructor;\n return { lib: 'angular', ...(ctor?.name ? { name: ctor.name } : {}) };\n } catch {\n return null;\n }\n}\n\nfunction detectSvelte(el: Element): FW | null {\n // Svelte exposes very little at runtime. Look for $$ properties on the host.\n const anyEl = el as unknown as Record<string, unknown>;\n if ('__svelte_meta' in anyEl) return { lib: 'svelte' };\n return null;\n}\n\nexport function detectFramework(el: Element): Pin['framework'] | undefined {\n const result = detectReact(el) ?? detectVue(el) ?? detectAngular(el) ?? detectSvelte(el);\n return result ?? undefined;\n}\n","// Capture per-pin element data: outerHTML (truncated), selector, computed styles, bounding rect, framework hint.\n\nimport type { RawPinCapture } from '../types';\nimport { buildSelector } from './selector';\nimport { detectFramework } from './framework';\n\n// Limits matched to the /api/feedback zod schema. The route caps each list / string\n// length defensively — exceed any of these and the entire payload 400s with no\n// useful detail surfaced in the beacon UI, so we mirror the caps here.\nconst OUTER_HTML_LIMIT = 5000; // schema: outerHTML max 8000\nconst PARENT_OUTER_HTML_LIMIT = 1000; // schema: parentOuterHTML max 2000\nconst SELECTOR_LIMIT = 1000; // schema: selector max 1000\nconst ID_LIMIT = 200; // schema: id max 200\nconst CLASSLIST_MAX_ENTRIES = 50; // schema: classList array max 50\nconst CLASS_NAME_LIMIT = 200; // schema: each class max 200\nconst STYLE_VALUE_LIMIT = 500; // schema: computedStyles value max 500\n\n// A focused, useful subset of computed style properties. Dumping all 400+ resolved\n// properties is noise; this list covers layout, typography, color, and key visual hints.\nconst USEFUL_STYLE_PROPS = [\n 'display', 'position', 'top', 'right', 'bottom', 'left',\n 'width', 'height', 'min-width', 'min-height', 'max-width', 'max-height',\n 'margin', 'padding',\n 'font-family', 'font-size', 'font-weight', 'line-height', 'text-align',\n 'color', 'background-color', 'background-image',\n 'border', 'border-radius',\n 'opacity', 'visibility', 'overflow',\n 'z-index', 'transform', 'transition',\n 'flex', 'flex-direction', 'justify-content', 'align-items', 'gap',\n 'grid-template-columns', 'grid-template-rows',\n] as const;\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max) + `\\n\\n/* … truncated, original was ${s.length} chars */`;\n}\n\nfunction pickStyles(el: Element): Record<string, string> {\n const computed = getComputedStyle(el);\n const out: Record<string, string> = {};\n for (const prop of USEFUL_STYLE_PROPS) {\n const value = computed.getPropertyValue(prop);\n if (value && value !== 'normal' && value !== 'none' && value !== 'auto' && value !== '0px') {\n out[prop] = value.trim().slice(0, STYLE_VALUE_LIMIT);\n }\n }\n return out;\n}\n\nfunction capClassList(el: Element): string[] {\n const all = Array.from(el.classList);\n // First slice to the entry cap, then truncate each class name. Order matters:\n // truncating first and then slicing would still produce >50 entries.\n return all\n .slice(0, CLASSLIST_MAX_ENTRIES)\n .map((c) => (c.length > CLASS_NAME_LIMIT ? c.slice(0, CLASS_NAME_LIMIT) : c));\n}\n\nexport function capturePin(el: Element): RawPinCapture {\n const rect = el.getBoundingClientRect();\n const rawSelector = buildSelector(el);\n const rawId = el.id || null;\n return {\n selector: rawSelector.length > SELECTOR_LIMIT ? rawSelector.slice(0, SELECTOR_LIMIT) : rawSelector,\n tagName: el.tagName.toLowerCase(),\n id: rawId && rawId.length > ID_LIMIT ? rawId.slice(0, ID_LIMIT) : rawId,\n classList: capClassList(el),\n outerHTML: truncate(el.outerHTML, OUTER_HTML_LIMIT),\n ...(el.parentElement\n ? { parentOuterHTML: truncate(el.parentElement.outerHTML, PARENT_OUTER_HTML_LIMIT) }\n : {}),\n computedStyles: pickStyles(el),\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n ...(detectFramework(el) ? { framework: detectFramework(el)! } : {}),\n };\n}\n","// Capture browser / viewport / locale metadata. Pure read-only — no instrumentation.\n\nimport type { Metadata } from '../types';\n\ninterface UADataLike {\n brands: Array<{ brand: string; version: string }>;\n mobile: boolean;\n platform: string;\n}\n\nfunction getUaData(): Metadata['uaData'] {\n const nav = navigator as Navigator & { userAgentData?: UADataLike };\n if (!nav.userAgentData) return undefined;\n // Pick the first non-\"Not.A/Brand\" brand for legibility.\n const brand = nav.userAgentData.brands.find((b) => !/Not[.\\-]?A.?Brand/i.test(b.brand))?.brand\n ?? nav.userAgentData.brands[0]?.brand\n ?? 'unknown';\n return {\n brand,\n mobile: nav.userAgentData.mobile,\n platform: nav.userAgentData.platform,\n };\n}\n\nfunction getTheme(): Metadata['theme'] {\n if (window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark';\n if (window.matchMedia('(prefers-color-scheme: light)').matches) return 'light';\n return undefined;\n}\n\nexport function captureMetadata(): Metadata {\n return {\n url: window.location.href,\n ...(document.referrer ? { referrer: document.referrer } : {}),\n userAgent: navigator.userAgent,\n ...(getUaData() ? { uaData: getUaData()! } : {}),\n viewport: {\n w: window.innerWidth,\n h: window.innerHeight,\n dpr: window.devicePixelRatio || 1,\n },\n screen: {\n w: window.screen.width,\n h: window.screen.height,\n },\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n locale: navigator.language,\n ...(getTheme() ? { theme: getTheme()! } : {}),\n capturedAt: new Date().toISOString(),\n };\n}\n","// Lazy-loaded screenshot capture via html-to-image.\n// Captures the viewport (document.documentElement) as a JPEG data URL.\n//\n// Cross-origin images that don't return CORS headers (e.g., GitHub avatar redirects\n// from github.com → avatars.githubusercontent.com) cause html-to-image to taint\n// the canvas → toJpeg throws SecurityError. Filter alone wasn't reliable because\n// html-to-image fetches some images outside the filter's reach. Belt-and-suspenders:\n// physically swap cross-origin <img>.src to a transparent pixel before capture,\n// restore after. The user sees a brief blank where the avatar was during capture\n// (~hundreds of ms); the page never sees a screenshot failure.\n\nlet htmlToImage: typeof import('html-to-image') | null = null;\n\nasync function load() {\n if (!htmlToImage) {\n htmlToImage = await import('html-to-image');\n }\n return htmlToImage;\n}\n\nexport interface ScreenshotOptions {\n quality?: number; // 0..1, default 0.7\n pixelRatio?: number; // default min(devicePixelRatio, 2) — capping to keep file size sane\n excludeShadowRoot?: ShadowRoot; // skip our own widget elements\n}\n\nconst TRANSPARENT_PIXEL =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=';\n\nfunction isUrlSafeForCanvas(rawUrl: string, crossOriginAttr?: string | null): boolean {\n if (!rawUrl) return true;\n if (rawUrl.startsWith('data:') || rawUrl.startsWith('blob:')) return true;\n if (rawUrl.startsWith('/') || rawUrl.startsWith('#')) return true;\n try {\n const u = new URL(rawUrl, window.location.href);\n if (u.origin === window.location.origin) return true;\n } catch {\n return false;\n }\n return crossOriginAttr === 'anonymous' || crossOriginAttr === 'use-credentials';\n}\n\n/**\n * Replace cross-origin image sources with a transparent pixel for the duration of\n * the capture so html-to-image can't even attempt to fetch them. Returns a restore\n * function that puts the originals back.\n *\n * Covers two element types:\n * - HTML <img> (uses .src)\n * - SVG <image> (uses href / xlink:href) — used by AstronautAvatar for GitHub avatars\n */\nfunction neutralizeCrossOriginImages(): () => void {\n const stashedImg: Array<{ el: HTMLImageElement; src: string }> = [];\n const stashedSvg: Array<{ el: SVGImageElement; href: string | null; xlink: string | null }> = [];\n\n document.querySelectorAll('img').forEach((img) => {\n if (!isUrlSafeForCanvas(img.src, img.crossOrigin)) {\n stashedImg.push({ el: img, src: img.src });\n img.src = TRANSPARENT_PIXEL;\n }\n });\n\n document.querySelectorAll('image').forEach((img) => {\n const svgImg = img as unknown as SVGImageElement;\n const href = svgImg.getAttribute('href');\n const xlink = svgImg.getAttributeNS('http://www.w3.org/1999/xlink', 'href');\n const url = href || xlink || '';\n if (url && !isUrlSafeForCanvas(url)) {\n stashedSvg.push({ el: svgImg, href, xlink });\n if (href !== null) svgImg.setAttribute('href', TRANSPARENT_PIXEL);\n if (xlink !== null) svgImg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', TRANSPARENT_PIXEL);\n }\n });\n\n return () => {\n for (const { el, src } of stashedImg) {\n el.src = src;\n }\n for (const { el, href, xlink } of stashedSvg) {\n if (href !== null) el.setAttribute('href', href);\n if (xlink !== null) el.setAttributeNS('http://www.w3.org/1999/xlink', 'href', xlink);\n }\n };\n}\n\nexport async function captureScreenshot(opts: ScreenshotOptions = {}): Promise<string> {\n const { quality = 0.7, pixelRatio = Math.min(window.devicePixelRatio || 1, 2), excludeShadowRoot } = opts;\n const lib = await load();\n\n // Skip:\n // - the widget's host element (drawer / floating trigger)\n // - any element marked .beacon-no-capture (overlays mounted to document.body\n // because shadow-DOM children get trapped inside transformed ancestors)\n const filter = excludeShadowRoot\n ? (node: Node) => {\n let cur: Node | null = node;\n while (cur) {\n if (cur === excludeShadowRoot.host) return false;\n if (cur instanceof Element && cur.classList.contains('beacon-no-capture')) return false;\n cur = cur.parentNode;\n }\n return true;\n }\n : undefined;\n\n const restore = neutralizeCrossOriginImages();\n\n try {\n return await lib.toJpeg(document.documentElement, {\n quality,\n pixelRatio,\n cacheBust: true,\n ...(filter ? { filter } : {}),\n imagePlaceholder: TRANSPARENT_PIXEL,\n // Cap dimensions to viewport so we don't accidentally capture full document height.\n width: window.innerWidth,\n height: window.innerHeight,\n style: {\n // Avoid scrolling artifacts.\n transform: 'none',\n },\n });\n } finally {\n restore();\n }\n}\n","// Draw the captured pins onto a screenshot. Takes the viewport screenshot data\n// URL and the pin list, returns a new data URL with two things baked per pin:\n//\n// 1. An outline rectangle around the pinned element (so triagers can tell\n// WHICH element was pinned without clicking into the pin data).\n// 2. A numbered circle at the outline's top-right corner.\n//\n// Rect freshness: pin.boundingRect is captured at pin time. If the user scrolls\n// between pinning and screenshot capture, that rect is in stale viewport coords.\n// We recompute via the same fallback chain the live overlay uses:\n// live element ref → selector lookup → captured rect\n// This keeps outlines and markers correctly anchored to what was pinned.\n\nimport type { Pin } from '../types';\n\nconst MARKER_RADIUS = 14;\nconst MARKER_STROKE = '#ffffff';\nconst MARKER_TEXT = '#ffffff';\nconst OUTLINE_WIDTH = 3;\nconst DEFAULT_ACCENT = '#0ea5e9';\n\nexport async function drawMarkers(\n screenshotDataUrl: string,\n pins: Pin[],\n viewportSize: { w: number; h: number; dpr: number },\n pinElements?: WeakMap<Pin, Element>,\n accent: string = DEFAULT_ACCENT,\n): Promise<string> {\n const MARKER_FILL = accent;\n const OUTLINE_COLOR = accent;\n const img = await loadImage(screenshotDataUrl);\n\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('Could not get 2D canvas context');\n\n ctx.drawImage(img, 0, 0);\n\n // Map viewport coords → screenshot pixel coords using the ratio between image\n // size and the captured viewport dimensions.\n const scaleX = canvas.width / viewportSize.w;\n const scaleY = canvas.height / viewportSize.h;\n\n for (const pin of pins) {\n const rect = getFreshRect(pin, pinElements);\n if (!rect) continue;\n\n const x = rect.x * scaleX;\n const y = rect.y * scaleY;\n const w = rect.w * scaleX;\n const h = rect.h * scaleY;\n\n // ── Outline rectangle ──\n ctx.lineWidth = OUTLINE_WIDTH;\n ctx.strokeStyle = OUTLINE_COLOR;\n ctx.strokeRect(x, y, w, h);\n\n // ── Numbered marker at top-right corner (matches the live overlay placement\n // so what users saw during pin mode looks like what triagers see later). ──\n const cx = x + w;\n const cy = y;\n\n // Filled circle.\n ctx.beginPath();\n ctx.fillStyle = MARKER_FILL;\n ctx.arc(cx, cy, MARKER_RADIUS, 0, Math.PI * 2);\n ctx.fill();\n\n // White outer stroke for contrast.\n ctx.lineWidth = 3;\n ctx.strokeStyle = MARKER_STROKE;\n ctx.stroke();\n\n // Number text.\n ctx.fillStyle = MARKER_TEXT;\n ctx.font = 'bold 16px system-ui, -apple-system, sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(String(pin.number), cx, cy + 1);\n }\n\n return canvas.toDataURL('image/jpeg', 0.85);\n}\n\n/**\n * Three-tier fallback for \"where is this pinned element NOW\":\n * 1. Live element ref via WeakMap (most accurate — handles scroll, layout shift)\n * 2. Selector re-query (handles React re-render swapping the node identity)\n * 3. Original captured rect (last resort — may be stale relative to current viewport)\n */\nfunction getFreshRect(\n pin: Pin,\n pinElements?: WeakMap<Pin, Element>,\n): { x: number; y: number; w: number; h: number } | null {\n const target = pinElements?.get(pin);\n if (target && document.contains(target)) {\n const r = target.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n return { x: r.left, y: r.top, w: r.width, h: r.height };\n }\n }\n\n if (pin.selector) {\n try {\n const found = document.querySelector(pin.selector);\n if (found) {\n const r = found.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n return { x: r.left, y: r.top, w: r.width, h: r.height };\n }\n }\n } catch {\n // Invalid selector — fall through to captured rect.\n }\n }\n\n return pin.boundingRect;\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (err) => reject(err);\n img.src = src;\n });\n}\n","// Capture runtime errors + unhandled promise rejections into a small ring buffer.\n// Drained by element.ts at submit time and attached to the feedback payload so the\n// reviewer (often Claude) can see what failed silently around the moment the user\n// hit the report button. Listeners are passive — zero cost on the happy path.\n//\n// Intentionally narrow: only `error` and `unhandledrejection`. No fetch monkey-\n// patching, no PerformanceObserver. Those can come later if real reports show the\n// gap; today's reports have nothing at all in this slot.\n\nimport type { CapturedEvent } from '../types';\n\nconst MAX_EVENTS = 30;\nconst MESSAGE_LIMIT = 500;\nconst STACK_LIMIT = 2000;\nconst SOURCE_LIMIT = 500;\nconst DEDUPE_WINDOW_MS = 5000;\n\n// Stack frame fragments that mean \"this came from the beacon itself\" — used to\n// avoid recursion (capturing our own errors would loop the report payload).\n// Patterns match both source-mode (dev consumer) and bundled output names.\nconst BEACON_STACK_PATTERN = /launch-kit-beacon|beacon-client|beacon\\.(?:es|umd|mjs)/i;\n\nconst buffer: CapturedEvent[] = [];\nconst recentSignatures = new Map<string, number>();\nconst listeners = new Set<() => void>();\nlet installed = false;\n\nfunction trunc(value: string | undefined, limit: number): string | undefined {\n if (!value) return undefined;\n return value.length > limit ? value.slice(0, limit) : value;\n}\n\nfunction signature(message: string, stack: string | undefined): string {\n // Top three frames are enough to distinguish \"same bug\" from \"different bug\"\n // without making the signature sensitive to async boundaries far up the stack.\n const stackHead = stack?.split('\\n').slice(0, 3).join('|') ?? '';\n return `${message}::${stackHead}`;\n}\n\nfunction fromBeacon(stack: string | undefined): boolean {\n return !!stack && BEACON_STACK_PATTERN.test(stack);\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value).slice(0, MESSAGE_LIMIT);\n } catch {\n return String(value);\n }\n}\n\nfunction push(event: CapturedEvent): void {\n // 1. Self-capture guard. If the failure came from inside the beacon, swallow it —\n // otherwise reporting a bug could itself generate the bug we report next time.\n if (fromBeacon(event.stack)) return;\n\n // 2. Drop AbortError. SPAs cancel fetches as a normal part of routing/cleanup\n // and they surface as unhandled rejections; they aren't bugs.\n if (event.kind === 'unhandledrejection' && /AbortError/i.test(event.message)) return;\n\n // 3. Dedupe within a short window so a render loop firing 200x doesn't blow the buffer.\n const sig = signature(event.message, event.stack);\n const last = recentSignatures.get(sig);\n if (last !== undefined && event.ts - last < DEDUPE_WINDOW_MS) {\n recentSignatures.set(sig, event.ts);\n return;\n }\n recentSignatures.set(sig, event.ts);\n\n buffer.push(event);\n if (buffer.length > MAX_EVENTS) buffer.shift();\n\n // Notify subscribers AFTER buffer mutation so they see the new state. Each\n // listener is wrapped — a throw here would block remaining listeners and\n // recursively trip the global error handler.\n for (const fn of listeners) {\n try { fn(); } catch { /* swallow */ }\n }\n}\n\n/**\n * Attach `error` and `unhandledrejection` listeners on `window`. Idempotent — safe\n * to call repeatedly (e.g., HMR reloads). No-op in non-browser environments.\n *\n * Called at module load from index.ts so we start capturing before the beacon\n * element mounts. Errors that fire during initial page hydration are exactly\n * the ones users are most likely to report and least able to describe.\n */\nexport function installEventCapture(): void {\n if (installed) return;\n if (typeof window === 'undefined') return;\n installed = true;\n\n window.addEventListener('error', (e: ErrorEvent) => {\n try {\n const errMessage = e.error instanceof Error ? e.error.message : undefined;\n const errStack = e.error instanceof Error ? e.error.stack : undefined;\n push({\n ts: Date.now(),\n kind: 'error',\n message: trunc(e.message || errMessage || 'Unknown error', MESSAGE_LIMIT) ?? 'Unknown error',\n ...(errStack ? { stack: trunc(errStack, STACK_LIMIT)! } : {}),\n ...(e.filename ? { source: trunc(e.filename, SOURCE_LIMIT)! } : {}),\n ...(Number.isFinite(e.lineno) ? { line: e.lineno } : {}),\n ...(Number.isFinite(e.colno) ? { col: e.colno } : {}),\n });\n } catch {\n // Never let our handler throw — it'd reenter the same listener.\n }\n });\n\n window.addEventListener('unhandledrejection', (e: PromiseRejectionEvent) => {\n try {\n const reason: unknown = e.reason;\n const message = reason instanceof Error\n ? reason.message\n : typeof reason === 'string'\n ? reason\n : safeStringify(reason);\n const stack = reason instanceof Error ? reason.stack : undefined;\n push({\n ts: Date.now(),\n kind: 'unhandledrejection',\n message: trunc(message || 'Unknown rejection', MESSAGE_LIMIT) ?? 'Unknown rejection',\n ...(stack ? { stack: trunc(stack, STACK_LIMIT)! } : {}),\n });\n } catch {\n // Same — swallow.\n }\n });\n}\n\n/** Snapshot of the captured events buffer. Returns a copy; callers can mutate it. */\nexport function getCapturedEvents(): CapturedEvent[] {\n return buffer.slice();\n}\n\n/**\n * Register a callback that fires every time a new event is added to the buffer.\n * Returns an unsubscribe function. Used by the drawer to live-update its chip\n * count so users see errors arrive in real-time, regardless of whether the\n * widget was opened before or after the error fired.\n */\nexport function subscribeToEvents(fn: () => void): () => void {\n listeners.add(fn);\n return () => { listeners.delete(fn); };\n}\n","// POST the feedback payload to the configured endpoint.\n\nimport type { FeedbackPayload, SubmitResponse } from '../types';\n\nexport async function submitFeedback(\n endpoint: string,\n payload: FeedbackPayload,\n headers?: Record<string, string>,\n): Promise<SubmitResponse> {\n const res = await fetch(endpoint, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...(headers ?? {}),\n },\n body: JSON.stringify(payload),\n });\n\n let body: unknown = null;\n const contentType = res.headers.get('Content-Type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n body = await res.json();\n } catch {\n body = null;\n }\n } else {\n try {\n body = await res.text();\n } catch {\n body = null;\n }\n }\n\n return {\n ok: res.ok,\n status: res.status,\n body,\n };\n}\n","// <launch-kit-beacon> custom element. Orchestrates the capture pipeline + UI.\n\nimport stylesCss from './styles.css?inline';\n\nimport type { BeaconConfig, FeedbackPayload, Pin, RawPinCapture, Severity } from './types';\nimport { createTriggerButton } from './ui/button';\nimport { DrawerView } from './ui/drawer';\nimport { showPinPopover } from './ui/pin-popover';\nimport { createPickModeOverlay } from './ui/pick-mode-overlay';\nimport { startPicker } from './capture/picker';\nimport { capturePin } from './capture/element';\nimport { captureMetadata } from './capture/metadata';\nimport { captureScreenshot } from './capture/screenshot';\nimport { drawMarkers } from './capture/overlay';\nimport { getCapturedEvents, subscribeToEvents } from './capture/events';\nimport { submitFeedback } from './transport/submit';\n\nconst ATTRS = ['endpoint', 'position', 'theme', 'severities'] as const;\n\n// Inject the beacon stylesheet into <head> once, idempotently. Needed because the\n// drawer + pin popover are appended to document.body to escape transformed-ancestor\n// stacking contexts (sticky headers, etc.) — they're outside the shadow root, so the\n// shadow-scoped <style> doesn't reach them.\nconst GLOBAL_STYLE_ID = 'launch-kit-beacon-portal-styles';\nfunction ensureGlobalStyles(stylesText: string): void {\n if (document.getElementById(GLOBAL_STYLE_ID)) return;\n const tag = document.createElement('style');\n tag.id = GLOBAL_STYLE_ID;\n tag.textContent = stylesText;\n document.head.appendChild(tag);\n}\n\n// CSS custom properties consumers can override. The drawer's stylesheet uses\n// var(--beacon-*); after the body-mount refactor we copy the host's resolved\n// values onto the body-mounted drawer/popover (CSS inheritance no longer reaches\n// across the body boundary).\nconst CUSTOMIZABLE_VARS = [\n '--beacon-accent',\n '--beacon-bg',\n '--beacon-fg',\n '--beacon-muted',\n '--beacon-border',\n '--beacon-radius',\n '--beacon-shadow',\n '--beacon-z-index',\n '--beacon-bug',\n '--beacon-idea',\n '--beacon-ux',\n '--beacon-a11y',\n] as const;\n\nconst DEFAULT_ACCENT = '#0ea5e9';\n\nexport class LaunchKitBeacon extends HTMLElement {\n static get observedAttributes() { return ATTRS as unknown as string[]; }\n\n private shadow!: ShadowRoot;\n private trigger?: HTMLElement;\n private drawer?: DrawerView;\n private slotEl?: HTMLSlotElement;\n\n private _config: BeaconConfig | null = null;\n private pins: Pin[] = [];\n // Tracks the live DOM element each pin came from so re-entering annotate mode\n // can restore visual markers for previously pinned items. Off-payload by design.\n private pinElements = new WeakMap<Pin, Element>();\n private description = '';\n private severity: Severity = 'bug';\n // While drawer is open, block clicks on the host page so users can't accidentally\n // navigate away mid-feedback (and lose their pins). Same approach as a modal.\n private documentClickBlocker?: (e: MouseEvent) => void;\n // Set when submit succeeds so the close() warn skips during the 1.5s delay before\n // auto-close — without this, users who click the X during that window would see\n // \"Discard your feedback?\" right after they just sent it.\n private submitSucceeded = false;\n // Unsubscribe from the runtime-events buffer when the element is removed\n // (HMR, framework teardown). Without this the listener leaks across reloads.\n private eventsUnsubscribe?: () => void;\n\n /** Public — wrappers can set `widget.config = {...}` for dynamic endpoint/headers/context. */\n set config(value: BeaconConfig) {\n this._config = value;\n }\n get config(): BeaconConfig | null {\n if (this._config) return this._config;\n const endpoint = this.getAttribute('endpoint');\n return endpoint ? { endpoint } : null;\n }\n\n connectedCallback() {\n if (!this.shadow) {\n this.shadow = this.attachShadow({ mode: 'open' });\n const style = document.createElement('style');\n style.textContent = stylesCss;\n this.shadow.appendChild(style);\n\n // Slot for custom trigger override.\n this.slotEl = document.createElement('slot');\n this.slotEl.name = 'trigger';\n this.shadow.appendChild(this.slotEl);\n\n // Default trigger (shown unless slot is filled or position=\"hidden\").\n this.trigger = createTriggerButton();\n this.shadow.appendChild(this.trigger);\n this.trigger.addEventListener('click', () => this.open());\n\n // If consumer provided a slot=\"trigger\" child, hook clicks on it.\n this.slotEl.addEventListener('slotchange', () => {\n const assigned = this.slotEl!.assignedElements();\n if (assigned.length > 0) {\n // Hide the default; wire all assigned elements to open the drawer.\n if (this.trigger) (this.trigger as HTMLElement).style.display = 'none';\n assigned.forEach((el) => el.addEventListener('click', () => this.open()));\n }\n });\n\n this.drawer = new DrawerView(this.parseSeverities(), {\n onClose: () => this.close(),\n onAnnotate: () => this.startAnnotate(),\n onSubmit: () => this.handleSubmit(),\n onPinNoteChange: (n, note) => this.updatePinNote(n, note),\n onPinDelete: (n) => this.deletePin(n),\n onDescriptionChange: (v) => { this.description = v; },\n onSeverityChange: (s) => { this.severity = s; },\n });\n // Mount the drawer at document.body so it escapes any transformed ancestor\n // (sticky headers, blurred toolbars) that would otherwise trap it in a sub-\n // stacking-context and put it underneath other floating UI like a Command\n // Center / PDA shell. The trigger stays in shadow DOM (slotted from the\n // header is fine; that's where the user expects to see it).\n ensureGlobalStyles(stylesCss);\n this.drawer.root.classList.add('beacon-no-capture');\n this.drawer.root.classList.add(`beacon-theme-${this.getAttribute('theme') ?? 'auto'}`);\n document.body.appendChild(this.drawer.root);\n\n // Live-update the chip as new runtime errors come in. Without this the\n // count is frozen at whatever the buffer held at drawer-open time, so\n // errors fired while the widget is open would silently miss the chip\n // (though they're still in the payload at submit). The chip update is a\n // partial DOM patch — it does NOT re-render bodyEl, so the user's\n // textarea focus/cursor survive.\n this.eventsUnsubscribe = subscribeToEvents(() => {\n this.drawer?.setEvents(getCapturedEvents());\n });\n }\n\n // Default attributes if not set.\n if (!this.hasAttribute('position')) this.setAttribute('position', 'bottom-right');\n if (!this.hasAttribute('theme')) this.setAttribute('theme', 'auto');\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (name === 'severities' && this.drawer) {\n // Re-create drawer with new severities. Keep current state.\n // Cheapest path: instruct drawer to refresh — but our drawer captures severities at construction.\n // Acceptable simplification: log a warning if attribute changes mid-life.\n // Production wrappers should set severities at construction via initial attribute.\n console.warn('[launch-kit-beacon] severities attribute changed after mount; not yet hot-reloaded.');\n }\n if (name === 'theme' && this.drawer && oldValue !== newValue) {\n this.drawer.root.classList.remove(`beacon-theme-${oldValue ?? 'auto'}`);\n this.drawer.root.classList.add(`beacon-theme-${newValue ?? 'auto'}`);\n }\n }\n\n // ── Public API ──────────────────────────────────────────\n\n open() {\n if (!this.drawer) return;\n // Edge-aware positioning when consumer is using a slotted trigger\n // (typical pattern when position=\"hidden\" — e.g., the trigger lives in a header).\n // Otherwise fall back to CSS-driven default position (bottom-right / bottom-left).\n if (this.getAttribute('position') === 'hidden') {\n const triggerEl = this.slotEl?.assignedElements()[0] as HTMLElement | undefined;\n if (triggerEl) {\n positionDrawerRelativeTo(this.drawer.root, triggerEl);\n }\n }\n this.submitSucceeded = false;\n // Snapshot the runtime-events buffer so the drawer shows a count. The\n // payload at submit time re-drains the buffer separately, so anything\n // captured between open and submit is still attached.\n this.drawer.setEvents(getCapturedEvents());\n this.syncCustomProperties();\n this.installClickBlocker();\n this.drawer.open();\n }\n\n close() {\n if (!this.drawer) return;\n if (!this.submitSucceeded && this.hasUnsavedData()) {\n // eslint-disable-next-line no-alert\n const ok = window.confirm('You have unsaved feedback. Close and discard it?');\n if (!ok) return;\n }\n this.forceClose();\n }\n\n disconnectedCallback() {\n // Custom element being removed from DOM (e.g., HMR or framework teardown).\n // Make sure we don't leak the document-level click listener.\n this.uninstallClickBlocker();\n this.eventsUnsubscribe?.();\n this.eventsUnsubscribe = undefined;\n // Drawer is mounted at body level — pull it out so we don't leave orphans\n // behind on HMR or framework teardown.\n if (this.drawer && this.drawer.root.parentNode) {\n this.drawer.root.parentNode.removeChild(this.drawer.root);\n }\n }\n\n async openWithPicker() {\n this.open();\n // Defer to next tick so the drawer is in DOM before we minimize it.\n setTimeout(() => this.startAnnotate(), 0);\n }\n\n // ── Annotate flow ──────────────────────────────────────────\n\n private async startAnnotate() {\n if (!this.drawer) return;\n this.drawer.minimize();\n\n const accent = this.getAccentColor();\n const overlay = createPickModeOverlay({ accent });\n\n // Restore markers for pins from prior annotate sessions. Use the WeakMap'd\n // element ref if it's still in the DOM; the overlay's reposition logic also\n // falls back to selector and captured rect if this ref is stale.\n for (const pin of this.pins) {\n const target = this.pinElements.get(pin);\n if (target) {\n overlay.addPin(pin.number, {\n target,\n selector: pin.selector,\n fallbackRect: pin.boundingRect,\n });\n }\n }\n\n try {\n let next = true;\n while (next) {\n const handle = startPicker({ shadowRoot: this.shadow, accent });\n const el = await handle.promise;\n if (!el) break; // user pressed Escape\n\n const rect = el.getBoundingClientRect();\n const popoverResult = await showPinPopover({\n shadowRoot: this.shadow,\n anchor: { x: rect.left, y: rect.bottom },\n pinNumber: this.pins.length + 1,\n });\n // 'all' (Escape) ends annotation; 'pin' (cross icon) drops this one and\n // re-enters pick mode for the next element. false falls through to capture.\n if (popoverResult.cancelled === 'all') break;\n if (popoverResult.cancelled === 'pin') continue;\n\n const raw = capturePin(el);\n const pin: Pin = {\n number: this.pins.length + 1,\n ...raw,\n ...(popoverResult.note ? { note: popoverResult.note } : {}),\n };\n this.pins.push(pin);\n this.pinElements.set(pin, el);\n overlay.addPin(pin.number, {\n target: el,\n selector: raw.selector,\n fallbackRect: raw.boundingRect,\n });\n\n // Loop continues — user picks another element OR presses Escape to finish.\n }\n\n // Capture final screenshot + draw markers + reopen drawer with preview.\n if (this.pins.length > 0) {\n // Swap the hint pill into a spinner BEFORE the capture so the user has\n // visible feedback during the 500ms-2s html-to-image walks the DOM.\n // Yield one frame so the swap actually paints before the main thread\n // gets busy with capture work.\n overlay.setLoading('Capturing screenshot…');\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n\n try {\n const meta = captureMetadata();\n const raw = await captureScreenshot({ excludeShadowRoot: this.shadow });\n const annotated = await drawMarkers(raw, this.pins, meta.viewport, this.pinElements, accent);\n this.drawer.setPins(this.pins, annotated);\n } catch (err) {\n // Don't drop the report — pins still post. But surface the failure so users\n // know why their preview is missing instead of guessing.\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[launch-kit-beacon] screenshot capture failed:', err);\n this.drawer.setPins(this.pins);\n this.drawer.setStatus(`Screenshot capture failed: ${msg}`, 'error');\n }\n }\n } finally {\n overlay.destroy();\n }\n\n this.drawer.open();\n }\n\n private updatePinNote(num: number, note: string) {\n const pin = this.pins.find((p) => p.number === num);\n if (!pin) return;\n if (note.trim()) {\n pin.note = note;\n } else {\n delete pin.note;\n }\n // Don't re-render — the input is already up to date; rerender would lose focus.\n }\n\n private deletePin(num: number) {\n this.pins = this.pins.filter((p) => p.number !== num);\n // Renumber.\n this.pins.forEach((p, i) => { p.number = i + 1; });\n // Invalidate the cached annotated screenshot — it bakes the deleted pin's\n // marker into the JPEG. handleSubmit will recapture if needed.\n this.drawer?.setAnnotatedScreenshot(undefined);\n this.drawer?.setPins(this.pins);\n }\n\n // ── Submit flow ──────────────────────────────────────────\n\n private async handleSubmit() {\n if (!this.drawer) return;\n const cfg = this.config;\n if (!cfg?.endpoint) {\n this.drawer.setStatus('Missing endpoint configuration', 'error');\n return;\n }\n\n const description = this.drawer.getDescription().trim();\n const severity = this.drawer.getSeverity();\n if (!description) {\n this.drawer.setStatus('Description is required', 'error');\n return;\n }\n\n // Show the loading state IMMEDIATELY after validation, before any expensive\n // async work. Without this, the user clicks Save and sees nothing change for\n // 500ms-2s while captureScreenshot walks the DOM. Yield one frame so the\n // disabled state actually paints before the main thread gets busy.\n this.drawer.setSubmitting(true);\n\n // Reuse the screenshot already produced at end of annotate. Only recapture\n // if missing — invalidated by deletePin or never produced (e.g., user typed\n // a description and clicked Save without annotating).\n let screenshotDataUrl = this.drawer.getAnnotatedScreenshot();\n const needsCapture = !screenshotDataUrl && this.pins.length > 0;\n\n this.drawer.setStatus(needsCapture ? 'Capturing screenshot…' : 'Sending…');\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n\n const meta = captureMetadata();\n\n if (needsCapture) {\n try {\n const raw = await captureScreenshot({ excludeShadowRoot: this.shadow });\n screenshotDataUrl = await drawMarkers(raw, this.pins, meta.viewport, this.pinElements, this.getAccentColor());\n } catch (err) {\n console.error('[launch-kit-beacon] screenshot capture failed at submit:', err);\n }\n }\n\n // Drain any errors / unhandled rejections captured since page load. These let\n // the reviewer see what failed silently around the moment the user reported.\n const events = getCapturedEvents();\n\n const payload: FeedbackPayload = {\n description,\n severity,\n ...(screenshotDataUrl ? { screenshot: { dataUrl: screenshotDataUrl, mime: 'image/jpeg' } } : {}),\n metadata: meta,\n pins: this.pins,\n ...(events.length > 0 ? { events } : {}),\n ...(this.resolveContext() ? { context: this.resolveContext() } : {}),\n };\n\n // Pre-submit hook (cancellable).\n const beforeEvent = new CustomEvent('beacon-before-submit', {\n detail: { payload },\n cancelable: true,\n bubbles: true,\n composed: true,\n });\n const proceed = this.dispatchEvent(beforeEvent);\n if (!proceed) {\n this.drawer.setSubmitting(false);\n this.drawer.setStatus('Submission cancelled', 'error');\n return;\n }\n\n this.drawer.setStatus('Sending…');\n\n try {\n const headers = this.resolveHeaders();\n const response = await submitFeedback(cfg.endpoint, payload, headers);\n this.drawer.setSubmitting(false);\n\n if (response.ok) {\n this.submitSucceeded = true;\n this.drawer.setStatus('Sent — thanks!', 'success');\n this.dispatchEvent(new CustomEvent('beacon-after-submit', {\n detail: { response },\n bubbles: true,\n composed: true,\n }));\n // Reset state and close after a moment. forceClose skips the \"discard?\"\n // warn (because submitSucceeded is true) and tears down the click blocker.\n setTimeout(() => {\n this.forceClose();\n }, 1500);\n } else {\n this.drawer.setStatus(`Failed: ${response.status}`, 'error');\n }\n } catch (err) {\n this.drawer.setSubmitting(false);\n const msg = err instanceof Error ? err.message : 'Network error';\n this.drawer.setStatus(`Failed: ${msg}`, 'error');\n }\n }\n\n // ── Helpers ──────────────────────────────────────────\n\n /**\n * Resolved accent color — reads --beacon-accent from the host's computed style\n * (which picks up any inline `style=\"--beacon-accent: …\"` or stylesheet override\n * targeting the host). Falls back to the default sky-blue if unset.\n */\n private getAccentColor(): string {\n if (typeof window === 'undefined') return DEFAULT_ACCENT;\n const v = getComputedStyle(this).getPropertyValue('--beacon-accent').trim();\n return v || DEFAULT_ACCENT;\n }\n\n /**\n * Mirror every customizable --beacon-* var from the host onto the body-mounted\n * drawer. CSS inheritance stops at the body boundary, so we copy the host's\n * resolved values forward. Called on open() so changes mid-session are picked up.\n */\n private syncCustomProperties(): void {\n if (!this.drawer) return;\n const cs = getComputedStyle(this);\n for (const name of CUSTOMIZABLE_VARS) {\n const val = cs.getPropertyValue(name).trim();\n if (val) this.drawer.root.style.setProperty(name, val);\n }\n }\n\n private hasUnsavedData(): boolean {\n if (this.pins.length > 0) return true;\n const desc = this.drawer?.getDescription() ?? '';\n return desc.trim().length > 0;\n }\n\n private resetState(): void {\n this.pins = [];\n this.description = '';\n this.severity = 'bug';\n this.pinElements = new WeakMap();\n this.drawer?.reset();\n }\n\n private forceClose(): void {\n this.uninstallClickBlocker();\n this.resetState();\n this.submitSucceeded = false;\n this.drawer?.close();\n }\n\n private installClickBlocker(): void {\n if (this.documentClickBlocker) return;\n this.documentClickBlocker = (e: MouseEvent) => {\n const path = e.composedPath();\n // Allow:\n // 1. Clicks inside the shadow root or on the slotted trigger — both go\n // through the host element on their composed path.\n // 2. Clicks on body-mounted beacon UI — drawer, popover, and any future\n // body-mounted UI carry the `beacon-no-capture` class, so we allowlist\n // anything whose path crosses such an element.\n // Pick-mode border/hint/markers are pointer-events:none and never appear in\n // an event path, so they don't need to be allowlisted explicitly.\n if (path.includes(this.shadow.host)) return;\n for (const node of path) {\n if (node instanceof Element && node.classList.contains('beacon-no-capture')) return;\n }\n e.preventDefault();\n e.stopPropagation();\n };\n document.addEventListener('click', this.documentClickBlocker, true);\n }\n\n private uninstallClickBlocker(): void {\n if (!this.documentClickBlocker) return;\n document.removeEventListener('click', this.documentClickBlocker, true);\n this.documentClickBlocker = undefined;\n }\n\n private resolveHeaders(): Record<string, string> | undefined {\n const h = this.config?.headers;\n if (!h) return undefined;\n return typeof h === 'function' ? h() : h;\n }\n\n private resolveContext(): Record<string, unknown> | undefined {\n const c = this.config?.context;\n if (!c) return undefined;\n return typeof c === 'function' ? c() : c;\n }\n\n private parseSeverities(): Severity[] {\n const attr = this.getAttribute('severities');\n if (!attr) return ['bug', 'idea', 'ux', 'a11y'];\n return attr.split(',').map((s) => s.trim()).filter(Boolean) as Severity[];\n }\n}\n\nexport function defineBeacon(tagName = 'launch-kit-beacon'): void {\n if (typeof window === 'undefined') return;\n if (!customElements.get(tagName)) {\n customElements.define(tagName, LaunchKitBeacon);\n }\n}\n\n// ── Helpers ──────────────────────────────────────────\n\nconst DRAWER_WIDTH = 380;\nconst VIEWPORT_MARGIN = 8;\nconst ESTIMATED_DRAWER_HEIGHT = 520;\n\n/**\n * Position the drawer relative to a trigger element, edge-aware.\n *\n * Default placement: directly below the trigger, with the drawer's right edge\n * aligned to the trigger's right edge. Falls back to opening above the trigger\n * if there isn't enough space below. Always clamps within the viewport so the\n * drawer never overflows off-screen.\n */\nfunction positionDrawerRelativeTo(drawer: HTMLElement, trigger: HTMLElement): void {\n const rect = trigger.getBoundingClientRect();\n const viewportW = window.innerWidth;\n const viewportH = window.innerHeight;\n\n // ── Horizontal: align drawer's right edge to trigger's right edge ─────────\n // Compute desired right offset; clamp so drawer never overflows past either edge.\n let rightOffset = Math.max(VIEWPORT_MARGIN, viewportW - rect.right);\n // If aligning right would push the drawer's left edge past the viewport, shift it.\n const leftEdgeIfApplied = viewportW - rightOffset - DRAWER_WIDTH;\n if (leftEdgeIfApplied < VIEWPORT_MARGIN) {\n rightOffset = Math.max(VIEWPORT_MARGIN, viewportW - DRAWER_WIDTH - VIEWPORT_MARGIN);\n }\n\n // ── Vertical: prefer below trigger, fall back to above ────────────────────\n const spaceBelow = viewportH - rect.bottom - VIEWPORT_MARGIN;\n const spaceAbove = rect.top - VIEWPORT_MARGIN;\n\n // Set ALL four anchors explicitly. Use 'auto' (not '') to override CSS defaults\n // (the drawer's CSS has `bottom: 20px` for the floating-trigger case — empty\n // string falls back to that; 'auto' is the only way to truly clear it).\n drawer.style.left = 'auto';\n drawer.style.right = `${rightOffset}px`;\n\n if (spaceBelow >= ESTIMATED_DRAWER_HEIGHT || spaceBelow >= spaceAbove) {\n drawer.style.top = `${rect.bottom + VIEWPORT_MARGIN}px`;\n drawer.style.bottom = 'auto';\n } else {\n drawer.style.top = 'auto';\n drawer.style.bottom = `${viewportH - rect.top + VIEWPORT_MARGIN}px`;\n }\n}\n","// DOM-level capture for monitor mode: clicks, route changes, dialog mounts.\n//\n// Click capture is the differentiating feature. The recurring debugging shape we\n// see is \"user clicked X, nothing happened (or the wrong thing happened)\". A bare\n// click event tells you the target, but the *interesting* information is usually\n// further up the stack: what other overlays are sitting at the click coordinates,\n// is the body's pointer-events disabled, are there open Radix dialogs whose\n// dismissable layer is intercepting. We snapshot all of that on every click.\n//\n// We listen in the capture phase so we see the event even if a handler later\n// calls stopPropagation(). We do NOT preventDefault — capture is observational.\n\nimport type { MonitorClickEvent, MonitorClickTarget, MonitorDialogEvent, MonitorOverlayInfo, MonitorRouteEvent } from './types';\n\ntype Emit<E> = (event: Omit<E, 'ts' | 'sessionId' | 'seq'>) => void;\n\ninterface CaptureCallbacks {\n emitClick: Emit<MonitorClickEvent>;\n emitRoute: Emit<MonitorRouteEvent>;\n emitDialog: Emit<MonitorDialogEvent>;\n}\n\ninterface Installation {\n uninstall(): void;\n}\n\nconst HTML_LIMIT = 1024;\nconst MAX_OVERLAYS = 5;\n\nfunction truncate(s: string, n: number): string {\n return s.length > n ? s.slice(0, n) : s;\n}\n\n/**\n * Build a stable CSS selector for an element. Prefer #id, then tag.class.class,\n * walking up at most 3 levels. Not guaranteed unique but good enough for\n * \"the developer looking at the events stream can find this element.\"\n */\nfunction buildSelector(el: Element): string {\n if (el.id) return `#${CSS.escape(el.id)}`;\n const parts: string[] = [];\n let cur: Element | null = el;\n for (let i = 0; i < 3 && cur; i++) {\n const tag = cur.tagName.toLowerCase();\n const id = cur.id ? `#${CSS.escape(cur.id)}` : '';\n const cls = cur.classList.length > 0\n ? '.' + Array.from(cur.classList).slice(0, 3).map(CSS.escape).join('.')\n : '';\n parts.unshift(`${tag}${id}${cls}`);\n if (id) break; // id is unique-enough; stop walking\n cur = cur.parentElement;\n }\n return parts.join(' > ');\n}\n\nfunction describeTarget(el: Element): MonitorClickTarget {\n return {\n tag: el.tagName.toLowerCase(),\n id: el.id || null,\n classes: Array.from(el.classList).slice(0, 10),\n role: el.getAttribute('role'),\n selector: buildSelector(el),\n };\n}\n\n/**\n * Snapshot the overlay stack at a point. Walks all fixed/sticky candidates whose\n * computed `inset:0px` (or close to it) covers the entire viewport — these are\n * the elements most likely to be intercepting clicks. Returns the top N by z-index.\n */\nfunction overlaysAtPoint(x: number, y: number): MonitorOverlayInfo[] {\n // querySelectorAll('*') is expensive on large DOMs (10k+ nodes); only do this\n // when monitor is on. The result drives debugging of click-through bugs which\n // is exactly the kind of thing you turn monitor on for.\n const candidates: MonitorOverlayInfo[] = [];\n const all = document.querySelectorAll<HTMLElement>('body *');\n for (const el of Array.from(all)) {\n const cs = getComputedStyle(el);\n if (cs.position !== 'fixed' && cs.position !== 'sticky') continue;\n const rect = el.getBoundingClientRect();\n // Must cover the click point.\n if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) continue;\n const z = parseInt(cs.zIndex, 10);\n if (!Number.isFinite(z) && cs.zIndex !== 'auto') continue;\n candidates.push({\n tag: el.tagName.toLowerCase(),\n zIndex: Number.isFinite(z) ? z : 0,\n pointerEvents: cs.pointerEvents,\n classes: Array.from(el.classList).slice(0, 5).join(' '),\n });\n }\n return candidates\n .sort((a, b) => b.zIndex - a.zIndex)\n .slice(0, MAX_OVERLAYS);\n}\n\n/**\n * Install click/mousedown capture. Both events fire because they expose\n * different things — mousedown is the one Radix DismissableLayer listens to\n * for outside-click dismissal, click is the one navigation actions hang off of.\n */\nfunction installClickCapture(cb: CaptureCallbacks): () => void {\n const handle = (kind: 'click' | 'mousedown') => (e: Event): void => {\n const me = e as MouseEvent;\n const target = me.target;\n if (!(target instanceof Element)) return;\n\n const x = me.clientX;\n const y = me.clientY;\n // elementFromPoint may differ from target if there's an overlay above it —\n // that mismatch is itself diagnostic (\"the element you wanted is being\n // occluded by X\"). Compare and surface.\n const hit = document.elementFromPoint(x, y);\n const hitMatches = hit === target || (hit ? target.contains(hit) || hit.contains(target) : false);\n\n const openDialogs = document.querySelectorAll('[role=\"dialog\"][data-state=\"open\"]').length;\n const bodyPe = getComputedStyle(document.body).pointerEvents;\n const overlays = overlaysAtPoint(x, y);\n\n cb.emitClick({\n kind,\n target: describeTarget(target),\n hitMatchesTarget: hitMatches,\n ...(!hitMatches && hit instanceof Element ? { hitTarget: describeTarget(hit) } : {}),\n coords: { x, y },\n openDialogs,\n bodyPointerEvents: bodyPe,\n ...(overlays.length > 0 ? { overlaysAtPoint: overlays } : {}),\n });\n };\n\n const onClick = handle('click');\n const onMouseDown = handle('mousedown');\n // Capture-phase + passive so we never block the underlying handler. We use\n // the capture phase to ensure we see the event even when a downstream handler\n // calls stopPropagation/stopImmediatePropagation.\n document.addEventListener('click', onClick, { capture: true, passive: true });\n document.addEventListener('mousedown', onMouseDown, { capture: true, passive: true });\n\n return () => {\n document.removeEventListener('click', onClick, { capture: true });\n document.removeEventListener('mousedown', onMouseDown, { capture: true });\n };\n}\n\n/**\n * Capture SPA route changes. History.pushState + replaceState don't fire any\n * event; we monkey-patch to emit. popstate + hashchange are real events.\n */\nfunction installRouteCapture(cb: CaptureCallbacks): () => void {\n const originalPush = history.pushState;\n const originalReplace = history.replaceState;\n let lastUrl = window.location.href;\n\n const emit = (via: MonitorRouteEvent['via']): void => {\n const to = window.location.href;\n if (to === lastUrl) return;\n const from = lastUrl;\n lastUrl = to;\n cb.emitRoute({ kind: 'route', from, to, via });\n };\n\n history.pushState = function patchedPushState(...args: Parameters<typeof history.pushState>) {\n const ret = originalPush.apply(this, args);\n emit('pushState');\n return ret;\n };\n history.replaceState = function patchedReplaceState(...args: Parameters<typeof history.replaceState>) {\n const ret = originalReplace.apply(this, args);\n emit('replaceState');\n return ret;\n };\n\n const onPop = (): void => emit('popstate');\n const onHash = (): void => emit('hashchange');\n window.addEventListener('popstate', onPop);\n window.addEventListener('hashchange', onHash);\n\n return () => {\n history.pushState = originalPush;\n history.replaceState = originalReplace;\n window.removeEventListener('popstate', onPop);\n window.removeEventListener('hashchange', onHash);\n };\n}\n\n/**\n * Watch for [role=\"dialog\"] subtree changes. Mount + unmount drive most modal\n * bugs in this codebase (Radix dismissable, stuck overlay, focus trap). We\n * also watch data-state changes for \"the dialog visibly closed but kept its\n * element / outside-click handler\" cases.\n */\nfunction installDialogCapture(cb: CaptureCallbacks): () => void {\n // Track currently-open dialog elements so we can emit unmount for the right ones.\n const seen = new WeakSet<Element>();\n\n const handle = (el: Element, action: 'mount' | 'unmount' | 'state'): void => {\n const selector = buildSelector(el);\n cb.emitDialog({\n kind: 'dialog',\n action,\n selector,\n state: el.getAttribute('data-state'),\n ...(action === 'mount' ? { outerHTML: truncate(el.outerHTML, HTML_LIMIT) } : {}),\n });\n };\n\n // Seed with already-mounted dialogs at install time so we get unmount events\n // for them when they later disappear.\n for (const el of Array.from(document.querySelectorAll('[role=\"dialog\"]'))) {\n seen.add(el);\n }\n\n const obs = new MutationObserver((mutations) => {\n for (const m of mutations) {\n for (const node of Array.from(m.addedNodes)) {\n if (!(node instanceof Element)) continue;\n // The dialog itself, OR a descendant added in a subtree (rare but possible).\n const dialogs = node.matches?.('[role=\"dialog\"]')\n ? [node]\n : Array.from(node.querySelectorAll?.('[role=\"dialog\"]') ?? []);\n for (const d of dialogs) {\n if (seen.has(d)) continue;\n seen.add(d);\n handle(d, 'mount');\n }\n }\n for (const node of Array.from(m.removedNodes)) {\n if (!(node instanceof Element)) continue;\n const dialogs = node.matches?.('[role=\"dialog\"]')\n ? [node]\n : Array.from(node.querySelectorAll?.('[role=\"dialog\"]') ?? []);\n for (const d of dialogs) {\n if (!seen.has(d)) continue;\n seen.delete(d);\n handle(d, 'unmount');\n }\n }\n if (m.type === 'attributes' && m.attributeName === 'data-state' && m.target instanceof Element) {\n if (m.target.getAttribute('role') === 'dialog') handle(m.target, 'state');\n }\n }\n });\n obs.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['data-state'],\n });\n\n return () => obs.disconnect();\n}\n\nexport function installDomCapture(cb: CaptureCallbacks): Installation {\n const undoClick = installClickCapture(cb);\n const undoRoute = installRouteCapture(cb);\n const undoDialog = installDialogCapture(cb);\n return {\n uninstall() {\n undoClick();\n undoRoute();\n undoDialog();\n },\n };\n}\n","// Capture fetch + XMLHttpRequest activity for monitor mode.\n//\n// Default policy: emit only failed requests (status >= 400 OR threw). Successful\n// requests are silently skipped — capturing every successful API call drowns the\n// signal. Verbose mode (passed in via start()) captures everything.\n//\n// We never read request/response bodies. They are PII-shaped (user input, tokens\n// in response payloads) and can be large. URL + method + status + duration is\n// usually enough to triage; the dev can re-run with verbose tooling if needed.\n\nimport type { MonitorNetworkEvent } from './types';\n\ntype Emit = (event: Omit<MonitorNetworkEvent, 'ts' | 'sessionId' | 'seq'>) => void;\n\ninterface InstallOptions {\n emit: Emit;\n verbose: boolean;\n}\n\ninterface Installation {\n uninstall(): void;\n}\n\nconst URL_LIMIT = 1000;\n\nfunction trunc(s: string, n: number): string {\n return s.length > n ? s.slice(0, n) : s;\n}\n\n/**\n * Wrap window.fetch. Captures method, URL, status, duration, and whether the\n * call failed. Restores the original on uninstall.\n *\n * We wrap (rather than register an Observer / PerformanceObserver) because we\n * need the *URL the developer wrote*, not the resolved one — and because\n * PerformanceObserver doesn't tell us whether the response was an error.\n */\nfunction wrapFetch(opts: InstallOptions): () => void {\n const original = window.fetch;\n if (typeof original !== 'function') return () => { /* nothing to restore */ };\n\n const wrapped: typeof fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const start = performance.now();\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n try {\n // Call bound to window so fetch's internal `this`-dependent paths still\n // work. Arrow function doesn't have its own `this`; passing globalThis\n // explicitly is the spec-correct way to invoke a free-standing fetch.\n const res = await original.call(window, input as RequestInfo, init);\n const durationMs = Math.round(performance.now() - start);\n const failed = res.status >= 400;\n if (failed || opts.verbose) {\n opts.emit({\n kind: 'fetch',\n url: trunc(url, URL_LIMIT),\n method,\n status: res.status,\n durationMs,\n failed,\n });\n }\n return res;\n } catch (err) {\n const durationMs = Math.round(performance.now() - start);\n opts.emit({\n kind: 'fetch',\n url: trunc(url, URL_LIMIT),\n method,\n status: 0,\n durationMs,\n failed: true,\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n };\n\n // Tag so we can detect \"is this still our wrapper\" on uninstall.\n // (window.fetch can be re-wrapped by analytics SDKs after us — in which case\n // we should NOT restore over their wrapper. We leave it; they'll handle their\n // own teardown.)\n (wrapped as unknown as { __lsBeaconWrapped: true }).__lsBeaconWrapped = true;\n window.fetch = wrapped;\n\n return () => {\n if ((window.fetch as unknown as { __lsBeaconWrapped?: true }).__lsBeaconWrapped) {\n window.fetch = original;\n }\n // else: someone wrapped over us. Leave their wrapper in place — restoring\n // would break their instrumentation. Our wrapper still gets called via theirs.\n };\n}\n\n/**\n * Wrap XMLHttpRequest. Tracks method+URL+start via open()/send(), reads status\n * on loadend. Same emission policy as fetch.\n */\nfunction wrapXhr(opts: InstallOptions): () => void {\n const proto = XMLHttpRequest.prototype;\n const originalOpen = proto.open;\n const originalSend = proto.send;\n\n // Stash per-XHR metadata in a WeakMap so we don't pollute the prototype.\n const state = new WeakMap<XMLHttpRequest, { method: string; url: string; start: number }>();\n\n proto.open = function patchedOpen(\n method: string,\n url: string | URL,\n ...rest: unknown[]\n ): void {\n state.set(this, {\n method: method.toUpperCase(),\n url: typeof url === 'string' ? url : url.toString(),\n start: 0,\n });\n // @ts-expect-error — passthrough overload matrix is unwieldy; rest is forwarded as-is.\n return originalOpen.call(this, method, url, ...rest);\n };\n\n proto.send = function patchedSend(this: XMLHttpRequest, body?: Document | XMLHttpRequestBodyInit | null): void {\n const meta = state.get(this);\n if (meta) meta.start = performance.now();\n\n const onLoadEnd = (): void => {\n this.removeEventListener('loadend', onLoadEnd);\n const m = state.get(this);\n if (!m) return;\n const durationMs = Math.round(performance.now() - m.start);\n // status === 0 indicates the request errored or was aborted before a response.\n const failed = this.status === 0 || this.status >= 400;\n if (failed || opts.verbose) {\n opts.emit({\n kind: 'xhr',\n url: trunc(m.url, URL_LIMIT),\n method: m.method,\n status: this.status,\n durationMs,\n failed,\n });\n }\n state.delete(this);\n };\n this.addEventListener('loadend', onLoadEnd);\n return originalSend.call(this, body as XMLHttpRequestBodyInit | null);\n };\n\n return () => {\n proto.open = originalOpen;\n proto.send = originalSend;\n };\n}\n\nexport function installNetworkCapture(opts: InstallOptions): Installation {\n const undoFetch = wrapFetch(opts);\n const undoXhr = wrapXhr(opts);\n return {\n uninstall() {\n undoFetch();\n undoXhr();\n },\n };\n}\n","// Batched POST transport for monitor events.\n//\n// Buffers events in memory and flushes to the configured URL on a timer, on a\n// size threshold, or synchronously on pagehide via navigator.sendBeacon.\n//\n// Why not fire-per-event:\n// - A burst of clicks during a repro can be 50+ events/sec. Per-event POSTs\n// would flood the receiver and the network panel.\n// - Some events (route changes, navigation) arrive right before the browser\n// tears the page down — only sendBeacon survives that.\n\nimport type { MonitorBatch, MonitorEvent } from './types';\n\nconst FLUSH_INTERVAL_MS = 1000;\nconst FLUSH_AT_COUNT = 50;\nconst MAX_BUFFER = 500;\n\nexport interface TransportOptions {\n url: string;\n sessionId: string;\n /** Called when a flush attempt failed (network error or non-2xx). For UI badge. */\n onError?: (err: Error) => void;\n}\n\nexport class MonitorTransport {\n private url: string;\n private sessionId: string;\n private onError?: (err: Error) => void;\n private buffer: MonitorEvent[] = [];\n private inflight = false;\n private timer: ReturnType<typeof setInterval> | null = null;\n private pagehideHandler?: () => void;\n private destroyed = false;\n\n constructor(opts: TransportOptions) {\n this.url = opts.url;\n this.sessionId = opts.sessionId;\n this.onError = opts.onError;\n\n this.timer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);\n this.pagehideHandler = () => this.flushSync();\n // pagehide fires for both unload AND bfcache eviction. Prefer it over\n // beforeunload (which doesn't fire on mobile when the user switches tabs).\n window.addEventListener('pagehide', this.pagehideHandler);\n // visibilitychange to 'hidden' is the only reliable signal on iOS Safari\n // when the user backgrounds the tab. Flush sync there too.\n document.addEventListener('visibilitychange', this.handleVisibilityChange);\n }\n\n private handleVisibilityChange = (): void => {\n if (document.visibilityState === 'hidden') this.flushSync();\n };\n\n enqueue(event: MonitorEvent): void {\n if (this.destroyed) return;\n this.buffer.push(event);\n if (this.buffer.length >= MAX_BUFFER) {\n // Drop the oldest non-flushed event rather than grow unbounded.\n this.buffer.shift();\n }\n if (this.buffer.length >= FLUSH_AT_COUNT) this.flush();\n }\n\n /** Async flush via fetch. No-op when in-flight or empty. */\n async flush(): Promise<void> {\n if (this.destroyed) return;\n if (this.inflight || this.buffer.length === 0) return;\n const events = this.buffer.splice(0, FLUSH_AT_COUNT);\n const batch = this.makeBatch(events);\n this.inflight = true;\n try {\n const res = await fetch(this.url, {\n method: 'POST',\n // No credentials — this is going to the developer's local server,\n // not the app's own backend. Avoid leaking session cookies.\n credentials: 'omit',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(batch),\n // keepalive lets the request survive a same-tick navigation when\n // we missed pagehide (e.g. a window.location.assign from script).\n keepalive: true,\n });\n if (!res.ok) {\n this.onError?.(new Error(`monitor flush: HTTP ${res.status}`));\n }\n } catch (err) {\n // Network failure (server gone, CORS, etc.) — surface but don't crash.\n // Events in this batch are LOST — re-queueing risks duplicates and we\n // can't tell the receiver \"this is a retry.\" Acceptable trade for dev tooling.\n this.onError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n this.inflight = false;\n }\n }\n\n /** Synchronous flush via sendBeacon, used on pagehide. */\n private flushSync(): void {\n if (this.destroyed || this.buffer.length === 0) return;\n if (!navigator.sendBeacon) {\n // Old browsers — best-effort fetch with keepalive (no await; we're tearing down).\n void this.flush();\n return;\n }\n const events = this.buffer.splice(0);\n const batch = this.makeBatch(events);\n // sendBeacon doesn't accept Content-Type; the receiver should detect JSON\n // by best-effort parsing (or treat as application/x-www-form-urlencoded\n // and JSON.parse the body anyway).\n const blob = new Blob([JSON.stringify(batch)], { type: 'application/json' });\n try {\n navigator.sendBeacon(this.url, blob);\n } catch {\n // sendBeacon can throw on payloads too large (~64KB). Drop the batch.\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n if (this.timer) clearInterval(this.timer);\n if (this.pagehideHandler) window.removeEventListener('pagehide', this.pagehideHandler);\n document.removeEventListener('visibilitychange', this.handleVisibilityChange);\n // Best-effort final flush so events from the moment of stop() make it out.\n this.flushSync();\n }\n\n private makeBatch(events: MonitorEvent[]): MonitorBatch {\n return {\n sessionId: this.sessionId,\n events,\n meta: {\n url: window.location.href,\n userAgent: navigator.userAgent,\n viewport: {\n w: window.innerWidth,\n h: window.innerHeight,\n dpr: window.devicePixelRatio || 1,\n },\n v: 1,\n },\n };\n }\n}\n","// Monitor mode orchestrator + window.__lsBeacon public API.\n//\n// Lifecycle:\n// start(cfg) → install capture modules, kick off transport, persist URL in\n// sessionStorage so a page reload within the same tab resumes\n// stop() → uninstall capture, destroy transport, clear sessionStorage\n// probe() → emit a custom event (no-op when inactive)\n//\n// Subscribes to the existing capture/events.ts buffer so errors that arrive\n// before monitor mode is enabled are still picked up (one-shot drain on start).\n\nimport { getCapturedEvents, subscribeToEvents } from '../capture/events';\nimport type { CapturedEvent } from '../types';\nimport { installDomCapture } from './dom';\nimport { installNetworkCapture } from './network';\nimport { MonitorTransport } from './transport';\nimport type {\n MonitorConfig,\n MonitorEvent,\n MonitorPublicAPI,\n} from './types';\n\n// Distributive Omit so the union members keep their discriminant + body when\n// we strip the auto-filled ts/sessionId/seq fields. Without distribution,\n// TypeScript collapses to \"only fields all members share\" — which excludes\n// label, data, etc., breaking every emit call site.\ntype EventInput<T> = T extends unknown ? Omit<T, 'ts' | 'sessionId' | 'seq'> : never;\ntype MonitorEventInput = EventInput<MonitorEvent>;\n\nconst SESSION_URL_KEY = '__lsBeaconMonitorUrl';\nconst SESSION_ID_KEY = '__lsBeaconMonitorSession';\nconst SESSION_VERBOSE_KEY = '__lsBeaconMonitorVerbose';\nconst SESSION_DEADLINE_KEY = '__lsBeaconMonitorDeadline';\nconst DEFAULT_MAX_SESSION_MS = 30 * 60_000;\nconst PROBE_DATA_LIMIT = 4_096;\n\ntype Listener = (active: boolean, url: string | null) => void;\n\ninterface ActiveSession {\n url: string;\n sessionId: string;\n verbose: boolean;\n deadlineMs: number;\n seq: number;\n transport: MonitorTransport;\n uninstallNetwork: () => void;\n uninstallDom: () => void;\n uninstallErrors: () => void;\n deadlineTimer: ReturnType<typeof setTimeout>;\n}\n\nlet active: ActiveSession | null = null;\nconst listeners = new Set<Listener>();\n// Track the last error event index we drained on start, so we can\n// re-drain newly-arriving errors via subscribeToEvents.\nlet drainedThrough = 0;\n\nfunction randomSessionId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n // crypto.randomUUID() always returns \"xxxxxxxx-xxxx-...\" so split[0] exists.\n // Slice instead of split to keep TS happy under noUncheckedIndexedAccess.\n return crypto.randomUUID().slice(0, 8);\n }\n return Math.random().toString(36).slice(2, 10);\n}\n\nfunction safeSerialize(value: unknown): unknown {\n // Defend against cyclic refs + functions + large blobs. Strings come through\n // truncated; objects/arrays round-trip through JSON which strips functions\n // and throws on cycles (we catch and stringify defensively).\n const seen = new WeakSet<object>();\n const walk = (v: unknown): unknown => {\n if (v === null || typeof v !== 'object') {\n if (typeof v === 'string') return v.length > PROBE_DATA_LIMIT ? v.slice(0, PROBE_DATA_LIMIT) : v;\n return v;\n }\n if (seen.has(v as object)) return '[cyclic]';\n seen.add(v as object);\n if (Array.isArray(v)) return v.map(walk);\n const out: Record<string, unknown> = {};\n for (const k of Object.keys(v as object).slice(0, 50)) {\n try {\n out[k] = walk((v as Record<string, unknown>)[k]);\n } catch {\n out[k] = '[unreadable]';\n }\n }\n return out;\n };\n try {\n return walk(value);\n } catch {\n return '[unserialisable]';\n }\n}\n\nfunction notify(): void {\n for (const fn of listeners) {\n try {\n fn(active !== null, active?.url ?? null);\n } catch {\n // listeners must not throw; ignore.\n }\n }\n}\n\nfunction stamp(partial: MonitorEventInput): MonitorEvent {\n if (!active) {\n // Programmer error — caller should check isActive() first. Throwing here\n // would crash the host page, so synthesize a no-op event instead.\n return {\n ...(partial as object),\n ts: Date.now(),\n sessionId: '',\n seq: 0,\n } as unknown as MonitorEvent;\n }\n active.seq += 1;\n return {\n ...(partial as object),\n ts: Date.now(),\n sessionId: active.sessionId,\n seq: active.seq,\n } as unknown as MonitorEvent;\n}\n\nfunction enqueue(partial: MonitorEventInput): void {\n if (!active) return;\n const event = stamp(partial);\n active.transport.enqueue(event);\n}\n\nfunction persistSession(): void {\n if (!active) return;\n try {\n sessionStorage.setItem(SESSION_URL_KEY, active.url);\n sessionStorage.setItem(SESSION_ID_KEY, active.sessionId);\n sessionStorage.setItem(SESSION_VERBOSE_KEY, active.verbose ? '1' : '0');\n sessionStorage.setItem(SESSION_DEADLINE_KEY, String(active.deadlineMs));\n } catch {\n // sessionStorage can be disabled (Safari private mode). The session still\n // works, just doesn't survive reload.\n }\n}\n\nfunction clearPersistedSession(): void {\n try {\n sessionStorage.removeItem(SESSION_URL_KEY);\n sessionStorage.removeItem(SESSION_ID_KEY);\n sessionStorage.removeItem(SESSION_VERBOSE_KEY);\n sessionStorage.removeItem(SESSION_DEADLINE_KEY);\n } catch {\n // ignore\n }\n}\n\nfunction readPersistedSession(): { url: string; sessionId: string; verbose: boolean; deadlineMs: number } | null {\n try {\n const url = sessionStorage.getItem(SESSION_URL_KEY);\n if (!url) return null;\n const sessionId = sessionStorage.getItem(SESSION_ID_KEY) ?? randomSessionId();\n const verbose = sessionStorage.getItem(SESSION_VERBOSE_KEY) === '1';\n const deadlineRaw = sessionStorage.getItem(SESSION_DEADLINE_KEY);\n const deadlineMs = deadlineRaw ? Number(deadlineRaw) : Date.now() + DEFAULT_MAX_SESSION_MS;\n if (Number.isFinite(deadlineMs) && deadlineMs <= Date.now()) {\n clearPersistedSession();\n return null;\n }\n return { url, sessionId, verbose, deadlineMs };\n } catch {\n return null;\n }\n}\n\nfunction start(config: MonitorConfig): void {\n if (active) stop();\n if (!config.url) return;\n\n const maxMs = config.maxSessionMs ?? DEFAULT_MAX_SESSION_MS;\n const deadlineMs = Date.now() + maxMs;\n const sessionId = randomSessionId();\n const verbose = !!config.verbose;\n\n const transport = new MonitorTransport({\n url: config.url,\n sessionId,\n onError: (err) => {\n // Soft-fail. We don't tear down on transient errors — the dev's local\n // server might just be restarting. But we surface to the console once,\n // so the user knows monitor isn't reaching anything.\n console.warn('[launch-kit-beacon] monitor transport error:', err.message);\n },\n });\n\n // Bridge: drain any errors already captured by capture/events.ts before\n // monitor was started, and subscribe to future ones.\n const existing = getCapturedEvents();\n drainedThrough = existing.length;\n for (const ev of existing) emitErrorEvent(ev, transport, sessionId);\n let seqForErrors = 0;\n const errorsUnsub = subscribeToEvents(() => {\n const all = getCapturedEvents();\n while (drainedThrough < all.length) {\n const ev = all[drainedThrough];\n if (ev) emitErrorEvent(ev, transport, sessionId);\n drainedThrough += 1;\n seqForErrors += 1;\n }\n });\n\n const net = installNetworkCapture({\n emit: (partial) => enqueue(partial),\n verbose,\n });\n\n const dom = installDomCapture({\n emitClick: (partial) => enqueue(partial),\n emitRoute: (partial) => enqueue(partial),\n emitDialog: (partial) => enqueue(partial),\n });\n\n const deadlineTimer = setTimeout(() => {\n console.info('[launch-kit-beacon] monitor session expired (max duration reached)');\n stop();\n }, Math.max(0, deadlineMs - Date.now()));\n\n active = {\n url: config.url,\n sessionId,\n verbose,\n deadlineMs,\n seq: 0,\n transport,\n uninstallNetwork: net.uninstall,\n uninstallDom: dom.uninstall,\n uninstallErrors: errorsUnsub,\n deadlineTimer,\n };\n // Track seqForErrors to satisfy lint about unused — it's incremented for\n // possible future use (per-source counters) but currently piggybacks on\n // the unified seq via emitErrorEvent. Suppress with a void.\n void seqForErrors;\n\n persistSession();\n notify();\n}\n\n/** Emit a CapturedEvent (from capture/events.ts) into the monitor stream. */\nfunction emitErrorEvent(ev: CapturedEvent, transport: MonitorTransport, sessionId: string): void {\n if (!active) return;\n active.seq += 1;\n transport.enqueue({\n kind: ev.kind,\n ts: ev.ts,\n sessionId,\n seq: active.seq,\n message: ev.message,\n ...(ev.stack ? { stack: ev.stack } : {}),\n ...(ev.source ? { source: ev.source } : {}),\n ...(typeof ev.line === 'number' ? { line: ev.line } : {}),\n ...(typeof ev.col === 'number' ? { col: ev.col } : {}),\n });\n}\n\nfunction stop(): void {\n if (!active) return;\n clearTimeout(active.deadlineTimer);\n active.uninstallNetwork();\n active.uninstallDom();\n active.uninstallErrors();\n active.transport.destroy();\n active = null;\n drainedThrough = 0;\n clearPersistedSession();\n notify();\n}\n\nfunction probe(label: string, data?: unknown): void {\n if (!active) return;\n enqueue({\n kind: 'probe',\n label: label.slice(0, 200),\n data: safeSerialize(data),\n });\n}\n\nfunction isActive(): boolean {\n return active !== null;\n}\n\nfunction currentUrl(): string | null {\n return active?.url ?? null;\n}\n\n/** Subscribe to active-state changes. Used by the panel UI to update its display. */\nexport function subscribeToMonitor(fn: Listener): () => void {\n listeners.add(fn);\n return () => { listeners.delete(fn); };\n}\n\nexport const monitor: MonitorPublicAPI = {\n start,\n stop,\n probe,\n isActive,\n currentUrl,\n};\n\n/**\n * Resume a persisted session if one exists in sessionStorage. Called at module\n * load. Without this, a page reload during active monitoring silently drops\n * capture even though the URL is still configured.\n */\nexport function resumeIfPersisted(): void {\n if (active) return;\n const persisted = readPersistedSession();\n if (!persisted) return;\n start({\n url: persisted.url,\n verbose: persisted.verbose,\n maxSessionMs: Math.max(60_000, persisted.deadlineMs - Date.now()),\n });\n}\n\n/**\n * Install the public API on window. Idempotent. Called from index.ts at module\n * load so consumers can call `window.__lsBeacon.start(...)` from devtools or\n * a bookmarklet without waiting for the element to mount.\n */\nexport function installPublicAPI(): void {\n if (typeof window === 'undefined') return;\n const w = window as unknown as { __lsBeacon?: MonitorPublicAPI };\n if (w.__lsBeacon) return; // don't overwrite (e.g. on HMR)\n w.__lsBeacon = monitor;\n}\n","// Entry point for the launch-kit beacon Web Component.\n// Importing this module auto-registers the <launch-kit-beacon> custom element.\n// Exposed via the @launchsecure/launch-kit/beacon subpath export.\n\nimport { defineBeacon, LaunchKitBeacon } from './element';\nimport { installEventCapture } from './capture/events';\nimport { installPublicAPI, resumeIfPersisted } from './monitor';\n\nexport { LaunchKitBeacon, defineBeacon };\nexport type {\n BeaconConfig,\n CapturedEvent,\n FeedbackPayload,\n Pin,\n Metadata,\n Severity,\n HeaderProvider,\n ContextProvider,\n SubmitResponse,\n} from './types';\nexport type {\n MonitorConfig,\n MonitorEvent,\n MonitorEventKind,\n MonitorBatch,\n MonitorPublicAPI,\n MonitorErrorEvent,\n MonitorNetworkEvent,\n MonitorClickEvent,\n MonitorRouteEvent,\n MonitorDialogEvent,\n MonitorProbeEvent,\n} from './monitor/types';\n\n// Auto-register on import. Consumers who want to control the tag name can call\n// defineBeacon('my-tag') themselves before any <launch-kit-beacon> elements are parsed.\ndefineBeacon();\n\n// Start listening for runtime errors immediately — well before any beacon element\n// is mounted. Bugs that happen during initial hydration are exactly the ones users\n// can't describe later, and the listeners are passive (zero cost on the happy path).\ninstallEventCapture();\n\n// Expose window.__lsBeacon so devs can call start()/stop()/probe() from devtools\n// without waiting for the element to mount. Also resume any session that was\n// active in this tab before reload (sessionStorage-backed) — without this, a\n// page reload mid-debug silently drops the stream.\ninstallPublicAPI();\nresumeIfPersisted();\n"],"names":["ICONS","createTriggerButton","label","btn","DEFAULT_SEVERITIES","DrawerView","severities","callbacks","pins","annotatedScreenshot","events","chip","count","summaryLabel","list","ev","escapeHtml","value","submitting","status","kind","canSubmit","sev","p","desc","submitBtn","input","_a","_b","num","item","s","showPinPopover","opts","resolve","popover","POPOVER_W","POPOVER_H","left","top","textarea","close","result","handleGlobalKey","e","action","note","NO_CAPTURE_CLASS","DEFAULT_ACCENT","DEFAULT_HINT","withAlpha","color","alphaHex","createPickModeOverlay","ACCENT","ACCENT_BORDER","ACCENT_GLOW","styleTag","frame","hint","SPINNER_HTML","c","tracked","makeMarker","m","makeOutline","o","placeAt","entry","rect","isStale","opacity","hide","reposition","liveTarget","r","fr","raf","schedule","anchor","marker","outline","message","startPicker","shadowRoot","onHover","accent","accentFill","tooltip","previousCursor","resolved","resolvePromise","promise","res","isWidgetElement","el","node","findTarget","x","y","candidates","positionOutline","tag","cls","above","handleMove","handlePointerDown","swallow","handleKey","finish","MAX_DEPTH","isUniqueId","id","root","tagWithClasses","classes","nthOfTypeIndex","parent","buildSelector","target","parts","depth","current","base","part","currentClasses","detectReact","keys","k","fiber","i","f","type","name","detectVue","anyEl","vueParent","detectAngular","ng","cmp","ctor","detectSvelte","detectFramework","OUTER_HTML_LIMIT","PARENT_OUTER_HTML_LIMIT","SELECTOR_LIMIT","ID_LIMIT","CLASSLIST_MAX_ENTRIES","CLASS_NAME_LIMIT","STYLE_VALUE_LIMIT","USEFUL_STYLE_PROPS","truncate","max","pickStyles","computed","out","prop","capClassList","capturePin","rawSelector","rawId","getUaData","nav","b","getTheme","captureMetadata","htmlToImage","load","TRANSPARENT_PIXEL","isUrlSafeForCanvas","rawUrl","crossOriginAttr","neutralizeCrossOriginImages","stashedImg","stashedSvg","img","svgImg","href","xlink","url","src","captureScreenshot","quality","pixelRatio","excludeShadowRoot","lib","filter","cur","restore","MARKER_RADIUS","MARKER_STROKE","MARKER_TEXT","OUTLINE_WIDTH","drawMarkers","screenshotDataUrl","viewportSize","pinElements","MARKER_FILL","OUTLINE_COLOR","loadImage","canvas","ctx","scaleX","scaleY","pin","getFreshRect","w","cx","cy","found","reject","err","MAX_EVENTS","MESSAGE_LIMIT","STACK_LIMIT","SOURCE_LIMIT","DEDUPE_WINDOW_MS","BEACON_STACK_PATTERN","buffer","recentSignatures","listeners","installed","trunc","limit","signature","stack","stackHead","fromBeacon","safeStringify","push","event","sig","last","fn","installEventCapture","errMessage","errStack","reason","getCapturedEvents","subscribeToEvents","submitFeedback","endpoint","payload","headers","body","ATTRS","GLOBAL_STYLE_ID","ensureGlobalStyles","stylesText","CUSTOMIZABLE_VARS","LaunchKitBeacon","style","stylesCss","assigned","v","oldValue","newValue","triggerEl","positionDrawerRelativeTo","overlay","next","popoverResult","raw","meta","annotated","msg","cfg","description","severity","needsCapture","beforeEvent","response","cs","val","path","h","attr","defineBeacon","tagName","DRAWER_WIDTH","VIEWPORT_MARGIN","ESTIMATED_DRAWER_HEIGHT","drawer","trigger","viewportW","viewportH","rightOffset","spaceBelow","spaceAbove","HTML_LIMIT","MAX_OVERLAYS","n","describeTarget","overlaysAtPoint","all","z","a","installClickCapture","cb","handle","me","hit","hitMatches","openDialogs","bodyPe","overlays","onClick","onMouseDown","installRouteCapture","originalPush","originalReplace","lastUrl","emit","via","to","from","args","ret","onPop","onHash","installDialogCapture","seen","selector","obs","mutations","dialogs","d","_c","_d","installDomCapture","undoClick","undoRoute","undoDialog","URL_LIMIT","wrapFetch","original","wrapped","init","start","method","durationMs","failed","wrapXhr","proto","originalOpen","originalSend","state","rest","onLoadEnd","installNetworkCapture","undoFetch","undoXhr","FLUSH_INTERVAL_MS","FLUSH_AT_COUNT","MAX_BUFFER","MonitorTransport","batch","blob","SESSION_URL_KEY","SESSION_ID_KEY","SESSION_VERBOSE_KEY","SESSION_DEADLINE_KEY","DEFAULT_MAX_SESSION_MS","PROBE_DATA_LIMIT","active","drainedThrough","randomSessionId","safeSerialize","walk","notify","stamp","partial","enqueue","persistSession","clearPersistedSession","readPersistedSession","sessionId","verbose","deadlineRaw","deadlineMs","config","stop","maxMs","transport","existing","emitErrorEvent","errorsUnsub","net","dom","deadlineTimer","probe","data","isActive","currentUrl","monitor","resumeIfPersisted","persisted","installPublicAPI"],"mappings":"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"}