@fixback/sdk 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"fixback.umd.js","names":["URL_RE"],"sources":["../src/boot.ts","../src/dom.ts","../src/element-picker.ts","../src/scrub.ts","../src/breadcrumbs.ts","../src/annotation.ts","../src/report.ts","../../../node_modules/.pnpm/modern-screenshot@4.7.0/node_modules/modern-screenshot/dist/index.mjs","../src/screenshot.ts","../src/auto-report-backoff.ts","../src/submit.ts","../src/version.ts","../src/error-capture.ts","../src/identity.ts","../src/invite.ts","../src/styles.ts","../src/launcher.ts","../src/onboarding-styles.ts","../src/onboarding.ts","../src/draw-surface.ts","../src/region-capture.ts","../src/overlay-styles.ts","../src/overlay.ts","../src/init.ts"],"sourcesContent":["/**\n * The ingest **boot** wire-contract, vendored.\n *\n * The SDK deliberately does not import `@fixback/shared` — that package is\n * private and server-shaped (ticket #47). The boot request/response is small and\n * stable, so the exact slice the SDK needs is copied here. Keep it in lock-step\n * with the server: the request body accepted by `POST /api/ingest/boot`\n * (`apps/api/src/ingest/ingest.controller.ts`) and the `BootAnswer` returned by\n * `evaluateBoot` (`apps/api/src/ingest/reporter-identity.ts`).\n */\n\n/** A Project's Gate — who may submit. Mirrors the server's `ProjectGate`. */\nexport type ProjectGate = \"open\" | \"invited\" | \"internal\";\n\n/** The trust tier a Reporter holds. Mirrors the server's `ReporterTier`. */\nexport type ReporterTier = \"public\" | \"invited\" | \"internal\";\n\n/**\n * Optional identity evidence the SDK forwards to boot. None of it is a tier: the\n * server re-derives trust from this evidence and never honours a self-declared\n * tier, so the SDK does not send one.\n */\nexport interface IdentityInputs {\n readonly signedIdentity?: string;\n readonly reporterId?: string;\n readonly anonymousId?: string;\n}\n\n/** The JSON body `POST /api/ingest/boot` accepts. */\nexport interface BootRequest extends IdentityInputs {\n readonly key: string;\n}\n\n/**\n * The Project's effective console/network capture config, served on the boot answer\n * (spec #122 §L; ticket #138). Each flag is the per-project master toggle ANDed with\n * that stream's own toggle, so the SDK gates instrumentation on one boolean per\n * stream. Optional on the wire: an older server that does not send it (or a\n * malformed value) is treated as **capture on** — default-on, matching the server\n * default — and `init` options override whatever is served.\n */\nexport interface CaptureConfig {\n readonly console: boolean;\n readonly network: boolean;\n}\n\n/**\n * The boot answer: whether this origin is allowlisted, the Project's Gate, the\n * caller's derived tier (`null` when a presented identity was refused), whether a\n * submission would be accepted right now, and the Project's capture config. The\n * launcher shows only when `canSubmit` is true.\n */\nexport interface BootAnswer {\n readonly originAllowed: boolean;\n readonly gate: ProjectGate;\n readonly tier: ReporterTier | null;\n readonly canSubmit: boolean;\n /** The Project's console/network capture config; absent ⇒ default-on (#138). */\n readonly capture?: CaptureConfig;\n}\n\n/** Join an API base URL with the boot path, tolerating a trailing slash. */\nexport function bootEndpoint(apiUrl: string): string {\n return `${apiUrl.replace(/\\/+$/, \"\")}/api/ingest/boot`;\n}\n\n/** Narrow an unknown JSON body to a `BootAnswer` before the SDK trusts it. */\nfunction isBootAnswer(value: unknown): value is BootAnswer {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.originAllowed === \"boolean\" &&\n typeof v.canSubmit === \"boolean\" &&\n typeof v.gate === \"string\" &&\n (v.tier === null || typeof v.tier === \"string\")\n );\n}\n\n/**\n * Ask ingest whether a submission would be accepted for this key / origin / Gate.\n * Resolves to the boot answer, or `null` when Fixback could not be reached, the\n * key was refused, or the response was not a boot answer. It never throws: any\n * non-answer is treated by the caller as \"do not show the launcher\", so a Fixback\n * outage stays invisible to the host page (ticket #47: \"fails quietly\").\n *\n * The browser attaches the `Origin` header itself on this cross-origin request —\n * the server reads it to decide `originAllowed` — so the SDK neither sets nor\n * needs to set it. `fetchImpl` is injectable purely so the boot call is testable.\n */\nexport async function requestBoot(\n apiUrl: string,\n request: BootRequest,\n fetchImpl: typeof fetch = fetch,\n): Promise<BootAnswer | null> {\n let response: Response;\n try {\n response = await fetchImpl(bootEndpoint(apiUrl), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n } catch {\n return null; // network error / Fixback unreachable\n }\n\n if (!response.ok) return null; // 401 unknown key, or any other refusal\n\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n return null;\n }\n\n return isBootAnswer(body) ? body : null;\n}\n","/**\n * Small DOM helpers shared across the SDK's report surfaces.\n *\n * The SDK mounts its own host elements into the host page — the launcher and the\n * overlay panel — each tagged with a `data-fixback-*` marker attribute (the\n * element-picker's highlight lives inside the overlay's shadow, so it is covered\n * by the shadow-boundary walk below). These helpers let the picker skip the SDK's\n * own UI and let the screenshot exclude it, so a report never captures or targets\n * Fixback's chrome.\n */\n\n/** Marker attributes on the SDK's own host elements in the light DOM. */\nexport const FIXBACK_HOST_MARKERS = [\n \"data-fixback-root\",\n \"data-fixback-overlay\",\n] as const;\n\nconst HOST_SELECTOR = FIXBACK_HOST_MARKERS.map((m) => `[${m}]`).join(\",\");\n\n/**\n * Is this node itself one of the SDK's own host elements (the launcher / overlay\n * roots)? A self-only check — the screenshot's clone walk excludes a node's whole\n * subtree once the host is matched, so catching the host is enough to keep all of\n * Fixback's chrome (light DOM and its shadow tree) out of a capture.\n */\nexport function isFixbackHostElement(node: Node | null | undefined): boolean {\n return (\n node instanceof Element &&\n FIXBACK_HOST_MARKERS.some((marker) => node.hasAttribute(marker))\n );\n}\n\n/**\n * Is this node part of the SDK's own UI? Walks up parents and out through any\n * Shadow DOM boundary (via `getRootNode().host`), so a click inside the overlay's\n * shadow is recognised as Fixback's own — not a host-page element to pick.\n */\nexport function isFixbackNode(node: EventTarget | null | undefined): boolean {\n let current: Node | null = node instanceof Node ? node : null;\n while (current) {\n if (current instanceof Element) {\n for (const marker of FIXBACK_HOST_MARKERS) {\n if (current.hasAttribute(marker)) return true;\n }\n }\n const root = current.getRootNode();\n if (root instanceof ShadowRoot && root !== current) {\n current = root.host;\n continue;\n }\n current = current.parentNode;\n }\n return false;\n}\n\n/**\n * Remove the SDK's own host elements from a (cloned) subtree, so a captured\n * screenshot never contains the launcher, overlay, or picker highlight.\n */\nexport function stripFixbackNodes(root: ParentNode): void {\n for (const el of Array.from(root.querySelectorAll(HOST_SELECTOR))) {\n el.remove();\n }\n}\n","import { isFixbackNode } from \"./dom\";\nimport type { ElementRect, SelectedElement } from \"./report\";\n\n/**\n * Escape a string for use in a CSS selector, preferring the platform's\n * `CSS.escape` and falling back to a conservative backslash escape where it is\n * unavailable (older engines, some test environments).\n */\nfunction cssEscape(value: string): string {\n const api = (globalThis as { CSS?: { escape?: (v: string) => string } }).CSS;\n if (api?.escape) return api.escape(value);\n return value.replace(/[^\\w-]/g, (ch) => `\\\\${ch}`);\n}\n\n/** The 1-based position of `el` among its same-tag siblings (`:nth-of-type`). */\nfunction nthOfType(el: Element): number {\n let n = 1;\n let sib = el.previousElementSibling;\n while (sib) {\n if (sib.tagName === el.tagName) n += 1;\n sib = sib.previousElementSibling;\n }\n return n;\n}\n\n/**\n * A stable CSS selector for `el`: its own id when it has one, otherwise a path of\n * tag (with `:nth-of-type` to disambiguate same-tag siblings) climbing until it\n * reaches an ancestor with an id — the shortest anchor that still resolves.\n */\nexport function cssSelectorFor(el: Element): string {\n if (el.id) return `#${cssEscape(el.id)}`;\n\n const parts: string[] = [];\n let node: Element | null = el;\n while (node && node.tagName.toLowerCase() !== \"html\") {\n if (node.id) {\n parts.unshift(`#${cssEscape(node.id)}`);\n break;\n }\n const tag = node.tagName.toLowerCase();\n const parent: Element | null = node.parentElement;\n if (parent) {\n const sameTag = Array.from(parent.children).filter(\n (c) => c.tagName === node!.tagName,\n );\n parts.unshift(\n sameTag.length > 1 ? `${tag}:nth-of-type(${nthOfType(node)})` : tag,\n );\n } else {\n parts.unshift(tag);\n }\n node = parent;\n }\n return parts.join(\" > \");\n}\n\n/** One node's readable label: `tag`, `tag#id`, or `tag.firstClass`. */\nfunction describeNode(el: Element): string {\n const tag = el.tagName.toLowerCase();\n if (el.id) return `${tag}#${el.id}`;\n const firstClass = el.classList[0];\n return firstClass ? `${tag}.${firstClass}` : tag;\n}\n\n/** A readable ancestry path from the document root down to `el`. */\nexport function domPathFor(el: Element): string {\n const chain: string[] = [];\n let node: Element | null = el;\n while (node) {\n chain.unshift(describeNode(node));\n node = node.parentElement;\n }\n return chain.join(\" > \");\n}\n\nfunction roundedRect(el: Element): ElementRect {\n const r = el.getBoundingClientRect();\n return {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n };\n}\n\n/**\n * Describe a picked element as the Annotation ingest stores: a stable selector, a\n * readable DOM path, the tag, and the viewport bounding rect (spec MVP §B).\n */\nexport function describeElement(el: Element): SelectedElement {\n return {\n selector: cssSelectorFor(el),\n domPath: domPathFor(el),\n tag: el.tagName.toLowerCase(),\n rect: roundedRect(el),\n };\n}\n\n/** Options for {@link startElementPicker}. */\nexport interface ElementPickerOptions {\n /** Document to attach to. Defaults to the global `document`. */\n readonly doc?: Document;\n /** Called with the element being hovered (or `null` over nothing pickable). */\n readonly onHover?: (element: Element | null) => void;\n /** Called with the element the Reporter clicked to pin. */\n readonly onPick: (element: Element) => void;\n /** Called when the Reporter presses Escape to abandon the pick. */\n readonly onCancel?: () => void;\n /** Return true to skip a node (defaults to skipping the SDK's own UI). */\n readonly ignore?: (element: Element) => boolean;\n}\n\n/** A running element-picker; call {@link ElementPicker.stop} to detach it. */\nexport interface ElementPicker {\n stop(): void;\n}\n\n/**\n * Enter element-select mode: as the Reporter moves over the host page the element\n * under the pointer is reported through `onHover` (the overlay draws a highlight),\n * a click pins it through `onPick`, and Escape abandons through `onCancel`. The\n * click that pins is swallowed (prevent-default + stop-propagation) so it never\n * also activates the host page. The SDK's own UI is skipped by default, so the\n * Reporter can never pick the overlay itself.\n *\n * Listeners are attached in the capture phase so the pick is intercepted before\n * any host-page handler sees it; `stop()` (called automatically on pick/cancel)\n * detaches them all.\n */\nexport function startElementPicker(options: ElementPickerOptions): ElementPicker {\n const doc = options.doc ?? document;\n const ignore = options.ignore ?? isFixbackNode;\n let current: Element | null = null;\n let stopped = false;\n\n function resolveTarget(event: Event): Element | null {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n const deepest = path[0] ?? event.target;\n if (deepest instanceof Element) return ignore(deepest) ? null : deepest;\n return null;\n }\n\n function onOver(event: Event): void {\n if (stopped) return;\n current = resolveTarget(event);\n options.onHover?.(current);\n }\n\n function onClick(event: MouseEvent): void {\n if (stopped) return;\n const el = resolveTarget(event) ?? current;\n if (!el) return; // nothing pickable under the pointer — let the click pass\n event.preventDefault();\n event.stopPropagation();\n stop();\n options.onPick(el);\n }\n\n function onKey(event: KeyboardEvent): void {\n if (stopped) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n stop();\n options.onCancel?.();\n }\n }\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n doc.removeEventListener(\"mouseover\", onOver, true);\n doc.removeEventListener(\"click\", onClick, true);\n doc.removeEventListener(\"keydown\", onKey, true);\n current = null;\n }\n\n doc.addEventListener(\"mouseover\", onOver, true);\n doc.addEventListener(\"click\", onClick, true);\n doc.addEventListener(\"keydown\", onKey, true);\n\n return { stop };\n}\n","/**\n * The single client-side **scrub choke point** every report passes through\n * before transport (spec 0003 §C; research `sentry-error-capture-findings.md`\n * §7.4) — the SDK's `beforeSend` equivalent.\n *\n * Masking is the SDK's job, done in the browser before anything leaves the page.\n * The screenshot is masked at capture, and breadcrumbs never record a value or a\n * body at the source; `runBeforeSend` is the **last** gate over the assembled\n * report. Its default scrubbers are **on**: they strip credentials, query\n * strings, and bearer tokens from URLs, and redact obvious PII (emails, long\n * digit runs, bearer tokens) from crumb and error text. The result is then handed\n * to an optional per-project hook that can mutate it further or drop the whole\n * report by returning `null`.\n *\n * The hook is **synchronous and network-free** by contract, and both manual\n * (overlay) and automatic (error-capture) reports run through the very same\n * choke point. A project relaxes the defaults with `scrub: false`, or reshapes\n * the draft in its own hook — never a silent raw send.\n */\n\nimport type { Breadcrumb, BreadcrumbData, ConsoleArg } from \"./breadcrumbs\";\nimport type { ReportContent } from \"./report\";\n\n/** The per-project client scrub hook. Return `null` to drop the whole report. */\nexport type BeforeSend = (draft: ReportContent) => ReportContent | null;\n\n/** Options for {@link runBeforeSend}. */\nexport interface BeforeSendOptions {\n /** The per-project hook, run **after** the default scrubbers. */\n readonly hook?: BeforeSend | null;\n /** Run the built-in default scrubbers first. Defaults to `true`. */\n readonly scrub?: boolean;\n}\n\n/** A digit run at least this long is treated as sensitive (phone, card, id). */\nconst MIN_DIGIT_RUN = 7;\nconst EMAIL_RE = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi;\nconst DIGIT_RUN_RE = new RegExp(`\\\\d{${MIN_DIGIT_RUN},}`, \"g\");\nconst BEARER_RE = /\\b(bearer|token)\\s+[\\w.\\-~+/]+=*/gi;\n/** An http(s) URL embedded in free text (e.g. a console log line). */\nconst URL_IN_TEXT_RE = /\\bhttps?:\\/\\/[^\\s\"'<>]+/gi;\n\n/**\n * Redact obvious PII from free text: email addresses, `Bearer <token>` /\n * `token <value>` pairs, and long digit runs. Conservative by design — it keeps\n * the shape of the message readable while removing the sensitive spans.\n */\nexport function redactPii(text: string): string {\n if (typeof text !== \"string\" || text.length === 0) return text;\n return text\n .replace(EMAIL_RE, \"[redacted-email]\")\n .replace(BEARER_RE, (_match, keyword: string) => `${keyword} [redacted]`)\n .replace(DIGIT_RUN_RE, \"[redacted-number]\");\n}\n\n/**\n * Redact PII from the **path** portion of a URL (spec #122 §E, ticket #139):\n * emails and long digit runs in path (or fragment-route) segments — a network\n * list shows URLs prominently, so an identifier baked into a path\n * (`/users/jane@acme.app`, `/card/4111111111111111`) must not leak. Deliberately\n * narrower than {@link redactPii}: no bearer/token rule (URL credentials are\n * already stripped by {@link scrubUrl}) and it is only ever applied to the\n * post-authority remainder, so a host or port with digits is never touched.\n */\nfunction redactPathPii(pathAndBeyond: string): string {\n return pathAndBeyond\n .replace(EMAIL_RE, \"[redacted-email]\")\n .replace(DIGIT_RUN_RE, \"[redacted-number]\");\n}\n\n/**\n * Strip the sensitive parts of a URL: userinfo credentials\n * (`scheme://user:pass@host`), the entire query string, a token-bearing\n * fragment (one that carries `key=value`), and PII (emails, long digit runs) in\n * the **path segments** (#139). Plain hash routes (`#/checkout`) are kept. Works\n * on absolute and relative URLs alike, with no dependency and no throw. The host\n * (authority) is never redacted — only the path and any surviving fragment route.\n */\nexport function scrubUrl(url: string): string {\n if (typeof url !== \"string\" || url.length === 0) return url;\n let out = url;\n // Drop userinfo credentials: scheme://user:pass@host → scheme://host\n out = out.replace(/(^[a-z][a-z0-9+.-]*:\\/\\/)[^/@?#]*@/i, \"$1\");\n // Drop the query string entirely (everything from '?' up to a '#').\n out = out.replace(/\\?[^#]*/, \"\");\n // Drop a token-bearing fragment (it carries '='); keep plain hash routes.\n out = out.replace(/#.*$/, (fragment) =>\n fragment.includes(\"=\") ? \"\" : fragment,\n );\n // Redact PII in the path (and any kept fragment route), never in the authority.\n // Split off `scheme://authority` (or a protocol-relative `//authority`) so a\n // host/port that contains digits is preserved; the remainder is the path onward.\n const absolute = out.match(/^([a-z][a-z0-9+.-]*:\\/\\/[^/?#]*)([\\s\\S]*)$/i);\n if (absolute) return absolute[1] + redactPathPii(absolute[2] ?? \"\");\n const protocolRelative = out.match(/^(\\/\\/[^/?#]*)([\\s\\S]*)$/);\n if (protocolRelative) {\n return protocolRelative[1] + redactPathPii(protocolRelative[2] ?? \"\");\n }\n // A relative URL is all path — redact the whole thing.\n return redactPathPii(out);\n}\n\ntype MutableBreadcrumbData = { -readonly [K in keyof BreadcrumbData]: BreadcrumbData[K] };\ntype MutableBreadcrumb = { -readonly [K in keyof Breadcrumb]: Breadcrumb[K] };\ntype MutableContent = { -readonly [K in keyof ReportContent]: ReportContent[K] };\n\nfunction scrubCrumbData(data: BreadcrumbData): BreadcrumbData {\n const next: MutableBreadcrumbData = { ...data };\n if (typeof next.url === \"string\") next.url = scrubUrl(next.url);\n if (typeof next.from === \"string\") next.from = scrubUrl(next.from);\n if (typeof next.to === \"string\") next.to = scrubUrl(next.to);\n return next;\n}\n\n/** Scrub a crumb's free-text message: strip URL query strings, then redact PII. */\nfunction scrubMessage(message: string): string {\n return redactPii(message.replace(URL_IN_TEXT_RE, (url) => scrubUrl(url)));\n}\n\n/**\n * Scrub the string leaves of a structured console-arg value (spec #122 §C/§E) — the\n * value a `json` arg carries. Walks arrays and plain objects, applying the same\n * URL-strip + PII redaction as a crumb message to every nested string, so a value\n * logged through `console.*` is swept just like the flattened preview.\n */\nfunction scrubArgValue(value: unknown): unknown {\n if (typeof value === \"string\") return scrubMessage(value);\n if (Array.isArray(value)) return value.map(scrubArgValue);\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n out[key] = scrubArgValue(v);\n }\n return out;\n }\n return value;\n}\n\n/**\n * Scrub one structured console argument (spec #122 §C): redact PII / strip URL query\n * strings from a `string` value, from every string leaf of a `json` value, and from an\n * `error` value's `message` and `stack`. Other tags (`number`/`bool`/`null`) carry no\n * free text and pass through unchanged.\n */\nfunction scrubConsoleArg(arg: ConsoleArg): ConsoleArg {\n switch (arg.t) {\n case \"string\":\n return typeof arg.v === \"string\" ? { t: \"string\", v: scrubMessage(arg.v) } : arg;\n case \"json\":\n return { t: \"json\", v: scrubArgValue(arg.v) };\n case \"error\": {\n if (!arg.v || typeof arg.v !== \"object\") return arg;\n const v = arg.v as { message?: unknown; stack?: unknown };\n const next: Record<string, unknown> = { ...v };\n if (typeof next.message === \"string\") next.message = scrubMessage(next.message);\n if (typeof next.stack === \"string\") next.stack = scrubMessage(next.stack);\n return { t: \"error\", v: next };\n }\n default:\n return arg;\n }\n}\n\nfunction scrubCrumb(crumb: Breadcrumb): Breadcrumb {\n const next: MutableBreadcrumb = { ...crumb };\n if (typeof next.message === \"string\") next.message = scrubMessage(next.message);\n if (next.data) next.data = scrubCrumbData(next.data);\n // A rich network crumb (#139) carries its scrubbed URL at the top level — sweep it\n // again here (idempotent) so the choke point holds whether the URL rode in `data`\n // (a legacy thin crumb) or top-level, and path-PII redaction is never skipped.\n if (typeof next.url === \"string\") next.url = scrubUrl(next.url);\n // A console crumb's structured args carry the same free text as its preview — sweep\n // them too, so PII redaction holds whether a value is read from `message` or `args`.\n if (Array.isArray(next.args)) next.args = next.args.map(scrubConsoleArg);\n return next;\n}\n\n/**\n * Apply the built-in default scrubbers to a report draft: strip the page URL,\n * and scrub every crumb's URLs and redact PII from its text. The Reporter's own\n * `comment` is intentionally left untouched — it is authored on purpose, not\n * scraped. The screenshot and input values are masked elsewhere (at capture and\n * at crumb creation); this is the final URL/PII sweep.\n */\nexport function applyDefaultScrub(draft: ReportContent): ReportContent {\n const next: MutableContent = { ...draft };\n if (typeof next.url === \"string\") next.url = scrubUrl(next.url);\n if (next.trace && next.trace.length > 0) {\n next.trace = next.trace.map(scrubCrumb);\n }\n return next;\n}\n\n/**\n * Run the report draft through the client scrub choke point: the default\n * scrubbers first (unless `scrub` is `false`), then the optional per-project\n * hook. Returns the scrubbed (and possibly hook-mutated) draft, or `null` when\n * the hook drops the report. A hook that throws is treated as a no-op — the\n * already-scrubbed draft is kept, so a buggy hook never breaks the report path\n * nor leaks unscrubbed data.\n */\nexport function runBeforeSend(\n draft: ReportContent,\n options: BeforeSendOptions = {},\n): ReportContent | null {\n const current =\n options.scrub === false ? draft : applyDefaultScrub(draft);\n const hook = options.hook;\n if (!hook) return current;\n try {\n const result = hook(current);\n return result ?? null;\n } catch {\n return current;\n }\n}\n","/**\n * The thin trace **breadcrumb ring buffer** and its capture instrumentation\n * (spec 0003 §C; research `sentry-error-capture-findings.md` §7.5).\n *\n * A fixed-size FIFO buffer of the most recent activity — console, navigation,\n * network metadata, masked user actions, and the failing error — that rides on a\n * report as Evidence. It is trimmed exactly like Sentry (`crumbs.slice(-N)`),\n * defaults to a deliberately thin `N ≈ 30` because it ships on **every** payload,\n * and takes an optional age cap. A `beforeBreadcrumb(crumb) => crumb | null`\n * filter lets a Project mute or edit crumbs before they enter the buffer.\n *\n * Everything private is kept out **at the source**: `ui.input` records that an\n * input changed, never its value; `fetch`/`xhr` crumbs carry method + URL +\n * status only, **never** bodies; URLs are scrubbed as the crumb is built. The\n * `beforeSend` choke point (`scrub.ts`) is the final gate over the whole report.\n *\n * The SDK stays dependency-free and must never throw into the host page, so every\n * instrumentation hook is wrapped: a capture failure is swallowed and the original\n * behaviour (the real `console`, `fetch`, navigation) always runs.\n */\n\nimport { isFixbackNode } from \"./dom\";\nimport { cssSelectorFor } from \"./element-picker\";\nimport { scrubUrl } from \"./scrub\";\n\n/** Console-style severity a `console` crumb records. */\nexport type BreadcrumbLevel =\n | \"log\"\n | \"info\"\n | \"warn\"\n | \"error\"\n | \"assert\"\n | \"debug\";\n\n/** The kind of activity a crumb records. */\nexport type BreadcrumbCategory =\n | \"console\"\n | \"navigation\"\n | \"fetch\"\n | \"xhr\"\n | \"beacon\"\n | \"ui.click\"\n | \"ui.input\"\n | \"error\";\n\n/**\n * Which browser API issued a captured network request (spec #122 §D, ticket #139).\n * Every network crumb's `category` is one of these too, so a stream router and the\n * read model agree on what is a network entry.\n */\nexport type NetworkApi = \"fetch\" | \"xhr\" | \"beacon\";\n\n/**\n * A network request's failure classification (spec #122 §D, ticket #139). `ok` and\n * the HTTP status classes come from a settled response; `network-error` / `timeout`\n * / `aborted` from how a request failed; `opaque-cors` from a cross-origin response\n * whose status is unreadable. The Network tab flags every non-`ok` outcome.\n */\nexport type NetworkOutcome =\n | \"ok\"\n | \"http-4xx\"\n | \"http-5xx\"\n | \"network-error\"\n | \"timeout\"\n | \"aborted\"\n | \"opaque-cors\";\n\n/**\n * A crumb's structured detail. Deliberately narrow: there is **no** field for a\n * request/response body or an input value, so those can never be recorded.\n */\nexport interface BreadcrumbData {\n readonly url?: string;\n readonly method?: string;\n readonly status?: number;\n /** A masked CSS selector for a `ui.*` target — never its text or value. */\n readonly target?: string;\n readonly from?: string;\n readonly to?: string;\n readonly errorType?: string;\n}\n\n/**\n * The type tag on a structured console argument (spec #122 §C, decision D7). A\n * console call's arguments are preserved **type-tagged** rather than flattened to a\n * string, so an object/array argument can be inspected in the Console tab rather\n * than read as `[object Object]`: `string`/`number`/`bool`/`null` carry the value\n * directly, `json` a depth-/byte-capped JSON-safe clone, and `error` an Error's\n * `{ name, message, stack }`.\n */\nexport type ConsoleArgType =\n | \"string\"\n | \"number\"\n | \"bool\"\n | \"null\"\n | \"json\"\n | \"error\";\n\n/**\n * One structured console argument (spec #122 §C): a type tag plus a JSON-safe value.\n * `v` is always serializable — a `json` arg is depth-, breadth-, and string-capped at\n * assembly, and exotic values (bigint, symbol, function, circular refs) are rendered\n * to safe text — so a console crumb can never carry an unserializable or unbounded\n * value onto the wire.\n */\nexport interface ConsoleArg {\n readonly t: ConsoleArgType;\n readonly v: unknown;\n}\n\n/** A `file:line` source location (spec #122 §C) — where a console call was made. */\nexport interface SourceLocation {\n readonly file: string;\n readonly line: number;\n}\n\n/**\n * One entry in a trace stream. Alongside its semantic fields every entry carries a\n * stable {@link id} and a high-res monotonic {@link mono} timestamp — both stamped\n * by the buffer on `add` — so entries from the three independent streams order and\n * cross-link exactly (spec #122 §B, decision D9). `timestamp` stays epoch ms.\n */\nexport interface Breadcrumb {\n readonly category: BreadcrumbCategory;\n readonly message?: string;\n readonly level?: BreadcrumbLevel;\n /** Epoch milliseconds when the crumb was recorded. */\n readonly timestamp: number;\n /** A stable id, unique within the buffer — assigned on `add` when not already set. */\n readonly id?: string;\n /** A high-res monotonic timestamp (`performance.now()`) — assigned on `add`. */\n readonly mono?: number;\n readonly data?: BreadcrumbData;\n /**\n * For a `console` crumb (spec #122 §C): the call's arguments preserved as\n * structured, type-tagged values (see {@link ConsoleArg}), so the Console tab can\n * render each argument expandably instead of a flattened string. `message` stays\n * the one-line preview. Absent on non-console crumbs.\n */\n readonly args?: readonly ConsoleArg[];\n /**\n * For a `console` crumb (spec #122 §C): the `file:line` the call was made from,\n * parsed best-effort from the call stack. Captured only for the levels that keep a\n * source — `warn`/`error`/`assert` (ticket #159; see {@link SOURCE_CAPTURE_LEVELS}) —\n * and only when the stack yields a usable location; a chatty app's `log`/`info`/`debug`\n * omit it so the hot-page capture cost stays low. Absent on non-console crumbs.\n */\n readonly source?: SourceLocation;\n /**\n * For an auto-captured `error` crumb only (spec #122 §F): the ids of the entries\n * immediately preceding the throw — a causal pointer into the same trace, so a\n * machine-filed crash names its lead-up. Absent on every other crumb.\n */\n readonly causedBy?: readonly string[];\n /**\n * For a network crumb (`fetch` / `xhr` / `beacon`) — spec #122 §D, ticket #139.\n * The rich request metadata the Network tab renders, lifted to the top level (the\n * console-enrichment precedent) so the read model shapes each into a\n * `NetworkTraceEntry`. **No field carries a request/response body or an arbitrary\n * header** — `respSize` derives from the `content-length` response header only and\n * `contentType` from `content-type`; nothing else is read. Absent on every other crumb.\n */\n readonly api?: NetworkApi;\n /** The request method (network crumb) — e.g. `GET`, `POST`. */\n readonly method?: string;\n /** The scrubbed request URL (network crumb) — query dropped, path PII redacted. */\n readonly url?: string;\n /** The final HTTP status (network crumb), when one was known; absent on a network error/beacon. */\n readonly status?: number;\n /** The HTTP status text (network crumb), when the response carried one. */\n readonly statusText?: string;\n /** Wall-clock duration of the request in ms (network crumb) — a `performance.now()` delta. */\n readonly durationMs?: number;\n /** Request body size in bytes (network crumb) — only when trivially known (string/Blob/ArrayBuffer), never by reading a stream. */\n readonly reqSize?: number;\n /** Response body size in bytes (network crumb) — from the `content-length` response header only. */\n readonly respSize?: number;\n /** Response content type (network crumb) — the `content-type` header's media type. */\n readonly contentType?: string;\n /** The request's failure classification (network crumb) — see {@link NetworkOutcome}. */\n readonly outcome?: NetworkOutcome;\n}\n\n/**\n * The three independent trace streams (spec #122 §A, decision D6). Each is its own\n * FIFO ring with its own size budget, so a chatty stream can't evict another's\n * lead-up. Every {@link BreadcrumbCategory} maps to exactly one stream via\n * {@link streamOf}.\n */\nexport type TraceStream = \"network\" | \"console\" | \"breadcrumbs\";\n\n/**\n * Per-stream ring budgets — starting points from the grill (D6): network is the\n * chattiest, breadcrumbs the sparsest. Per-project tunable, never frozen.\n */\nexport const DEFAULT_STREAM_BUDGETS: Readonly<Record<TraceStream, number>> = {\n network: 100,\n console: 80,\n breadcrumbs: 40,\n};\n\n/**\n * The shared age cap (spec #122 §A): entries older than this are pruned from every\n * stream, whichever trims first. ~3 minutes and — unlike the thin buffer's\n * off-by-default cap — **on** by default, so an idle tab never ships stale context.\n */\nexport const DEFAULT_MAX_AGE_MS = 3 * 60 * 1000;\n\n/**\n * Console levels captured by default (spec #122 §C, decision D7): **all** of them, so\n * the Console tab is a real console and not just an error log. Eviction priority (not\n * capture) is what keeps a chatty app's `log`/`info`/`debug` from burying the signal —\n * see {@link PINNED_CONSOLE_LEVELS}.\n */\nexport const DEFAULT_CONSOLE_LEVELS: readonly BreadcrumbLevel[] = [\n \"log\",\n \"info\",\n \"warn\",\n \"error\",\n \"assert\",\n \"debug\",\n];\n\n/**\n * The console levels **pinned** against eviction (spec #122 §C, decision D7). When the\n * console stream overflows its budget, `warn`/`error`/`assert` are retained ahead of\n * `log`/`info`/`debug`, so an error is never evicted by a burst of chatter — the\n * low-priority levels fill the remainder and are dropped first.\n */\nexport const PINNED_CONSOLE_LEVELS: readonly BreadcrumbLevel[] = [\n \"warn\",\n \"error\",\n \"assert\",\n];\n\n/** Whether a console level is pinned against eviction (see {@link PINNED_CONSOLE_LEVELS}). */\nfunction isPinnedConsoleLevel(level: BreadcrumbLevel | undefined): boolean {\n return level !== undefined && PINNED_CONSOLE_LEVELS.includes(level);\n}\n\n/**\n * The console levels for which `source` (`file:line`) is captured (ticket #159).\n *\n * Capturing a call site constructs a `new Error()` to read its stack on **every** console\n * call — a measurable hot-page cost when a chatty app logs in a tight loop (spec #122's\n * \"hot-page performance budget\" open question, handed onward from the grill). The\n * spec-sanctioned mitigation (decision D7) narrows source capture to the **levels that\n * matter for debugging** — the same `warn`/`error`/`assert` that are pinned against\n * eviction — so `log`/`info`/`debug` pay no per-call stack cost and simply omit `source`.\n * Full-fidelity `source` is preserved exactly where it earns its keep: on warnings,\n * errors, and failed assertions. Per-project tunability of this set is future work; today\n * it deliberately mirrors {@link PINNED_CONSOLE_LEVELS} so \"what survives eviction\" and\n * \"what carries a call site\" stay one idea.\n */\nexport const SOURCE_CAPTURE_LEVELS: readonly BreadcrumbLevel[] =\n PINNED_CONSOLE_LEVELS;\n\n/** Whether a console level captures `source` `file:line` (see {@link SOURCE_CAPTURE_LEVELS}). */\nfunction capturesSource(level: BreadcrumbLevel): boolean {\n return SOURCE_CAPTURE_LEVELS.includes(level);\n}\n\n/**\n * Which stream a crumb's category belongs to (spec #122 §A). Network APIs\n * (`fetch` / `xhr` / `beacon`) form the network stream, `console` its own, and\n * everything else (navigation, masked UI events, the failing error) breadcrumbs.\n */\nexport function streamOf(category: string): TraceStream {\n if (category === \"console\") return \"console\";\n if (category === \"fetch\" || category === \"xhr\" || category === \"beacon\") {\n return \"network\";\n }\n return \"breadcrumbs\";\n}\n\n/** Filters or edits each crumb before it enters the buffer; `null` drops it. */\nexport type BeforeBreadcrumb = (crumb: Breadcrumb) => Breadcrumb | null;\n\n/** Configuration for {@link createBreadcrumbBuffer}. All values are optional. */\nexport interface BreadcrumbBufferConfig {\n /**\n * Per-stream size budgets (oldest drop, independently per stream). Any stream\n * omitted falls back to {@link DEFAULT_STREAM_BUDGETS}.\n */\n readonly budgets?: Partial<Record<TraceStream, number>>;\n /**\n * Shared age cap in ms: entries older than this are dropped from every stream.\n * Defaults to {@link DEFAULT_MAX_AGE_MS} (on); pass `0` (or a non-positive value)\n * to disable age pruning.\n */\n readonly maxAgeMs?: number;\n /** A per-crumb filter (mute a category, edit, or drop by returning `null`). */\n readonly beforeBreadcrumb?: BeforeBreadcrumb | null;\n /** Epoch clock source, injectable for tests. Defaults to `Date.now`. */\n readonly now?: () => number;\n /** High-res monotonic clock, injectable for tests. Defaults to `performance.now`. */\n readonly mono?: () => number;\n /** Stable id generator, injectable for tests. Defaults to a per-buffer sequence. */\n readonly nextId?: () => string;\n}\n\n/** A live trace buffer. */\nexport interface BreadcrumbBuffer {\n /** Record a crumb (subject to `beforeBreadcrumb`, id/mono stamping, size, and age trimming). */\n add(crumb: Breadcrumb): void;\n /** The current crumbs, merged across streams and ordered in time — a fresh array. */\n snapshot(): Breadcrumb[];\n /** Drop every crumb. */\n clear(): void;\n}\n\nfunction normalizeBudget(value: number | undefined, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 1) {\n return fallback;\n }\n return Math.floor(value);\n}\n\n/** The default high-res clock: `performance.now()` where available, else `Date.now`. */\nfunction defaultMono(): number {\n return typeof performance !== \"undefined\" &&\n typeof performance.now === \"function\"\n ? performance.now()\n : Date.now();\n}\n\n/** A per-buffer id factory: a short random salt + a base-36 sequence, stable once assigned. */\nfunction createIdFactory(): () => string {\n const salt = Math.random().toString(36).slice(2, 8);\n let seq = 0;\n return () => `${salt}${(seq++).toString(36)}`;\n}\n\n/** The streams, in a fixed order for a deterministic merge. */\nconst STREAMS: readonly TraceStream[] = [\"network\", \"console\", \"breadcrumbs\"];\n\n/** One held entry, tagged with its insertion order for a stable cross-stream sort. */\ninterface HeldCrumb {\n readonly crumb: Breadcrumb;\n readonly seq: number;\n}\n\n/**\n * Trim the **console** stream to its budget with eviction priority (spec #122 §C,\n * decision D7): `warn`/`error`/`assert` are pinned, so the oldest `log`/`info`/`debug`\n * entries are dropped first; a pinned entry is evicted only when dropping every\n * low-priority one still leaves the stream over budget (oldest pinned first). Survivors\n * keep their insertion order. A plain FIFO `slice(-budget)` handles every other stream.\n */\nfunction trimConsoleStream(held: HeldCrumb[], budget: number): HeldCrumb[] {\n const over = held.length - budget;\n if (over <= 0) return held;\n const drop = new Set<number>();\n // First: oldest low-priority (not pinned) entries, until enough room is freed.\n for (let i = 0; i < held.length && drop.size < over; i += 1) {\n if (!isPinnedConsoleLevel(held[i]!.crumb.level)) drop.add(i);\n }\n // Then, only if the low-priority ones weren't enough: oldest pinned entries.\n for (let i = 0; i < held.length && drop.size < over; i += 1) {\n if (!drop.has(i)) drop.add(i);\n }\n return held.filter((_, i) => !drop.has(i));\n}\n\n/**\n * Create the per-stream trace buffer (spec #122 §A/§B). It holds **three\n * independent FIFO rings** — `network`, `console`, `breadcrumbs` — each trimmed to\n * its own budget so a chatty stream never evicts another's lead-up, plus a shared\n * age cap. On `add`, a crumb passes through `beforeBreadcrumb`, is stamped with a\n * stable `id` and a high-res `mono` timestamp (and an epoch `timestamp` if it has\n * none), routed to its stream, then that stream is pruned by age and trimmed to its\n * budget. `snapshot` prunes by age again, then merges the three streams into one\n * `mono`-ordered array for transport — so the wire keeps its single `trace` field.\n */\nexport function createBreadcrumbBuffer(\n config: BreadcrumbBufferConfig = {},\n): BreadcrumbBuffer {\n const budgets: Record<TraceStream, number> = {\n network: normalizeBudget(config.budgets?.network, DEFAULT_STREAM_BUDGETS.network),\n console: normalizeBudget(config.budgets?.console, DEFAULT_STREAM_BUDGETS.console),\n breadcrumbs: normalizeBudget(\n config.budgets?.breadcrumbs,\n DEFAULT_STREAM_BUDGETS.breadcrumbs,\n ),\n };\n const maxAgeMs =\n config.maxAgeMs === undefined ? DEFAULT_MAX_AGE_MS : config.maxAgeMs;\n const beforeBreadcrumb = config.beforeBreadcrumb;\n const now = config.now ?? Date.now;\n const mono = config.mono ?? defaultMono;\n const nextId = config.nextId ?? createIdFactory();\n\n const streams: Record<TraceStream, HeldCrumb[]> = {\n network: [],\n console: [],\n breadcrumbs: [],\n };\n let seq = 0;\n\n function pruneByAge(): void {\n if (typeof maxAgeMs !== \"number\" || maxAgeMs <= 0) return;\n const cutoff = now() - maxAgeMs;\n for (const stream of STREAMS) {\n const held = streams[stream];\n if (held.length > 0) {\n streams[stream] = held.filter((h) => h.crumb.timestamp >= cutoff);\n }\n }\n }\n\n return {\n add(crumb: Breadcrumb): void {\n let entry: Breadcrumb | null = crumb;\n if (beforeBreadcrumb) {\n try {\n entry = beforeBreadcrumb(crumb);\n } catch {\n // A throwing filter must never break capture; keep the (already\n // masked) crumb rather than silently erasing the trace.\n entry = crumb;\n }\n }\n if (!entry) return;\n // Stamp a stable id + high-res mono (and an epoch timestamp if absent) so\n // every entry orders and cross-links exactly, whatever stream it lands in.\n const stamped: Breadcrumb = {\n ...entry,\n id: entry.id ?? nextId(),\n timestamp: typeof entry.timestamp === \"number\" ? entry.timestamp : now(),\n mono: typeof entry.mono === \"number\" ? entry.mono : mono(),\n };\n const stream = streamOf(stamped.category);\n streams[stream].push({ crumb: stamped, seq: seq++ });\n // Age-prune every stream first (it may reassign the array), then trim this\n // stream to its own budget — a flood here never evicts another stream.\n pruneByAge();\n const held = streams[stream];\n const budget = budgets[stream];\n if (held.length > budget) {\n streams[stream] =\n stream === \"console\"\n ? trimConsoleStream(held, budget)\n : held.slice(-budget);\n }\n },\n snapshot(): Breadcrumb[] {\n pruneByAge();\n const merged: HeldCrumb[] = [];\n for (const stream of STREAMS) merged.push(...streams[stream]);\n // Order in time by the high-res mono clock (every entry has one), with the\n // insertion sequence as a stable tiebreak so equal clocks never scramble.\n merged.sort((a, b) => {\n const am =\n typeof a.crumb.mono === \"number\" ? a.crumb.mono : a.crumb.timestamp;\n const bm =\n typeof b.crumb.mono === \"number\" ? b.crumb.mono : b.crumb.timestamp;\n return am - bm || a.seq - b.seq;\n });\n return merged.map((h) => h.crumb);\n },\n clear(): void {\n streams.network = [];\n streams.console = [];\n streams.breadcrumbs = [];\n seq = 0;\n },\n };\n}\n\n// --- Pure crumb builders -----------------------------------------------------\n\n/** Longest crumb message kept; a huge log line is truncated, never dropped. */\nconst MAX_MESSAGE_LENGTH = 300;\n\n/**\n * Longest scrubbed URL kept on a crumb (spec #122 §F): capped at assembly so an\n * over-long URL is truncated, never dropped and never allowed to bloat a report.\n */\nexport const MAX_URL_LENGTH = 2048;\n\n/**\n * Structured console argument caps (spec #122 §C/§F), all applied **at assembly** so a\n * single console crumb can never bloat a report:\n * - {@link MAX_ARG_DEPTH} bounds how deep a `json` argument is cloned (deeper nodes\n * collapse to an `[Object]`/`[Array]` marker);\n * - {@link MAX_ARG_ITEMS} bounds how many keys/elements are kept at each level;\n * - {@link MAX_ARG_STRING_LENGTH} truncates a single over-long string value;\n * - {@link MAX_CONSOLE_ARGS_BYTES} bounds the serialized size of the whole args array\n * (trailing args are dropped to fit), kept well under ingest's per-entry byte cap.\n */\nexport const MAX_ARG_DEPTH = 4;\nexport const MAX_ARG_ITEMS = 100;\nexport const MAX_ARG_STRING_LENGTH = 1024;\nexport const MAX_CONSOLE_ARGS_BYTES = 4096;\n\n/** Longest Error `stack` kept on a structured `error` arg, truncated never dropped. */\nconst MAX_ERROR_STACK_LENGTH = 2048;\n\n/** Truncate a string to `max` with an ellipsis marker; keeps the value, never drops it. */\nfunction capLength(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}…` : value;\n}\n\nfunction stringifyArg(arg: unknown): string {\n if (typeof arg === \"string\") return arg;\n if (arg instanceof Error) return `${arg.name}: ${arg.message}`;\n if (arg === null || arg === undefined) return String(arg);\n if (typeof arg === \"number\" || typeof arg === \"boolean\") return String(arg);\n try {\n return JSON.stringify(arg) ?? String(arg);\n } catch {\n return \"[object]\";\n }\n}\n\nfunction joinArgs(args: readonly unknown[]): string {\n const text = args.map(stringifyArg).join(\" \");\n return text.length > MAX_MESSAGE_LENGTH\n ? `${text.slice(0, MAX_MESSAGE_LENGTH)}…`\n : text;\n}\n\n/** An Error rendered to a structured, size-capped `{ name, message, stack? }`. */\nfunction describeErrorValue(error: Error): {\n name: string;\n message: string;\n stack?: string;\n} {\n const out: { name: string; message: string; stack?: string } = {\n name: error.name || \"Error\",\n message: capLength(String(error.message ?? \"\"), MAX_ARG_STRING_LENGTH),\n };\n if (typeof error.stack === \"string\" && error.stack.length > 0) {\n out.stack = capLength(error.stack, MAX_ERROR_STACK_LENGTH);\n }\n return out;\n}\n\n/**\n * Build a JSON-safe, depth-/breadth-/string-capped clone of a value for a `json`\n * console argument. Beyond {@link MAX_ARG_DEPTH} the node collapses to a marker;\n * at each level at most {@link MAX_ARG_ITEMS} keys/elements are kept; strings are\n * truncated to {@link MAX_ARG_STRING_LENGTH}; circular references become\n * `\"[Circular]\"`; and exotic values (bigint / symbol / function / undefined) are\n * rendered to safe text — so the result is always serializable and bounded.\n */\nfunction safeCloneValue(\n value: unknown,\n depth: number,\n seen: Set<object>,\n): unknown {\n if (value === null) return null;\n const type = typeof value;\n if (type === \"string\") return capLength(value as string, MAX_ARG_STRING_LENGTH);\n if (type === \"number\") return Number.isFinite(value as number) ? value : String(value);\n if (type === \"boolean\") return value;\n if (type === \"bigint\") return `${(value as bigint).toString()}n`;\n if (type === \"symbol\") return (value as symbol).toString();\n if (type === \"function\") return \"[Function]\";\n if (type === \"undefined\") return null;\n const obj = value as object;\n if (value instanceof Error) {\n const { name, message } = describeErrorValue(value);\n return { name, message };\n }\n if (seen.has(obj)) return \"[Circular]\";\n if (depth <= 0) return Array.isArray(value) ? \"[Array]\" : \"[Object]\";\n seen.add(obj);\n try {\n if (Array.isArray(value)) {\n const items = value\n .slice(0, MAX_ARG_ITEMS)\n .map((item) => safeCloneValue(item, depth - 1, seen));\n if (value.length > MAX_ARG_ITEMS) {\n items.push(`… ${value.length - MAX_ARG_ITEMS} more`);\n }\n return items;\n }\n const source = value as Record<string, unknown>;\n const keys = Object.keys(source);\n const out: Record<string, unknown> = {};\n for (const key of keys.slice(0, MAX_ARG_ITEMS)) {\n const child = source[key];\n // Undefined / function values JSON drops anyway — omit them for a clean clone.\n if (typeof child === \"undefined\" || typeof child === \"function\") continue;\n out[key] = safeCloneValue(child, depth - 1, seen);\n }\n if (keys.length > MAX_ARG_ITEMS) out[\"…\"] = `${keys.length - MAX_ARG_ITEMS} more`;\n return out;\n } finally {\n seen.delete(obj);\n }\n}\n\n/** Classify one console argument into a type-tagged {@link ConsoleArg} (spec #122 §C). */\nexport function toConsoleArg(value: unknown): ConsoleArg {\n if (value === null || value === undefined) return { t: \"null\", v: null };\n const type = typeof value;\n if (type === \"string\") {\n return { t: \"string\", v: capLength(value as string, MAX_ARG_STRING_LENGTH) };\n }\n if (type === \"number\") {\n return Number.isFinite(value as number)\n ? { t: \"number\", v: value }\n : { t: \"string\", v: String(value) };\n }\n if (type === \"boolean\") return { t: \"bool\", v: value };\n if (type === \"bigint\") return { t: \"string\", v: `${(value as bigint).toString()}n` };\n if (type === \"symbol\") return { t: \"string\", v: (value as symbol).toString() };\n if (type === \"function\") return { t: \"string\", v: \"[Function]\" };\n if (value instanceof Error) return { t: \"error\", v: describeErrorValue(value) };\n return { t: \"json\", v: safeCloneValue(value, MAX_ARG_DEPTH, new Set()) };\n}\n\n/** The serialized UTF-8 byte length of a value; `Infinity` when it cannot serialize. */\nfunction serializedBytes(value: unknown): number {\n try {\n const json = JSON.stringify(value) ?? \"\";\n return typeof TextEncoder !== \"undefined\"\n ? new TextEncoder().encode(json).length\n : json.length;\n } catch {\n return Number.POSITIVE_INFINITY;\n }\n}\n\n/**\n * Cap an entry's structured args to {@link MAX_CONSOLE_ARGS_BYTES} (spec #122 §F):\n * drop trailing args until the array fits, keeping the earliest (usually the format\n * string / main message); if even a single arg is over budget, keep one honest\n * placeholder rather than an unbounded value. Per-arg depth/breadth/string caps bound\n * most cases already — this is the whole-entry backstop.\n */\nfunction capConsoleArgs(args: ConsoleArg[]): ConsoleArg[] {\n if (serializedBytes(args) <= MAX_CONSOLE_ARGS_BYTES) return args;\n let out = args.slice();\n while (out.length > 1 && serializedBytes(out) > MAX_CONSOLE_ARGS_BYTES) {\n out = out.slice(0, -1);\n }\n if (out.length === 1 && serializedBytes(out) > MAX_CONSOLE_ARGS_BYTES) {\n return [{ t: \"string\", v: \"[trace: console argument omitted (too large)]\" }];\n }\n return out;\n}\n\n/**\n * A `console` crumb from a captured call's level and arguments (spec #122 §C). The\n * `message` is the one-line preview (flattened, truncated); `args` preserves each\n * argument as a structured, type-tagged, size-capped value so the Console tab can\n * render objects/errors expandably; `source` is the best-effort `file:line`, attached\n * only when the stack yielded one. Args are omitted entirely for a no-argument call.\n */\nexport function consoleCrumb(\n level: BreadcrumbLevel,\n args: readonly unknown[],\n timestamp: number,\n source?: SourceLocation,\n): Breadcrumb {\n const structured = capConsoleArgs(args.map(toConsoleArg));\n const crumb: Breadcrumb = {\n category: \"console\",\n level,\n message: joinArgs(args),\n timestamp,\n ...(structured.length > 0 ? { args: structured } : {}),\n ...(source ? { source } : {}),\n };\n return crumb;\n}\n\n/** A `navigation` crumb; both URLs are scrubbed and length-capped as the crumb is built. */\nexport function navigationCrumb(\n from: string,\n to: string,\n timestamp: number,\n): Breadcrumb {\n const fromUrl = capLength(scrubUrl(from), MAX_URL_LENGTH);\n const toUrl = capLength(scrubUrl(to), MAX_URL_LENGTH);\n return {\n category: \"navigation\",\n message: `${fromUrl} → ${toUrl}`,\n timestamp,\n data: { from: fromUrl, to: toUrl },\n };\n}\n\n/**\n * Classify an HTTP status into a {@link NetworkOutcome} (spec #122 §D). A missing or\n * `0` status is a `network-error` (a request that never got a response); otherwise\n * the 4xx/5xx classes flag failures and everything else is `ok`. Used both as the\n * fallback outcome and by the thin {@link fetchCrumb} / {@link xhrCrumb} builders.\n */\nexport function outcomeFromStatus(status: number | undefined): NetworkOutcome {\n if (typeof status !== \"number\" || status <= 0) return \"network-error\";\n if (status >= 500) return \"http-5xx\";\n if (status >= 400) return \"http-4xx\";\n return \"ok\";\n}\n\n/**\n * The trivially-known byte size of a request body (spec #122 §D) — a string's UTF-8\n * length, a `Blob`'s `.size`, or an `ArrayBuffer`/typed-array `.byteLength`. Anything\n * that would require **reading** the body (a `ReadableStream`, `FormData`, a `Request`\n * with a stream body) returns `undefined` — the \"never read the body\" line holds.\n */\nexport function trivialBodySize(body: unknown): number | undefined {\n if (typeof body === \"string\") return utf8ByteLength(body);\n if (typeof Blob !== \"undefined\" && body instanceof Blob) return body.size;\n if (typeof ArrayBuffer !== \"undefined\") {\n if (body instanceof ArrayBuffer) return body.byteLength;\n if (ArrayBuffer.isView(body)) return (body as ArrayBufferView).byteLength;\n }\n return undefined;\n}\n\nfunction utf8ByteLength(value: string): number {\n try {\n return typeof TextEncoder !== \"undefined\"\n ? new TextEncoder().encode(value).length\n : value.length;\n } catch {\n return value.length;\n }\n}\n\n/** Parse a `content-length` header into a non-negative byte count, or `undefined`. */\nexport function parseContentLength(value: string | null | undefined): number | undefined {\n if (typeof value !== \"string\") return undefined;\n const bytes = Number.parseInt(value, 10);\n return Number.isFinite(bytes) && bytes >= 0 ? bytes : undefined;\n}\n\n/** The media type from a `content-type` header (the part before any `;` parameters). */\nexport function contentTypeOf(value: string | null | undefined): string | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n const media = value.split(\";\")[0]?.trim();\n return media && media.length > 0 ? media : undefined;\n}\n\n/** The rich metadata a network crumb records (spec #122 §D) — never a body or header. */\nexport interface NetworkCrumbInput {\n readonly api: NetworkApi;\n readonly method: string;\n /** The raw request URL — scrubbed (query dropped, path PII redacted) as the crumb is built. */\n readonly url: string;\n readonly status?: number;\n readonly statusText?: string;\n readonly durationMs?: number;\n readonly reqSize?: number;\n readonly respSize?: number;\n readonly contentType?: string;\n readonly outcome: NetworkOutcome;\n}\n\n/**\n * A network crumb (`fetch` / `xhr` / `beacon`) with the rich, metadata-only fields\n * the Network tab renders (spec #122 §D, ticket #139): api, method, scrubbed URL,\n * status + statusText, duration, request/response sizes, content type, and a failure\n * outcome. The URL is scrubbed and length-capped at assembly. The shape has **no field\n * for a request/response body or an arbitrary header**, so neither can ever be\n * recorded; only a positive status, and fields that were actually supplied, ride along.\n */\nexport function networkCrumb(input: NetworkCrumbInput, timestamp: number): Breadcrumb {\n const url = capLength(scrubUrl(input.url), MAX_URL_LENGTH);\n const hasStatus = typeof input.status === \"number\" && input.status > 0;\n const statusPart = hasStatus ? ` → ${input.status}` : \"\";\n const outcomePart = input.outcome !== \"ok\" ? ` (${input.outcome})` : \"\";\n return {\n category: input.api,\n api: input.api,\n method: input.method,\n url,\n message: `${input.method} ${url}${statusPart}${outcomePart}`,\n timestamp,\n ...(hasStatus ? { status: input.status } : {}),\n ...(input.statusText ? { statusText: input.statusText } : {}),\n ...(typeof input.durationMs === \"number\" ? { durationMs: input.durationMs } : {}),\n ...(typeof input.reqSize === \"number\" ? { reqSize: input.reqSize } : {}),\n ...(typeof input.respSize === \"number\" ? { respSize: input.respSize } : {}),\n ...(input.contentType ? { contentType: input.contentType } : {}),\n outcome: input.outcome,\n };\n}\n\n/**\n * A thin `fetch` crumb from method + URL + status (outcome derived from the status).\n * The instrumentation uses {@link networkCrumb} directly to carry the full metadata;\n * this convenience builder seeds a network crumb from a status alone.\n */\nexport function fetchCrumb(\n method: string,\n url: string,\n status: number | undefined,\n timestamp: number,\n): Breadcrumb {\n return networkCrumb(\n { api: \"fetch\", method, url, status, outcome: outcomeFromStatus(status) },\n timestamp,\n );\n}\n\n/** A thin `xhr` crumb from method + URL + status (outcome derived from the status). */\nexport function xhrCrumb(\n method: string,\n url: string,\n status: number | undefined,\n timestamp: number,\n): Breadcrumb {\n return networkCrumb(\n { api: \"xhr\", method, url, status, outcome: outcomeFromStatus(status) },\n timestamp,\n );\n}\n\nfunction safeSelector(target: Element): string {\n try {\n return cssSelectorFor(target);\n } catch {\n return target.tagName ? target.tagName.toLowerCase() : \"unknown\";\n }\n}\n\n/** A `ui.click` crumb: a masked target selector only — no text or value. */\nexport function clickCrumb(target: Element, timestamp: number): Breadcrumb {\n const selector = safeSelector(target);\n return {\n category: \"ui.click\",\n message: `click ${selector}`,\n timestamp,\n data: { target: selector },\n };\n}\n\n/**\n * A `ui.input` crumb: records **that** an input changed and which field, never\n * the value typed into it. The `target` element's `.value` is never read.\n */\nexport function inputCrumb(target: Element, timestamp: number): Breadcrumb {\n const selector = safeSelector(target);\n return {\n category: \"ui.input\",\n message: `input ${selector}`,\n timestamp,\n data: { target: selector },\n };\n}\n\nfunction describeError(error: unknown): { name: string; message: string } {\n if (error instanceof Error) {\n return { name: error.name || \"Error\", message: error.message };\n }\n if (typeof error === \"string\") return { name: \"Error\", message: error };\n return { name: \"Error\", message: stringifyArg(error) };\n}\n\n/**\n * An `error` crumb for the failing exception or rejection that ends the trace. When\n * `causedBy` is given (an auto-captured error), it rides on the crumb as the causal\n * pointer to the ids of the entries immediately preceding the throw (spec #122 §F).\n */\nexport function errorCrumb(\n error: unknown,\n timestamp: number,\n causedBy?: readonly string[],\n): Breadcrumb {\n const { name, message } = describeError(error);\n const crumb: Breadcrumb = {\n category: \"error\",\n level: \"error\",\n message: message ? `${name}: ${message}` : name,\n timestamp,\n data: { errorType: name },\n };\n return causedBy && causedBy.length > 0 ? { ...crumb, causedBy } : crumb;\n}\n\n// --- Instrumentation ---------------------------------------------------------\n\n/** Detaches an installed instrumentation, restoring the original behaviour. */\nexport type Teardown = () => void;\n\ntype AnyFn = (...args: unknown[]) => unknown;\ntype ConsoleLike = Partial<Record<BreadcrumbLevel, AnyFn>>;\ntype FetchFn = (\n input: string | URL | Request,\n init?: RequestInit,\n) => Promise<Response>;\n\ninterface HistoryLike {\n pushState(data: unknown, unused: string, url?: string | URL | null): void;\n replaceState(data: unknown, unused: string, url?: string | URL | null): void;\n}\n\ninterface XhrInstance {\n status: number;\n statusText?: string;\n open(method: string, url: string | URL, ...rest: unknown[]): void;\n send(body?: unknown): void;\n getResponseHeader?(name: string): string | null;\n addEventListener(type: string, listener: () => void): void;\n removeEventListener(type: string, listener: () => void): void;\n}\ninterface XhrConstructor {\n new (): XhrInstance;\n prototype: XhrInstance;\n}\n\n/** The `navigator.sendBeacon` surface the beacon instrumentation wraps. */\nexport interface BeaconNavigator {\n sendBeacon?: (url: string | URL, data?: BodyInit | null) => boolean;\n}\n\n/** The structural window surface the instrumentation reaches into. */\nexport interface InstrumentWindow {\n fetch?: FetchFn;\n history?: HistoryLike;\n location?: { href: string };\n XMLHttpRequest?: XhrConstructor;\n navigator?: BeaconNavigator;\n addEventListener(\n type: string,\n listener: (event: Event) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n removeEventListener(\n type: string,\n listener: (event: Event) => void,\n options?: boolean | EventListenerOptions,\n ): void;\n}\n\n/** Options for {@link instrumentBreadcrumbs} and the individual installers. */\nexport interface InstrumentOptions {\n readonly win?: InstrumentWindow;\n readonly doc?: Document;\n readonly consoleObj?: ConsoleLike;\n readonly consoleLevels?: readonly BreadcrumbLevel[];\n /** Skip URLs (e.g. the SDK's own ingest calls) so they never become crumbs. */\n readonly ignoreUrl?: (url: string) => boolean;\n readonly now?: () => number;\n /**\n * High-res monotonic clock (spec #122 §D) — used to measure a request's duration as\n * a delta around the wrapped call. Defaults to `performance.now`; injectable for tests.\n */\n readonly mono?: () => number;\n /**\n * Whether to instrument the **console** stream (spec #122 §L; ticket #138).\n * Defaults to `true`; pass `false` and `console` is never wrapped, so no console\n * entry is ever recorded — the per-project toggle stops the stream at its source.\n */\n readonly captureConsole?: boolean;\n /**\n * Whether to instrument the **network** stream — `fetch` and `XHR` (spec #122 §L;\n * ticket #138). Defaults to `true`; pass `false` and neither is wrapped, so no\n * network entry is ever recorded. Navigation and masked UI events are unaffected.\n */\n readonly captureNetwork?: boolean;\n}\n\nfunction noop(): void {\n /* nothing installed */\n}\n\n/**\n * Parse a single stack line into a `{ file, line }` location, or `undefined`. Handles\n * V8 (`at fn (file:line:col)` / `at file:line:col`) and Firefox/Safari (`fn@file:line:col`)\n * frames; a query string on the asset URL is dropped (a cache-buster, or defensively a\n * token) both for parse safety and privacy.\n */\nfunction parseStackFrame(line: string): SourceLocation | undefined {\n let loc: string | undefined;\n const v8Named = line.match(/^at\\s+.+?\\s+\\((.+)\\)$/);\n if (v8Named) {\n loc = v8Named[1];\n } else {\n const v8Bare = line.match(/^at\\s+(.+)$/);\n if (v8Bare) {\n loc = v8Bare[1];\n } else {\n const at = line.indexOf(\"@\");\n if (at >= 0) loc = line.slice(at + 1);\n }\n }\n if (!loc) return undefined;\n loc = loc.replace(/\\?[^:]*/, \"\");\n const m = loc.match(/^(.*):(\\d+):\\d+$/) ?? loc.match(/^(.*):(\\d+)$/);\n if (!m) return undefined;\n const file = m[1] ?? \"\";\n const lineNo = Number(m[2]);\n if (!file || !Number.isFinite(lineNo)) return undefined;\n return { file, line: lineNo };\n}\n\n/**\n * The best-effort `file:line` a console call was made from (spec #122 §C). Parses the\n * frames of a stack, skipping `skipFrames` leading (SDK-internal) frames so the source\n * points at the host code that called `console.*`. Returns `undefined` when no frame\n * yields a usable location — the crumb then simply omits `source`.\n */\nexport function sourceFromStack(\n stack: string | undefined,\n skipFrames = 0,\n): SourceLocation | undefined {\n if (typeof stack !== \"string\" || stack.length === 0) return undefined;\n const frames: SourceLocation[] = [];\n for (const raw of stack.split(\"\\n\")) {\n const frame = parseStackFrame(raw.trim());\n if (frame) frames.push(frame);\n }\n return frames[skipFrames];\n}\n\n/**\n * Frames between `new Error()` (created inside the console wrapper) and the host caller:\n * just the wrapper frame itself. Skipping it points {@link sourceFromStack} at the app\n * code. The wrapper is called through the console object's property, so it is not a\n * direct-call inlining candidate — keeping this skip count stable.\n */\nconst CONSOLE_SOURCE_SKIP_FRAMES = 1;\n\n/** Wrap `console` methods so calls at the captured levels become crumbs. */\nexport function instrumentConsole(\n buffer: BreadcrumbBuffer,\n consoleObj: ConsoleLike,\n levels: readonly BreadcrumbLevel[],\n now: () => number,\n): Teardown {\n const restores: Teardown[] = [];\n for (const level of levels) {\n const original = consoleObj[level];\n if (typeof original !== \"function\") continue;\n // Decide once per level — not once per call — whether this level pays the\n // source-capture cost. Only the levels that matter for debugging construct a\n // `new Error()` to read the call site; the chatty log/info/debug skip it entirely\n // so a tight logging loop stays cheap (ticket #159; see SOURCE_CAPTURE_LEVELS).\n const withSource = capturesSource(level);\n const wrapper = (...args: unknown[]): unknown => {\n // Capture the call site before anything else so the wrapper is the top frame —\n // but only for the levels that keep a source (the hot-page budget, ticket #159).\n let source: SourceLocation | undefined;\n if (withSource) {\n try {\n source = sourceFromStack(new Error().stack, CONSOLE_SOURCE_SKIP_FRAMES);\n } catch {\n source = undefined;\n }\n }\n try {\n if (level === \"assert\") {\n // console.assert records only when the asserted condition is falsy.\n if (!args[0]) {\n buffer.add(consoleCrumb(\"assert\", args.slice(1), now(), source));\n }\n } else {\n buffer.add(consoleCrumb(level, args, now(), source));\n }\n } catch {\n // Capture must never throw into the host page.\n }\n return original.apply(consoleObj, args);\n };\n consoleObj[level] = wrapper;\n restores.push(() => {\n consoleObj[level] = original;\n });\n }\n return () => {\n for (const restore of restores) restore();\n };\n}\n\nfunction requestUrl(input: string | URL | Request): string {\n if (typeof input === \"string\") return input;\n if (input instanceof URL) return input.toString();\n return input.url;\n}\n\nfunction requestMethod(\n input: string | URL | Request,\n init: RequestInit | undefined,\n): string {\n const method =\n init?.method ??\n (typeof input === \"object\" && \"method\" in input ? input.method : undefined) ??\n \"GET\";\n return method.toUpperCase();\n}\n\n/** Read one response header defensively — `null` on an opaque response or any throw. */\nfunction safeResponseHeader(response: Response, name: string): string | null {\n try {\n return response.headers?.get?.(name) ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Classify a settled `fetch` response into a {@link NetworkOutcome} (spec #122 §D). An\n * opaque cross-origin response (status masked to `0`) is `opaque-cors`; otherwise the\n * outcome follows the HTTP status.\n */\nfunction classifyFetchResponse(response: Response): NetworkOutcome {\n if (response.type === \"opaque\" || response.type === \"opaqueredirect\") {\n return \"opaque-cors\";\n }\n return outcomeFromStatus(response.status);\n}\n\n/**\n * Classify a rejected `fetch` into a {@link NetworkOutcome} (spec #122 §D) by the\n * error's name: an `AbortError` is `aborted`, a `TimeoutError` (an `AbortSignal.timeout`)\n * is `timeout`, and anything else is a plain `network-error`.\n */\nfunction classifyFetchError(error: unknown): NetworkOutcome {\n const name =\n typeof error === \"object\" && error !== null && \"name\" in error\n ? String((error as { name?: unknown }).name)\n : \"\";\n if (name === \"AbortError\") return \"aborted\";\n if (name === \"TimeoutError\") return \"timeout\";\n return \"network-error\";\n}\n\n/**\n * Wrap `fetch` to record a rich network crumb on settlement (spec #122 §D, ticket\n * #139): method, scrubbed URL, status + statusText, a `performance.now()` duration,\n * request size (only when the body is trivially sized), response size (from the\n * `content-length` header only), content type, and a failure outcome. The **original**\n * outcome is returned untouched — the response is passed through **without its body\n * being read** (only two metadata headers are inspected), and a rejection is re-thrown\n * so the caller's `unhandledrejection` semantics are preserved.\n */\nexport function instrumentFetch(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n ignoreUrl: (url: string) => boolean,\n now: () => number,\n mono: () => number = defaultMono,\n): Teardown {\n const original = win.fetch;\n if (typeof original !== \"function\") return noop;\n const wrapper: FetchFn = (\n input: string | URL | Request,\n init?: RequestInit,\n ): Promise<Response> => {\n const url = requestUrl(input);\n const method = requestMethod(input, init);\n // Size only a body passed literally in `init` — never a `Request`'s stream body.\n const reqSize = trivialBodySize(init?.body);\n const started = mono();\n // Native `fetch` must run against the window, so bind the receiver rather\n // than forward whatever `this` a free call carries.\n const promise = original.call(win, input, init);\n if (ignoreUrl(url)) return promise;\n return promise.then(\n (response) => {\n try {\n buffer.add(\n networkCrumb(\n {\n api: \"fetch\",\n method,\n url,\n status: response.status || undefined,\n statusText: response.statusText || undefined,\n durationMs: Math.max(0, mono() - started),\n reqSize,\n respSize: parseContentLength(\n safeResponseHeader(response, \"content-length\"),\n ),\n contentType: contentTypeOf(\n safeResponseHeader(response, \"content-type\"),\n ),\n outcome: classifyFetchResponse(response),\n },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n return response;\n },\n (error: unknown) => {\n try {\n buffer.add(\n networkCrumb(\n {\n api: \"fetch\",\n method,\n url,\n durationMs: Math.max(0, mono() - started),\n reqSize,\n outcome: classifyFetchError(error),\n },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n throw error;\n },\n );\n };\n win.fetch = wrapper;\n return () => {\n win.fetch = original;\n };\n}\n\ninterface XhrMeta {\n __fixbackMeta?: { method: string; url: string };\n}\n\n/** Read one XHR response header defensively — `null` when unavailable or on any throw. */\nfunction safeXhrHeader(xhr: XhrInstance, name: string): string | null {\n try {\n return typeof xhr.getResponseHeader === \"function\"\n ? xhr.getResponseHeader(name)\n : null;\n } catch {\n return null;\n }\n}\n\n/** Read an XHR's `statusText` defensively — `undefined` when empty or on any throw. */\nfunction safeXhrStatusText(xhr: XhrInstance): string | undefined {\n try {\n return xhr.statusText || undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Patch `XMLHttpRequest` to record a rich network crumb when a request settles (spec\n * #122 §D, ticket #139): method, scrubbed URL, status + statusText, a `performance.now()`\n * duration, request size (only when the body is trivially sized), response size (from\n * the `content-length` header only), content type, and a failure outcome distinguished\n * by which terminal event fired (`error` / `timeout` / `abort` / `load`). The `send`\n * body argument is **never read for content** — only its trivially-known size — so a body\n * can never reach the buffer.\n */\nexport function instrumentXhr(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n ignoreUrl: (url: string) => boolean,\n now: () => number,\n mono: () => number = defaultMono,\n): Teardown {\n const ctor = win.XMLHttpRequest;\n if (typeof ctor !== \"function\") return noop;\n const proto = ctor.prototype;\n const originalOpen = proto.open;\n const originalSend = proto.send;\n\n proto.open = function (\n this: XhrInstance & XhrMeta,\n method: string,\n url: string | URL,\n ...rest: unknown[]\n ): void {\n this.__fixbackMeta = { method: String(method).toUpperCase(), url: String(url) };\n return originalOpen.call(this, method, url, ...rest);\n };\n\n proto.send = function (this: XhrInstance & XhrMeta, body?: unknown): void {\n const meta = this.__fixbackMeta;\n if (meta && !ignoreUrl(meta.url)) {\n const started = mono();\n const reqSize = trivialBodySize(body);\n // The terminal event names the outcome; `loadend` always follows exactly one of\n // load/error/timeout/abort, so by the time we record, `settled` is set.\n let settled: NetworkOutcome | undefined;\n const onLoad = (): void => {\n settled = outcomeFromStatus(this.status || undefined);\n };\n const onError = (): void => {\n settled = \"network-error\";\n };\n const onTimeout = (): void => {\n settled = \"timeout\";\n };\n const onAbort = (): void => {\n settled = \"aborted\";\n };\n // An arrow captures the request instance as `this` without aliasing it.\n const onDone = (): void => {\n try {\n buffer.add(\n networkCrumb(\n {\n api: \"xhr\",\n method: meta.method,\n url: meta.url,\n status: this.status || undefined,\n statusText: safeXhrStatusText(this),\n durationMs: Math.max(0, mono() - started),\n reqSize,\n respSize: parseContentLength(safeXhrHeader(this, \"content-length\")),\n contentType: contentTypeOf(safeXhrHeader(this, \"content-type\")),\n outcome: settled ?? outcomeFromStatus(this.status || undefined),\n },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n this.removeEventListener(\"load\", onLoad);\n this.removeEventListener(\"error\", onError);\n this.removeEventListener(\"timeout\", onTimeout);\n this.removeEventListener(\"abort\", onAbort);\n this.removeEventListener(\"loadend\", onDone);\n };\n this.addEventListener(\"load\", onLoad);\n this.addEventListener(\"error\", onError);\n this.addEventListener(\"timeout\", onTimeout);\n this.addEventListener(\"abort\", onAbort);\n this.addEventListener(\"loadend\", onDone);\n }\n return originalSend.call(this, body);\n };\n\n return () => {\n proto.open = originalOpen;\n proto.send = originalSend;\n };\n}\n\n/**\n * Wrap `navigator.sendBeacon` to record a network crumb for each beacon (spec #122 §D,\n * ticket #139). `sendBeacon` is fire-and-forget with a **synchronous boolean** return —\n * `true` when the user agent queued the beacon, `false` when it declined — so wrapping\n * must return that boolean unchanged: the original is called first and its result both\n * classifies the crumb (`ok` / `network-error`) and is returned to the caller. Only the\n * URL and the trivially-known request size are recorded (no response exists to read);\n * capture failure is swallowed and the boolean still returned, and if the original itself\n * throws we record best-effort and re-throw so the contract is preserved exactly.\n */\nexport function instrumentBeacon(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n ignoreUrl: (url: string) => boolean,\n now: () => number,\n): Teardown {\n const nav = win.navigator;\n if (!nav || typeof nav.sendBeacon !== \"function\") return noop;\n const original = nav.sendBeacon;\n const record = (url: string, data: unknown, outcome: NetworkOutcome): void => {\n if (ignoreUrl(url)) return;\n try {\n buffer.add(\n networkCrumb(\n { api: \"beacon\", method: \"POST\", url, reqSize: trivialBodySize(data), outcome },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n };\n const wrapper = function (url: string | URL, data?: BodyInit | null): boolean {\n const target = typeof url === \"string\" ? url : String(url);\n let queued: boolean;\n try {\n queued = original.call(nav, url, data);\n } catch (error) {\n // The original threw: record a best-effort failure, then preserve semantics.\n record(target, data, \"network-error\");\n throw error;\n }\n record(target, data, queued ? \"ok\" : \"network-error\");\n return queued;\n };\n nav.sendBeacon = wrapper;\n return () => {\n nav.sendBeacon = original;\n };\n}\n\n/** Record a `navigation` crumb on `pushState`/`replaceState`/pop/hash changes. */\nexport function instrumentNavigation(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n now: () => number,\n): Teardown {\n const history = win.history;\n const location = win.location;\n if (!history || !location) return noop;\n\n let last = location.href;\n const record = (to: string): void => {\n try {\n buffer.add(navigationCrumb(last, to, now()));\n } catch {\n /* never throw into the host page */\n }\n last = to;\n };\n\n const originalPush = history.pushState;\n const originalReplace = history.replaceState;\n\n history.pushState = function (\n this: HistoryLike,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n const result = originalPush.call(this, data, unused, url);\n record(location.href);\n return result;\n };\n history.replaceState = function (\n this: HistoryLike,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n const result = originalReplace.call(this, data, unused, url);\n record(location.href);\n return result;\n };\n\n const onPopState = (): void => record(location.href);\n const onHashChange = (): void => record(location.href);\n win.addEventListener(\"popstate\", onPopState);\n win.addEventListener(\"hashchange\", onHashChange);\n\n return () => {\n history.pushState = originalPush;\n history.replaceState = originalReplace;\n win.removeEventListener(\"popstate\", onPopState);\n win.removeEventListener(\"hashchange\", onHashChange);\n };\n}\n\nfunction eventTargetElement(event: Event): Element | null {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n const deepest = path[0] ?? event.target;\n return deepest instanceof Element ? deepest : null;\n}\n\n/** Listen (capture-phase) for clicks and input changes as masked crumbs. */\nexport function instrumentUiEvents(\n buffer: BreadcrumbBuffer,\n doc: Document,\n now: () => number,\n): Teardown {\n const onClick = (event: Event): void => {\n const target = eventTargetElement(event);\n if (!target || isFixbackNode(target)) return;\n try {\n buffer.add(clickCrumb(target, now()));\n } catch {\n /* never throw into the host page */\n }\n };\n const onInput = (event: Event): void => {\n const target = eventTargetElement(event);\n if (!target || isFixbackNode(target)) return;\n try {\n buffer.add(inputCrumb(target, now()));\n } catch {\n /* never throw into the host page */\n }\n };\n doc.addEventListener(\"click\", onClick, true);\n doc.addEventListener(\"input\", onInput, true);\n return () => {\n doc.removeEventListener(\"click\", onClick, true);\n doc.removeEventListener(\"input\", onInput, true);\n };\n}\n\n/**\n * Install every capture hook onto a window/document and return a single teardown\n * that removes them all. Each hook is independent and defensive: a failure in one\n * never blocks the others, and none can throw into the host page.\n */\nexport function instrumentBreadcrumbs(\n buffer: BreadcrumbBuffer,\n options: InstrumentOptions = {},\n): Teardown {\n const win =\n options.win ?? (globalThis as unknown as InstrumentWindow | undefined);\n const doc =\n options.doc ??\n (typeof document !== \"undefined\" ? document : undefined);\n const consoleObj =\n options.consoleObj ??\n (typeof console !== \"undefined\"\n ? (console as unknown as ConsoleLike)\n : undefined);\n const levels = options.consoleLevels ?? DEFAULT_CONSOLE_LEVELS;\n const ignoreUrl = options.ignoreUrl ?? (() => false);\n const now = options.now ?? Date.now;\n const mono = options.mono ?? defaultMono;\n // Per-project capture toggles (#138): a stream is captured unless explicitly\n // turned off, so a boot config that omits it — or an older server — stays on.\n const captureConsole = options.captureConsole !== false;\n const captureNetwork = options.captureNetwork !== false;\n\n const teardowns: Teardown[] = [];\n if (consoleObj && captureConsole) {\n teardowns.push(instrumentConsole(buffer, consoleObj, levels, now));\n }\n if (win) {\n if (captureNetwork) {\n teardowns.push(instrumentFetch(buffer, win, ignoreUrl, now, mono));\n teardowns.push(instrumentXhr(buffer, win, ignoreUrl, now, mono));\n teardowns.push(instrumentBeacon(buffer, win, ignoreUrl, now));\n }\n teardowns.push(instrumentNavigation(buffer, win, now));\n }\n if (doc) {\n teardowns.push(instrumentUiEvents(buffer, doc, now));\n }\n\n return () => {\n for (const teardown of teardowns) {\n try {\n teardown();\n } catch {\n /* teardown is best-effort */\n }\n }\n };\n}\n","/**\n * The Annotation & vector-marks model (spec 0003 §B/§D).\n *\n * An Annotation is everything a Reporter marked on the page, as three\n * **composable, optional** layers over one full masked screenshot: the picked\n * `element` (from the element-picker), a drag-captured `region`, and vector\n * `marks` — arrow / box / pen / text. Marks live in the **screenshot's coordinate\n * space** (the full viewport the screenshot is rasterised at), never baked into\n * the PNG: the dashboard composites them at view time (#91).\n *\n * This module is the marks' single home — the pure types and geometry used by the\n * region-capture and draw controllers and by the overlay's Send assembly. Like the\n * rest of the SDK's wire types it is vendored (no `@fixback/shared` import); keep\n * `Annotation` in lock-step with the server's ingest contract (spec §D/§H).\n */\n\nimport type { SelectedElement } from \"./report\";\n\n/** A point in screenshot (viewport) coordinate space. */\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A rectangle in screenshot coordinates — the same shape as an element's rect. */\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** The draw tools the overlay offers, in toolbar order (spec §B, prototype). */\nexport type DrawTool = \"arrow\" | \"box\" | \"pen\" | \"text\";\n\n/** Fields shared by every vector mark. */\ninterface MarkBase {\n /** Stroke/fill colour, as a CSS colour string. */\n readonly color: string;\n}\n\n/** A directional arrow from `(x0,y0)` to its tip at `(x1,y1)`. */\nexport interface ArrowMark extends MarkBase {\n readonly type: \"arrow\";\n readonly x0: number;\n readonly y0: number;\n readonly x1: number;\n readonly y1: number;\n}\n\n/** A rectangle spanning the drag from `(x0,y0)` to `(x1,y1)`. */\nexport interface BoxMark extends MarkBase {\n readonly type: \"box\";\n readonly x0: number;\n readonly y0: number;\n readonly x1: number;\n readonly y1: number;\n}\n\n/** A freehand polyline through `points` (in order). */\nexport interface PenMark extends MarkBase {\n readonly type: \"pen\";\n readonly points: ReadonlyArray<Point>;\n}\n\n/** A text label anchored at `(x,y)` (its baseline-left, as SVG text). */\nexport interface TextMark extends MarkBase {\n readonly type: \"text\";\n readonly x: number;\n readonly y: number;\n readonly text: string;\n}\n\n/** A single vector mark, in screenshot coordinates. */\nexport type Mark = ArrowMark | BoxMark | PenMark | TextMark;\n\n/**\n * The structured Annotation carried on a report's content (spec §D): the three\n * optional layers. Every field is optional — a report may carry any subset or\n * none (a bare Kind + comment is a valid Send).\n */\nexport interface Annotation {\n readonly element?: SelectedElement;\n readonly region?: Rect;\n readonly marks?: ReadonlyArray<Mark>;\n}\n\n/**\n * The default mark colour — Signal's danger red, matching the frozen Reporter\n * prototype's draw layer (`docs/design/Fixback Reporter.dc.html`).\n */\nexport const MARK_COLOR = \"#e5484d\";\n\n/**\n * Normalise a drag from a start to an end point into a positive-extent rect\n * (top-left origin, non-negative width/height), rounded to whole pixels — the\n * screenshot is a pixel raster, so sub-pixel extents carry no meaning. Shared by\n * region-capture and the box mark.\n */\nexport function normalizeRect(x0: number, y0: number, x1: number, y1: number): Rect {\n return {\n x: Math.round(Math.min(x0, x1)),\n y: Math.round(Math.min(y0, y1)),\n width: Math.round(Math.abs(x1 - x0)),\n height: Math.round(Math.abs(y1 - y0)),\n };\n}\n\n/**\n * The three points of an arrow's head, given its line `(x0,y0)→(x1,y1)` and a head\n * length: the tip, then the two barbs splayed ±30° behind it. Pure geometry the\n * draw surface renders as a filled triangle at the arrow's tip.\n */\nexport function arrowHeadPoints(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n size = 14,\n): [Point, Point, Point] {\n const angle = Math.atan2(y1 - y0, x1 - x0);\n return [\n { x: x1, y: y1 },\n {\n x: x1 - size * Math.cos(angle - Math.PI / 6),\n y: y1 - size * Math.sin(angle - Math.PI / 6),\n },\n {\n x: x1 - size * Math.cos(angle + Math.PI / 6),\n y: y1 - size * Math.sin(angle + Math.PI / 6),\n },\n ];\n}\n\n/**\n * Assemble the structured Annotation from whatever a Reporter marked, dropping\n * empty layers: no element, no region, and an empty marks list are omitted, so the\n * result is `undefined` when nothing was marked. Marks are copied into a plain,\n * independent array so the annotation is a serialisable snapshot decoupled from the\n * live draw state.\n */\nexport function assembleAnnotation(parts: {\n readonly element?: SelectedElement | null;\n readonly region?: Rect | null;\n readonly marks?: ReadonlyArray<Mark> | null;\n}): Annotation | undefined {\n const annotation: {\n element?: SelectedElement;\n region?: Rect;\n marks?: ReadonlyArray<Mark>;\n } = {};\n if (parts.element) annotation.element = parts.element;\n if (parts.region) annotation.region = parts.region;\n if (parts.marks && parts.marks.length > 0) annotation.marks = parts.marks.slice();\n return Object.keys(annotation).length > 0 ? annotation : undefined;\n}\n","/**\n * The ingest **feedback** content wire-contract, vendored, plus the helpers that\n * assemble it from what a Reporter composed in the overlay.\n *\n * Like `boot.ts`, the SDK does not import `@fixback/shared`; the slice of the\n * submission shape it needs is copied here. Keep it in lock-step with the server:\n * the JSON `payload` part accepted by `POST /api/ingest/feedback`\n * (`apps/api/src/ingest/ingest.controller.ts` — `feedbackContentBody`) and the\n * `SubmissionContent` it parses (`apps/api/src/ingest/reporter-identity.ts`).\n */\n\nimport { assembleAnnotation, type Annotation, type Mark, type Rect } from \"./annotation\";\nimport type { Breadcrumb } from \"./breadcrumbs\";\n\n/** The Kind a Reporter tags a report with. Mirrors the server's `ISSUE_KINDS`. */\nexport type IssueKind = \"bug\" | \"improvement\" | \"idea\";\n\n/**\n * Where a Feedback came from — a human in the overlay (`reporter`, the default) or\n * the SDK's automatic error capture (`auto`). Mirrors the server's `FEEDBACK_SOURCES`;\n * the server derives trust independently and ignores anything else the client claims.\n */\nexport type FeedbackSource = \"reporter\" | \"auto\";\n\n/** The picked element's viewport rectangle, as the server's annotation `rect`. */\nexport interface ElementRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/**\n * The picked element — the `element` layer of an {@link Annotation}: a stable CSS\n * selector, a readable DOM path, the tag, and the bounding rect. Exactly the\n * server's annotation `element` object shape.\n */\nexport interface SelectedElement {\n readonly selector: string;\n readonly domPath: string;\n readonly tag: string;\n readonly rect: ElementRect;\n}\n\n/** The capture environment recorded alongside a report. */\nexport interface CaptureEnvironment {\n readonly viewportWidth?: number;\n readonly viewportHeight?: number;\n readonly browser?: string;\n readonly sdkVersion?: string;\n}\n\n/**\n * The JSON content of a feedback submission — the object serialised into the\n * multipart `payload` part next to the `key` and identity evidence. Every field\n * is optional: none of it feeds the server's trust decision, so a submission may\n * carry any subset. `annotation` is the structured `{ element?, region?, marks? }`\n * (spec §D); the screenshot is a separate binary part, never part of this JSON.\n */\nexport interface ReportContent {\n readonly comment?: string;\n readonly kind?: IssueKind;\n readonly url?: string;\n readonly environment?: CaptureEnvironment;\n readonly annotation?: Annotation;\n /** The masked breadcrumb trace buffer that rode on this report (spec §C). */\n readonly trace?: readonly Breadcrumb[];\n /**\n * Provenance (spec §D/§E). Omitted for a manual report — the transport stamps the\n * `reporter` default on the wire; set to `auto` by the SDK's error capture.\n */\n readonly source?: FeedbackSource;\n /** For `source: auto` only — the SDK's per-session error fingerprint (spec §E). */\n readonly errorSignature?: string;\n /** For `source: auto` only — the running occurrence count within the session (spec §E). */\n readonly occurrences?: number;\n}\n\n/**\n * What the overlay hands to {@link assembleContent} when the Reporter sends. The\n * three marking layers arrive flat (`element` / `region` / `marks`); `assembleContent`\n * folds whatever is present into the structured {@link Annotation}.\n */\nexport interface ReportDraft {\n readonly kind?: IssueKind;\n readonly comment?: string;\n readonly element?: SelectedElement;\n readonly region?: Rect;\n readonly marks?: ReadonlyArray<Mark>;\n readonly url?: string;\n readonly environment?: CaptureEnvironment;\n readonly trace?: readonly Breadcrumb[];\n}\n\n/**\n * Read the capture environment off a window: the viewport size, the browser's\n * user-agent, and the SDK version. A dimension is recorded only when it is a\n * positive number (a headless/zero viewport records nothing rather than an\n * invalid `0`, which the server would reject).\n */\nexport function collectEnvironment(\n win: Window,\n sdkVersion: string,\n): CaptureEnvironment {\n const env: {\n viewportWidth?: number;\n viewportHeight?: number;\n browser?: string;\n sdkVersion?: string;\n } = {};\n\n const width = win.innerWidth;\n if (typeof width === \"number\" && width > 0) env.viewportWidth = Math.round(width);\n const height = win.innerHeight;\n if (typeof height === \"number\" && height > 0) {\n env.viewportHeight = Math.round(height);\n }\n\n const ua = win.navigator?.userAgent;\n if (typeof ua === \"string\" && ua.length > 0) env.browser = ua;\n\n if (sdkVersion.length > 0) env.sdkVersion = sdkVersion;\n\n return env;\n}\n\n/**\n * Assemble the ingest content from what the Reporter composed. Empty pieces are\n * dropped rather than sent as blanks: a whitespace-only comment, an absent\n * element, or an empty environment are simply omitted, so the payload carries\n * only what was actually provided (mirroring the server's all-optional content).\n */\nexport function assembleContent(draft: ReportDraft): ReportContent {\n const content: {\n comment?: string;\n kind?: IssueKind;\n url?: string;\n environment?: CaptureEnvironment;\n annotation?: Annotation;\n trace?: readonly Breadcrumb[];\n } = {};\n\n if (draft.kind) content.kind = draft.kind;\n\n const comment = draft.comment?.trim();\n if (comment) content.comment = comment;\n\n if (draft.url) content.url = draft.url;\n\n if (draft.environment && Object.keys(draft.environment).length > 0) {\n content.environment = draft.environment;\n }\n\n const annotation = assembleAnnotation({\n element: draft.element,\n region: draft.region,\n marks: draft.marks,\n });\n if (annotation) content.annotation = annotation;\n\n // Only a non-empty trace rides along — an empty buffer is simply omitted.\n if (draft.trace && draft.trace.length > 0) content.trace = draft.trace;\n\n return content;\n}\n","function changeJpegDpi(uint8Array, dpi) {\n uint8Array[13] = 1;\n uint8Array[14] = dpi >> 8;\n uint8Array[15] = dpi & 255;\n uint8Array[16] = dpi >> 8;\n uint8Array[17] = dpi & 255;\n return uint8Array;\n}\n\nconst _P = \"p\".charCodeAt(0);\nconst _H = \"H\".charCodeAt(0);\nconst _Y = \"Y\".charCodeAt(0);\nconst _S = \"s\".charCodeAt(0);\nlet pngDataTable;\nfunction createPngDataTable() {\n const crcTable = new Int32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;\n }\n crcTable[n] = c;\n }\n return crcTable;\n}\nfunction calcCrc(uint8Array) {\n let c = -1;\n if (!pngDataTable)\n pngDataTable = createPngDataTable();\n for (let n = 0; n < uint8Array.length; n++) {\n c = pngDataTable[(c ^ uint8Array[n]) & 255] ^ c >>> 8;\n }\n return c ^ -1;\n}\nfunction searchStartOfPhys(uint8Array) {\n const length = uint8Array.length - 1;\n for (let i = length; i >= 4; i--) {\n if (uint8Array[i - 4] === 9 && uint8Array[i - 3] === _P && uint8Array[i - 2] === _H && uint8Array[i - 1] === _Y && uint8Array[i] === _S) {\n return i - 3;\n }\n }\n return 0;\n}\nfunction changePngDpi(uint8Array, dpi, overwritepHYs = false) {\n const physChunk = new Uint8Array(13);\n dpi *= 39.3701;\n physChunk[0] = _P;\n physChunk[1] = _H;\n physChunk[2] = _Y;\n physChunk[3] = _S;\n physChunk[4] = dpi >>> 24;\n physChunk[5] = dpi >>> 16;\n physChunk[6] = dpi >>> 8;\n physChunk[7] = dpi & 255;\n physChunk[8] = physChunk[4];\n physChunk[9] = physChunk[5];\n physChunk[10] = physChunk[6];\n physChunk[11] = physChunk[7];\n physChunk[12] = 1;\n const crc = calcCrc(physChunk);\n const crcChunk = new Uint8Array(4);\n crcChunk[0] = crc >>> 24;\n crcChunk[1] = crc >>> 16;\n crcChunk[2] = crc >>> 8;\n crcChunk[3] = crc & 255;\n if (overwritepHYs) {\n const startingIndex = searchStartOfPhys(uint8Array);\n uint8Array.set(physChunk, startingIndex);\n uint8Array.set(crcChunk, startingIndex + 13);\n return uint8Array;\n } else {\n const chunkLength = new Uint8Array(4);\n chunkLength[0] = 0;\n chunkLength[1] = 0;\n chunkLength[2] = 0;\n chunkLength[3] = 9;\n const finalHeader = new Uint8Array(54);\n finalHeader.set(uint8Array, 0);\n finalHeader.set(chunkLength, 33);\n finalHeader.set(physChunk, 37);\n finalHeader.set(crcChunk, 50);\n return finalHeader;\n }\n}\nconst b64PhysSignature1 = \"AAlwSFlz\";\nconst b64PhysSignature2 = \"AAAJcEhZ\";\nconst b64PhysSignature3 = \"AAAACXBI\";\nfunction detectPhysChunkFromDataUrl(dataUrl) {\n let b64index = dataUrl.indexOf(b64PhysSignature1);\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature2);\n }\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature3);\n }\n return b64index;\n}\n\nconst PREFIX = \"[modern-screenshot]\";\nconst IN_BROWSER = typeof window !== \"undefined\";\nconst SUPPORT_WEB_WORKER = IN_BROWSER && \"Worker\" in window;\nconst SUPPORT_ATOB = IN_BROWSER && \"atob\" in window;\nconst SUPPORT_BTOA = IN_BROWSER && \"btoa\" in window;\nconst USER_AGENT = IN_BROWSER ? window.navigator?.userAgent : \"\";\nconst IN_CHROME = USER_AGENT.includes(\"Chrome\");\nconst IN_SAFARI = USER_AGENT.includes(\"AppleWebKit\") && !IN_CHROME;\nconst IN_FIREFOX = USER_AGENT.includes(\"Firefox\");\nconst isContext = (value) => value && \"__CONTEXT__\" in value;\nconst isCssFontFaceRule = (rule) => rule.constructor.name === \"CSSFontFaceRule\";\nconst isCSSImportRule = (rule) => rule.constructor.name === \"CSSImportRule\";\nconst isLayerBlockRule = (rule) => rule.constructor.name === \"CSSLayerBlockRule\";\nconst isElementNode = (node) => node.nodeType === 1;\nconst isSVGElementNode = (node) => typeof node.className === \"object\";\nconst isSVGImageElementNode = (node) => node.tagName === \"image\";\nconst isSVGUseElementNode = (node) => node.tagName === \"use\";\nconst isHTMLElementNode = (node) => isElementNode(node) && typeof node.style !== \"undefined\" && !isSVGElementNode(node);\nconst isCommentNode = (node) => node.nodeType === 8;\nconst isTextNode = (node) => node.nodeType === 3;\nconst isImageElement = (node) => node.tagName === \"IMG\";\nconst isVideoElement = (node) => node.tagName === \"VIDEO\";\nconst isCanvasElement = (node) => node.tagName === \"CANVAS\";\nconst isTextareaElement = (node) => node.tagName === \"TEXTAREA\";\nconst isInputElement = (node) => node.tagName === \"INPUT\";\nconst isStyleElement = (node) => node.tagName === \"STYLE\";\nconst isScriptElement = (node) => node.tagName === \"SCRIPT\";\nconst isSelectElement = (node) => node.tagName === \"SELECT\";\nconst isSlotElement = (node) => node.tagName === \"SLOT\";\nconst isIFrameElement = (node) => node.tagName === \"IFRAME\";\nconst consoleWarn = (...args) => console.warn(PREFIX, ...args);\nfunction supportWebp(ownerDocument) {\n const canvas = ownerDocument?.createElement?.(\"canvas\");\n if (canvas) {\n canvas.height = canvas.width = 1;\n }\n return Boolean(canvas) && \"toDataURL\" in canvas && Boolean(canvas.toDataURL(\"image/webp\").includes(\"image/webp\"));\n}\nconst isDataUrl = (url) => url.startsWith(\"data:\");\nfunction resolveUrl(url, baseUrl) {\n if (url.match(/^[a-z]+:\\/\\//i))\n return url;\n if (IN_BROWSER && url.match(/^\\/\\//))\n return window.location.protocol + url;\n if (url.match(/^[a-z]+:/i))\n return url;\n if (!IN_BROWSER)\n return url;\n const doc = getDocument().implementation.createHTMLDocument();\n const base = doc.createElement(\"base\");\n const a = doc.createElement(\"a\");\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl)\n base.href = baseUrl;\n a.href = url;\n return a.href;\n}\nfunction getDocument(target) {\n return (target && isElementNode(target) ? target?.ownerDocument : target) ?? window.document;\n}\nconst XMLNS = \"http://www.w3.org/2000/svg\";\nfunction createSvg(width, height, ownerDocument) {\n const svg = getDocument(ownerDocument).createElementNS(XMLNS, \"svg\");\n svg.setAttributeNS(null, \"width\", width.toString());\n svg.setAttributeNS(null, \"height\", height.toString());\n svg.setAttributeNS(null, \"viewBox\", `0 0 ${width} ${height}`);\n return svg;\n}\nfunction svgToDataUrl(svg, removeControlCharacter) {\n let xhtml = new XMLSerializer().serializeToString(svg);\n if (removeControlCharacter) {\n xhtml = xhtml.replace(/[\\u0000-\\u0008\\v\\f\\u000E-\\u001F\\uD800-\\uDFFF\\uFFFE\\uFFFF]/gu, \"\");\n }\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(xhtml)}`;\n}\nasync function canvasToBlob(canvas, type = \"image/png\", quality = 1) {\n try {\n return await new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error(\"Blob is null\"));\n }\n }, type, quality);\n });\n } catch (error) {\n if (SUPPORT_ATOB) {\n return dataUrlToBlob(canvas.toDataURL(type, quality));\n }\n throw error;\n }\n}\nfunction dataUrlToBlob(dataUrl) {\n const [header, base64] = dataUrl.split(\",\");\n const type = header.match(/data:(.+);/)?.[1] ?? void 0;\n const decoded = window.atob(base64);\n const length = decoded.length;\n const buffer = new Uint8Array(length);\n for (let i = 0; i < length; i += 1) {\n buffer[i] = decoded.charCodeAt(i);\n }\n return new Blob([buffer], { type });\n}\nfunction readBlob(blob, type) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.onabort = () => reject(new Error(`Failed read blob to ${type}`));\n if (type === \"dataUrl\") {\n reader.readAsDataURL(blob);\n } else if (type === \"arrayBuffer\") {\n reader.readAsArrayBuffer(blob);\n }\n });\n}\nconst blobToDataUrl = (blob) => readBlob(blob, \"dataUrl\");\nconst blobToArrayBuffer = (blob) => readBlob(blob, \"arrayBuffer\");\nfunction createImage(url, ownerDocument) {\n const img = getDocument(ownerDocument).createElement(\"img\");\n img.decoding = \"sync\";\n img.loading = \"eager\";\n img.src = url;\n return img;\n}\nfunction loadMedia(media, options) {\n return new Promise((resolve) => {\n const { timeout, ownerDocument, onError: userOnError, onWarn } = options ?? {};\n const node = typeof media === \"string\" ? createImage(media, getDocument(ownerDocument)) : media;\n let timer = null;\n let removeEventListeners = null;\n function onResolve() {\n resolve(node);\n timer && clearTimeout(timer);\n removeEventListeners?.();\n }\n if (timeout) {\n timer = setTimeout(onResolve, timeout);\n }\n if (isVideoElement(node)) {\n const currentSrc = node.currentSrc || node.src;\n if (!currentSrc) {\n if (node.poster) {\n return loadMedia(node.poster, options).then(resolve);\n }\n return onResolve();\n }\n if (node.readyState >= 2) {\n return onResolve();\n }\n const onLoadeddata = onResolve;\n const onError = (error) => {\n onWarn?.(\n \"Failed video load\",\n currentSrc,\n error\n );\n userOnError?.(error);\n onResolve();\n };\n removeEventListeners = () => {\n node.removeEventListener(\"loadeddata\", onLoadeddata);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"loadeddata\", onLoadeddata, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n } else {\n const currentSrc = isSVGImageElementNode(node) ? node.href.baseVal : node.currentSrc || node.src;\n if (!currentSrc) {\n return onResolve();\n }\n const onLoad = async () => {\n if (isImageElement(node) && \"decode\" in node) {\n try {\n await node.decode();\n } catch (error) {\n onWarn?.(\n \"Failed to decode image, trying to render anyway\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n }\n }\n onResolve();\n };\n const onError = (error) => {\n onWarn?.(\n \"Failed image load\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n onResolve();\n };\n if (isImageElement(node) && node.complete) {\n return onLoad();\n }\n removeEventListeners = () => {\n node.removeEventListener(\"load\", onLoad);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"load\", onLoad, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n }\n });\n}\nasync function waitUntilLoad(node, options) {\n if (isHTMLElementNode(node)) {\n if (isImageElement(node) || isVideoElement(node)) {\n await loadMedia(node, options);\n } else {\n await Promise.all(\n [\"img\", \"video\"].flatMap((selectors) => {\n return Array.from(node.querySelectorAll(selectors)).map((el) => loadMedia(el, options));\n })\n );\n }\n }\n}\nconst uuid = /* @__PURE__ */ function uuid2() {\n let counter = 0;\n const random = () => `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n}();\nfunction splitFontFamily(fontFamily) {\n return fontFamily?.split(\",\").map((val) => val.trim().replace(/\"|'/g, \"\").toLowerCase()).filter(Boolean);\n}\n\nlet uid = 0;\nfunction createLogger(debug) {\n const prefix = `${PREFIX}[#${uid}]`;\n uid++;\n return {\n // eslint-disable-next-line no-console\n time: (label) => debug && console.time(`${prefix} ${label}`),\n // eslint-disable-next-line no-console\n timeEnd: (label) => debug && console.timeEnd(`${prefix} ${label}`),\n warn: (...args) => debug && consoleWarn(...args)\n };\n}\n\nfunction getDefaultRequestInit(bypassingCache) {\n return {\n cache: bypassingCache ? \"no-cache\" : \"force-cache\"\n };\n}\n\nasync function orCreateContext(node, options) {\n return isContext(node) ? node : createContext(node, { ...options, autoDestruct: true });\n}\nasync function createContext(node, options) {\n const { scale = 1, workerUrl, workerNumber = 1 } = options || {};\n const debug = Boolean(options?.debug);\n const features = options?.features ?? true;\n const ownerDocument = node.ownerDocument ?? (IN_BROWSER ? window.document : void 0);\n const ownerWindow = node.ownerDocument?.defaultView ?? (IN_BROWSER ? window : void 0);\n const requests = /* @__PURE__ */ new Map();\n const context = {\n // Options\n width: 0,\n height: 0,\n quality: 1,\n type: \"image/png\",\n scale,\n backgroundColor: null,\n style: null,\n filter: null,\n maximumCanvasSize: 0,\n timeout: 3e4,\n progress: null,\n debug,\n fetch: {\n requestInit: getDefaultRequestInit(options?.fetch?.bypassingCache),\n placeholderImage: \"data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\",\n bypassingCache: false,\n ...options?.fetch\n },\n fetchFn: null,\n font: {},\n drawImageInterval: 100,\n workerUrl: null,\n workerNumber,\n onCloneEachNode: null,\n onCloneNode: null,\n onEmbedNode: null,\n onCreateForeignObjectSvg: null,\n includeStyleProperties: null,\n autoDestruct: false,\n ...options,\n // InternalContext\n __CONTEXT__: true,\n log: createLogger(debug),\n node,\n ownerDocument,\n ownerWindow,\n dpi: scale === 1 ? null : 96 * scale,\n svgStyleElement: createStyleElement(ownerDocument),\n svgDefsElement: ownerDocument?.createElementNS(XMLNS, \"defs\"),\n svgStyles: /* @__PURE__ */ new Map(),\n defaultComputedStyles: /* @__PURE__ */ new Map(),\n workers: [\n ...Array.from({\n length: SUPPORT_WEB_WORKER && workerUrl && workerNumber ? workerNumber : 0\n })\n ].map(() => {\n try {\n const worker = new Worker(workerUrl);\n worker.onmessage = async (event) => {\n const { url, result } = event.data;\n if (result) {\n requests.get(url)?.resolve?.(result);\n } else {\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n }\n };\n worker.onmessageerror = (event) => {\n const { url } = event.data;\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n };\n return worker;\n } catch (error) {\n context.log.warn(\"Failed to new Worker\", error);\n return null;\n }\n }).filter(Boolean),\n fontFamilies: /* @__PURE__ */ new Map(),\n fontCssTexts: /* @__PURE__ */ new Map(),\n acceptOfImage: `${[\n supportWebp(ownerDocument) && \"image/webp\",\n \"image/svg+xml\",\n \"image/*\",\n \"*/*\"\n ].filter(Boolean).join(\",\")};q=0.8`,\n requests,\n drawImageCount: 0,\n tasks: [],\n features,\n isEnable: (key) => {\n if (key === \"restoreScrollPosition\") {\n return typeof features === \"boolean\" ? false : features[key] ?? false;\n }\n if (typeof features === \"boolean\") {\n return features;\n }\n return features[key] ?? true;\n },\n shadowRoots: []\n };\n context.log.time(\"wait until load\");\n await waitUntilLoad(node, { timeout: context.timeout, onWarn: context.log.warn });\n context.log.timeEnd(\"wait until load\");\n const { width, height } = resolveBoundingBox(node, context);\n context.width = width;\n context.height = height;\n return context;\n}\nfunction createStyleElement(ownerDocument) {\n if (!ownerDocument)\n return void 0;\n const style = ownerDocument.createElement(\"style\");\n const cssText = style.ownerDocument.createTextNode(`\n.______background-clip--text {\n background-clip: text;\n -webkit-background-clip: text;\n}\n`);\n style.appendChild(cssText);\n return style;\n}\nfunction resolveBoundingBox(node, context) {\n let { width, height } = context;\n if (isElementNode(node) && (!width || !height)) {\n const box = node.getBoundingClientRect();\n width = width || box.width || Number(node.getAttribute(\"width\")) || 0;\n height = height || box.height || Number(node.getAttribute(\"height\")) || 0;\n }\n return { width, height };\n}\n\nasync function imageToCanvas(image, context) {\n const {\n log,\n timeout,\n drawImageCount,\n drawImageInterval\n } = context;\n log.time(\"image to canvas\");\n const loaded = await loadMedia(image, { timeout, onWarn: context.log.warn });\n const { canvas, context2d } = createCanvas(image.ownerDocument, context);\n const drawImage = () => {\n try {\n context2d?.drawImage(loaded, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to drawImage\", error);\n }\n };\n drawImage();\n if (context.isEnable(\"fixSvgXmlDecode\")) {\n for (let i = 0; i < drawImageCount; i++) {\n await new Promise((resolve) => {\n setTimeout(() => {\n context2d?.clearRect(0, 0, canvas.width, canvas.height);\n drawImage();\n resolve();\n }, i + drawImageInterval);\n });\n }\n }\n context.drawImageCount = 0;\n log.timeEnd(\"image to canvas\");\n return canvas;\n}\nfunction createCanvas(ownerDocument, context) {\n const { width, height, scale, backgroundColor, maximumCanvasSize: max } = context;\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = Math.floor(width * scale);\n canvas.height = Math.floor(height * scale);\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n if (max) {\n if (canvas.width > max || canvas.height > max) {\n if (canvas.width > max && canvas.height > max) {\n if (canvas.width > canvas.height) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n } else if (canvas.width > max) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n }\n }\n const context2d = canvas.getContext(\"2d\");\n if (context2d && backgroundColor) {\n context2d.fillStyle = backgroundColor;\n context2d.fillRect(0, 0, canvas.width, canvas.height);\n }\n return { canvas, context2d };\n}\n\nfunction cloneCanvas(canvas, context) {\n if (canvas.ownerDocument) {\n try {\n const dataURL = canvas.toDataURL();\n if (dataURL !== \"data:,\") {\n return createImage(dataURL, canvas.ownerDocument);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n }\n const cloned = canvas.cloneNode(false);\n const ctx = canvas.getContext(\"2d\");\n const clonedCtx = cloned.getContext(\"2d\");\n try {\n if (ctx && clonedCtx) {\n clonedCtx.putImageData(\n ctx.getImageData(0, 0, canvas.width, canvas.height),\n 0,\n 0\n );\n }\n return cloned;\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n return cloned;\n}\n\nfunction cloneIframe(iframe, context) {\n try {\n if (iframe?.contentDocument?.documentElement) {\n return cloneNode(iframe.contentDocument.documentElement, context);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone iframe\", error);\n }\n return iframe.cloneNode(false);\n}\n\nfunction cloneImage(image) {\n const cloned = image.cloneNode(false);\n if (image.currentSrc && image.currentSrc !== image.src) {\n cloned.src = image.currentSrc;\n cloned.srcset = \"\";\n }\n if (cloned.loading === \"lazy\") {\n cloned.loading = \"eager\";\n }\n return cloned;\n}\n\nasync function cloneVideo(video, context) {\n if (video.ownerDocument && !video.currentSrc && video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n const cloned = video.cloneNode(false);\n cloned.crossOrigin = \"anonymous\";\n if (video.currentSrc && video.currentSrc !== video.src) {\n cloned.src = video.currentSrc;\n }\n const ownerDocument = cloned.ownerDocument;\n if (ownerDocument) {\n let canPlay = true;\n await loadMedia(cloned, { onError: () => canPlay = false, onWarn: context.log.warn });\n if (!canPlay) {\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n cloned.currentTime = video.currentTime;\n await new Promise((resolve) => {\n cloned.addEventListener(\"seeked\", resolve, { once: true });\n });\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = video.offsetWidth;\n canvas.height = video.offsetHeight;\n try {\n const ctx = canvas.getContext(\"2d\");\n if (ctx)\n ctx.drawImage(cloned, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to clone video\", error);\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n return cloneCanvas(canvas, context);\n }\n return cloned;\n}\n\nfunction cloneElement(node, context) {\n if (isCanvasElement(node)) {\n return cloneCanvas(node, context);\n }\n if (isIFrameElement(node)) {\n return cloneIframe(node, context);\n }\n if (isImageElement(node)) {\n return cloneImage(node);\n }\n if (isVideoElement(node)) {\n return cloneVideo(node, context);\n }\n return node.cloneNode(false);\n}\n\nfunction getSandBox(context) {\n let sandbox = context.sandbox;\n if (!sandbox) {\n const { ownerDocument } = context;\n try {\n if (ownerDocument) {\n sandbox = ownerDocument.createElement(\"iframe\");\n sandbox.id = `__SANDBOX__${uuid()}`;\n sandbox.width = \"0\";\n sandbox.height = \"0\";\n sandbox.style.visibility = \"hidden\";\n sandbox.style.position = \"fixed\";\n ownerDocument.body.appendChild(sandbox);\n sandbox.srcdoc = '<!DOCTYPE html><meta charset=\"UTF-8\"><title></title><body>';\n context.sandbox = sandbox;\n }\n } catch (error) {\n context.log.warn(\"Failed to getSandBox\", error);\n }\n }\n return sandbox;\n}\n\nconst ignoredStyles = [\n \"width\",\n \"height\",\n \"-webkit-text-fill-color\"\n];\nconst includedAttributes = [\n \"stroke\",\n \"fill\"\n];\nfunction getDefaultStyle(node, pseudoElement, context) {\n const { defaultComputedStyles } = context;\n const nodeName = node.nodeName.toLowerCase();\n const isSvgNode = isSVGElementNode(node) && nodeName !== \"svg\";\n const attributes = isSvgNode ? includedAttributes.map((name) => [name, node.getAttribute(name)]).filter(([, value]) => value !== null) : [];\n const key = [\n isSvgNode && \"svg\",\n nodeName,\n attributes.map((name, value) => `${name}=${value}`).join(\",\"),\n pseudoElement\n ].filter(Boolean).join(\":\");\n if (defaultComputedStyles.has(key))\n return defaultComputedStyles.get(key);\n const sandbox = getSandBox(context);\n const sandboxWindow = sandbox?.contentWindow;\n if (!sandboxWindow)\n return /* @__PURE__ */ new Map();\n const sandboxDocument = sandboxWindow?.document;\n let root;\n let el;\n if (isSvgNode) {\n root = sandboxDocument.createElementNS(XMLNS, \"svg\");\n el = root.ownerDocument.createElementNS(root.namespaceURI, nodeName);\n attributes.forEach(([name, value]) => {\n el.setAttributeNS(null, name, value);\n });\n root.appendChild(el);\n } else {\n root = el = sandboxDocument.createElement(nodeName);\n }\n el.textContent = \" \";\n sandboxDocument.body.appendChild(root);\n const computedStyle = sandboxWindow.getComputedStyle(el, pseudoElement);\n const styles = /* @__PURE__ */ new Map();\n for (let len = computedStyle.length, i = 0; i < len; i++) {\n const name = computedStyle.item(i);\n if (ignoredStyles.includes(name))\n continue;\n styles.set(name, computedStyle.getPropertyValue(name));\n }\n sandboxDocument.body.removeChild(root);\n defaultComputedStyles.set(key, styles);\n return styles;\n}\n\nfunction getDiffStyle(style, defaultStyle, includeStyleProperties) {\n const diffStyle = /* @__PURE__ */ new Map();\n const prefixs = [];\n const prefixTree = /* @__PURE__ */ new Map();\n if (includeStyleProperties) {\n for (const name of includeStyleProperties) {\n applyTo(name);\n }\n } else {\n for (let len = style.length, i = 0; i < len; i++) {\n const name = style.item(i);\n applyTo(name);\n }\n }\n for (let len = prefixs.length, i = 0; i < len; i++) {\n prefixTree.get(prefixs[i])?.forEach((value, name) => diffStyle.set(name, value));\n }\n function applyTo(name) {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n const subIndex = name.lastIndexOf(\"-\");\n const prefix = subIndex > -1 ? name.substring(0, subIndex) : void 0;\n if (prefix) {\n let map = prefixTree.get(prefix);\n if (!map) {\n map = /* @__PURE__ */ new Map();\n prefixTree.set(prefix, map);\n }\n map.set(name, [value, priority]);\n }\n if (defaultStyle.get(name) === value && !priority)\n return;\n if (prefix) {\n prefixs.push(prefix);\n } else {\n diffStyle.set(name, [value, priority]);\n }\n }\n return diffStyle;\n}\n\nfunction copyCssStyles(node, cloned, isRoot, context) {\n const { ownerWindow, includeStyleProperties, currentParentNodeStyle } = context;\n const clonedStyle = cloned.style;\n const computedStyle = ownerWindow.getComputedStyle(node);\n const defaultStyle = getDefaultStyle(node, null, context);\n currentParentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, includeStyleProperties);\n style.delete(\"transition-property\");\n style.delete(\"all\");\n style.delete(\"d\");\n style.delete(\"content\");\n if (isRoot) {\n style.delete(\"position\");\n style.delete(\"margin-top\");\n style.delete(\"margin-right\");\n style.delete(\"margin-bottom\");\n style.delete(\"margin-left\");\n style.delete(\"margin-block-start\");\n style.delete(\"margin-block-end\");\n style.delete(\"margin-inline-start\");\n style.delete(\"margin-inline-end\");\n style.set(\"box-sizing\", [\"border-box\", \"\"]);\n }\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n if (IN_CHROME) {\n if (!style.has(\"font-kerning\"))\n style.set(\"font-kerning\", [\"normal\", \"\"]);\n if ((style.get(\"overflow-x\")?.[0] === \"hidden\" || style.get(\"overflow-y\")?.[0] === \"hidden\") && style.get(\"text-overflow\")?.[0] === \"ellipsis\" && node.scrollWidth === node.clientWidth) {\n style.set(\"text-overflow\", [\"clip\", \"\"]);\n }\n }\n for (let len = clonedStyle.length, i = 0; i < len; i++) {\n clonedStyle.removeProperty(clonedStyle.item(i));\n }\n style.forEach(([value, priority], name) => {\n clonedStyle.setProperty(name, value, priority);\n });\n return style;\n}\n\nfunction copyInputValue(node, cloned) {\n if (isTextareaElement(node) || isInputElement(node) || isSelectElement(node)) {\n cloned.setAttribute(\"value\", node.value);\n }\n}\n\nconst pseudoClasses = [\n \"::before\",\n \"::after\"\n // '::placeholder', TODO\n];\nconst scrollbarPseudoClasses = [\n \"::-webkit-scrollbar\",\n \"::-webkit-scrollbar-button\",\n // '::-webkit-scrollbar:horizontal', TODO\n \"::-webkit-scrollbar-thumb\",\n \"::-webkit-scrollbar-track\",\n \"::-webkit-scrollbar-track-piece\",\n // '::-webkit-scrollbar:vertical', TODO\n \"::-webkit-scrollbar-corner\",\n \"::-webkit-resizer\"\n];\nfunction copyPseudoClass(node, cloned, copyScrollbar, context, addWordToFontFamilies) {\n const { ownerWindow, svgStyleElement, svgStyles, currentNodeStyle } = context;\n if (!svgStyleElement || !ownerWindow)\n return;\n function copyBy(pseudoClass) {\n const computedStyle = ownerWindow.getComputedStyle(node, pseudoClass);\n let content = computedStyle.getPropertyValue(\"content\");\n if (!content || content === \"none\")\n return;\n addWordToFontFamilies?.(content);\n content = content.replace(/(')|(\")|(counter\\(.+\\))/g, \"\");\n const klasses = [uuid()];\n const defaultStyle = getDefaultStyle(node, pseudoClass, context);\n currentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, context.includeStyleProperties);\n style.delete(\"content\");\n style.delete(\"-webkit-locale\");\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n const cloneStyle = [\n `content: '${content}';`\n ];\n style.forEach(([value, priority], name) => {\n cloneStyle.push(`${name}: ${value}${priority ? \" !important\" : \"\"};`);\n });\n if (cloneStyle.length === 1)\n return;\n try {\n cloned.className = [cloned.className, ...klasses].join(\" \");\n } catch (err) {\n context.log.warn(\"Failed to copyPseudoClass\", err);\n return;\n }\n const cssText = cloneStyle.join(\"\\n \");\n let allClasses = svgStyles.get(cssText);\n if (!allClasses) {\n allClasses = [];\n svgStyles.set(cssText, allClasses);\n }\n allClasses.push(`.${klasses[0]}${pseudoClass}`);\n }\n pseudoClasses.forEach(copyBy);\n if (copyScrollbar)\n scrollbarPseudoClasses.forEach(copyBy);\n}\n\nconst excludeParentNodes = /* @__PURE__ */ new Set([\n \"symbol\"\n // test/fixtures/svg.symbol.html\n]);\nasync function appendChildNode(node, cloned, child, context, addWordToFontFamilies) {\n if (isElementNode(child) && (isStyleElement(child) || isScriptElement(child)))\n return;\n if (context.filter && !context.filter(child))\n return;\n if (excludeParentNodes.has(cloned.nodeName) || excludeParentNodes.has(child.nodeName)) {\n context.currentParentNodeStyle = void 0;\n } else {\n context.currentParentNodeStyle = context.currentNodeStyle;\n }\n const childCloned = await cloneNode(child, context, false, addWordToFontFamilies);\n if (context.isEnable(\"restoreScrollPosition\")) {\n restoreScrollPosition(node, childCloned);\n }\n cloned.appendChild(childCloned);\n}\nasync function cloneChildNodes(node, cloned, context, addWordToFontFamilies) {\n let firstChild = node.firstChild;\n if (isElementNode(node)) {\n if (node.shadowRoot) {\n firstChild = node.shadowRoot?.firstChild;\n context.shadowRoots.push(node.shadowRoot);\n }\n }\n for (let child = firstChild; child; child = child.nextSibling) {\n if (isCommentNode(child))\n continue;\n if (isElementNode(child) && isSlotElement(child) && typeof child.assignedNodes === \"function\") {\n const nodes = child.assignedNodes();\n for (let i = 0; i < nodes.length; i++) {\n await appendChildNode(node, cloned, nodes[i], context, addWordToFontFamilies);\n }\n } else {\n await appendChildNode(node, cloned, child, context, addWordToFontFamilies);\n }\n }\n}\nfunction restoreScrollPosition(node, chlidCloned) {\n if (!isHTMLElementNode(node) || !isHTMLElementNode(chlidCloned))\n return;\n const { scrollTop, scrollLeft } = node;\n if (!scrollTop && !scrollLeft) {\n return;\n }\n const { transform } = chlidCloned.style;\n const matrix = new DOMMatrix(transform);\n const { a, b, c, d } = matrix;\n matrix.a = 1;\n matrix.b = 0;\n matrix.c = 0;\n matrix.d = 1;\n matrix.translateSelf(-scrollLeft, -scrollTop);\n matrix.a = a;\n matrix.b = b;\n matrix.c = c;\n matrix.d = d;\n chlidCloned.style.transform = matrix.toString();\n}\nfunction applyCssStyleWithOptions(cloned, context) {\n const { backgroundColor, width, height, style: styles } = context;\n const clonedStyle = cloned.style;\n if (backgroundColor)\n clonedStyle.setProperty(\"background-color\", backgroundColor, \"important\");\n if (width)\n clonedStyle.setProperty(\"width\", `${width}px`, \"important\");\n if (height)\n clonedStyle.setProperty(\"height\", `${height}px`, \"important\");\n if (styles) {\n for (const name in styles) clonedStyle[name] = styles[name];\n }\n}\nconst NORMAL_ATTRIBUTE_RE = /^[\\w-:]+$/;\nasync function cloneNode(node, context, isRoot = false, addWordToFontFamilies) {\n const { ownerDocument, ownerWindow, fontFamilies, onCloneEachNode } = context;\n if (ownerDocument && isTextNode(node)) {\n if (addWordToFontFamilies && /\\S/.test(node.data)) {\n addWordToFontFamilies(node.data);\n }\n return ownerDocument.createTextNode(node.data);\n }\n if (ownerDocument && ownerWindow && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {\n const cloned2 = await cloneElement(node, context);\n if (context.isEnable(\"removeAbnormalAttributes\")) {\n const names = cloned2.getAttributeNames();\n for (let len = names.length, i = 0; i < len; i++) {\n const name = names[i];\n if (!NORMAL_ATTRIBUTE_RE.test(name)) {\n cloned2.removeAttribute(name);\n }\n }\n }\n const style = context.currentNodeStyle = copyCssStyles(node, cloned2, isRoot, context);\n if (isRoot)\n applyCssStyleWithOptions(cloned2, context);\n let copyScrollbar = false;\n if (context.isEnable(\"copyScrollbar\")) {\n const overflow = [\n style.get(\"overflow-x\")?.[0],\n style.get(\"overflow-y\")?.[0]\n ];\n copyScrollbar = overflow.includes(\"scroll\") || (overflow.includes(\"auto\") || overflow.includes(\"overlay\")) && (node.scrollHeight > node.clientHeight || node.scrollWidth > node.clientWidth);\n }\n const textTransform = style.get(\"text-transform\")?.[0];\n const families = splitFontFamily(style.get(\"font-family\")?.[0]);\n const addWordToFontFamilies2 = families ? (word) => {\n if (textTransform === \"uppercase\") {\n word = word.toUpperCase();\n } else if (textTransform === \"lowercase\") {\n word = word.toLowerCase();\n } else if (textTransform === \"capitalize\") {\n word = word[0].toUpperCase() + word.substring(1);\n }\n families.forEach((family) => {\n let fontFamily = fontFamilies.get(family);\n if (!fontFamily) {\n fontFamilies.set(family, fontFamily = /* @__PURE__ */ new Set());\n }\n word.split(\"\").forEach((text) => fontFamily.add(text));\n });\n } : void 0;\n copyPseudoClass(\n node,\n cloned2,\n copyScrollbar,\n context,\n addWordToFontFamilies2\n );\n copyInputValue(node, cloned2);\n if (!isVideoElement(node)) {\n await cloneChildNodes(\n node,\n cloned2,\n context,\n addWordToFontFamilies2\n );\n }\n await onCloneEachNode?.(cloned2);\n return cloned2;\n }\n const cloned = node.cloneNode(false);\n await cloneChildNodes(node, cloned, context);\n await onCloneEachNode?.(cloned);\n return cloned;\n}\n\nfunction destroyContext(context) {\n context.ownerDocument = void 0;\n context.ownerWindow = void 0;\n context.svgStyleElement = void 0;\n context.svgDefsElement = void 0;\n context.svgStyles.clear();\n context.defaultComputedStyles.clear();\n if (context.sandbox) {\n try {\n context.sandbox.remove();\n } catch (err) {\n context.log.warn(\"Failed to destroyContext\", err);\n }\n context.sandbox = void 0;\n }\n context.workers = [];\n context.fontFamilies.clear();\n context.fontCssTexts.clear();\n context.requests.clear();\n context.tasks = [];\n context.shadowRoots = [];\n}\n\nfunction baseFetch(options) {\n const { url, timeout, responseType, ...requestInit } = options;\n const controller = new AbortController();\n const timer = timeout ? setTimeout(() => controller.abort(), timeout) : void 0;\n return fetch(url, { signal: controller.signal, ...requestInit }).then((response) => {\n if (!response.ok) {\n throw new Error(\"Failed fetch, not 2xx response\", { cause: response });\n }\n switch (responseType) {\n case \"arrayBuffer\":\n return response.arrayBuffer();\n case \"dataUrl\":\n return response.blob().then(blobToDataUrl);\n case \"text\":\n default:\n return response.text();\n }\n }).finally(() => clearTimeout(timer));\n}\nfunction contextFetch(context, options) {\n const { url: rawUrl, requestType = \"text\", responseType = \"text\", imageDom } = options;\n let url = rawUrl;\n const {\n timeout,\n acceptOfImage,\n requests,\n fetchFn,\n fetch: {\n requestInit,\n bypassingCache,\n placeholderImage\n },\n font,\n workers,\n fontFamilies\n } = context;\n if (requestType === \"image\" && (IN_SAFARI || IN_FIREFOX)) {\n context.drawImageCount++;\n }\n let request = requests.get(rawUrl);\n if (!request) {\n if (bypassingCache) {\n if (bypassingCache instanceof RegExp && bypassingCache.test(url)) {\n url += (/\\?/.test(url) ? \"&\" : \"?\") + (/* @__PURE__ */ new Date()).getTime();\n }\n }\n const canFontMinify = requestType.startsWith(\"font\") && font && font.minify;\n const fontTexts = /* @__PURE__ */ new Set();\n if (canFontMinify) {\n const families = requestType.split(\";\")[1].split(\",\");\n families.forEach((family) => {\n if (!fontFamilies.has(family))\n return;\n fontFamilies.get(family).forEach((text) => fontTexts.add(text));\n });\n }\n const needFontMinify = canFontMinify && fontTexts.size;\n const baseFetchOptions = {\n url,\n timeout,\n responseType: needFontMinify ? \"arrayBuffer\" : responseType,\n headers: requestType === \"image\" ? { accept: acceptOfImage } : void 0,\n ...requestInit\n };\n request = {\n type: requestType,\n resolve: void 0,\n reject: void 0,\n response: null\n };\n request.response = (async () => {\n if (fetchFn && requestType === \"image\") {\n const result = await fetchFn(rawUrl);\n if (result)\n return result;\n }\n if (!IN_SAFARI && rawUrl.startsWith(\"http\") && workers.length) {\n return new Promise((resolve, reject) => {\n const worker = workers[requests.size & workers.length - 1];\n worker.postMessage({ rawUrl, ...baseFetchOptions });\n request.resolve = resolve;\n request.reject = reject;\n });\n }\n return baseFetch(baseFetchOptions);\n })().catch((error) => {\n requests.delete(rawUrl);\n if (requestType === \"image\" && placeholderImage) {\n context.log.warn(\"Failed to fetch image base64, trying to use placeholder image\", url);\n return typeof placeholderImage === \"string\" ? placeholderImage : placeholderImage(imageDom);\n }\n throw error;\n });\n requests.set(rawUrl, request);\n }\n return request.response;\n}\n\nasync function replaceCssUrlToDataUrl(cssText, baseUrl, context, isImage) {\n if (!hasCssUrl(cssText))\n return cssText;\n for (const [rawUrl, url] of parseCssUrls(cssText, baseUrl)) {\n try {\n const dataUrl = await contextFetch(\n context,\n {\n url,\n requestType: isImage ? \"image\" : \"text\",\n responseType: \"dataUrl\"\n }\n );\n cssText = cssText.replace(toRE(rawUrl), `$1${dataUrl}$3`);\n } catch (error) {\n context.log.warn(\"Failed to fetch css data url\", rawUrl, error);\n }\n }\n return cssText;\n}\nfunction hasCssUrl(cssText) {\n return /url\\((['\"]?)([^'\"]+?)\\1\\)/.test(cssText);\n}\nconst URL_RE = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nfunction parseCssUrls(cssText, baseUrl) {\n const result = [];\n cssText.replace(URL_RE, (raw, quotation, url) => {\n result.push([url, resolveUrl(url, baseUrl)]);\n return raw;\n });\n return result.filter(([url]) => !isDataUrl(url));\n}\nfunction toRE(url) {\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, \"\\\\$1\");\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, \"g\");\n}\n\nconst properties = [\n \"background-image\",\n \"border-image-source\",\n \"-webkit-border-image\",\n \"-webkit-mask-image\",\n \"list-style-image\"\n];\nfunction embedCssStyleImage(style, context) {\n return properties.map((property) => {\n const value = style.getPropertyValue(property);\n if (!value || value === \"none\") {\n return null;\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n return replaceCssUrlToDataUrl(value, null, context, true).then((newValue) => {\n if (!newValue || value === newValue)\n return;\n style.setProperty(\n property,\n newValue,\n style.getPropertyPriority(property)\n );\n });\n }).filter(Boolean);\n}\n\nfunction embedImageElement(cloned, context) {\n if (isImageElement(cloned)) {\n const originalSrc = cloned.currentSrc || cloned.src;\n if (!isDataUrl(originalSrc)) {\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.srcset = \"\";\n cloned.dataset.originalSrc = originalSrc;\n cloned.src = url || \"\";\n })\n ];\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n } else if (isSVGElementNode(cloned) && !isDataUrl(cloned.href.baseVal)) {\n const originalSrc = cloned.href.baseVal;\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.dataset.originalSrc = originalSrc;\n cloned.href.baseVal = url || \"\";\n })\n ];\n }\n return [];\n}\n\nfunction embedSvgUse(cloned, context) {\n const { ownerDocument, svgDefsElement } = context;\n const href = cloned.getAttribute(\"href\") ?? cloned.getAttribute(\"xlink:href\");\n if (!href)\n return [];\n const [svgUrl, id] = href.split(\"#\");\n if (id) {\n const query = `#${id}`;\n const definition = context.shadowRoots.reduce(\n (res, root) => {\n return res ?? root.querySelector(`svg ${query}`);\n },\n ownerDocument?.querySelector(`svg ${query}`)\n );\n if (svgUrl) {\n cloned.setAttribute(\"href\", query);\n }\n if (svgDefsElement?.querySelector(query))\n return [];\n if (definition) {\n svgDefsElement?.appendChild(definition.cloneNode(true));\n return [];\n } else if (svgUrl) {\n return [\n contextFetch(context, {\n url: svgUrl,\n responseType: \"text\"\n }).then((svgData) => {\n svgDefsElement?.insertAdjacentHTML(\"beforeend\", svgData);\n })\n ];\n }\n }\n return [];\n}\n\nfunction embedNode(cloned, context) {\n const { tasks } = context;\n if (isElementNode(cloned)) {\n if (isImageElement(cloned) || isSVGImageElementNode(cloned)) {\n tasks.push(...embedImageElement(cloned, context));\n }\n if (isSVGUseElementNode(cloned)) {\n tasks.push(...embedSvgUse(cloned, context));\n }\n }\n if (isHTMLElementNode(cloned)) {\n tasks.push(...embedCssStyleImage(cloned.style, context));\n }\n cloned.childNodes.forEach((child) => {\n embedNode(child, context);\n });\n}\n\nasync function embedWebFont(clone, context) {\n const {\n ownerDocument,\n svgStyleElement,\n fontFamilies,\n fontCssTexts,\n tasks,\n font\n } = context;\n if (!ownerDocument || !svgStyleElement || !fontFamilies.size) {\n return;\n }\n if (font && font.cssText) {\n const cssText = filterPreferredFormat(font.cssText, context);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n const styleSheets = Array.from(ownerDocument.styleSheets).filter((styleSheet) => {\n try {\n return \"cssRules\" in styleSheet && Boolean(styleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(`Error while reading CSS rules from ${styleSheet.href}`, error);\n return false;\n }\n });\n const tempDoc = ownerDocument.implementation.createHTMLDocument(\"\");\n const tempStyleEl = tempDoc.createElement(\"style\");\n tempDoc.head.appendChild(tempStyleEl);\n const tempStyleSheet = tempStyleEl.sheet;\n await Promise.all(\n styleSheets.flatMap((styleSheet) => {\n return Array.from(styleSheet.cssRules).map(async (cssRule) => {\n if (isCSSImportRule(cssRule)) {\n const baseUrl = cssRule.href;\n let cssText = \"\";\n try {\n cssText = await contextFetch(context, {\n url: baseUrl,\n requestType: \"text\",\n responseType: \"text\"\n });\n } catch (error) {\n context.log.warn(`Error fetch remote css import from ${baseUrl}`, error);\n }\n const replacedCssText = cssText.replace(\n URL_RE,\n (raw, quotation, url) => raw.replace(url, resolveUrl(url, baseUrl))\n );\n for (const rule of parseCss(replacedCssText)) {\n try {\n tempStyleSheet.insertRule(rule, tempStyleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(\"Error inserting rule from remote css import\", { rule, error });\n }\n }\n }\n });\n })\n );\n if (tempStyleSheet.cssRules.length)\n styleSheets.push(tempStyleSheet);\n const cssRules = [];\n styleSheets.forEach((sheet) => {\n unwrapCssLayers(sheet.cssRules, cssRules);\n });\n cssRules.filter((cssRule) => isCssFontFaceRule(cssRule) && hasCssUrl(cssRule.style.getPropertyValue(\"src\")) && splitFontFamily(cssRule.style.getPropertyValue(\"font-family\"))?.some((val) => fontFamilies.has(val))).forEach((value) => {\n const rule = value;\n const cssText = fontCssTexts.get(rule.cssText);\n if (cssText) {\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n tasks.push(\n replaceCssUrlToDataUrl(\n rule.cssText,\n rule.parentStyleSheet ? rule.parentStyleSheet.href : null,\n context\n ).then((cssText2) => {\n cssText2 = filterPreferredFormat(cssText2, context);\n fontCssTexts.set(rule.cssText, cssText2);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText2}\n`));\n })\n );\n }\n });\n }\n}\nconst COMMENTS_RE = /(\\/\\*[\\s\\S]*?\\*\\/)/g;\nconst KEYFRAMES_RE = /((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})/gi;\nfunction parseCss(source) {\n if (source == null)\n return [];\n const result = [];\n let cssText = source.replace(COMMENTS_RE, \"\");\n while (true) {\n const matches = KEYFRAMES_RE.exec(cssText);\n if (!matches)\n break;\n result.push(matches[0]);\n }\n cssText = cssText.replace(KEYFRAMES_RE, \"\");\n const IMPORT_RE = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n const UNIFIED_RE = new RegExp(\n // eslint-disable-next-line\n \"((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})\",\n \"gi\"\n );\n while (true) {\n let matches = IMPORT_RE.exec(cssText);\n if (!matches) {\n matches = UNIFIED_RE.exec(cssText);\n if (!matches) {\n break;\n } else {\n IMPORT_RE.lastIndex = UNIFIED_RE.lastIndex;\n }\n } else {\n UNIFIED_RE.lastIndex = IMPORT_RE.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nconst URL_WITH_FORMAT_RE = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_RE = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction filterPreferredFormat(str, context) {\n const { font } = context;\n const preferredFormat = font ? font?.preferredFormat : void 0;\n return preferredFormat ? str.replace(FONT_SRC_RE, (match) => {\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_RE.exec(match) || [];\n if (!format)\n return \"\";\n if (format === preferredFormat)\n return `src: ${src};`;\n }\n }) : str;\n}\nfunction unwrapCssLayers(rules, out = []) {\n for (const rule of Array.from(rules)) {\n if (isLayerBlockRule(rule)) {\n out.push(...unwrapCssLayers(rule.cssRules));\n } else if (\"cssRules\" in rule) {\n unwrapCssLayers(rule.cssRules, out);\n } else {\n out.push(rule);\n }\n }\n return out;\n}\n\nconst SVG_EXTERNAL_RESOURCE_REGEX = /\\bx?link:?href\\s*=\\s*[\"'](?!data:)[^\"']+[\"']/i;\nfunction svgHasExternalResources(svg) {\n return SVG_EXTERNAL_RESOURCE_REGEX.test(svg.innerHTML);\n}\nasync function domToForeignObjectSvg(node, options) {\n const context = await orCreateContext(node, options);\n if (isElementNode(context.node) && isSVGElementNode(context.node) && !svgHasExternalResources(context.node))\n return context.node;\n const {\n ownerDocument,\n log,\n tasks,\n svgStyleElement,\n svgDefsElement,\n svgStyles,\n font,\n progress,\n autoDestruct,\n onCloneNode,\n onEmbedNode,\n onCreateForeignObjectSvg\n } = context;\n log.time(\"clone node\");\n const clone = await cloneNode(context.node, context, true);\n if (svgStyleElement && ownerDocument) {\n let allCssText = \"\";\n svgStyles.forEach((klasses, cssText) => {\n allCssText += `${klasses.join(\",\\n\")} {\n ${cssText}\n}\n`;\n });\n svgStyleElement.appendChild(ownerDocument.createTextNode(allCssText));\n }\n log.timeEnd(\"clone node\");\n await onCloneNode?.(clone);\n if (font !== false && isElementNode(clone)) {\n log.time(\"embed web font\");\n await embedWebFont(clone, context);\n log.timeEnd(\"embed web font\");\n }\n log.time(\"embed node\");\n embedNode(clone, context);\n const count = tasks.length;\n let current = 0;\n const runTask = async () => {\n while (true) {\n const task = tasks.pop();\n if (!task)\n break;\n try {\n await task;\n } catch (error) {\n context.log.warn(\"Failed to run task\", error);\n }\n progress?.(++current, count);\n }\n };\n progress?.(current, count);\n await Promise.all([...Array.from({ length: 4 })].map(runTask));\n log.timeEnd(\"embed node\");\n await onEmbedNode?.(clone);\n const svg = createForeignObjectSvg(clone, context);\n svgDefsElement && svg.insertBefore(svgDefsElement, svg.children[0]);\n svgStyleElement && svg.insertBefore(svgStyleElement, svg.children[0]);\n autoDestruct && destroyContext(context);\n await onCreateForeignObjectSvg?.(svg);\n return svg;\n}\nfunction createForeignObjectSvg(clone, context) {\n const { width, height } = context;\n const svg = createSvg(width, height, clone.ownerDocument);\n const foreignObject = svg.ownerDocument.createElementNS(svg.namespaceURI, \"foreignObject\");\n foreignObject.setAttributeNS(null, \"x\", \"0%\");\n foreignObject.setAttributeNS(null, \"y\", \"0%\");\n foreignObject.setAttributeNS(null, \"width\", \"100%\");\n foreignObject.setAttributeNS(null, \"height\", \"100%\");\n foreignObject.append(clone);\n svg.appendChild(foreignObject);\n return svg;\n}\n\nasync function domToCanvas(node, options) {\n const context = await orCreateContext(node, options);\n const svg = await domToForeignObjectSvg(context);\n const dataUrl = svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n if (!context.autoDestruct) {\n context.svgStyleElement = createStyleElement(context.ownerDocument);\n context.svgDefsElement = context.ownerDocument?.createElementNS(XMLNS, \"defs\");\n context.svgStyles.clear();\n }\n const image = createImage(dataUrl, svg.ownerDocument);\n return await imageToCanvas(image, context);\n}\n\nasync function domToBlob(node, options) {\n const context = await orCreateContext(node, options);\n const { log, type, quality, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to blob\");\n const blob = await canvasToBlob(canvas, type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi) {\n const arrayBuffer = await blobToArrayBuffer(blob.slice(0, 33));\n let uint8Array = new Uint8Array(arrayBuffer);\n if (type === \"image/png\") {\n uint8Array = changePngDpi(uint8Array, dpi);\n } else if (type === \"image/jpeg\") {\n uint8Array = changeJpegDpi(uint8Array, dpi);\n }\n log.timeEnd(\"canvas to blob\");\n return new Blob([uint8Array, blob.slice(33)], { type });\n }\n log.timeEnd(\"canvas to blob\");\n return blob;\n}\n\nasync function domToDataUrl(node, options) {\n const context = await orCreateContext(node, options);\n const { log, quality, type, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to data url\");\n let dataUrl = canvas.toDataURL(type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi && SUPPORT_ATOB && SUPPORT_BTOA) {\n const [format, body] = dataUrl.split(\",\");\n let headerLength = 0;\n let overwritepHYs = false;\n if (type === \"image/png\") {\n const b64Index = detectPhysChunkFromDataUrl(body);\n if (b64Index >= 0) {\n headerLength = Math.ceil((b64Index + 28) / 3) * 4;\n overwritepHYs = true;\n } else {\n headerLength = 33 / 3 * 4;\n }\n } else if (type === \"image/jpeg\") {\n headerLength = 18 / 3 * 4;\n }\n const stringHeader = body.substring(0, headerLength);\n const restOfData = body.substring(headerLength);\n const headerBytes = window.atob(stringHeader);\n const uint8Array = new Uint8Array(headerBytes.length);\n for (let i = 0; i < uint8Array.length; i++) {\n uint8Array[i] = headerBytes.charCodeAt(i);\n }\n const finalArray = type === \"image/png\" ? changePngDpi(uint8Array, dpi, overwritepHYs) : changeJpegDpi(uint8Array, dpi);\n const base64Header = window.btoa(String.fromCharCode(...finalArray));\n dataUrl = [format, \",\", base64Header, restOfData].join(\"\");\n }\n log.timeEnd(\"canvas to data url\");\n return dataUrl;\n}\n\nasync function domToSvg(node, options) {\n const context = await orCreateContext(node, options);\n const { width, height, ownerDocument } = context;\n const dataUrl = await domToDataUrl(context);\n const svg = createSvg(width, height, ownerDocument);\n const svgImage = svg.ownerDocument.createElementNS(svg.namespaceURI, \"image\");\n svgImage.setAttributeNS(null, \"href\", dataUrl);\n svgImage.setAttributeNS(null, \"height\", \"100%\");\n svgImage.setAttributeNS(null, \"width\", \"100%\");\n svg.appendChild(svgImage);\n return svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n}\n\nasync function domToImage(node, options) {\n const context = await orCreateContext(node, options);\n const { ownerDocument, width, height, scale, type } = context;\n const url = type === \"image/svg+xml\" ? await domToSvg(context) : await domToDataUrl(context);\n const image = createImage(url, ownerDocument);\n image.width = Math.floor(width * scale);\n image.height = Math.floor(height * scale);\n image.style.width = `${width}px`;\n image.style.height = `${height}px`;\n return image;\n}\n\nasync function domToJpeg(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/jpeg\" })\n );\n}\n\nasync function domToPixel(node, options) {\n const context = await orCreateContext(node, options);\n const canvas = await domToCanvas(context);\n return canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height).data;\n}\n\nasync function domToPng(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/png\" })\n );\n}\n\nasync function domToWebp(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/webp\" })\n );\n}\n\nexport { createContext, destroyContext, domToBlob, domToCanvas, domToDataUrl, domToForeignObjectSvg, domToImage, domToJpeg, domToPixel, domToPng, domToSvg, domToWebp, loadMedia, waitUntilLoad };\n","import { domToBlob } from \"modern-screenshot\";\n\nimport { isFixbackHostElement } from \"./dom\";\n\n/**\n * Client-side masked screenshot capture (spec MVP §E; ticket #54; ADR-0014).\n *\n * The capture is **private-by-default**: input values are masked and the SDK's own\n * UI is excluded from a *clone* of the view **before** anything is rasterised, so no\n * unmasked text and none of Fixback's chrome ever reaches the image.\n *\n * The rasterisation itself is delegated to `modern-screenshot` (ADR-0014): it clones\n * the target, inlines the page's real styles **and** its fonts and images as data\n * URIs, then draws the result through an SVG `<foreignObject>` onto a `<canvas>`.\n * That closes the fidelity gap a hand-rolled `<foreignObject>` left open — external\n * stylesheets, web fonts, and same-origin images now render — so the shot matches\n * what the Reporter saw and lines up with the annotation's viewport-space marks.\n *\n * We keep the privacy guarantee by driving it through two of its hooks: `filter`\n * drops Fixback's own host elements, and `onCloneNode` masks the clone's inputs —\n * both run on the library's internal clone, before it embeds or serialises anything,\n * so the live page is never touched and no real value reaches the raster. The backend\n * is injectable so the pipeline (and the masking-before-capture guarantee) is testable\n * without a real canvas, and it fails quietly: any problem resolves to `null` and the\n * report is simply sent without a screenshot.\n */\n\n/** The character private input content is replaced with. */\nexport const MASK_CHAR = \"•\";\n\n/** Upper bound on mask length, so a huge field doesn't produce a huge string. */\nconst MAX_MASK_LENGTH = 32;\n\n/** Input `type`s that carry no free-text private data, so are left as-is. */\nconst NON_TEXT_INPUT_TYPES = new Set([\n \"button\",\n \"submit\",\n \"reset\",\n \"checkbox\",\n \"radio\",\n \"range\",\n \"color\",\n \"file\",\n \"image\",\n \"hidden\",\n]);\n\nfunction maskString(length: number): string {\n const n = Math.min(Math.max(length, 1), MAX_MASK_LENGTH);\n return MASK_CHAR.repeat(n);\n}\n\n/**\n * Mask the private, user-entered content in a subtree: text `input` values,\n * `textarea` content, and `contenteditable` text. Developer-authored text\n * (placeholders, button labels, non-text controls) is left untouched. Operates in\n * place — call it on a *clone* of the view, never the live page.\n */\nexport function maskInputs(root: ParentNode): void {\n for (const input of Array.from(root.querySelectorAll(\"input\"))) {\n const type = (input.getAttribute(\"type\") ?? \"text\").toLowerCase();\n if (NON_TEXT_INPUT_TYPES.has(type)) continue;\n const value = input.value;\n if (!value) continue;\n const masked = maskString(value.length);\n input.value = masked;\n input.setAttribute(\"value\", masked);\n }\n\n for (const area of Array.from(root.querySelectorAll(\"textarea\"))) {\n const value = area.value || area.textContent || \"\";\n if (!value) continue;\n const masked = maskString(value.length);\n area.value = masked;\n area.textContent = masked;\n // A `<textarea>` has no `value` attribute of its own, but the raster backend\n // (modern-screenshot) mirrors the live `value` onto one when it clones. Mask\n // that too, so the un-rendered attribute can't carry the real text into the\n // serialised DOM the rasteriser consumes.\n area.setAttribute(\"value\", masked);\n }\n\n for (const editable of Array.from(\n root.querySelectorAll<HTMLElement>(\"[contenteditable]\"),\n )) {\n if (editable.getAttribute(\"contenteditable\") === \"false\") continue;\n const text = editable.textContent ?? \"\";\n if (!text.trim()) continue;\n editable.textContent = maskString(text.length);\n }\n}\n\n/** A captured screenshot: the image bytes plus its dimensions and content type. */\nexport interface Capture {\n readonly blob: Blob;\n readonly width: number;\n readonly height: number;\n readonly type: string;\n}\n\n/** Content type → screenshot file extension. */\nconst SCREENSHOT_EXTENSIONS: Readonly<Record<string, string>> = {\n \"image/png\": \"png\",\n \"image/jpeg\": \"jpg\",\n \"image/webp\": \"webp\",\n \"image/gif\": \"gif\",\n};\n\n/** The screenshot filename extension for a {@link Capture}'s content type (defaults to `png`). */\nexport function extensionFor(type: string): string {\n return SCREENSHOT_EXTENSIONS[type] ?? \"png\";\n}\n\n/** How the SDK prepares a capture: exclude Fixback's UI, mask the clone's inputs. */\ninterface CaptureHooks {\n /** Keep a node in the shot? Returns `false` for Fixback's own host elements. */\n readonly filter: (node: Node) => boolean;\n /** Mask private input content on the library's internal clone, pre-raster. */\n readonly onCloneNode: (clone: Node) => void;\n}\n\n/** Turns a DOM subtree into image bytes at a given size (injectable for tests). */\nexport type CaptureBackend = (\n target: Element,\n meta: { width: number; height: number; type: string } & CaptureHooks,\n) => Promise<Blob | null>;\n\n/** Options for {@link captureView}. */\nexport interface CaptureOptions {\n /** The element to capture. Defaults to the document element (the full view). */\n readonly target?: Element;\n readonly doc?: Document;\n readonly win?: Window;\n /** Output content type. Defaults to `image/png`. */\n readonly type?: string;\n /** Override the raster backend (the default is `modern-screenshot`). */\n readonly capture?: CaptureBackend;\n}\n\nfunction viewportExtent(\n win: Window | undefined,\n doc: Document,\n axis: \"Width\" | \"Height\",\n): number {\n const inner = win?.[`inner${axis}`];\n const client = doc.documentElement[`client${axis}`];\n const value = typeof inner === \"number\" && inner > 0 ? inner : client;\n return Math.max(1, Math.round(value || 0) || 1);\n}\n\n/** Load media + fetch remote assets timeout — bound the raster so a stuck font\n * or image can't hang the Send. Capture is best-effort: a timeout still yields\n * whatever embedded in time. */\nconst CAPTURE_TIMEOUT_MS = 6000;\n\n/**\n * The default backend: `modern-screenshot`, wired to the privacy hooks. `filter`\n * excludes Fixback's own chrome, `onCloneNode` masks the internal clone's inputs\n * before any embed/serialise, and `width`/`height` pin the raster to the viewport so\n * it shares the annotation marks' coordinate space. Any throw propagates to\n * {@link captureView}'s guard, which resolves it to `null`.\n */\nconst captureViaModernScreenshot: CaptureBackend = (target, meta) =>\n domToBlob(target, {\n width: meta.width,\n height: meta.height,\n type: meta.type,\n timeout: CAPTURE_TIMEOUT_MS,\n filter: meta.filter,\n onCloneNode: meta.onCloneNode,\n });\n\n/**\n * Capture the current view as a masked screenshot. Delegates the raster to the\n * backend ({@link captureViaModernScreenshot} by default), which excludes the SDK's\n * own UI and masks input values on its internal clone — **before** it embeds or\n * serialises anything — then returns the image bytes, or `null` if capture wasn't\n * possible.\n */\nexport async function captureView(\n options: CaptureOptions = {},\n): Promise<Capture | null> {\n try {\n const doc = options.doc ?? document;\n const win = options.win ?? doc.defaultView ?? undefined;\n const target = options.target ?? doc.documentElement;\n const type = options.type ?? \"image/png\";\n const width = viewportExtent(win, doc, \"Width\");\n const height = viewportExtent(win, doc, \"Height\");\n\n const capture = options.capture ?? captureViaModernScreenshot;\n const blob = await capture(target, {\n width,\n height,\n type,\n filter: (node) => !isFixbackHostElement(node),\n onCloneNode: (clone) => maskInputs(clone as ParentNode),\n });\n if (!blob) return null;\n return { blob, width, height, type };\n } catch {\n return null;\n }\n}\n","/**\n * Client-side backpressure for **automatic** error reports (spec 0003 §E/§H,\n * ticket #89). When ingest sheds `source: auto` load it answers `429` with a\n * `Retry-After`; the SDK honours it by holding a pause window during which further\n * `source: auto` reports are dropped without touching the network. **Manual**\n * reports — a human clicking Send — never consult this gate.\n *\n * This is the transport's counterpart to the server's per-Project token bucket\n * (`apps/api/src/ingest/auto-report-rate-limiter.ts`): one shared window per page,\n * so a 429 from one auto-report shed applies to the auto-reports that follow it.\n * The clock is injectable so the window is unit-tested deterministically, never on\n * wall time — mirroring the server limiter's `Clock`.\n */\n\n/** A source of the current time in epoch milliseconds — injectable for tests. */\nexport type Clock = () => number;\n\n/** The hold window applied when a `429` carries no usable `Retry-After` (spec §E). */\nexport const DEFAULT_RETRY_AFTER_SECONDS = 60;\n\n/**\n * Parse a `Retry-After` header into whole seconds to hold for. Handles both HTTP\n * forms — a delta-seconds integer and an HTTP-date (measured from `now`, rounded up\n * and clamped at zero) — and falls back to {@link DEFAULT_RETRY_AFTER_SECONDS} when\n * the header is absent, blank, or unparseable. Ingest sends the delta-seconds form;\n * the date form is handled for spec-completeness.\n */\nexport function parseRetryAfter(\n header: string | null | undefined,\n now: number,\n): number {\n if (header == null) return DEFAULT_RETRY_AFTER_SECONDS;\n const value = header.trim();\n if (value === \"\") return DEFAULT_RETRY_AFTER_SECONDS;\n\n if (/^\\d+$/.test(value)) {\n return Number(value);\n }\n\n const when = Date.parse(value);\n if (!Number.isNaN(when)) {\n return Math.max(0, Math.ceil((when - now) / 1000));\n }\n\n return DEFAULT_RETRY_AFTER_SECONDS;\n}\n\n/**\n * A single pause window for `source: auto` reports. `hold` opens (or extends) it\n * from a `429`'s `Retry-After`; `isPaused` reports whether it is still open. The\n * default instance in `submit.ts` is shared across a page's reports so the hold\n * persists across successive auto submissions.\n */\nexport class AutoReportBackoff {\n /** Epoch ms until which `source: auto` reports are held; `0` when clear. */\n private pausedUntil = 0;\n\n constructor(private readonly now: Clock = Date.now) {}\n\n /** Is the `source: auto` pause window currently open? */\n isPaused(): boolean {\n return this.now() < this.pausedUntil;\n }\n\n /** Whole seconds remaining in the pause window (`0` when clear). */\n retryAfterSeconds(): number {\n return Math.max(0, Math.ceil((this.pausedUntil - this.now()) / 1000));\n }\n\n /**\n * Open (or extend) the window from a `429`'s `Retry-After` value, returning the\n * seconds it will hold for. The window only ever grows — a shorter later hold\n * never clips a longer one already in effect.\n */\n hold(retryAfterHeader: string | null | undefined): number {\n const now = this.now();\n const seconds = parseRetryAfter(retryAfterHeader, now);\n const until = now + seconds * 1000;\n if (until > this.pausedUntil) this.pausedUntil = until;\n return seconds;\n }\n}\n","import { AutoReportBackoff } from \"./auto-report-backoff\";\nimport type { IdentityInputs, ReporterTier } from \"./boot\";\nimport type { FeedbackSource, ReportContent } from \"./report\";\n\n/**\n * The multipart feedback submission — the transport half of the capture loop.\n *\n * `POST /api/ingest/feedback` (spec MVP §C; tickets #50/#53) is a multipart\n * request: a single text part `payload` carrying the JSON (publishable key +\n * identity evidence + content) and an optional binary part `screenshot`. The\n * content-type header is deliberately not set, so the runtime writes the\n * `multipart/form-data` boundary itself. Like `requestBoot`, this never throws:\n * an unreachable Fixback or a refusal is a quiet result, so a Fixback problem\n * never breaks the host page.\n *\n * The `payload` carries the full report content — the structured `annotation`\n * (element + region + marks), the masked `trace` buffer, and the `source`\n * provenance (spec §D); the `screenshot` part is the full masked PNG, never\n * region-cropped. Automatic reports (`source: auto`) additionally honour ingest's\n * `429` + `Retry-After` backpressure: while the hold window is open they are\n * dropped without touching the network. Manual reports are never gated (spec §E/§H).\n */\n\n/** The multipart field the screenshot binary is sent under (mirrors the server). */\nconst SCREENSHOT_FIELD = \"screenshot\";\n\n/** What ingest returns for an accepted submission (vendored server shape). */\nexport interface RecordedFeedback {\n readonly feedbackId: string;\n readonly issueId: string;\n readonly reporterId: string;\n readonly tier: ReporterTier;\n}\n\n/** The captured screenshot to attach, if any. */\nexport interface SubmitScreenshot {\n readonly blob: Blob;\n readonly filename?: string;\n}\n\n/** Everything a single feedback submission carries. */\nexport interface SubmitInput {\n readonly key: string;\n readonly identity?: IdentityInputs;\n readonly content: ReportContent;\n readonly screenshot?: SubmitScreenshot | null;\n}\n\n/** The outcome of a submission — never an exception. */\nexport type SubmitResult =\n | { readonly ok: true; readonly feedback: RecordedFeedback | null }\n | {\n readonly ok: false;\n readonly reason: \"unreachable\" | \"refused\";\n readonly status?: number;\n }\n | {\n /**\n * A `source: auto` report shed under ingest backpressure (spec §E/§H) — either\n * held locally because the window is still open, or answered `429` by ingest,\n * which opened/extended the window. Carries the seconds left to wait. Manual\n * reports never produce this.\n */\n readonly ok: false;\n readonly reason: \"backpressure\";\n readonly retryAfterSeconds: number;\n };\n\n/**\n * The shared `source: auto` backpressure window for the page. One instance so a\n * `429` from an auto-report holds the auto-reports that follow it; tests inject\n * their own {@link AutoReportBackoff} to isolate the clock.\n */\nconst defaultBackoff = new AutoReportBackoff();\n\n/** Join an API base URL with the feedback path, tolerating a trailing slash. */\nexport function feedbackEndpoint(apiUrl: string): string {\n return `${apiUrl.replace(/\\/+$/, \"\")}/api/ingest/feedback`;\n}\n\n/** Drop `undefined` identity fields so the payload carries only what was given. */\nfunction compactIdentity(identity: IdentityInputs | undefined): IdentityInputs {\n if (!identity) return {};\n const out: { signedIdentity?: string; reporterId?: string; anonymousId?: string } = {};\n if (identity.signedIdentity) out.signedIdentity = identity.signedIdentity;\n if (identity.reporterId) out.reporterId = identity.reporterId;\n if (identity.anonymousId) out.anonymousId = identity.anonymousId;\n return out;\n}\n\n/**\n * Submit a report to ingest. Assembles the `payload` JSON (key + identity +\n * content, with an explicit `source` stamped) and the optional full masked\n * `screenshot` file into a `FormData`, posts it, and resolves to the recorded\n * Feedback on success or a named failure otherwise.\n *\n * A `source: auto` report first consults the shared backpressure window: while it\n * is open the report is dropped without a request (spec §E/§H). Ingest's `429` +\n * `Retry-After` opens/extends that window (default 60 s if the header is absent).\n * Manual reports (`source: reporter`, the default) never consult the window and a\n * non-2xx for them stays a plain refusal. The `fetchImpl` and `backoff` seams exist\n * purely so the call is testable.\n */\nexport async function submitReport(\n apiUrl: string,\n input: SubmitInput,\n fetchImpl: typeof fetch = fetch,\n backoff: AutoReportBackoff = defaultBackoff,\n): Promise<SubmitResult> {\n const source: FeedbackSource = input.content.source ?? \"reporter\";\n const isAuto = source === \"auto\";\n\n // Client-side backpressure: shed auto-reports while the hold window is open,\n // without touching the network. Manual reports are never gated.\n if (isAuto && backoff.isPaused()) {\n return {\n ok: false,\n reason: \"backpressure\",\n retryAfterSeconds: backoff.retryAfterSeconds(),\n };\n }\n\n const payload = {\n key: input.key,\n ...compactIdentity(input.identity),\n ...input.content,\n source,\n };\n\n const form = new FormData();\n form.append(\"payload\", JSON.stringify(payload));\n if (input.screenshot?.blob) {\n form.append(\n SCREENSHOT_FIELD,\n input.screenshot.blob,\n input.screenshot.filename ?? \"screenshot.png\",\n );\n }\n\n let response: Response;\n try {\n response = await fetchImpl(feedbackEndpoint(apiUrl), {\n method: \"POST\",\n body: form,\n });\n } catch {\n return { ok: false, reason: \"unreachable\" };\n }\n\n if (!response.ok) {\n // A `429` for an auto-report is backpressure, not a refusal: open/extend the\n // hold window from `Retry-After` and report the wait. Manual reports never 429\n // here, so any non-2xx for them stays a plain refusal.\n if (isAuto && response.status === 429) {\n const retryAfterSeconds = backoff.hold(response.headers.get(\"Retry-After\"));\n return { ok: false, reason: \"backpressure\", retryAfterSeconds };\n }\n return { ok: false, reason: \"refused\", status: response.status };\n }\n\n try {\n const feedback = (await response.json()) as RecordedFeedback;\n return { ok: true, feedback };\n } catch {\n // Accepted, but the body wasn't the expected JSON — still a success.\n return { ok: true, feedback: null };\n }\n}\n","/**\n * The SDK's own version string, reported to ingest as `environment.sdkVersion`\n * (spec MVP §B/§E). Kept as an inlined constant rather than a runtime `package.json`\n * import, so the published bundle stays a single self-contained file.\n *\n * It must equal `package.json`'s `version`. Two things keep it there: the Changesets\n * `version` step syncs it automatically (`scripts/sync-sdk-version.mjs`, wired into\n * `version-packages`), and `version.test.ts` fails the build if the two ever drift —\n * so a stale dogfood version (the SDK reporting an old number on our own dashboard)\n * can't slip through. Do not hand-edit this line to a value other than\n * `package.json`'s version.\n */\nexport const SDK_VERSION = \"0.3.0\";\n","/**\n * Automatic error capture — the SDK's signature capability: **errors report\n * themselves, no prompt** (spec 0003 §E, ADR-0011; research\n * `sentry-error-capture-findings.md` §7.1–7.3, §7.6).\n *\n * Exactly **two capture-phase listeners** (`window` `error` +\n * `unhandledrejection`) turn uncaught exceptions and unhandled rejections into\n * `source: auto`, `Kind = bug` Feedback for the current session's Reporter — no\n * native-API monkeypatching, no library. Each firing is deduped by a per-session\n * fingerprint, rate-limited by a token-bucket burst limiter and a per-session cap,\n * scrubbed through the same `beforeSend` choke point as manual reports (§C), and\n * shipped through the same transport (which honours ingest's `429` / `Retry-After`\n * backpressure, ticket #89). `console.error` is **not** promoted — it stays\n * breadcrumb-only Evidence.\n *\n * Per-firing order (research §7.1): **`canSubmit`/Gate → dedup → rate-limit/cap →\n * `beforeSend` scrub → enqueue Feedback**. The Gate is honoured by construction:\n * `init` installs this only when boot returned `canSubmit`, so an auto-error is\n * never filed where a manual report would be refused, and it inherits the session\n * Reporter's server-derived tier.\n *\n * The whole module is defensive — every handler is wrapped so a Fixback problem\n * (or an error thrown while capturing an error) never surfaces on the host page.\n * The fingerprint/`normalize` shape and the limiter numbers are **starting points**\n * from research (ticket #92), exposed as config — tunable, not frozen.\n */\n\nimport type { IdentityInputs } from \"./boot\";\nimport {\n type Breadcrumb,\n type BreadcrumbBuffer,\n errorCrumb,\n type Teardown,\n} from \"./breadcrumbs\";\nimport { assembleContent, collectEnvironment, type ReportContent } from \"./report\";\nimport { runBeforeSend, type BeforeSend } from \"./scrub\";\nimport { captureView, extensionFor, type Capture, type CaptureOptions } from \"./screenshot\";\nimport { submitReport, type SubmitInput, type SubmitResult } from \"./submit\";\nimport { SDK_VERSION } from \"./version\";\n\nexport type { Teardown };\n\n/** Burst limiter capacity — how many auto-reports may fire back-to-back (§E). */\nexport const DEFAULT_BURST_CAPACITY = 5;\n/** Burst limiter refill — one token returns every this-many ms (§E). */\nexport const DEFAULT_BURST_REFILL_MS = 2_000;\n/** Per-session ceiling on distinct auto-Feedback; beyond it, only a dropped-count (§E). */\nexport const DEFAULT_MAX_DISTINCT_AUTO = 20;\n\n/** How many top stack frames feed the fingerprint (research §7.2). */\nconst FINGERPRINT_FRAME_LIMIT = 5;\n\n/** How many preceding entries an auto-error's causal pointer names (spec #122 §F). */\nconst CAUSED_BY_LIMIT = 5;\n\n/**\n * The ids of up to the last {@link CAUSED_BY_LIMIT} entries preceding the throw, in\n * time order — the causal pointer an auto-captured error carries (spec #122 §F), so a\n * machine-filed crash names its lead-up. Entries without an id are skipped.\n */\nfunction precedingIds(entries: readonly Breadcrumb[] | undefined): string[] {\n if (!entries || entries.length === 0) return [];\n const ids: string[] = [];\n for (let i = entries.length - 1; i >= 0 && ids.length < CAUSED_BY_LIMIT; i -= 1) {\n const id = entries[i]?.id;\n if (typeof id === \"string\" && id.length > 0) ids.unshift(id);\n }\n return ids;\n}\n\n// --- Fingerprint (per-session flood-guard key, research §7.2) -----------------\n\nconst UUID_RE =\n /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;\nconst URL_RE = /\\bhttps?:\\/\\/[^\\s\"')]+/gi;\nconst HEX_0X_RE = /\\b0x[0-9a-f]+\\b/gi;\nconst HEX_RUN_RE = /\\b[0-9a-f]{8,}\\b/gi;\nconst DIGIT_RUN_RE = /\\d{4,}/g;\n\n/**\n * Collapse the volatile parts of an error message so a changing string doesn't\n * split one bug: UUIDs, URLs, `0x…` and long hex runs, and long digit runs are\n * replaced with stable placeholders. Short numbers and stable text are kept so\n * genuinely distinct bugs stay distinct. A small, dependency-free regex set —\n * tunable per ticket #92, never a frozen magic set.\n */\nexport function normalize(value: string): string {\n if (typeof value !== \"string\" || value.length === 0) return \"\";\n return value\n .replace(UUID_RE, \"<uuid>\")\n .replace(URL_RE, \"<url>\")\n .replace(HEX_0X_RE, \"<hex>\")\n .replace(HEX_RUN_RE, \"<hex>\")\n .replace(DIGIT_RUN_RE, \"<n>\")\n .trim();\n}\n\n/**\n * A dependency-free FNV-1a hash rendered in base-36. It only has to be stable and\n * well-distributed within one session (the client key is a flood guard; the server\n * does canonical cross-session clustering), so a non-cryptographic hash is right.\n */\nexport function hashString(input: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(36);\n}\n\n/** Reduce a frame location to `basename:line:col`, dropping origin and query. */\nfunction compactLocation(location: string): string {\n const noQuery = location.replace(/\\?[^:]*/, \"\");\n const lastSlash = noQuery.lastIndexOf(\"/\");\n return lastSlash >= 0 ? noQuery.slice(lastSlash + 1) : noQuery;\n}\n\n/** Parse one stack line into a compact `function@basename:line:col` frame id. */\nfunction parseFrame(line: string): string | null {\n // V8: \"at fn (loc)\" | \"at loc\"\n const v8Named = line.match(/^at\\s+(.+?)\\s+\\((.+)\\)$/);\n if (v8Named) return `${v8Named[1] ?? \"\"}@${compactLocation(v8Named[2] ?? \"\")}`;\n const v8Bare = line.match(/^at\\s+(.+)$/);\n if (v8Bare) return `@${compactLocation(v8Bare[1] ?? \"\")}`;\n // Firefox / Safari: \"fn@loc\" | \"@loc\"\n const at = line.indexOf(\"@\");\n if (at >= 0) {\n const fn = line.slice(0, at);\n return `${fn}@${compactLocation(line.slice(at + 1))}`;\n }\n return null;\n}\n\n/**\n * Extract a compact, stable signature of the top in-app frames of a stack: up to\n * {@link FINGERPRINT_FRAME_LIMIT} frames as `function@basename:line:col`, origin\n * and cache-busting query stripped so a per-deploy asset hash doesn't matter within\n * a session. Returns `\"\"` when there is no usable stack (message-only fallback).\n */\nexport function extractTopFrames(\n stack: string | undefined,\n limit = FINGERPRINT_FRAME_LIMIT,\n): string {\n if (typeof stack !== \"string\" || stack.length === 0) return \"\";\n const frames: string[] = [];\n for (const raw of stack.split(\"\\n\")) {\n const frame = parseFrame(raw.trim());\n if (frame) {\n frames.push(frame);\n if (frames.length >= limit) break;\n }\n }\n return frames.join(\" < \");\n}\n\n/**\n * The per-session fingerprint (research §7.2):\n * `hash(errorType + \"|\" + normalize(value) + \"|\" + topFrames)`. Stack frames\n * dominate when present; otherwise it falls back to type + normalized value.\n */\nexport function computeFingerprint(\n type: string,\n value: string,\n stack?: string,\n): string {\n return hashString(`${type}|${normalize(value)}|${extractTopFrames(stack)}`);\n}\n\n// --- Burst limiter (token bucket, research §7.3) ------------------------------\n\n/** Configuration for {@link TokenBucket}. */\nexport interface TokenBucketOptions {\n readonly capacity: number;\n readonly refillIntervalMs: number;\n /** Clock source, injectable for tests. Defaults to `Date.now`. */\n readonly now?: () => number;\n}\n\n/**\n * A token bucket: starts full at `capacity`, refills one token every\n * `refillIntervalMs`, and refuses (`take() === false`) when empty. So a fast error\n * loop that dodges dedup with distinct fingerprints still can't machine-gun ingest.\n * The clock is injectable so the window is unit-tested deterministically.\n */\nexport class TokenBucket {\n private tokens: number;\n private last: number;\n private readonly now: () => number;\n\n constructor(private readonly options: TokenBucketOptions) {\n this.now = options.now ?? Date.now;\n this.tokens = Math.max(0, options.capacity);\n this.last = this.now();\n }\n\n /** Consume a token if one is available (refilling first), else refuse. */\n take(): boolean {\n const now = this.now();\n const { capacity, refillIntervalMs } = this.options;\n if (refillIntervalMs > 0 && now > this.last) {\n const refill = Math.floor((now - this.last) / refillIntervalMs);\n if (refill > 0) {\n this.tokens = Math.min(capacity, this.tokens + refill);\n this.last += refill * refillIntervalMs;\n }\n }\n if (this.tokens >= 1) {\n this.tokens -= 1;\n return true;\n }\n return false;\n }\n}\n\n// --- Error extraction ---------------------------------------------------------\n\n/** The distilled shape a fingerprint + report is built from. */\ninterface ExtractedError {\n readonly type: string;\n readonly value: string;\n readonly stack?: string;\n /** The original throwable (Error or rejection reason) for the trace crumb. */\n readonly original: unknown;\n}\n\ninterface ErrorLike {\n name?: unknown;\n message?: unknown;\n stack?: unknown;\n}\n\nfunction asString(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (value == null) return \"\";\n try {\n return String(value);\n } catch {\n return \"\";\n }\n}\n\n/** Distil an uncaught `error` event into a fingerprint-able shape, or `null`. */\nfunction extractFromErrorEvent(event: Event): ExtractedError | null {\n const e = event as ErrorEvent & { error?: unknown };\n const error = e.error;\n if (error && typeof error === \"object\") {\n const err = error as ErrorLike;\n return {\n type: asString(err.name) || \"Error\",\n value: asString(err.message) || asString(e.message),\n stack: typeof err.stack === \"string\" ? err.stack : undefined,\n original: error,\n };\n }\n // No Error object: a message-only event (some browsers) is still capturable.\n const message = asString(e.message);\n if (message) return { type: \"Error\", value: message, original: message };\n // A resource-load error (img/script) has neither — never an uncaught exception.\n return null;\n}\n\n/** Distil an `unhandledrejection` event into a fingerprint-able shape, or `null`. */\nfunction extractFromRejectionEvent(event: Event): ExtractedError | null {\n const reason = (event as Event & { reason?: unknown }).reason;\n if (reason && typeof reason === \"object\") {\n const err = reason as ErrorLike;\n const type = asString(err.name) || \"UnhandledRejection\";\n const value = asString(err.message) || asString(reason);\n return {\n type,\n value,\n stack: typeof err.stack === \"string\" ? err.stack : undefined,\n original: reason,\n };\n }\n const value = asString(reason);\n return { type: \"UnhandledRejection\", value, original: reason ?? value };\n}\n\n// --- The capture controller ---------------------------------------------------\n\n/** Injectable collaborators, defaulted to the real implementations. */\nexport interface AutoCaptureDeps {\n readonly captureView: (options?: CaptureOptions) => Promise<Capture | null>;\n readonly submitReport: (\n apiUrl: string,\n input: SubmitInput,\n fetchImpl?: typeof fetch,\n ) => Promise<SubmitResult>;\n}\n\n/** Configuration for {@link installErrorCapture}. */\nexport interface AutoCaptureConfig {\n readonly apiUrl: string;\n readonly key: string;\n readonly identity?: IdentityInputs;\n /** The window whose global handlers are installed. Defaults to `window`. */\n readonly win?: Window;\n /** The document used for capture + environment. Defaults to the window's. */\n readonly doc?: Document;\n readonly sdkVersion?: string;\n /** The shared trace buffer; the failing error is added to it before filing. */\n readonly buffer?: BreadcrumbBuffer | null;\n /** Per-project client scrub hook, run at the `beforeSend` choke point (§C). */\n readonly beforeSend?: BeforeSend;\n /** Run the built-in default scrubbers. Defaults to `true` (private-by-default). */\n readonly scrub?: boolean;\n readonly deps?: Partial<AutoCaptureDeps>;\n /** Burst limiter capacity. Defaults to {@link DEFAULT_BURST_CAPACITY}. */\n readonly burstCapacity?: number;\n /** Burst limiter refill interval (ms). Defaults to {@link DEFAULT_BURST_REFILL_MS}. */\n readonly burstRefillMs?: number;\n /** Per-session distinct-Feedback cap. Defaults to {@link DEFAULT_MAX_DISTINCT_AUTO}. */\n readonly maxDistinct?: number;\n /** Clock source, injectable for tests. Defaults to `Date.now`. */\n readonly now?: () => number;\n}\n\n/** A per-session record of one fingerprinted error. */\ninterface AutoEntry {\n count: number;\n firstAt: number;\n lastAt: number;\n /** The occurrence count last shipped to ingest (`0` until the first send). */\n sentCount: number;\n}\n\n/** What to include when filing — a first report is rich; a flush is a light count update. */\ninterface FileOptions {\n readonly screenshot: boolean;\n readonly trace: boolean;\n}\n\n/** A running auto-capture: its teardown, plus the local dropped-count (spec §E). */\nexport interface AutoCaptureHandle {\n /** Remove the two global handlers and the flush hooks. Safe to call repeatedly. */\n readonly destroy: Teardown;\n /**\n * Distinct auto-Feedback dropped by the burst limiter or the per-session cap —\n * the \"keep only a local dropped-count\" fallback beyond the guardrails (spec §E).\n */\n droppedCount(): number;\n}\n\nconst NOOP_HANDLE: AutoCaptureHandle = { destroy: () => {}, droppedCount: () => 0 };\n\n/**\n * Install automatic error capture on a window and return a handle whose `destroy`\n * removes every listener it added (the two global handlers plus the flush hooks).\n * The caller (`init`) installs this only after boot returned `canSubmit`, so the\n * Gate is respected and the auto-error inherits the session Reporter's tier.\n */\nexport function installErrorCapture(config: AutoCaptureConfig): AutoCaptureHandle {\n const maybeWin =\n config.win ?? (typeof window !== \"undefined\" ? window : undefined);\n if (!maybeWin) return NOOP_HANDLE;\n const win: Window = maybeWin;\n const doc: Document | undefined =\n config.doc ??\n win.document ??\n (typeof document !== \"undefined\" ? document : undefined);\n\n const now = config.now ?? Date.now;\n const sdkVersion = config.sdkVersion ?? SDK_VERSION;\n const maxDistinct = config.maxDistinct ?? DEFAULT_MAX_DISTINCT_AUTO;\n const captureViewFn = config.deps?.captureView ?? captureView;\n const submitReportFn = config.deps?.submitReport ?? submitReport;\n\n const bucket = new TokenBucket({\n capacity: config.burstCapacity ?? DEFAULT_BURST_CAPACITY,\n refillIntervalMs: config.burstRefillMs ?? DEFAULT_BURST_REFILL_MS,\n now,\n });\n\n const seen = new Map<string, AutoEntry>();\n /** Distinct auto-Feedback dropped by the burst limiter or the session cap. */\n let dropped = 0;\n\n /** Build the `source: auto` content for a fingerprint at a given occurrence count. */\n function buildContent(fp: string, occurrences: number, opts: FileOptions): ReportContent {\n const base = assembleContent({\n kind: \"bug\",\n url: win.location?.href,\n environment: collectEnvironment(win, sdkVersion),\n trace: opts.trace ? config.buffer?.snapshot() : undefined,\n });\n return { ...base, source: \"auto\", errorSignature: fp, occurrences };\n }\n\n /**\n * Assemble, scrub, (optionally) screenshot, and ship one auto-Feedback. Sets the\n * entry's `sentCount` optimistically so a concurrent flush never double-sends,\n * and rolls it back on a failed send so the flush can retry the count update. A\n * `beforeSend` that returns `null` drops the report without transport.\n */\n async function file(fp: string, occurrences: number, opts: FileOptions): Promise<void> {\n const entry = seen.get(fp);\n if (!entry) return;\n const previouslySent = entry.sentCount;\n entry.sentCount = occurrences;\n try {\n const draft = buildContent(fp, occurrences, opts);\n const content = runBeforeSend(draft, {\n hook: config.beforeSend,\n scrub: config.scrub,\n });\n if (!content) return; // dropped at the client scrub choke point — no transport.\n\n let screenshot: SubmitInput[\"screenshot\"] = null;\n if (opts.screenshot) {\n const capture = await captureViewFn({ doc, win });\n screenshot = capture\n ? { blob: capture.blob, filename: `screenshot.${extensionFor(capture.type)}` }\n : null;\n }\n\n const result = await submitReportFn(config.apiUrl, {\n key: config.key,\n identity: config.identity,\n content,\n screenshot,\n });\n if (!result.ok && entry.sentCount === occurrences) {\n // Held under backpressure, refused, or unreachable — let a later flush retry.\n entry.sentCount = previouslySent;\n }\n } catch {\n if (entry.sentCount === occurrences) entry.sentCount = previouslySent;\n // The error path must never throw into the host page.\n }\n }\n\n /** Handle one distilled error: dedup → burst limiter → session cap → file. */\n function handle(extracted: ExtractedError): void {\n const fp = computeFingerprint(extracted.type, extracted.value, extracted.stack);\n const existing = seen.get(fp);\n if (existing) {\n // Dedup: one Feedback per fingerprint per session; count locally, flush later.\n existing.count += 1;\n existing.lastAt = now();\n return;\n }\n if (!bucket.take()) {\n dropped += 1; // burst limiter\n return;\n }\n if (seen.size >= maxDistinct) {\n dropped += 1; // per-session cap — keep only the local dropped-count\n return;\n }\n const at = now();\n seen.set(fp, { count: 1, firstAt: at, lastAt: at, sentCount: 0 });\n // The failing error joins the trace so the lead-up and the failure both show,\n // carrying a causal pointer to the ids of the entries that preceded the throw.\n try {\n const causedBy = precedingIds(config.buffer?.snapshot());\n config.buffer?.add(errorCrumb(extracted.original, at, causedBy));\n } catch {\n /* capture must never throw into the host page */\n }\n void file(fp, 1, { screenshot: true, trace: true });\n }\n\n const onError = (event: Event): void => {\n try {\n const extracted = extractFromErrorEvent(event);\n if (extracted) handle(extracted);\n } catch {\n /* never throw into the host page */\n }\n };\n\n const onRejection = (event: Event): void => {\n try {\n const extracted = extractFromRejectionEvent(event);\n if (extracted) handle(extracted);\n } catch {\n /* never throw into the host page */\n }\n };\n\n /** Flush the final occurrence count of every fingerprint that grew since its send. */\n const flush = (): void => {\n try {\n for (const [fp, entry] of seen) {\n if (entry.count > entry.sentCount) {\n void file(fp, entry.count, { screenshot: false, trace: false });\n }\n }\n } catch {\n /* best-effort on unload */\n }\n };\n\n const onVisibility = (): void => {\n if (doc?.visibilityState === \"hidden\") flush();\n };\n\n win.addEventListener(\"error\", onError, true);\n win.addEventListener(\"unhandledrejection\", onRejection, true);\n win.addEventListener(\"pagehide\", flush);\n doc?.addEventListener(\"visibilitychange\", onVisibility);\n\n return {\n destroy: () => {\n win.removeEventListener(\"error\", onError, true);\n win.removeEventListener(\"unhandledrejection\", onRejection, true);\n win.removeEventListener(\"pagehide\", flush);\n doc?.removeEventListener(\"visibilitychange\", onVisibility);\n },\n droppedCount: () => dropped,\n };\n}\n","/**\n * The Public Reporter's stable, first-party anonymous id.\n *\n * When the host site does not supply its own identity, the SDK establishes a\n * per-browser id and persists it, so repeated boots from the same browser are one\n * Reporter (the server counts distinct Reporters by it). Persistence is\n * best-effort: if storage is unavailable (private mode, blocked cookies), we fall\n * back to an ephemeral id rather than throw — the SDK must never disturb the host\n * page.\n */\n\nconst STORAGE_KEY = \"fixback.anonymousId\";\n\n/** A random id: a UUID where the platform offers one, else a compact fallback. */\nfunction generateId(): string {\n const c: Crypto | undefined = globalThis.crypto;\n if (c && typeof c.randomUUID === \"function\") return c.randomUUID();\n return `fb-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Return this browser's anonymous id, creating and persisting one on first use. */\nexport function ensureAnonymousId(): string {\n try {\n const store = globalThis.localStorage;\n const existing = store.getItem(STORAGE_KEY);\n if (existing) return existing;\n const id = generateId();\n store.setItem(STORAGE_KEY, id);\n return id;\n } catch {\n // Storage blocked or absent — an ephemeral id keeps this boot working.\n return generateId();\n }\n}\n","/**\n * Invite redemption & reporter identity (spec §F).\n *\n * The zero-integration path for an invited tester: detect an invite token on the\n * page (`?fixback_invite=<token>`) or an explicit `redeem()` call, read the\n * Invite's public status, and — on confirmation — redeem it into a persisted\n * `reporterId` the SDK thereafter presents as an identity input.\n *\n * This module is the wire + storage half (pure enough to unit-test directly): the\n * two invite endpoints, the localStorage persistence scoped by publishable key,\n * and the URL token detection / one-time consumption. The onboarding modal is\n * `onboarding.ts`; `init` wires the two together.\n *\n * Like `boot.ts`, the wire types are a **vendored** slice of the server contract\n * (`apps/api/src/invites/invite-redemption.controller.ts`) — the SDK never imports\n * the private server package. Keep them in lock-step with that controller.\n */\n\nimport type { ReporterTier } from \"./boot\";\n\n/** The Invite's shape. Mirrors the server's `InviteKind`. */\nexport type InviteKind = \"targeted\" | \"shared\";\n\n/** The dead/unknown states a status or redeem read can resolve to. */\nexport type InviteDeadStatus = \"revoked\" | \"expired\" | \"exhausted\" | \"not_found\";\n\n/**\n * The public status of an Invite (`GET /api/invites/:token`). A live (`pending`)\n * Invite reveals the minimal facts the onboarding modal needs — the Project, the\n * Invite's shape, and the **server-derived** tier the redemption would grant; a\n * dead or unknown token reveals only its state.\n */\nexport type InviteStatusAnswer =\n | {\n readonly status: \"pending\";\n readonly projectId: string;\n readonly kind: InviteKind;\n readonly tier: ReporterTier;\n }\n | { readonly status: InviteDeadStatus };\n\n/**\n * The result of redeeming an Invite (`POST /api/invites/:token/redeem`): the\n * minted Reporter (its handle + server-derived tier + Project), or why it was\n * refused.\n */\nexport type RedeemAnswer =\n | {\n readonly status: \"redeemed\";\n readonly reporterId: string;\n readonly tier: ReporterTier;\n readonly projectId: string;\n }\n | { readonly status: InviteDeadStatus };\n\n/**\n * The self-provided display fields captured in the onboarding modal. They ride\n * along as a Reporter's chosen name / email — **never** a trust signal (the tier\n * is always server-derived, spec §F).\n */\nexport interface ReporterDisplay {\n readonly name?: string;\n readonly email?: string;\n}\n\n/** A persisted redeemed Reporter: the server handle plus the display fields. */\nexport interface StoredReporter extends ReporterDisplay {\n readonly reporterId: string;\n}\n\n/** The URL query parameter that carries an invite token. */\nexport const INVITE_QUERY_PARAM = \"fixback_invite\";\n\n/** localStorage namespace for a redeemed Reporter, scoped by publishable key. */\nconst REPORTER_STORAGE_PREFIX = \"fixback:reporter:\";\n\n// ---------------------------------------------------------------------------\n// URL token detection & one-time consumption\n// ---------------------------------------------------------------------------\n\n/**\n * Read the invite token from a page URL's `?fixback_invite=` param. Returns the\n * token, or `null` when absent, empty, or the URL cannot be parsed — never throws.\n */\nexport function readInviteToken(href: string): string | null {\n try {\n const token = new URL(href).searchParams.get(INVITE_QUERY_PARAM);\n return token && token.length > 0 ? token : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Strip the invite token from the address bar (one-time consumption, spec §F) via\n * `history.replaceState`, so a reload or a shared link cannot re-trigger — or\n * re-consume — an already-redeemed Invite. Other params, the path, and the hash\n * are preserved. Best-effort: it never throws into the host page.\n */\nexport function stripInviteToken(win: Window): void {\n try {\n const url = new URL(win.location.href);\n if (!url.searchParams.has(INVITE_QUERY_PARAM)) return;\n url.searchParams.delete(INVITE_QUERY_PARAM);\n const query = url.searchParams.toString();\n const next = `${url.pathname}${query ? `?${query}` : \"\"}${url.hash}`;\n win.history.replaceState(win.history.state, \"\", next);\n } catch {\n // Never disturb the host page over a cosmetic URL rewrite.\n }\n}\n\n// ---------------------------------------------------------------------------\n// Persistence (scoped by publishable key)\n// ---------------------------------------------------------------------------\n\nfunction reporterStorageKey(key: string): string {\n return `${REPORTER_STORAGE_PREFIX}${key}`;\n}\n\n/** The ambient localStorage, or `null` when it is absent or blocked. */\nfunction safeStorage(): Storage | null {\n try {\n return globalThis.localStorage ?? null;\n } catch {\n return null;\n }\n}\n\n/** A trimmed non-empty string, or `undefined` — so blanks are never stored. */\nfunction cleanField(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Persist a redeemed Reporter for `key`. The `reporterId` is the identity the SDK\n * presents on later boots; the display name / email ride along as chosen fields.\n * Best-effort — storage being unavailable (private mode) is never fatal.\n */\nexport function persistReporter(\n key: string,\n reporter: StoredReporter,\n store: Storage | null = safeStorage(),\n): void {\n if (!store) return;\n const name = cleanField(reporter.name);\n const email = cleanField(reporter.email);\n const payload: StoredReporter = {\n reporterId: reporter.reporterId,\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n };\n try {\n store.setItem(reporterStorageKey(key), JSON.stringify(payload));\n } catch {\n // Storage blocked or full — the redemption still succeeded in this session.\n }\n}\n\n/**\n * Read the redeemed Reporter persisted for `key`, or `null` when none is stored,\n * the record is malformed, or it carries no `reporterId`. Never throws.\n */\nexport function readStoredReporter(\n key: string,\n store: Storage | null = safeStorage(),\n): StoredReporter | null {\n if (!store) return null;\n try {\n const raw = store.getItem(reporterStorageKey(key));\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Partial<StoredReporter>;\n if (typeof parsed?.reporterId !== \"string\" || parsed.reporterId.length === 0) {\n return null;\n }\n const name = cleanField(parsed.name);\n const email = cleanField(parsed.email);\n return {\n reporterId: parsed.reporterId,\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n };\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire client\n// ---------------------------------------------------------------------------\n\n/** Join an API base URL with the invite status path, tolerating a trailing slash. */\nexport function inviteStatusEndpoint(apiUrl: string, token: string): string {\n return `${apiUrl.replace(/\\/+$/, \"\")}/api/invites/${encodeURIComponent(token)}`;\n}\n\n/** Join an API base URL with the redeem path for a token. */\nexport function redeemEndpoint(apiUrl: string, token: string): string {\n return `${inviteStatusEndpoint(apiUrl, token)}/redeem`;\n}\n\nconst DEAD_STATUSES = new Set<InviteDeadStatus>([\n \"revoked\",\n \"expired\",\n \"exhausted\",\n \"not_found\",\n]);\n\nfunction isTier(value: unknown): value is ReporterTier {\n return value === \"public\" || value === \"invited\" || value === \"internal\";\n}\n\n/** Narrow an unknown JSON body to an {@link InviteStatusAnswer}. */\nfunction isInviteStatusAnswer(value: unknown): value is InviteStatusAnswer {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n if (v.status === \"pending\") {\n return (\n typeof v.projectId === \"string\" &&\n (v.kind === \"targeted\" || v.kind === \"shared\") &&\n isTier(v.tier)\n );\n }\n return typeof v.status === \"string\" && DEAD_STATUSES.has(v.status as InviteDeadStatus);\n}\n\n/** Narrow an unknown JSON body to a {@link RedeemAnswer}. */\nfunction isRedeemAnswer(value: unknown): value is RedeemAnswer {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n if (v.status === \"redeemed\") {\n return (\n typeof v.reporterId === \"string\" &&\n typeof v.projectId === \"string\" &&\n isTier(v.tier)\n );\n }\n return typeof v.status === \"string\" && DEAD_STATUSES.has(v.status as InviteDeadStatus);\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return null;\n }\n}\n\n/**\n * Read an Invite's public status. Resolves to the answer, or `null` when Fixback\n * could not be reached or the body was not a recognised answer. The endpoint\n * answers 200 for a live or dead Invite and 404 (with a JSON body) for an unknown\n * token, so the body — not the HTTP status — is what the caller narrows on. Never\n * throws: an outage stays invisible to the host page.\n */\nexport async function fetchInviteStatus(\n apiUrl: string,\n token: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<InviteStatusAnswer | null> {\n let response: Response;\n try {\n response = await fetchImpl(inviteStatusEndpoint(apiUrl, token), {\n method: \"GET\",\n headers: { accept: \"application/json\" },\n });\n } catch {\n return null;\n }\n const body = await readJson(response);\n return isInviteStatusAnswer(body) ? body : null;\n}\n\n/**\n * Redeem an Invite by token, minting and returning a Reporter. Resolves to the\n * answer, or `null` on an unreachable API or an unrecognised body. Never throws.\n */\nexport async function redeemInviteToken(\n apiUrl: string,\n token: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<RedeemAnswer | null> {\n let response: Response;\n try {\n response = await fetchImpl(redeemEndpoint(apiUrl, token), {\n method: \"POST\",\n headers: { accept: \"application/json\" },\n });\n } catch {\n return null;\n }\n const body = await readJson(response);\n return isRedeemAnswer(body) ? body : null;\n}\n","/**\n * The launcher's isolated styles.\n *\n * These live inside the launcher's Shadow DOM (see `launcher.ts`), so nothing\n * here can reach the host page and nothing on the host page can reach in. The\n * token values are **vendored** Signal design tokens — copied from\n * `packages/ui/src/tokens.css` rather than imported, because the SDK must not\n * depend on `@fixback/ui` at runtime (ticket #47). Keep them in sync by value.\n *\n * The launcher is the prototype's polished pill (spec 0003 §A): a bottom-right\n * **Feedback** pill that **hover-peeks**, can be **tucked away** (sliding off\n * behind an edge nub, with a corner hover-zone to bring it back), a first-visit\n * **welcome toast**, and a **reduce-motion** mode that stills the pulse. Every\n * piece — pill, nub, corner zone, toasts — lives in this one Shadow DOM.\n *\n * Motion is driven by two host-element attributes the mount toggles:\n * `data-fb-hidden` (tucked away) and `data-fb-peeking` (peeked back on hover);\n * `data-fb-reduce-motion` (or the OS `prefers-reduced-motion`) stills it all.\n */\nexport const LAUNCHER_STYLES = `\n:host {\n /* Vendored Signal tokens (packages/ui/src/tokens.css). */\n --fb-color-accent: #2f6fed;\n --fb-color-accent-hover: #245fd0;\n --fb-color-on-emphasis: #ffffff;\n --fb-color-text: #0f1720;\n /* Inverse (dark) surface for the toasts — Signal --fb-ink-900. */\n --fb-color-surface-inverse: #0f1720;\n --fb-font-sans: \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif;\n\n display: block;\n color: var(--fb-color-text);\n font-family: var(--fb-font-sans);\n font-size: 13px;\n line-height: 1.4;\n -webkit-font-smoothing: antialiased;\n}\n\n/* The pill: Feedback button + divider + tuck control, anchored bottom-right. */\n.fb-launcher {\n position: fixed;\n right: 20px;\n bottom: 20px;\n z-index: 2;\n display: inline-flex;\n align-items: stretch;\n box-sizing: border-box;\n height: 40px;\n margin: 0;\n border-radius: 999px;\n background: var(--fb-color-accent);\n box-shadow:\n 0 6px 18px rgba(15, 23, 32, 0.16),\n 0 1px 2px rgba(15, 23, 32, 0.12);\n transform: translateX(0);\n transition:\n transform 340ms cubic-bezier(0.2, 0.8, 0.3, 1),\n background-color 120ms ease;\n}\n\n.fb-launcher:hover {\n background: var(--fb-color-accent-hover);\n}\n\n.fb-launcher__button {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n box-sizing: border-box;\n height: 100%;\n margin: 0;\n padding: 0 6px 0 16px;\n border: 0;\n background: transparent;\n color: var(--fb-color-on-emphasis);\n font-family: inherit;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.01em;\n cursor: pointer;\n}\n\n.fb-launcher__button:focus-visible,\n.fb-launcher__tuck:focus-visible {\n outline: 2px solid var(--fb-color-on-emphasis);\n outline-offset: -3px;\n border-radius: 999px;\n}\n\n.fb-launcher__icon {\n display: block;\n flex: none;\n width: 16px;\n height: 16px;\n}\n\n.fb-launcher__label {\n white-space: nowrap;\n}\n\n.fb-launcher__divider {\n width: 1px;\n margin: 9px 0;\n flex: none;\n background: rgba(255, 255, 255, 0.28);\n}\n\n.fb-launcher__tuck {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: 32px;\n height: 100%;\n padding: 0;\n border: 0;\n background: transparent;\n color: rgba(255, 255, 255, 0.82);\n cursor: pointer;\n}\n\n.fb-launcher__tuck:hover {\n color: var(--fb-color-on-emphasis);\n}\n\n.fb-launcher__tuck-icon {\n display: block;\n width: 14px;\n height: 14px;\n}\n\n/* The corner hover-zone that peeks a tucked launcher back — inert until tucked,\n * so it never swallows the host page's own bottom-right clicks. */\n.fb-launcher__peekzone {\n position: fixed;\n right: 0;\n bottom: 0;\n z-index: 1;\n width: 160px;\n height: 160px;\n pointer-events: none;\n}\n\n/* The edge nub: the visible re-reveal affordance, hidden until tucked. */\n.fb-launcher__nub {\n position: fixed;\n right: 0;\n bottom: 22px;\n z-index: 2;\n width: 13px;\n height: 42px;\n border-radius: 9px 0 0 9px;\n background: var(--fb-color-accent);\n box-shadow: -6px 5px 18px rgba(47, 111, 237, 0.4);\n cursor: pointer;\n opacity: 0;\n transform: translateX(10px);\n pointer-events: none;\n transition:\n opacity 220ms ease,\n transform 220ms ease;\n}\n\n/* Tucked and not peeking: slide the pill off, reveal the nub, arm the zone. */\n:host([data-fb-hidden]:not([data-fb-peeking])) .fb-launcher {\n transform: translateX(calc(100% + 30px));\n}\n\n:host([data-fb-hidden]:not([data-fb-peeking])) .fb-launcher__nub {\n opacity: 1;\n transform: none;\n pointer-events: auto;\n}\n\n:host([data-fb-hidden]) .fb-launcher__peekzone {\n pointer-events: auto;\n}\n\n/* Toasts: the first-visit welcome (above the pill) and the tuck-away hint. */\n.fb-launcher__welcome,\n.fb-launcher__hint {\n position: fixed;\n right: 20px;\n z-index: 5;\n box-sizing: border-box;\n color: #fff;\n font-size: 12px;\n line-height: 1.45;\n background: var(--fb-color-surface-inverse);\n border-radius: 10px;\n box-shadow: 0 12px 30px rgba(15, 40, 70, 0.32);\n animation: fbToast 300ms ease both;\n}\n\n.fb-launcher__welcome {\n bottom: 70px;\n max-width: 210px;\n padding: 9px 13px;\n}\n\n.fb-launcher__welcome strong {\n color: #8fc0ff;\n font-weight: 600;\n}\n\n.fb-launcher__hint {\n bottom: 20px;\n max-width: 232px;\n padding: 10px 13px;\n}\n\n/* The pulse that draws the eye while the welcome shows. */\n.fb-launcher--pulse {\n animation: fbPulse 1.8s ease-in-out 2;\n}\n\n@keyframes fbPulse {\n 0%,\n 100% {\n box-shadow:\n 0 6px 18px rgba(15, 23, 32, 0.16),\n 0 0 0 0 rgba(47, 111, 237, 0.45);\n }\n 50% {\n box-shadow:\n 0 6px 18px rgba(15, 23, 32, 0.16),\n 0 0 0 12px rgba(47, 111, 237, 0);\n }\n}\n\n@keyframes fbToast {\n from {\n opacity: 0;\n transform: translateY(14px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n\n/* Reduce motion — the explicit opt-in and the OS setting both still it all. */\n:host([data-fb-reduce-motion]) .fb-launcher,\n:host([data-fb-reduce-motion]) .fb-launcher__nub {\n transition: none;\n}\n\n:host([data-fb-reduce-motion]) .fb-launcher--pulse,\n:host([data-fb-reduce-motion]) .fb-launcher__welcome,\n:host([data-fb-reduce-motion]) .fb-launcher__hint {\n animation: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fb-launcher,\n .fb-launcher__nub {\n transition: none;\n }\n .fb-launcher--pulse,\n .fb-launcher__welcome,\n .fb-launcher__hint {\n animation: none;\n }\n}\n`;\n","import { LAUNCHER_STYLES } from \"./styles\";\n\n/** Marks the SDK's host element in the light DOM, so it is findable and unique. */\nexport const ROOT_ATTRIBUTE = \"data-fixback-root\";\n\n/**\n * Dispatched from the host element when the launcher is activated. The report\n * overlay this opens is wired in `init`; this event is the seam it hangs off. It\n * is `composed` so host-page listeners outside the Shadow DOM can hear it.\n */\nexport const LAUNCH_EVENT = \"fixback:launch\";\n\n/** Storage-key namespace for the first-visit welcome flag, scoped per key. */\nconst WELCOME_STORAGE_PREFIX = \"fixback:welcomed:\";\n\n/** How long the welcome toast (and its pulse) linger before self-dismissing. */\nconst WELCOME_MS = 5000;\n/** How long the tuck-away hint lingers before fading out. */\nconst HINT_MS = 4400;\n/** Grace period before a peeked-open launcher tucks itself back on pointer-out. */\nconst PEEK_OUT_MS = 280;\n\nconst FEEDBACK_ICON =\n '<svg class=\"fb-launcher__icon\" viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">' +\n '<path fill=\"currentColor\" d=\"M3.25 2h9.5A1.25 1.25 0 0 1 14 3.25v6.5A1.25 1.25 0 0 1 12.75 11H7.6l-3.19 2.55A.6.6 0 0 1 3.4 13.1V11h-.15A1.25 1.25 0 0 1 2 9.75v-6.5A1.25 1.25 0 0 1 3.25 2Z\"/>' +\n \"</svg>\";\n\nconst TUCK_ICON =\n '<svg class=\"fb-launcher__tuck-icon\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">' +\n '<path d=\"M4 6l4 4 4-4\"/>' +\n \"</svg>\";\n\n/** Options that shape a mounted launcher. */\nexport interface LauncherOptions {\n /**\n * The Project's publishable key. Scopes the first-visit welcome flag so the\n * welcome greets once per key per browser.\n */\n readonly key?: string;\n /**\n * Still the pulse and motion. An explicit opt-in that complements the OS-level\n * `prefers-reduced-motion` (which the styles already honour on their own).\n */\n readonly reduceMotion?: boolean;\n}\n\n/** A mounted launcher and the handle needed to remove it again. */\nexport interface Launcher {\n readonly host: HTMLElement;\n /** Clears the launcher's pending timers. Called by {@link unmountLauncher}. */\n readonly dispose: () => void;\n}\n\n/**\n * Read the first-visit welcome flag and mark it seen, returning whether the\n * welcome should greet now. Never throws: when storage is unavailable (SSR,\n * sandboxed frame, blocked cookies) it greets without persisting.\n */\nfunction claimFirstVisitWelcome(win: Window | null, key: string | undefined): boolean {\n const flag = WELCOME_STORAGE_PREFIX + (key ?? \"default\");\n try {\n const storage = win?.localStorage;\n if (!storage) return true;\n if (storage.getItem(flag) === \"1\") return false;\n storage.setItem(flag, \"1\");\n return true;\n } catch {\n return true;\n }\n}\n\n/**\n * Mount the launcher into `target` (typically `document.body`). Everything the\n * launcher draws — the **Feedback** pill, its **tuck** control, the edge **nub**\n * and corner **hover-zone** that peek it back, and the first-visit **welcome**\n * and tuck-away **hint** toasts — lives inside one open Shadow DOM, so its styles\n * are fully isolated from the host page and vice-versa. The host element is\n * fixed-positioned and out of flow, so mounting never shifts the host page's\n * layout. Only one launcher can exist at a time — an earlier one is removed first.\n *\n * Tuck/peek state is expressed as `data-fb-hidden` / `data-fb-peeking` attributes\n * on the host, which the Shadow DOM stylesheet animates; `reduceMotion` sets\n * `data-fb-reduce-motion`, which (with the OS `prefers-reduced-motion`) stills it.\n */\nexport function mountLauncher(\n target: HTMLElement,\n options: LauncherOptions = {},\n): Launcher {\n const doc = target.ownerDocument;\n const win = doc.defaultView;\n\n const previous = doc.querySelector(`[${ROOT_ATTRIBUTE}]`);\n if (previous) previous.remove();\n\n const host = doc.createElement(\"div\");\n host.setAttribute(ROOT_ATTRIBUTE, \"\");\n // Positioning is inlined on the host (not in the Shadow DOM sheet) so it holds\n // even against a hostile host-page reset, and so the launcher is anchored to\n // the viewport without ever participating in the page's flow.\n host.style.cssText =\n \"position:fixed;right:20px;bottom:20px;z-index:2147483000;margin:0;padding:0;border:0;\";\n if (options.reduceMotion) host.setAttribute(\"data-fb-reduce-motion\", \"true\");\n\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = doc.createElement(\"style\");\n style.textContent = LAUNCHER_STYLES;\n shadow.appendChild(style);\n\n // --- The pill: Feedback button + divider + tuck control ---\n const pill = doc.createElement(\"div\");\n pill.className = \"fb-launcher\";\n\n const button = doc.createElement(\"button\");\n button.type = \"button\";\n button.className = \"fb-launcher__button\";\n button.setAttribute(\"aria-haspopup\", \"dialog\");\n button.setAttribute(\"aria-label\", \"Give feedback\");\n button.innerHTML = `${FEEDBACK_ICON}<span class=\"fb-launcher__label\">Feedback</span>`;\n button.addEventListener(\"click\", () => {\n host.dispatchEvent(\n new CustomEvent(LAUNCH_EVENT, { bubbles: true, composed: true }),\n );\n });\n\n const divider = doc.createElement(\"span\");\n divider.className = \"fb-launcher__divider\";\n divider.setAttribute(\"aria-hidden\", \"true\");\n\n const tuck = doc.createElement(\"button\");\n tuck.type = \"button\";\n tuck.className = \"fb-launcher__tuck\";\n tuck.setAttribute(\"data-fb-tuck\", \"\");\n tuck.setAttribute(\"aria-label\", \"Hide feedback button\");\n tuck.title = \"Tuck away — hover the corner to bring it back\";\n tuck.innerHTML = TUCK_ICON;\n\n pill.append(button, divider, tuck);\n\n // --- The peek chrome: corner hover-zone + edge nub ---\n const peekzone = doc.createElement(\"div\");\n peekzone.className = \"fb-launcher__peekzone\";\n peekzone.setAttribute(\"aria-hidden\", \"true\");\n\n const nub = doc.createElement(\"div\");\n nub.className = \"fb-launcher__nub\";\n nub.setAttribute(\"role\", \"button\");\n nub.setAttribute(\"tabindex\", \"0\");\n nub.setAttribute(\"aria-label\", \"Show feedback button\");\n\n shadow.append(pill, peekzone, nub);\n\n // --- Tuck / peek / welcome state ---\n let hidden = false;\n let peeking = false;\n let peekTimer: ReturnType<typeof setTimeout> | undefined;\n let welcomeTimer: ReturnType<typeof setTimeout> | undefined;\n let hintTimer: ReturnType<typeof setTimeout> | undefined;\n let welcome: HTMLElement | undefined;\n let hint: HTMLElement | undefined;\n\n const syncState = (): void => {\n if (hidden) host.setAttribute(\"data-fb-hidden\", \"true\");\n else host.removeAttribute(\"data-fb-hidden\");\n if (hidden && peeking) host.setAttribute(\"data-fb-peeking\", \"true\");\n else host.removeAttribute(\"data-fb-peeking\");\n };\n\n const dismissWelcome = (): void => {\n if (welcomeTimer !== undefined) {\n clearTimeout(welcomeTimer);\n welcomeTimer = undefined;\n }\n pill.classList.remove(\"fb-launcher--pulse\");\n welcome?.remove();\n welcome = undefined;\n };\n\n const dismissHint = (): void => {\n if (hintTimer !== undefined) {\n clearTimeout(hintTimer);\n hintTimer = undefined;\n }\n hint?.remove();\n hint = undefined;\n };\n\n const peekIn = (): void => {\n if (peekTimer !== undefined) {\n clearTimeout(peekTimer);\n peekTimer = undefined;\n }\n if (!peeking) {\n peeking = true;\n syncState();\n }\n };\n\n const peekOut = (): void => {\n if (peekTimer !== undefined) clearTimeout(peekTimer);\n peekTimer = setTimeout(() => {\n peekTimer = undefined;\n peeking = false;\n syncState();\n }, PEEK_OUT_MS);\n };\n\n // Hovering the pill, the nub, or the corner zone all keep the launcher peeked.\n for (const el of [pill, peekzone, nub]) {\n el.addEventListener(\"mouseenter\", peekIn);\n el.addEventListener(\"mouseleave\", peekOut);\n }\n\n const showLauncher = (): void => {\n if (peekTimer !== undefined) {\n clearTimeout(peekTimer);\n peekTimer = undefined;\n }\n hidden = false;\n peeking = false;\n syncState();\n dismissHint();\n };\n\n const hideLauncher = (): void => {\n dismissWelcome();\n hidden = true;\n peeking = false;\n syncState();\n\n dismissHint();\n hint = doc.createElement(\"div\");\n hint.className = \"fb-launcher__hint\";\n hint.setAttribute(\"role\", \"status\");\n hint.textContent =\n \"Tucked away down here. Hover the bottom-right corner and I'll bring it back.\";\n shadow.appendChild(hint);\n hintTimer = setTimeout(dismissHint, HINT_MS);\n };\n\n tuck.addEventListener(\"click\", hideLauncher);\n\n // The nub is a real re-reveal control for pointers that can't hover (touch,\n // keyboard): clicking or Enter/Space brings the launcher fully back.\n nub.addEventListener(\"click\", showLauncher);\n nub.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" || event.key === \" \" || event.key === \"Spacebar\") {\n event.preventDefault();\n showLauncher();\n }\n });\n\n // --- First-visit welcome + its pulse ---\n if (claimFirstVisitWelcome(win, options.key)) {\n welcome = doc.createElement(\"div\");\n welcome.className = \"fb-launcher__welcome\";\n welcome.setAttribute(\"role\", \"status\");\n welcome.innerHTML =\n \"You're all set — tap <strong>Feedback</strong> any time to report something.\";\n shadow.appendChild(welcome);\n if (!options.reduceMotion) pill.classList.add(\"fb-launcher--pulse\");\n welcomeTimer = setTimeout(dismissWelcome, WELCOME_MS);\n }\n\n target.appendChild(host);\n\n const dispose = (): void => {\n if (peekTimer !== undefined) clearTimeout(peekTimer);\n if (welcomeTimer !== undefined) clearTimeout(welcomeTimer);\n if (hintTimer !== undefined) clearTimeout(hintTimer);\n };\n\n return { host, dispose };\n}\n\n/** Remove a mounted launcher. Safe to call more than once. */\nexport function unmountLauncher(launcher: Launcher): void {\n launcher.dispose();\n launcher.host.remove();\n}\n","/**\n * Styles for the invite onboarding modal (spec §F) — the Signal look of the\n * frozen Reporter prototype (`docs/design/Fixback Reporter.dc.html`), scoped to\n * the modal's own Shadow DOM so the host page is never touched and never touches\n * it. Tokens mirror `overlay-styles.ts` so launcher, overlay, and modal read as\n * one system.\n */\nexport const ONBOARDING_STYLES = `\n:host {\n --fb-color-accent: #2f6fed;\n --fb-color-accent-hover: #245fd0;\n --fb-color-on-emphasis: #ffffff;\n --fb-color-ink: #0f1720;\n --fb-color-text: #1a2530;\n --fb-color-muted: #5a6875;\n --fb-color-faint: #9aa7b2;\n --fb-color-hint: #b7c1cb;\n --fb-color-border: #dce3ea;\n --fb-color-border-soft: #e6ebf0;\n --fb-color-surface: #ffffff;\n --fb-color-card: #f6f8fa;\n --fb-color-accent-bg: #eaf1fe;\n --fb-color-success: #2f9e5b;\n --fb-font-sans: \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif;\n --fb-font-mono: \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Menlo, Consolas,\n monospace;\n all: initial;\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\n.fb-ob-backdrop {\n position: fixed;\n inset: 0;\n z-index: 2147483010;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(15, 23, 32, 0.55);\n backdrop-filter: blur(3px);\n font-family: var(--fb-font-sans);\n color: var(--fb-color-text);\n animation: fb-ob-fade 0.25s ease both;\n}\n\n.fb-ob-panel {\n width: 400px;\n max-width: 100%;\n background: var(--fb-color-surface);\n border-radius: 16px;\n box-shadow: 0 30px 70px rgba(15, 40, 70, 0.4);\n overflow: hidden;\n animation: fb-ob-pop 0.32s cubic-bezier(0.2, 0.8, 0.3, 1) both;\n}\n\n.fb-ob-head {\n padding: 22px 24px 0;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.fb-ob-mark {\n width: 22px;\n height: 22px;\n border-radius: 6px;\n background: var(--fb-color-accent);\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.fb-ob-mark::after {\n content: \"\";\n width: 7px;\n height: 7px;\n border-radius: 2px;\n background: #fff;\n}\n.fb-ob-brand { font-size: 15px; font-weight: 600; color: var(--fb-color-ink); }\n.fb-ob-chip {\n margin-left: auto;\n font-family: var(--fb-font-mono);\n font-size: 10px;\n color: #8a97a3;\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 6px;\n padding: 2px 7px;\n}\n\n.fb-ob-body { padding: 16px 24px 8px; }\n.fb-ob-title {\n font-size: 19px;\n font-weight: 700;\n color: var(--fb-color-ink);\n letter-spacing: -0.01em;\n}\n.fb-ob-lede {\n font-size: 13.5px;\n color: var(--fb-color-muted);\n line-height: 1.5;\n margin: 7px 0 0;\n}\n.fb-ob-lede strong { color: var(--fb-color-text); }\n\n.fb-ob-card {\n margin: 16px 0;\n padding: 13px 14px;\n background: var(--fb-color-card);\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.fb-ob-row { display: flex; align-items: center; gap: 10px; }\n.fb-ob-row + .fb-ob-row {\n border-top: 1px solid #eef2f6;\n padding-top: 10px;\n}\n.fb-ob-rowlabel {\n font-family: var(--fb-font-mono);\n font-size: 10px;\n color: var(--fb-color-faint);\n width: 70px;\n flex: none;\n}\n.fb-ob-site { font-size: 13px; color: var(--fb-color-text); font-weight: 500; }\n.fb-ob-tier {\n font-size: 11px;\n font-weight: 600;\n color: var(--fb-color-accent);\n background: var(--fb-color-accent-bg);\n padding: 3px 9px;\n border-radius: 6px;\n}\n.fb-ob-tiernote { font-size: 11.5px; color: #8a97a3; }\n\n.fb-ob-fieldlabel {\n display: block;\n font-family: var(--fb-font-mono);\n font-size: 10px;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--fb-color-faint);\n margin-bottom: 6px;\n}\n.fb-ob-fields { display: flex; gap: 8px; }\n.fb-ob-input {\n height: 38px;\n padding: 0 12px;\n border: 1px solid var(--fb-color-border);\n border-radius: 9px;\n font-family: inherit;\n font-size: 13px;\n color: var(--fb-color-text);\n outline: none;\n min-width: 0;\n}\n.fb-ob-input:focus { border-color: var(--fb-color-accent); }\n.fb-ob-name { flex: 1; }\n.fb-ob-email { flex: 1.3; font-family: var(--fb-font-mono); font-size: 12.5px; color: var(--fb-color-muted); }\n\n.fb-ob-privacy {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 14px;\n font-size: 11.5px;\n color: #8a97a3;\n line-height: 1.5;\n}\n.fb-ob-privacy svg { flex: none; margin-top: 1px; }\n.fb-ob-privacy strong { color: var(--fb-color-muted); }\n\n.fb-ob-foot { padding: 16px 24px 22px; }\n.fb-ob-confirm {\n width: 100%;\n height: 44px;\n border: 0;\n border-radius: 11px;\n background: var(--fb-color-accent);\n color: var(--fb-color-on-emphasis);\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n}\n.fb-ob-confirm:hover { background: var(--fb-color-accent-hover); }\n.fb-ob-confirm:disabled { opacity: 0.6; cursor: default; }\n\n@keyframes fb-ob-fade { from { opacity: 0; } to { opacity: 1; } }\n@keyframes fb-ob-pop {\n from { opacity: 0; transform: translateY(8px) scale(0.98); }\n to { opacity: 1; transform: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fb-ob-backdrop, .fb-ob-panel { animation: none; }\n}\n`;\n","/**\n * The invite onboarding modal (spec §F) — the SDK-rendered redemption screen an\n * invited tester sees when a page carries an invite token. It shows the site\n * they were invited to, the **server-derived** access tier the redemption grants,\n * a private-by-default note, and a \"Continue as\" name / email, then confirms.\n *\n * Built to the frozen Signal Reporter prototype\n * (`docs/design/Fixback Reporter.dc.html`). It mounts lazily inside its own open\n * Shadow DOM so the host page is fully isolated, and — like the launcher and\n * overlay — never throws into the host page. It renders only data the SDK\n * truthfully holds: the site's own origin and the server-derived tier. The name /\n * email are **self-provided display fields**, never a trust signal (§F).\n */\n\nimport type { ReporterTier } from \"./boot\";\nimport type { ReporterDisplay } from \"./invite\";\nimport { ONBOARDING_STYLES } from \"./onboarding-styles\";\n\n/** Marks the modal's host element in the light DOM, so it is findable and unique. */\nexport const ONBOARDING_ATTRIBUTE = \"data-fixback-onboard\";\n\n/** The access badge label for each tier (the redemption grants invited or internal). */\nconst TIER_LABEL: Record<ReporterTier, string> = {\n invited: \"Invited tester\",\n internal: \"Internal\",\n public: \"Public\",\n};\n\n/** A short, plain-language note on what the tier means for a submission. */\nconst TIER_NOTE: Record<ReporterTier, string> = {\n invited: \"reviewed before it ships\",\n internal: \"ships straight through\",\n public: \"tracked, not auto-shipped\",\n};\n\nconst SHIELD_ICON =\n '<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"#2f9e5b\" stroke-width=\"1.5\" aria-hidden=\"true\">' +\n '<path d=\"M8 1.8 13.5 4v3.5c0 3.6-2.4 5.6-5.5 6.7C4.9 13.1 2.5 11.1 2.5 7.5V4z\"/>' +\n '<path d=\"M5.8 8 7.3 9.5 10.3 6.2\"/></svg>';\n\n/** Configuration for {@link createOnboardingModal}. */\nexport interface OnboardingConfig {\n /** The site the tester was invited to — its origin (`window.location.host`). */\n readonly origin: string;\n /** The **server-derived** tier the redemption grants (from the invite status). */\n readonly tier: ReporterTier;\n /** Prefill the Continue-as fields from a previously stored display identity. */\n readonly defaults?: ReporterDisplay;\n /** Called with the self-provided display fields when the tester confirms. */\n readonly onConfirm: (display: ReporterDisplay) => void;\n /** Where to mount the modal host. Defaults to `document.body`. */\n readonly target?: HTMLElement;\n /** The document to build in. Defaults to the target's owner document. */\n readonly doc?: Document;\n}\n\n/** A mounted onboarding modal. */\nexport interface OnboardingModal {\n destroy(): void;\n readonly host: HTMLElement;\n}\n\n/** Minimal typed `createElement` helper — attributes plus string / node children. */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n props: Partial<Record<string, string>> = {},\n children: ReadonlyArray<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = doc.createElement(tag);\n for (const [name, value] of Object.entries(props)) {\n if (value !== undefined) node.setAttribute(name, value);\n }\n for (const child of children) {\n node.appendChild(typeof child === \"string\" ? doc.createTextNode(child) : child);\n }\n return node;\n}\n\n/** A trimmed, non-empty field or `undefined` — display fields are never blanks. */\nfunction field(value: string): string | undefined {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Render the onboarding modal into `target` (default `document.body`) and return a\n * handle to remove it. Confirming reads the name / email, fires `onConfirm` once\n * (further clicks are ignored while the caller redeems), and leaves teardown to\n * the caller so it can strip the token and mount the launcher first.\n */\nexport function createOnboardingModal(config: OnboardingConfig): OnboardingModal {\n const target = config.target ?? document.body;\n const doc = config.doc ?? target.ownerDocument;\n\n // Only one onboarding modal can exist at a time — an earlier one is removed\n // first, so a repeated trigger never stacks two dialogs.\n doc.querySelector(`[${ONBOARDING_ATTRIBUTE}]`)?.remove();\n\n const host = h(doc, \"div\", { [ONBOARDING_ATTRIBUTE]: \"\" });\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = doc.createElement(\"style\");\n style.textContent = ONBOARDING_STYLES;\n shadow.appendChild(style);\n\n // Header — brand + \"invite link\" chip.\n const head = h(doc, \"div\", { class: \"fb-ob-head\" }, [\n h(doc, \"span\", { class: \"fb-ob-mark\" }),\n h(doc, \"span\", { class: \"fb-ob-brand\" }, [\"Fixback\"]),\n h(doc, \"span\", { class: \"fb-ob-chip\" }, [\"invite link\"]),\n ]);\n\n // Lede — names the site by its origin (no inviter identity is fetched or shown).\n const lede = h(doc, \"p\", { class: \"fb-ob-lede\" }, [\n \"You've been invited to give feedback on \",\n h(doc, \"strong\", {}, [config.origin]),\n \". Point, mark up, send.\",\n ]);\n\n // Info card — the site and the server-derived access tier.\n const siteRow = h(doc, \"div\", { class: \"fb-ob-row\" }, [\n h(doc, \"span\", { class: \"fb-ob-rowlabel\" }, [\"SITE\"]),\n h(doc, \"span\", { class: \"fb-ob-site\" }, [config.origin]),\n ]);\n const accessRow = h(doc, \"div\", { class: \"fb-ob-row\" }, [\n h(doc, \"span\", { class: \"fb-ob-rowlabel\" }, [\"ACCESS\"]),\n h(doc, \"span\", { class: \"fb-ob-tier\" }, [TIER_LABEL[config.tier]]),\n h(doc, \"span\", { class: \"fb-ob-tiernote\" }, [TIER_NOTE[config.tier]]),\n ]);\n const card = h(doc, \"div\", { class: \"fb-ob-card\" }, [siteRow, accessRow]);\n\n // Continue-as fields.\n const nameInput = h(doc, \"input\", {\n class: \"fb-ob-input fb-ob-name\",\n type: \"text\",\n \"aria-label\": \"Name\",\n placeholder: \"Name\",\n });\n const emailInput = h(doc, \"input\", {\n class: \"fb-ob-input fb-ob-email\",\n type: \"email\",\n \"aria-label\": \"Email\",\n placeholder: \"email@example.com\",\n });\n if (config.defaults?.name) nameInput.value = config.defaults.name;\n if (config.defaults?.email) emailInput.value = config.defaults.email;\n\n const privacy = h(doc, \"div\", { class: \"fb-ob-privacy\" });\n const icon = h(doc, \"span\");\n icon.innerHTML = SHIELD_ICON;\n privacy.appendChild(icon.firstChild ?? doc.createTextNode(\"\"));\n privacy.appendChild(\n h(doc, \"span\", {}, [\n h(doc, \"strong\", {}, [\"Private by default.\"]),\n \" Anything you type is masked before it leaves your browser.\",\n ]),\n );\n\n const body = h(doc, \"div\", { class: \"fb-ob-body\" }, [\n h(doc, \"div\", { class: \"fb-ob-title\" }, [\"You're invited to give feedback\"]),\n lede,\n card,\n h(doc, \"label\", { class: \"fb-ob-fieldlabel\", for: \"fb-ob-name-input\" }, [\"Continue as\"]),\n h(doc, \"div\", { class: \"fb-ob-fields\" }, [nameInput, emailInput]),\n privacy,\n ]);\n nameInput.id = \"fb-ob-name-input\";\n\n const confirm = h(doc, \"button\", { type: \"button\", class: \"fb-ob-confirm\" }, [\n \"Start giving feedback\",\n ]);\n const foot = h(doc, \"div\", { class: \"fb-ob-foot\" }, [confirm]);\n\n const panel = h(\n doc,\n \"div\",\n { class: \"fb-ob-panel\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-label\": \"Fixback invite\" },\n [head, body, foot],\n );\n const backdrop = h(doc, \"div\", { class: \"fb-ob-backdrop\" }, [panel]);\n shadow.appendChild(backdrop);\n\n let confirmed = false;\n confirm.addEventListener(\"click\", () => {\n if (confirmed) return;\n confirmed = true;\n confirm.disabled = true;\n const display: ReporterDisplay = {\n ...(field(nameInput.value) ? { name: field(nameInput.value) } : {}),\n ...(field(emailInput.value) ? { email: field(emailInput.value) } : {}),\n };\n config.onConfirm(display);\n });\n\n target.appendChild(host);\n return {\n host,\n destroy: () => host.remove(),\n };\n}\n","/**\n * The draw surface — arrow / box / pen / text marking over the captured frame\n * (spec 0003 §B, the Reporter prototype's draw toolbar). It is the interactive\n * editor behind the overlay's draw mode: a tool, a live preview, a committed list\n * of {@link Mark}s with undo, and an SVG it renders into. Marks are recorded in\n * **screenshot (viewport) coordinates** so they compose over the full masked\n * screenshot; the overlay reads {@link DrawSurface.marks} when the Reporter\n * attaches.\n *\n * Pointer listeners are capture-phase on the document, so a stroke is intercepted\n * before the host page; a stroke that begins on interactive chrome (the toolbar,\n * the label input) is ignored so the toolbar stays clickable. The surface draws\n * nothing into the host page — only into the SVG the overlay hands it inside its\n * own Shadow DOM.\n */\n\nimport {\n arrowHeadPoints,\n MARK_COLOR,\n type ArrowMark,\n type BoxMark,\n type DrawTool,\n type Mark,\n type PenMark,\n type Point,\n} from \"./annotation\";\n\n/** A mark mid-drag — always a stroke (arrow/box/pen); text is entered via the input. */\ntype StrokePreview = ArrowMark | BoxMark | PenMark;\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/** Stroke width for every mark, in px (matches the prototype). */\nconst STROKE_WIDTH = \"3\";\n\n/** The smallest arrow/box drag that commits, in px — smaller is a stray click. */\nconst MIN_DRAG = 4;\n\n/** The label font, vendored to match the overlay's Signal sans stack. */\nconst LABEL_FONT =\n '600 16px \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\n\n/** Options for {@link startDrawSurface}. */\nexport interface DrawSurfaceOptions {\n /** Document to attach to. Defaults to the global `document`. */\n readonly doc?: Document;\n /** The (viewport-filling) SVG the surface renders committed marks + preview into. */\n readonly svg: SVGSVGElement;\n /** The inline label input the text tool shows, positions, and reads. */\n readonly textInput: HTMLInputElement;\n /** Mark colour. Defaults to {@link MARK_COLOR}. */\n readonly color?: string;\n /** Marks to seed from, so re-entering draw continues an existing annotation. */\n readonly initialMarks?: ReadonlyArray<Mark>;\n /** Notified with a fresh snapshot whenever the committed marks change. */\n readonly onChange?: (marks: ReadonlyArray<Mark>) => void;\n}\n\n/** A running draw surface. */\nexport interface DrawSurface {\n /** Switch the active tool. */\n setTool(tool: DrawTool): void;\n /** The active tool. */\n getTool(): DrawTool;\n /** Remove the most recently committed mark. */\n undo(): void;\n /** A snapshot of the committed marks, in screenshot coordinates. */\n marks(): ReadonlyArray<Mark>;\n /** Detach all listeners and hide the label input. */\n stop(): void;\n}\n\n/**\n * Begin drawing. The returned surface tracks a tool, a live preview stroke, and the\n * committed marks; `marks()` snapshots them for the overlay's Send assembly. Text\n * labels are entered through the provided input (Enter commits, Escape/blur-empty\n * discards). `stop()` detaches everything.\n */\nexport function startDrawSurface(options: DrawSurfaceOptions): DrawSurface {\n const doc = options.doc ?? document;\n const { svg, textInput } = options;\n const color = options.color ?? MARK_COLOR;\n\n let tool: DrawTool = \"arrow\";\n let committed: Mark[] = options.initialMarks ? options.initialMarks.slice() : [];\n let preview: StrokePreview | null = null;\n let drawing = false;\n let pendingText: Point | null = null;\n let stopped = false;\n\n function emitChange(): void {\n options.onChange?.(committed.slice());\n }\n\n function point(event: MouseEvent): Point {\n return { x: Math.round(event.clientX), y: Math.round(event.clientY) };\n }\n\n /** Does the event begin on interactive chrome (a button/input in the path)? */\n function hitsChrome(event: Event): boolean {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [event.target];\n for (const node of path) {\n if (node === doc) break;\n if (node instanceof Element) {\n const tag = node.tagName;\n if (tag === \"BUTTON\" || tag === \"INPUT\" || tag === \"TEXTAREA\") return true;\n }\n }\n return false;\n }\n\n function meaningful(mark: Mark): boolean {\n if (mark.type === \"pen\") return mark.points.length > 1;\n if (mark.type === \"text\") return mark.text.trim().length > 0;\n return Math.abs(mark.x1 - mark.x0) > MIN_DRAG || Math.abs(mark.y1 - mark.y0) > MIN_DRAG;\n }\n\n function onDown(event: MouseEvent): void {\n if (stopped || drawing || hitsChrome(event)) return;\n const p = point(event);\n if (tool === \"text\") {\n openText(p);\n return;\n }\n if (event.cancelable) event.preventDefault();\n drawing = true;\n preview =\n tool === \"pen\"\n ? { type: \"pen\", points: [p], color }\n : { type: tool, x0: p.x, y0: p.y, x1: p.x, y1: p.y, color };\n render();\n }\n\n function onMove(event: MouseEvent): void {\n if (stopped || !drawing || !preview) return;\n const p = point(event);\n if (preview.type === \"pen\") {\n preview = { type: \"pen\", points: [...preview.points, p], color: preview.color };\n } else {\n preview = { ...preview, x1: p.x, y1: p.y };\n }\n render();\n }\n\n function onUp(): void {\n if (stopped || !drawing) return;\n drawing = false;\n const pv = preview;\n preview = null;\n if (pv && meaningful(pv)) {\n committed = [...committed, pv];\n emitChange();\n }\n render();\n }\n\n function openText(p: Point): void {\n pendingText = p;\n textInput.value = \"\";\n textInput.style.display = \"block\";\n textInput.style.left = `${p.x}px`;\n textInput.style.top = `${p.y}px`;\n textInput.onkeydown = onTextKey;\n textInput.onblur = commitText;\n // Focus on the next tick so the current click doesn't immediately blur it.\n setTimeout(() => {\n try {\n textInput.focus();\n } catch {\n /* focus is best-effort — never throw into the host page */\n }\n }, 0);\n }\n\n function onTextKey(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n commitText();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n discardText();\n }\n }\n\n function commitText(): void {\n if (!pendingText) return;\n const text = textInput.value.trim();\n const at = pendingText;\n discardText();\n if (text.length > 0) {\n committed = [...committed, { type: \"text\", x: at.x, y: at.y, text, color }];\n emitChange();\n render();\n }\n }\n\n function discardText(): void {\n pendingText = null;\n textInput.onkeydown = null;\n textInput.onblur = null;\n textInput.value = \"\";\n textInput.style.display = \"none\";\n }\n\n function render(): void {\n while (svg.firstChild) svg.removeChild(svg.firstChild);\n for (const mark of committed) svg.appendChild(renderMark(doc, mark));\n if (preview) svg.appendChild(renderMark(doc, preview));\n }\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n doc.removeEventListener(\"mousedown\", onDown, true);\n doc.removeEventListener(\"mousemove\", onMove, true);\n doc.removeEventListener(\"mouseup\", onUp, true);\n discardText();\n }\n\n doc.addEventListener(\"mousedown\", onDown, true);\n doc.addEventListener(\"mousemove\", onMove, true);\n doc.addEventListener(\"mouseup\", onUp, true);\n render();\n\n return {\n setTool: (next) => {\n tool = next;\n },\n getTool: () => tool,\n undo: () => {\n if (committed.length === 0) return;\n committed = committed.slice(0, -1);\n emitChange();\n render();\n },\n marks: () => committed.slice(),\n stop,\n };\n}\n\n/** Build the SVG element(s) for one mark, in the mark's own coordinate space. */\nfunction renderMark(doc: Document, mark: Mark): SVGElement {\n switch (mark.type) {\n case \"box\": {\n const rect = svgEl(doc, \"rect\", {\n x: String(Math.min(mark.x0, mark.x1)),\n y: String(Math.min(mark.y0, mark.y1)),\n width: String(Math.abs(mark.x1 - mark.x0)),\n height: String(Math.abs(mark.y1 - mark.y0)),\n rx: \"2\",\n fill: \"none\",\n stroke: mark.color,\n \"stroke-width\": STROKE_WIDTH,\n });\n return rect;\n }\n case \"pen\": {\n return svgEl(doc, \"polyline\", {\n points: mark.points.map((p) => `${p.x},${p.y}`).join(\" \"),\n fill: \"none\",\n stroke: mark.color,\n \"stroke-width\": STROKE_WIDTH,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n });\n }\n case \"text\": {\n const text = svgEl(doc, \"text\", {\n x: String(mark.x),\n y: String(mark.y),\n fill: mark.color,\n style: `font:${LABEL_FONT}`,\n });\n text.textContent = mark.text;\n return text;\n }\n case \"arrow\": {\n const group = svgEl(doc, \"g\", {});\n group.appendChild(\n svgEl(doc, \"line\", {\n x1: String(mark.x0),\n y1: String(mark.y0),\n x2: String(mark.x1),\n y2: String(mark.y1),\n stroke: mark.color,\n \"stroke-width\": STROKE_WIDTH,\n \"stroke-linecap\": \"round\",\n }),\n );\n const head = arrowHeadPoints(mark.x0, mark.y0, mark.x1, mark.y1);\n group.appendChild(\n svgEl(doc, \"polygon\", {\n points: head.map((p) => `${p.x},${p.y}`).join(\" \"),\n fill: mark.color,\n }),\n );\n return group;\n }\n }\n}\n\n/** Create a namespaced SVG element with the given attributes. */\nfunction svgEl(\n doc: Document,\n tag: string,\n attrs: Record<string, string>,\n): SVGElement {\n const node = doc.createElementNS(SVG_NS, tag) as SVGElement;\n for (const [name, value] of Object.entries(attrs)) node.setAttribute(name, value);\n return node;\n}\n","/**\n * Region-capture — drag a rectangle over the page to focus the report on one area\n * (spec 0003 §B, the Reporter prototype's capture layer). It produces a `region`\n * rect in screenshot (viewport) coordinates; Escape or a too-small drag abandons\n * it. One of the overlay's three composable, optional marking layers, alongside\n * element-pick and draw.\n *\n * Listeners are attached in the **capture phase** so the drag is intercepted before\n * any host-page handler sees it. It is armed deliberately — the overlay lays a\n * full-screen capture layer over the page (and hides the panel) while it runs — so\n * it captures whatever the Reporter drags, its own layer included. Purely a producer\n * of a `Rect`: it draws nothing; the overlay renders the live selection box from\n * `onProgress`.\n */\n\nimport { normalizeRect, type Rect } from \"./annotation\";\n\n/** Options for {@link startRegionCapture}. */\nexport interface RegionCaptureOptions {\n /** Document to attach to. Defaults to the global `document`. */\n readonly doc?: Document;\n /** Called on each drag update with the current rect (to draw a selection box). */\n readonly onProgress?: (rect: Rect) => void;\n /** Called with the captured rect when the drag ends large enough to keep. */\n readonly onComplete: (rect: Rect) => void;\n /** Called when the capture is abandoned (Escape, or a drag below the floor). */\n readonly onCancel?: () => void;\n /** Minimum width and height, in px, to count as a capture. Defaults to 12. */\n readonly minSize?: number;\n}\n\n/** A running region-capture; call {@link RegionCapture.stop} to detach it. */\nexport interface RegionCapture {\n stop(): void;\n}\n\n/** The smallest drag that counts as a region (matches the prototype's 12px floor). */\nconst DEFAULT_MIN_SIZE = 12;\n\n/**\n * Enter region-capture mode: the next drag on the host page draws out a rectangle,\n * reported live through `onProgress` and committed through `onComplete` on release\n * (when it clears the size floor). Escape, or a drag too small to be meaningful,\n * calls `onCancel`. `stop()` (called automatically on complete/cancel) detaches all\n * listeners.\n */\nexport function startRegionCapture(options: RegionCaptureOptions): RegionCapture {\n const doc = options.doc ?? document;\n const minSize = options.minSize ?? DEFAULT_MIN_SIZE;\n let start: { x: number; y: number } | null = null;\n let stopped = false;\n\n function onDown(event: MouseEvent): void {\n if (stopped || start) return;\n start = { x: event.clientX, y: event.clientY };\n if (event.cancelable) event.preventDefault();\n }\n\n function onMove(event: MouseEvent): void {\n if (stopped || !start) return;\n options.onProgress?.(normalizeRect(start.x, start.y, event.clientX, event.clientY));\n }\n\n function onUp(event: MouseEvent): void {\n if (stopped || !start) return;\n const rect = normalizeRect(start.x, start.y, event.clientX, event.clientY);\n start = null;\n stop();\n if (rect.width < minSize || rect.height < minSize) {\n options.onCancel?.();\n return;\n }\n options.onComplete(rect);\n }\n\n function onKey(event: KeyboardEvent): void {\n if (stopped) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n stop();\n options.onCancel?.();\n }\n }\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n doc.removeEventListener(\"mousedown\", onDown, true);\n doc.removeEventListener(\"mousemove\", onMove, true);\n doc.removeEventListener(\"mouseup\", onUp, true);\n doc.removeEventListener(\"keydown\", onKey, true);\n start = null;\n }\n\n doc.addEventListener(\"mousedown\", onDown, true);\n doc.addEventListener(\"mousemove\", onMove, true);\n doc.addEventListener(\"mouseup\", onUp, true);\n doc.addEventListener(\"keydown\", onKey, true);\n\n return { stop };\n}\n","/**\n * The report overlay's isolated styles, built to the frozen Signal Reporter\n * overlay (`docs/design/Fixback Visual Identity.dc.html`, badge `1d`). Like the\n * launcher's styles these live inside the overlay's Shadow DOM, so nothing here\n * reaches the host page and nothing on the host page reaches in. Token values are\n * vendored Signal tokens (copied from `packages/ui/src/tokens.css`, not imported —\n * the SDK must not depend on `@fixback/ui` at runtime). Keep them in sync by value.\n */\nexport const OVERLAY_STYLES = `\n:host {\n --fb-color-accent: #2f6fed;\n --fb-color-accent-hover: #245fd0;\n --fb-color-on-emphasis: #ffffff;\n --fb-color-ink: #0f1720;\n --fb-color-text: #1a2530;\n --fb-color-muted: #5a6875;\n --fb-color-faint: #9aa7b2;\n --fb-color-border: #e0e6ec;\n --fb-color-border-soft: #e6ebf0;\n --fb-color-surface: #ffffff;\n --fb-color-bug: #e5484d;\n --fb-color-bug-bg: #fdecec;\n --fb-color-impr: #2f6fed;\n --fb-color-impr-bg: #eaf1fe;\n --fb-color-idea: #8b5cf6;\n --fb-color-idea-bg: #f2ecfe;\n --fb-color-success: #2f9e5b;\n --fb-font-sans: \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif;\n --fb-font-mono: \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Menlo, Consolas,\n monospace;\n\n display: block;\n color: var(--fb-color-text);\n font-family: var(--fb-font-sans);\n font-size: 13px;\n line-height: 1.45;\n -webkit-font-smoothing: antialiased;\n}\n\n* { box-sizing: border-box; }\n\n.fb-ov-panel {\n width: 300px;\n max-width: calc(100vw - 40px);\n background: var(--fb-color-surface);\n border: 1px solid var(--fb-color-border);\n border-radius: 13px;\n box-shadow: 0 18px 44px rgba(20, 40, 70, 0.2);\n overflow: hidden;\n}\n\n.fb-ov-head {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 12px 14px;\n border-bottom: 1px solid var(--fb-color-border-soft);\n}\n.fb-ov-mark-sq {\n width: 13px;\n height: 13px;\n border-radius: 4px;\n background: var(--fb-color-accent);\n flex: none;\n}\n.fb-ov-brand { font-size: 14px; font-weight: 600; color: var(--fb-color-ink); }\n.fb-ov-tier {\n flex: none;\n font-family: var(--fb-font-mono);\n font-size: 9.5px;\n color: var(--fb-color-faint);\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 5px;\n padding: 1px 6px;\n}\n.fb-ov-close {\n margin-left: auto;\n border: 0;\n background: none;\n color: var(--fb-color-faint);\n font-size: 16px;\n line-height: 1;\n padding: 2px 4px;\n cursor: pointer;\n border-radius: 6px;\n}\n.fb-ov-close:hover { color: var(--fb-color-muted); background: #f4f7fa; }\n\n.fb-ov-tabs { display: flex; gap: 6px; padding: 12px 14px 6px; }\n.fb-ov-tab {\n flex: 1;\n text-align: center;\n font-size: 11px;\n font-weight: 600;\n padding: 6px;\n border-radius: 7px;\n border: 1px solid var(--fb-color-border);\n background: var(--fb-color-surface);\n color: var(--fb-color-muted);\n cursor: pointer;\n font-family: inherit;\n}\n.fb-ov-tab:hover { border-color: #cfd8e2; }\n.fb-ov-tab.is-active[data-kind=\"bug\"] {\n background: var(--fb-color-bug-bg); color: var(--fb-color-bug); border-color: transparent;\n}\n.fb-ov-tab.is-active[data-kind=\"improvement\"] {\n background: var(--fb-color-impr-bg); color: var(--fb-color-impr); border-color: transparent;\n}\n.fb-ov-tab.is-active[data-kind=\"idea\"] {\n background: var(--fb-color-idea-bg); color: var(--fb-color-idea); border-color: transparent;\n}\n\n.fb-ov-mark {\n margin: 10px 14px;\n min-height: 52px;\n border-radius: 9px;\n border: 1px solid var(--fb-color-border-soft);\n background: repeating-linear-gradient(135deg, #f4f7fa, #f4f7fa 7px, #eaeff4 7px, #eaeff4 14px);\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n gap: 6px;\n padding: 10px 12px;\n}\n.fb-ov-selector {\n display: none;\n max-width: 100%;\n font-family: var(--fb-font-mono);\n font-size: 10px;\n color: var(--fb-color-on-emphasis);\n background: var(--fb-color-accent);\n padding: 3px 8px;\n border-radius: 5px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.fb-ov-mark.has-element .fb-ov-selector { display: inline-block; }\n.fb-ov-mark-caption { font-size: 10px; color: var(--fb-color-faint); font-family: var(--fb-font-mono); }\n\n.fb-ov-comment {\n display: block;\n width: calc(100% - 28px);\n margin: 0 14px 10px;\n min-height: 62px;\n resize: vertical;\n font-family: inherit;\n font-size: 13px;\n color: var(--fb-color-text);\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 9px;\n padding: 10px 11px;\n}\n.fb-ov-comment::placeholder { color: var(--fb-color-faint); }\n.fb-ov-comment:focus-visible { outline: 2px solid var(--fb-color-accent); outline-offset: 1px; }\n\n.fb-ov-status { padding: 0 14px; font-size: 11px; min-height: 0; }\n.fb-ov-status.is-error { color: var(--fb-color-bug); }\n\n.fb-ov-tools { display: flex; align-items: center; gap: 7px; padding: 8px 14px 14px; }\n.fb-ov-pickbtn,\n.fb-ov-capturebtn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n font-size: 12px;\n color: var(--fb-color-muted);\n background: var(--fb-color-surface);\n border: 1px solid var(--fb-color-border);\n border-radius: 8px;\n padding: 8px 11px;\n cursor: pointer;\n}\n.fb-ov-capturebtn { padding: 8px 9px; }\n.fb-ov-pickbtn:hover,\n.fb-ov-capturebtn:hover { border-color: #cfd8e2; }\n.fb-ov-pickbtn.is-active,\n.fb-ov-capturebtn.is-active,\n.fb-ov-capturebtn.is-attached {\n color: var(--fb-color-accent);\n border-color: var(--fb-color-accent);\n background: var(--fb-color-impr-bg);\n}\n.fb-ov-pickbtn__glyph { font-size: 14px; line-height: 1; }\n.fb-ov-icon { display: block; }\n\n.fb-ov-send {\n margin-left: auto;\n font-family: inherit;\n font-size: 13px;\n font-weight: 600;\n color: var(--fb-color-on-emphasis);\n background: var(--fb-color-accent);\n border: 0;\n border-radius: 8px;\n padding: 9px 18px;\n cursor: pointer;\n}\n.fb-ov-send:hover { background: var(--fb-color-accent-hover); }\n.fb-ov-send:disabled { opacity: 0.6; cursor: default; }\n\n.fb-ov-done { display: none; padding: 24px 18px; text-align: center; }\n.fb-ov-panel.is-sent .fb-ov-form { display: none; }\n.fb-ov-panel.is-sent .fb-ov-done { display: block; }\n.fb-ov-done__check {\n width: 40px; height: 40px; margin: 0 auto 12px;\n border-radius: 50%;\n background: #e7f6ee; color: var(--fb-color-success);\n display: flex; align-items: center; justify-content: center;\n font-size: 20px; font-weight: 700;\n}\n.fb-ov-done__title { font-size: 15px; font-weight: 600; color: var(--fb-color-ink); }\n.fb-ov-done__sub { font-size: 12px; color: var(--fb-color-muted); margin-top: 4px; }\n\n/* The panel is hidden while any full-screen marking layer is active. */\n.fb-ov-panel.is-marking { visibility: hidden; }\n\n.fb-ov-pick,\n.fb-ov-capture,\n.fb-ov-draw { position: fixed; inset: 0; z-index: 2147483002; display: none; }\n.fb-ov-pick.is-visible,\n.fb-ov-capture.is-visible,\n.fb-ov-draw.is-visible { display: block; }\n\n/* Element-pick highlight layer — visual only, never intercepts host events. */\n.fb-ov-pick { pointer-events: none; }\n.fb-ov-highlight {\n position: absolute;\n border: 2px dashed var(--fb-color-accent);\n border-radius: 6px;\n box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.14);\n transition: all 60ms ease;\n}\n.fb-ov-hint {\n position: absolute;\n top: 16px;\n left: 50%;\n transform: translateX(-50%);\n font-family: var(--fb-font-mono);\n font-size: 11px;\n color: var(--fb-color-on-emphasis);\n background: var(--fb-color-ink);\n padding: 6px 12px;\n border-radius: 7px;\n box-shadow: 0 8px 20px rgba(20, 40, 70, 0.25);\n}\n\n/* Region-capture layer — a dim wash with a live selection box. */\n.fb-ov-capture { cursor: crosshair; }\n.fb-ov-capture-dim { position: absolute; inset: 0; background: rgba(15, 23, 32, 0.28); }\n.fb-ov-capture-sel {\n position: absolute;\n border: 2px solid var(--fb-color-accent);\n border-radius: 4px;\n box-shadow: 0 0 0 100vmax rgba(15, 23, 32, 0.32);\n}\n\n/* Draw layer — the mark SVG, the region frame, the label input, and the toolbar. */\n.fb-ov-draw-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }\n.fb-ov-draw-frame {\n position: absolute;\n border: 1px solid rgba(47, 111, 237, 0.5);\n border-radius: 4px;\n box-shadow: 0 0 0 100vmax rgba(15, 23, 32, 0.18);\n pointer-events: none;\n}\n.fb-ov-draw-text {\n position: absolute;\n display: none;\n font-family: var(--fb-font-sans);\n font-size: 15px;\n font-weight: 600;\n color: var(--fb-color-bug);\n background: rgba(255, 255, 255, 0.92);\n border: 1px dashed var(--fb-color-bug);\n border-radius: 4px;\n padding: 2px 6px;\n outline: none;\n z-index: 3;\n}\n.fb-ov-draw-toolbar {\n position: fixed;\n left: 50%;\n bottom: 26px;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 5px;\n background: var(--fb-color-ink);\n border-radius: 12px;\n padding: 7px;\n box-shadow: 0 16px 40px rgba(15, 40, 70, 0.4);\n}\n.fb-ov-drawtool {\n width: 34px;\n height: 34px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #c4ccd4;\n cursor: pointer;\n font-family: inherit;\n}\n.fb-ov-drawtool:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }\n.fb-ov-drawtool.is-active { background: var(--fb-color-accent); color: var(--fb-color-on-emphasis); }\n.fb-ov-drawtool__t { font-weight: 700; font-size: 14px; line-height: 1; }\n.fb-ov-draw-divider { width: 1px; height: 22px; background: #2a343e; margin: 0 3px; }\n.fb-ov-draw-undo {\n width: 34px;\n height: 34px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #c4ccd4;\n cursor: pointer;\n}\n.fb-ov-draw-undo:hover:not(:disabled) { background: rgba(255, 255, 255, 0.08); color: #fff; }\n.fb-ov-draw-undo:disabled { opacity: 0.4; cursor: default; }\n.fb-ov-draw-cancel {\n height: 34px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: var(--fb-color-faint);\n font-family: inherit;\n font-size: 12.5px;\n cursor: pointer;\n}\n.fb-ov-draw-cancel:hover { color: #fff; }\n.fb-ov-draw-attach {\n height: 34px;\n padding: 0 15px;\n border: 0;\n border-radius: 8px;\n background: var(--fb-color-accent);\n color: var(--fb-color-on-emphasis);\n font-family: inherit;\n font-size: 12.5px;\n font-weight: 600;\n cursor: pointer;\n}\n.fb-ov-draw-attach:hover { background: var(--fb-color-accent-hover); }\n\n@media (prefers-reduced-motion: reduce) {\n .fb-ov-highlight { transition: none; }\n}\n`;\n","import type { DrawTool, Mark, Rect } from \"./annotation\";\nimport type { IdentityInputs, ProjectGate, ReporterTier } from \"./boot\";\nimport type { Breadcrumb } from \"./breadcrumbs\";\nimport { startDrawSurface, type DrawSurface } from \"./draw-surface\";\nimport {\n describeElement,\n startElementPicker,\n type ElementPicker,\n type ElementPickerOptions,\n} from \"./element-picker\";\nimport {\n assembleContent,\n collectEnvironment,\n type IssueKind,\n type SelectedElement,\n} from \"./report\";\nimport { startRegionCapture, type RegionCapture } from \"./region-capture\";\nimport { OVERLAY_STYLES } from \"./overlay-styles\";\nimport { runBeforeSend, type BeforeSend } from \"./scrub\";\nimport { captureView, extensionFor, type Capture, type CaptureOptions } from \"./screenshot\";\nimport { submitReport, type SubmitInput, type SubmitResult } from \"./submit\";\nimport { SDK_VERSION } from \"./version\";\n\n/** Marks the overlay's host element in the light DOM (skipped by capture/picker). */\nexport const OVERLAY_ATTRIBUTE = \"data-fixback-overlay\";\n\n/** The SVG namespace, for the draw surface's mark layer. */\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/** The Kind tabs, in order — value is the ingest Kind, label is the overlay text. */\nconst KIND_TABS: ReadonlyArray<{ value: IssueKind; label: string }> = [\n { value: \"bug\", label: \"Bug\" },\n { value: \"improvement\", label: \"Improve\" },\n { value: \"idea\", label: \"Idea\" },\n];\n\n/** The draw tools, in toolbar order (spec §B, the Reporter prototype). */\nconst DRAW_TOOLS: ReadonlyArray<{ tool: DrawTool; label: string }> = [\n { tool: \"arrow\", label: \"Arrow\" },\n { tool: \"box\", label: \"Box\" },\n { tool: \"pen\", label: \"Pen\" },\n { tool: \"text\", label: \"Text label\" },\n];\n\n/** How long the confirmation shows before the overlay closes itself. */\nconst AUTO_CLOSE_MS = 1800;\n\ntype CaptureViewFn = (options?: CaptureOptions) => Promise<Capture | null>;\ntype SubmitReportFn = (\n apiUrl: string,\n input: SubmitInput,\n fetchImpl?: typeof fetch,\n) => Promise<SubmitResult>;\ntype StartPickerFn = (options: ElementPickerOptions) => ElementPicker;\n\n/** Injectable collaborators, defaulted to the real implementations. */\nexport interface OverlayDeps {\n readonly captureView: CaptureViewFn;\n readonly submitReport: SubmitReportFn;\n readonly startElementPicker: StartPickerFn;\n}\n\n/** A read-only view of the trace buffer the overlay attaches to a report. */\nexport interface BreadcrumbSource {\n snapshot(): readonly Breadcrumb[];\n}\n\n/** Configuration for {@link createOverlay}. */\nexport interface OverlayConfig {\n readonly apiUrl: string;\n readonly key: string;\n readonly identity?: IdentityInputs;\n /**\n * The Project's Gate, forwarded verbatim from the boot answer. Reserved for\n * Gate-aware launcher / redemption behaviour (spec §A/§F); the overlay itself\n * does not read it yet, but `init` plumbs it through here (ticket #85 / §G).\n */\n readonly gate?: ProjectGate;\n /**\n * The Reporter's **server-derived** trust tier from the boot answer, or `null`\n * when a presented identity was refused. Rendered as a **display-only** chip in\n * the overlay header (spec §G) — never a trust signal, never read for a decision,\n * and never sent back to the server. When `null`/absent no tier is asserted.\n */\n readonly tier?: ReporterTier | null;\n readonly sdkVersion?: string;\n /** Where to mount the overlay host. Defaults to `document.body`. */\n readonly target?: HTMLElement;\n readonly doc?: Document;\n readonly win?: Window;\n readonly deps?: Partial<OverlayDeps>;\n /** The trace buffer whose snapshot rides on each report (spec §C). */\n readonly buffer?: BreadcrumbSource | null;\n /** Per-project client scrub hook, run at the `beforeSend` choke point. */\n readonly beforeSend?: BeforeSend;\n /** Run the built-in default scrubbers. Defaults to `true` (private-by-default). */\n readonly scrub?: boolean;\n}\n\n/** A mounted overlay the launcher opens. */\nexport interface OverlayController {\n open(): void;\n close(): void;\n destroy(): void;\n readonly isOpen: boolean;\n}\n\n/** Which full-screen marking mode is active, if any. */\ntype MarkMode = \"compose\" | \"picking\" | \"capturing\" | \"drawing\";\n\ninterface Refs {\n readonly panel: HTMLElement;\n readonly tabs: Map<IssueKind, HTMLButtonElement>;\n readonly mark: HTMLElement;\n readonly selector: HTMLElement;\n readonly caption: HTMLElement;\n readonly comment: HTMLTextAreaElement;\n readonly status: HTMLElement;\n readonly pickBtn: HTMLButtonElement;\n readonly captureBtn: HTMLButtonElement;\n readonly sendBtn: HTMLButtonElement;\n readonly highlight: HTMLElement;\n readonly pickLayer: HTMLElement;\n readonly captureLayer: HTMLElement;\n readonly selBox: HTMLElement;\n readonly drawLayer: HTMLElement;\n readonly drawSvg: SVGSVGElement;\n readonly drawText: HTMLInputElement;\n readonly drawFrame: HTMLElement;\n readonly drawTools: Map<DrawTool, HTMLButtonElement>;\n readonly undoBtn: HTMLButtonElement;\n}\n\nfunction h<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n props: Partial<Record<string, string>> = {},\n children: ReadonlyArray<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = doc.createElement(tag);\n for (const [name, value] of Object.entries(props)) {\n if (value !== undefined) node.setAttribute(name, value);\n }\n for (const child of children) {\n node.appendChild(typeof child === \"string\" ? doc.createTextNode(child) : child);\n }\n return node;\n}\n\n/** Create a namespaced SVG element with attributes and optional SVG children. */\nfunction svgNode(\n doc: Document,\n tag: string,\n attrs: Record<string, string> = {},\n children: ReadonlyArray<SVGElement> = [],\n): SVGElement {\n const node = doc.createElementNS(SVG_NS, tag) as SVGElement;\n for (const [name, value] of Object.entries(attrs)) node.setAttribute(name, value);\n for (const child of children) node.appendChild(child);\n return node;\n}\n\n/**\n * Create the report overlay — the on-page panel a Reporter files a report from,\n * built to the frozen Signal Reporter prototype (`docs/design/Fixback Reporter.dc.html`).\n * It mounts lazily inside its own Shadow DOM (isolated from the host page, and\n * marked so the screenshot and element-picker skip it), opens on the launcher's\n * `fixback:launch` seam, and offers three **composable, optional** marking layers\n * over one full masked screenshot (spec §B): **element-pick**, **region-capture**\n * (drag), and **draw** (arrow / box / pen / text, with undo / cancel / attach). On\n * Send it captures the masked screenshot, assembles the structured Annotation\n * (`{ element?, region?, marks? }`, spec §D — marks stay vector, never baked into\n * the PNG), and submits to ingest — showing a confirmation on success and failing\n * quietly otherwise.\n */\nexport function createOverlay(config: OverlayConfig): OverlayController {\n const doc = config.doc ?? document;\n const win = config.win ?? doc.defaultView ?? window;\n const sdkVersion = config.sdkVersion ?? SDK_VERSION;\n const deps: OverlayDeps = {\n captureView: config.deps?.captureView ?? captureView,\n submitReport: config.deps?.submitReport ?? submitReport,\n startElementPicker: config.deps?.startElementPicker ?? startElementPicker,\n };\n\n let host: HTMLElement | null = null;\n let refs: Refs | null = null;\n let picker: ElementPicker | null = null;\n let regionCapture: RegionCapture | null = null;\n let drawSurface: DrawSurface | null = null;\n let pendingRegion: Rect | null = null;\n let autoClose: ReturnType<typeof setTimeout> | null = null;\n let open = false;\n let mode: MarkMode = \"compose\";\n\n const state: {\n kind: IssueKind;\n selectedElement: SelectedElement | null;\n region: Rect | null;\n marks: Mark[];\n phase: \"compose\" | \"sending\" | \"sent\";\n } = { kind: \"bug\", selectedElement: null, region: null, marks: [], phase: \"compose\" };\n\n function setStatus(message: string, isError: boolean): void {\n if (!refs) return;\n refs.status.textContent = message;\n refs.status.classList.toggle(\"is-error\", isError);\n }\n\n function setKind(kind: IssueKind): void {\n state.kind = kind;\n if (!refs) return;\n for (const [value, button] of refs.tabs) {\n const active = value === kind;\n button.classList.toggle(\"is-active\", active);\n button.setAttribute(\"aria-pressed\", String(active));\n }\n }\n\n /** Show exactly one full-screen marking layer, hiding the panel while it runs. */\n function setMode(next: MarkMode): void {\n mode = next;\n if (!refs) return;\n const marking = next !== \"compose\";\n refs.panel.classList.toggle(\"is-marking\", marking);\n refs.pickLayer.classList.toggle(\"is-visible\", next === \"picking\");\n refs.captureLayer.classList.toggle(\"is-visible\", next === \"capturing\");\n refs.drawLayer.classList.toggle(\"is-visible\", next === \"drawing\");\n refs.pickBtn.classList.toggle(\"is-active\", next === \"picking\");\n refs.captureBtn.classList.toggle(\"is-active\", next === \"capturing\" || next === \"drawing\");\n }\n\n /** Reflect the current marking state in the compose panel's mark region. */\n function renderMarking(): void {\n if (!refs) return;\n const hasElement = !!state.selectedElement;\n const hasRegion = !!state.region;\n const markCount = state.marks.length;\n\n refs.mark.classList.toggle(\"has-element\", hasElement);\n refs.selector.textContent = hasElement ? state.selectedElement!.selector : \"\";\n\n refs.pickBtn.textContent = \"\";\n refs.pickBtn.append(\n glyph(doc),\n doc.createTextNode(hasElement ? \"Change element\" : \"Pick element\"),\n );\n refs.captureBtn.classList.toggle(\"is-attached\", hasRegion || markCount > 0);\n\n const bits: string[] = [];\n if (hasElement) bits.push(\"Element\");\n if (hasRegion) bits.push(\"Region\");\n if (markCount > 0) bits.push(`${markCount} mark${markCount === 1 ? \"\" : \"s\"}`);\n refs.caption.textContent = bits.length\n ? `${bits.join(\" · \")} · masked screenshot on Send`\n : \"Masked screenshot attached on Send\";\n }\n\n function positionHighlight(element: Element | null): void {\n if (!refs) return;\n if (!element) {\n refs.highlight.style.display = \"none\";\n return;\n }\n const rect = element.getBoundingClientRect();\n refs.highlight.style.display = \"block\";\n refs.highlight.style.left = `${rect.left}px`;\n refs.highlight.style.top = `${rect.top}px`;\n refs.highlight.style.width = `${rect.width}px`;\n refs.highlight.style.height = `${rect.height}px`;\n }\n\n // ---- element-pick -------------------------------------------------------\n\n function stopPicker(): void {\n picker?.stop();\n picker = null;\n }\n\n function endPick(): void {\n if (refs) refs.highlight.style.display = \"none\";\n stopPicker();\n if (mode === \"picking\") setMode(\"compose\");\n }\n\n function beginPick(): void {\n if (!refs) return;\n closeMarkingModes();\n setMode(\"picking\");\n picker = deps.startElementPicker({\n doc,\n onHover: positionHighlight,\n onPick: (element) => {\n state.selectedElement = describeElement(element);\n endPick();\n renderMarking();\n },\n onCancel: endPick,\n });\n }\n\n // ---- region-capture -----------------------------------------------------\n\n function positionSelBox(rect: Rect | null): void {\n if (!refs) return;\n const box = refs.selBox;\n if (!rect) {\n box.style.display = \"none\";\n return;\n }\n box.style.display = \"block\";\n box.style.left = `${rect.x}px`;\n box.style.top = `${rect.y}px`;\n box.style.width = `${rect.width}px`;\n box.style.height = `${rect.height}px`;\n }\n\n function stopRegionCapture(): void {\n regionCapture?.stop();\n regionCapture = null;\n }\n\n function beginCapture(): void {\n if (!refs) return;\n closeMarkingModes();\n positionSelBox(null);\n setMode(\"capturing\");\n regionCapture = startRegionCapture({\n doc,\n onProgress: positionSelBox,\n onComplete: (rect) => {\n stopRegionCapture();\n positionSelBox(null);\n beginDraw(rect);\n },\n onCancel: () => {\n stopRegionCapture();\n positionSelBox(null);\n setMode(\"compose\");\n },\n });\n }\n\n // ---- draw ---------------------------------------------------------------\n\n function positionDrawFrame(region: Rect): void {\n if (!refs) return;\n refs.drawFrame.style.left = `${region.x}px`;\n refs.drawFrame.style.top = `${region.y}px`;\n refs.drawFrame.style.width = `${region.width}px`;\n refs.drawFrame.style.height = `${region.height}px`;\n }\n\n function setDrawTool(tool: DrawTool): void {\n drawSurface?.setTool(tool);\n if (!refs) return;\n for (const [value, button] of refs.drawTools) {\n button.classList.toggle(\"is-active\", value === tool);\n }\n }\n\n function onMarksChange(marks: ReadonlyArray<Mark>): void {\n if (refs) refs.undoBtn.disabled = marks.length === 0;\n }\n\n function stopDrawSurface(): void {\n drawSurface?.stop();\n drawSurface = null;\n }\n\n function beginDraw(region: Rect): void {\n if (!refs) return;\n pendingRegion = region;\n positionDrawFrame(region);\n setMode(\"drawing\");\n drawSurface = startDrawSurface({\n doc,\n svg: refs.drawSvg,\n textInput: refs.drawText,\n initialMarks: state.marks,\n onChange: onMarksChange,\n });\n setDrawTool(\"arrow\");\n onMarksChange(state.marks);\n }\n\n function attachDraw(): void {\n if (drawSurface) {\n state.marks = drawSurface.marks().slice();\n if (pendingRegion) state.region = pendingRegion;\n }\n endDraw();\n renderMarking();\n }\n\n function cancelDraw(): void {\n // Discard the in-flight capture; previously attached marking is untouched.\n endDraw();\n renderMarking();\n }\n\n function endDraw(): void {\n stopDrawSurface();\n pendingRegion = null;\n if (mode === \"drawing\") setMode(\"compose\");\n }\n\n /** Tear down any active marking mode (before starting another, or on close). */\n function closeMarkingModes(): void {\n stopPicker();\n stopRegionCapture();\n stopDrawSurface();\n pendingRegion = null;\n positionSelBox(null);\n if (refs) refs.highlight.style.display = \"none\";\n if (mode !== \"compose\") setMode(\"compose\");\n }\n\n // ---- send ---------------------------------------------------------------\n\n function clearAutoClose(): void {\n if (autoClose !== null) {\n clearTimeout(autoClose);\n autoClose = null;\n }\n }\n\n async function send(): Promise<void> {\n if (!refs || state.phase === \"sending\") return;\n closeMarkingModes();\n state.phase = \"sending\";\n refs.sendBtn.disabled = true;\n refs.sendBtn.textContent = \"Sending…\";\n setStatus(\"\", false);\n try {\n const assembled = assembleContent({\n kind: state.kind,\n comment: refs.comment.value,\n element: state.selectedElement ?? undefined,\n region: state.region ?? undefined,\n marks: state.marks.length > 0 ? state.marks : undefined,\n url: win.location?.href,\n environment: collectEnvironment(win, sdkVersion),\n trace: config.buffer?.snapshot(),\n });\n // The single client-side scrub choke point (spec §C): default scrubbers +\n // the per-project hook run before transport; a `null` result drops the\n // report entirely.\n const content = runBeforeSend(assembled, {\n hook: config.beforeSend,\n scrub: config.scrub,\n });\n if (!content) {\n state.phase = \"sent\";\n refs.panel.classList.add(\"is-sent\");\n autoClose = setTimeout(close, AUTO_CLOSE_MS);\n return;\n }\n const capture = await deps.captureView({ doc, win });\n const screenshot = capture\n ? { blob: capture.blob, filename: `screenshot.${extensionFor(capture.type)}` }\n : null;\n const result = await deps.submitReport(config.apiUrl, {\n key: config.key,\n identity: config.identity,\n content,\n screenshot,\n });\n if (result.ok) {\n state.phase = \"sent\";\n refs.panel.classList.add(\"is-sent\");\n autoClose = setTimeout(close, AUTO_CLOSE_MS);\n } else {\n resetSendControl();\n setStatus(\n result.reason === \"unreachable\"\n ? \"Couldn't reach Fixback — try again.\"\n : \"Fixback couldn't accept this report.\",\n true,\n );\n }\n } catch {\n resetSendControl();\n setStatus(\"Something went wrong — try again.\", true);\n }\n }\n\n function resetSendControl(): void {\n state.phase = \"compose\";\n if (!refs) return;\n refs.sendBtn.disabled = false;\n refs.sendBtn.textContent = \"Send\";\n }\n\n // ---- build --------------------------------------------------------------\n\n function build(): void {\n host = h(doc, \"div\", { [OVERLAY_ATTRIBUTE]: \"\" });\n host.style.cssText =\n \"position:fixed;right:20px;bottom:84px;z-index:2147483001;margin:0;padding:0;border:0;display:none;\";\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = doc.createElement(\"style\");\n style.textContent = OVERLAY_STYLES;\n shadow.appendChild(style);\n\n // Header\n const closeBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-close\", \"aria-label\": \"Close\" }, [\"✕\"]);\n const head = h(doc, \"div\", { class: \"fb-ov-head\" }, [\n h(doc, \"span\", { class: \"fb-ov-mark-sq\" }),\n h(doc, \"span\", { class: \"fb-ov-brand\" }, [\"Fixback\"]),\n ]);\n // Display-only trust tier chip — present only when boot derived a tier. It\n // reflects the server-derived value verbatim; the client never asserts trust.\n if (config.tier != null) {\n head.appendChild(\n h(doc, \"span\", { class: \"fb-ov-tier\", \"aria-label\": `Trust tier: ${config.tier}` }, [config.tier]),\n );\n }\n head.appendChild(closeBtn);\n\n // Kind tabs\n const tabs = new Map<IssueKind, HTMLButtonElement>();\n const tabRow = h(doc, \"div\", { class: \"fb-ov-tabs\" });\n for (const { value, label } of KIND_TABS) {\n const tab = h(doc, \"button\", {\n type: \"button\",\n class: \"fb-ov-tab\",\n \"data-kind\": value,\n }, [label]);\n tab.addEventListener(\"click\", () => setKind(value));\n tabs.set(value, tab);\n tabRow.appendChild(tab);\n }\n\n // Annotation / screenshot marking region\n const selector = h(doc, \"span\", { class: \"fb-ov-selector\" });\n const caption = h(doc, \"span\", { class: \"fb-ov-mark-caption\" });\n const mark = h(doc, \"div\", { class: \"fb-ov-mark\" }, [selector, caption]);\n\n // Comment\n const comment = h(doc, \"textarea\", {\n class: \"fb-ov-comment\",\n placeholder: \"Describe what you saw or want…\",\n \"aria-label\": \"Comment\",\n });\n\n // Status + tools\n const status = h(doc, \"div\", { class: \"fb-ov-status\", role: \"status\", \"aria-live\": \"polite\" });\n const pickBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-pickbtn\", title: \"Point at an element\" });\n pickBtn.addEventListener(\"click\", () => {\n if (state.phase === \"sending\") return;\n if (mode === \"picking\") endPick();\n else beginPick();\n });\n const captureBtn = h(doc, \"button\", {\n type: \"button\",\n class: \"fb-ov-capturebtn\",\n title: \"Capture a region and draw\",\n \"aria-label\": \"Capture a region and draw\",\n });\n captureBtn.appendChild(captureGlyph(doc));\n captureBtn.addEventListener(\"click\", () => {\n if (state.phase === \"sending\") return;\n beginCapture();\n });\n const sendBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-send\" }, [\"Send\"]);\n sendBtn.addEventListener(\"click\", () => void send());\n const tools = h(doc, \"div\", { class: \"fb-ov-tools\" }, [pickBtn, captureBtn, sendBtn]);\n\n const form = h(doc, \"div\", { class: \"fb-ov-form\" }, [tabRow, mark, comment, status, tools]);\n\n // Confirmation\n const done = h(doc, \"div\", { class: \"fb-ov-done\" }, [\n h(doc, \"div\", { class: \"fb-ov-done__check\" }, [\"✓\"]),\n h(doc, \"div\", { class: \"fb-ov-done__title\" }, [\"Report sent\"]),\n h(doc, \"div\", { class: \"fb-ov-done__sub\" }, [\"Thanks — the team can see it now.\"]),\n ]);\n\n const panel = h(doc, \"div\", {\n class: \"fb-ov-panel\",\n role: \"dialog\",\n \"aria-label\": \"Fixback feedback\",\n }, [head, form, done]);\n\n // Element-pick highlight layer (visual only; never intercepts host events)\n const highlight = h(doc, \"div\", { class: \"fb-ov-highlight\" });\n highlight.style.display = \"none\";\n const pickLayer = h(doc, \"div\", { class: \"fb-ov-pick\" }, [\n h(doc, \"div\", { class: \"fb-ov-hint\" }, [\"Click the element you mean · Esc to cancel\"]),\n highlight,\n ]);\n\n // Region-capture layer (a dim + a live selection box)\n const selBox = h(doc, \"div\", { class: \"fb-ov-capture-sel\" });\n selBox.style.display = \"none\";\n const captureLayer = h(doc, \"div\", { class: \"fb-ov-capture\" }, [\n h(doc, \"div\", { class: \"fb-ov-capture-dim\" }),\n h(doc, \"div\", { class: \"fb-ov-hint\" }, [\"Drag to capture an area · Esc to cancel\"]),\n selBox,\n ]);\n\n // Draw layer: the mark SVG, the label input, the region frame, and the toolbar.\n const drawSvg = svgNode(doc, \"svg\", {\n class: \"fb-ov-draw-svg\",\n width: \"100%\",\n height: \"100%\",\n }) as SVGSVGElement;\n const drawText = h(doc, \"input\", {\n class: \"fb-ov-draw-text\",\n placeholder: \"label…\",\n \"aria-label\": \"Mark label\",\n });\n drawText.style.display = \"none\";\n const drawFrame = h(doc, \"div\", { class: \"fb-ov-draw-frame\" });\n\n const drawTools = new Map<DrawTool, HTMLButtonElement>();\n const toolButtons: HTMLButtonElement[] = [];\n for (const { tool, label } of DRAW_TOOLS) {\n const button = h(doc, \"button\", {\n type: \"button\",\n class: \"fb-ov-drawtool\",\n \"data-tool\": tool,\n title: label,\n \"aria-label\": label,\n });\n button.appendChild(drawToolGlyph(doc, tool));\n button.addEventListener(\"click\", () => setDrawTool(tool));\n drawTools.set(tool, button);\n toolButtons.push(button);\n }\n const undoBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-draw-undo\", title: \"Undo\", \"aria-label\": \"Undo\" });\n undoBtn.appendChild(undoGlyph(doc));\n undoBtn.addEventListener(\"click\", () => drawSurface?.undo());\n const cancelDrawBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-draw-cancel\" }, [\"Cancel\"]);\n cancelDrawBtn.addEventListener(\"click\", () => cancelDraw());\n const attachBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-draw-attach\" }, [\"Attach\"]);\n attachBtn.addEventListener(\"click\", () => attachDraw());\n const drawToolbar = h(doc, \"div\", { class: \"fb-ov-draw-toolbar\" }, [\n ...toolButtons,\n h(doc, \"span\", { class: \"fb-ov-draw-divider\" }),\n undoBtn,\n cancelDrawBtn,\n attachBtn,\n ]);\n const drawLayer = h(doc, \"div\", { class: \"fb-ov-draw\" }, [drawFrame, drawSvg, drawText, drawToolbar]);\n\n shadow.append(panel, pickLayer, captureLayer, drawLayer);\n\n closeBtn.addEventListener(\"click\", close);\n\n (config.target ?? doc.body).appendChild(host);\n refs = {\n panel,\n tabs,\n mark,\n selector,\n caption,\n comment,\n status,\n pickBtn,\n captureBtn,\n sendBtn,\n highlight,\n pickLayer,\n captureLayer,\n selBox,\n drawLayer,\n drawSvg,\n drawText,\n drawFrame,\n drawTools,\n undoBtn,\n };\n }\n\n function ensureBuilt(): void {\n if (!host || !refs) build();\n }\n\n function openOverlay(): void {\n ensureBuilt();\n if (!host || !refs) return;\n clearAutoClose();\n closeMarkingModes();\n state.phase = \"compose\";\n state.selectedElement = null;\n state.region = null;\n state.marks = [];\n refs.panel.classList.remove(\"is-sent\");\n refs.comment.value = \"\";\n resetSendControl();\n setStatus(\"\", false);\n setKind(\"bug\");\n renderMarking();\n host.style.display = \"block\";\n open = true;\n try {\n refs.comment.focus();\n } catch {\n /* focus is best-effort — never let it throw into the host page */\n }\n }\n\n function close(): void {\n clearAutoClose();\n closeMarkingModes();\n if (host) host.style.display = \"none\";\n open = false;\n }\n\n function destroy(): void {\n clearAutoClose();\n closeMarkingModes();\n host?.remove();\n host = null;\n refs = null;\n open = false;\n }\n\n return {\n open: openOverlay,\n close,\n destroy,\n get isOpen() {\n return open;\n },\n };\n}\n\n/** The crosshair glyph on the element-pick control (matches the `⌖` in the prototype). */\nfunction glyph(doc: Document): HTMLElement {\n return h(doc, \"span\", { class: \"fb-ov-pickbtn__glyph\", \"aria-hidden\": \"true\" }, [\"⌖\"]);\n}\n\n/** The frame glyph on the region-capture control (matches the prototype's crop icon). */\nfunction captureGlyph(doc: Document): SVGElement {\n return svgNode(\n doc,\n \"svg\",\n { class: \"fb-ov-icon\", width: \"14\", height: \"14\", viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.5\", \"aria-hidden\": \"true\" },\n [svgNode(doc, \"path\", { d: \"M2 5V2h3M14 5V2h-3M2 11v3h3M14 11v3h-3\" })],\n );\n}\n\n/** The undo glyph on the draw toolbar. */\nfunction undoGlyph(doc: Document): SVGElement {\n return svgNode(\n doc,\n \"svg\",\n { class: \"fb-ov-icon\", width: \"15\", height: \"15\", viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.6\", \"aria-hidden\": \"true\" },\n [svgNode(doc, \"path\", { d: \"M6 4 3 7l3 3M3 7h6a4 4 0 0 1 0 8H7\" })],\n );\n}\n\n/** The per-tool glyph on the draw toolbar (matches the prototype's icons). */\nfunction drawToolGlyph(doc: Document, tool: DrawTool): Node {\n if (tool === \"text\") {\n return h(doc, \"span\", { class: \"fb-ov-drawtool__t\", \"aria-hidden\": \"true\" }, [\"T\"]);\n }\n const paths: Record<Exclude<DrawTool, \"text\">, SVGElement> = {\n arrow: svgNode(doc, \"path\", { d: \"M3 13 13 3M7 3h6v6\" }),\n box: svgNode(doc, \"rect\", { x: \"2.5\", y: \"3.5\", width: \"11\", height: \"9\", rx: \"1\" }),\n pen: svgNode(doc, \"path\", { d: \"M3 13l1-3 6-6 2 2-6 6-3 1Z\" }),\n };\n return svgNode(\n doc,\n \"svg\",\n { class: \"fb-ov-icon\", width: \"15\", height: \"15\", viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.6\", \"aria-hidden\": \"true\" },\n [paths[tool]],\n );\n}\n","import { type BootAnswer, type IdentityInputs, requestBoot } from \"./boot\";\nimport {\n createBreadcrumbBuffer,\n instrumentBreadcrumbs,\n type BeforeBreadcrumb,\n type BreadcrumbBuffer,\n type BreadcrumbLevel,\n type Teardown,\n type TraceStream,\n} from \"./breadcrumbs\";\nimport { installErrorCapture } from \"./error-capture\";\nimport { ensureAnonymousId } from \"./identity\";\nimport {\n fetchInviteStatus,\n persistReporter,\n readInviteToken,\n readStoredReporter,\n redeemInviteToken,\n type ReporterDisplay,\n stripInviteToken,\n} from \"./invite\";\nimport { LAUNCH_EVENT, type Launcher, mountLauncher, unmountLauncher } from \"./launcher\";\nimport { createOnboardingModal } from \"./onboarding\";\nimport { createOverlay } from \"./overlay\";\nimport type { BeforeSend } from \"./scrub\";\nimport { SDK_VERSION } from \"./version\";\n\n/**\n * The hosted Fixback API origin the SDK talks to by default. A self-hosted or\n * local deployment overrides it with `apiUrl` (the dashboard's install snippet\n * pre-fills the right value for the Project).\n */\nexport const DEFAULT_API_URL = \"https://api.fixback.dev\";\n\n/**\n * Does `url` address one of the SDK's **own** API endpoints? Every request the SDK\n * issues lives under two namespaces beneath the API origin: `/api/ingest/*` — boot\n * (`bootEndpoint`, boot.ts) and feedback (`feedbackEndpoint`, submit.ts) — and\n * `/api/invites/*` (`inviteStatusEndpoint` / `redeemEndpoint`, invite.ts).\n *\n * The trace's network capture ignores **only** these, never the whole origin. That\n * distinction matters when the instrumented app and the Fixback API share an origin — a\n * self-hosted deployment, or Fixback running its own SDK on its own dashboard — where\n * ignoring the origin wholesale would swallow all of the app's own requests and leave the\n * Network tab empty. When the app and the API sit on different origins (the common case)\n * this matches nothing extra, since the app's origin is never `apiUrl`. `url` is the raw\n * request URL — absolute for every call the SDK makes — so a prefix test over the\n * normalised origin is exact.\n */\nexport function isFixbackApiRequest(apiUrl: string, url: string): boolean {\n const apiBase = apiUrl.replace(/\\/+$/, \"\");\n return (\n url.startsWith(`${apiBase}/api/ingest/`) || url.startsWith(`${apiBase}/api/invites/`)\n );\n}\n\n/**\n * Trace buffer tuning (spec #122 §A). These are configurable **starting points**\n * from the grill — three per-stream ring budgets (network ≈ 100 / console ≈ 80 /\n * breadcrumbs ≈ 40), a shared age cap (~3 min, on), and **all** console levels\n * captured (eviction priority, not capture, keeps warn/error above the chatter) —\n * never frozen magic numbers. Pass `false` for {@link InitOptions.trace} to disable\n * capture entirely.\n */\nexport interface TraceOptions {\n /**\n * Per-stream ring budgets (network / console / breadcrumbs); each stream evicts\n * independently, so a chatty stream can't drop another's lead-up. Any stream\n * omitted uses its default.\n */\n readonly budgets?: Partial<Record<TraceStream, number>>;\n /** Shared age cap in ms. Defaults to ~3 min (on); pass `0` to disable age pruning. */\n readonly maxAgeMs?: number;\n /** Console levels captured. Defaults to **all** levels (log/info/warn/error/assert/debug). */\n readonly consoleLevels?: readonly BreadcrumbLevel[];\n /** Per-crumb filter: mute a category, edit a crumb, or drop it (`null`). */\n readonly beforeBreadcrumb?: BeforeBreadcrumb;\n}\n\n/** Options for {@link init}. Only `key` is required. */\nexport interface InitOptions extends IdentityInputs {\n /** The Project's **publishable** key — an identifier that ships in the page. */\n readonly key: string;\n /** The Fixback API origin. Defaults to {@link DEFAULT_API_URL}. */\n readonly apiUrl?: string;\n /** Where to mount the launcher. Defaults to `document.body`. */\n readonly target?: HTMLElement;\n /**\n * Still the launcher's pulse and motion. An explicit opt-in that complements\n * the visitor's OS-level `prefers-reduced-motion`, which the launcher already\n * honours on its own.\n */\n readonly reduceMotion?: boolean;\n /**\n * The synchronous, network-free client scrub hook every report passes through\n * before transport (spec §C). Mutate the draft to scrub further, or return\n * `null` to drop the report. Runs after the default scrubbers.\n */\n readonly beforeSend?: BeforeSend;\n /** Run the built-in default scrubbers. Defaults to `true` (private-by-default). */\n readonly scrub?: boolean;\n /** Trace buffer tuning, or `false` to turn the buffer off entirely. */\n readonly trace?: TraceOptions | false;\n /**\n * The dev-side override of the Project's server-served capture config (spec #122\n * §L; ticket #138). Capture is **default-on** and normally governed per-project\n * from the dashboard, surfaced on the boot answer; set a stream here to override\n * what the server serves for it — `{ network: false }` turns network capture off\n * even where the Project leaves it on, and a stream left unset follows the served\n * config. Independent of {@link trace} `false`, which turns the whole buffer off.\n */\n readonly capture?: { readonly console?: boolean; readonly network?: boolean };\n /**\n * Automatic error capture — the SDK files uncaught exceptions / unhandled\n * rejections as `source: auto` Feedback with no prompt (spec §E, ADR-0011).\n * **Default-on across all Gates**; set `false` for the per-project toggle that\n * turns it off. It is gated by boot's `canSubmit` either way, so an auto-error is\n * never filed where a manual report would be refused.\n */\n readonly autoCapture?: boolean;\n}\n\n/**\n * Options for {@link redeem} — the explicit form of the `?fixback_invite=` URL\n * detection {@link init} performs. Identical to {@link InitOptions} plus the\n * `token` to redeem (the value the invite link carried).\n */\nexport interface RedeemOptions extends InitOptions {\n /** The invite token to redeem — the `?fixback_invite=` value from the link. */\n readonly token: string;\n}\n\n/** A running SDK instance. */\nexport interface FixbackInstance {\n /** Remove the launcher and release its DOM. Safe to call more than once. */\n destroy(): void;\n}\n\nconst NOOP_INSTANCE: FixbackInstance = { destroy() {} };\n\n/** The host site's origin (for the onboarding modal); never throws. */\nfunction originHost(): string {\n try {\n const loc = window.location;\n return loc.host || loc.hostname || \"this site\";\n } catch {\n return \"this site\";\n }\n}\n\n/** The current page URL, or `\"\"` when it cannot be read; never throws. */\nfunction safeHref(): string {\n try {\n return window.location.href;\n } catch {\n return \"\";\n }\n}\n\n/** Context for mounting the launcher + overlay + trace once boot says yes. */\ninterface MountContext {\n readonly options: InitOptions;\n readonly apiUrl: string;\n readonly key: string;\n readonly identity: IdentityInputs;\n readonly target: HTMLElement;\n readonly answer: BootAnswer;\n}\n\n/**\n * Mount the launcher and the report overlay it opens, the thin trace buffer\n * (spec §C), and automatic error capture (spec §E). Returns a teardown that removes\n * them all. The boot answer's `gate` + `tier` ride into the overlay (no second\n * call): `tier` drives the display-only header chip (§G), `gate` is reserved for\n * Gate-aware behaviour. The overlay and the auto-capture handlers carry the resolved\n * identity, so both a filed report and an auto-captured error are attributed to the\n * very Reporter boot recognised.\n */\nfunction mountReporter(ctx: MountContext): Teardown {\n const { options, apiUrl, key, identity, target, answer } = ctx;\n const launcher: Launcher = mountLauncher(target, {\n key,\n reduceMotion: options.reduceMotion,\n });\n\n let buffer: BreadcrumbBuffer | null = null;\n let teardownTrace: Teardown = () => {};\n if (options.trace !== false) {\n const trace = options.trace ?? {};\n // Effective per-stream capture (#138): start from what boot served (default-on\n // when the server omits it or a value is not a boolean), then let an explicit\n // `init` option override that stream. Turning a stream off means it is never\n // instrumented, so no entry of that kind ever reaches the wire.\n const served = ctx.answer.capture;\n const captureConsole =\n options.capture?.console ??\n (typeof served?.console === \"boolean\" ? served.console : true);\n const captureNetwork =\n options.capture?.network ??\n (typeof served?.network === \"boolean\" ? served.network : true);\n buffer = createBreadcrumbBuffer({\n budgets: trace.budgets,\n maxAgeMs: trace.maxAgeMs,\n beforeBreadcrumb: trace.beforeBreadcrumb,\n });\n teardownTrace = instrumentBreadcrumbs(buffer, {\n consoleLevels: trace.consoleLevels,\n ignoreUrl: (url) => isFixbackApiRequest(apiUrl, url),\n captureConsole,\n captureNetwork,\n });\n }\n\n const overlay = createOverlay({\n apiUrl,\n key,\n identity,\n gate: answer.gate,\n tier: answer.tier,\n sdkVersion: SDK_VERSION,\n target,\n buffer,\n beforeSend: options.beforeSend,\n scrub: options.scrub,\n });\n const onLaunch = (): void => overlay.open();\n launcher.host.addEventListener(LAUNCH_EVENT, onLaunch);\n\n // Automatic error capture (spec §E, ADR-0011): two global handlers file uncaught\n // errors as `source: auto` Feedback for this session's Reporter, with no prompt.\n // Default-on; `autoCapture: false` is the per-project toggle. Reaching here means\n // boot already returned `canSubmit`, so the Gate is respected and the auto-error\n // inherits the very tier boot derived — a Public crash stays tracked-not-shipped.\n let teardownAutoCapture: Teardown = () => {};\n if (options.autoCapture !== false) {\n teardownAutoCapture = installErrorCapture({\n apiUrl,\n key,\n identity,\n sdkVersion: SDK_VERSION,\n buffer,\n beforeSend: options.beforeSend,\n scrub: options.scrub,\n }).destroy;\n }\n\n return () => {\n launcher.host.removeEventListener(LAUNCH_EVENT, onLaunch);\n overlay.destroy();\n unmountLauncher(launcher);\n teardownTrace();\n teardownAutoCapture();\n };\n}\n\n/**\n * The shared boot + identity flow behind {@link init} and {@link redeem}.\n *\n * When an invite `token` is present and its Invite is live, the SDK renders the\n * onboarding modal (spec §F) instead of mounting immediately; on confirm it\n * redeems the Invite, persists the returned `reporterId` (scoped by publishable\n * key), strips the token from the URL (one-time consumption), and only then boots\n * with that identity and mounts the launcher. With no token — or a dead one — it\n * boots with any previously stored `reporterId` (a returning invited tester) or\n * an anonymous id, and mounts solely when boot's `canSubmit` is true. So on an\n * Invited / Internal Gate the launcher is absent until redemption, while an Open\n * Gate shows it to an anonymous visitor. Everything is wrapped so a Fixback\n * problem resolves to a no-op instance and never surfaces on the host page.\n */\nasync function run(\n options: InitOptions,\n inviteToken: string | null,\n): Promise<FixbackInstance> {\n try {\n // No DOM (server-side render, worker) — nothing to mount.\n if (typeof document === \"undefined\") return NOOP_INSTANCE;\n\n const key = options?.key;\n if (typeof key !== \"string\" || key.length === 0) return NOOP_INSTANCE;\n\n const apiUrl = options.apiUrl ?? DEFAULT_API_URL;\n const anonymousId = options.anonymousId ?? ensureAnonymousId();\n const target = options.target ?? document.body;\n\n // The launcher / overlay and the modal mount at different times (the modal\n // now, the launcher after redemption). `destroy()` tears down whichever exist.\n let disposed = false;\n let teardownMounted: Teardown = () => {};\n let teardownModal: Teardown = () => {};\n const instance: FixbackInstance = {\n destroy: () => {\n disposed = true;\n teardownModal();\n teardownModal = () => {};\n teardownMounted();\n teardownMounted = () => {};\n },\n };\n\n /** The identity to present when there is no fresh redemption to honour. */\n const storedIdentity = (): IdentityInputs => {\n const stored = readStoredReporter(key);\n return {\n signedIdentity: options.signedIdentity,\n reporterId: options.reporterId ?? stored?.reporterId,\n anonymousId,\n };\n };\n\n /** Boot with a resolved identity and mount the launcher when accepted. */\n const bootAndMount = async (identity: IdentityInputs): Promise<void> => {\n const answer = await requestBoot(apiUrl, { key, ...identity });\n if (disposed || !answer?.canSubmit) return;\n teardownMounted = mountReporter({ options, apiUrl, key, identity, target, answer });\n };\n\n if (inviteToken) {\n const status = await fetchInviteStatus(apiUrl, inviteToken);\n if (disposed) return instance;\n if (status && status.status === \"pending\") {\n const stored = readStoredReporter(key);\n\n const confirmRedeem = async (display: ReporterDisplay): Promise<void> => {\n const result = await redeemInviteToken(apiUrl, inviteToken);\n if (disposed) return;\n teardownModal();\n teardownModal = () => {};\n if (result && result.status === \"redeemed\") {\n persistReporter(key, {\n reporterId: result.reporterId,\n name: display.name,\n email: display.email,\n });\n stripInviteToken(window);\n await bootAndMount({\n signedIdentity: options.signedIdentity,\n reporterId: result.reporterId,\n anonymousId,\n });\n } else {\n // The Invite died between reading its status and redeeming it (a\n // race, or an already-spent shared link) — fall back to whatever\n // identity we already hold; on a gated Project that means no launcher.\n await bootAndMount(storedIdentity());\n }\n };\n\n const modal = createOnboardingModal({\n origin: originHost(),\n tier: status.tier,\n defaults: stored ? { name: stored.name, email: stored.email } : undefined,\n target,\n onConfirm: (display) => {\n void confirmRedeem(display);\n },\n });\n teardownModal = () => modal.destroy();\n return instance;\n }\n // A dead, unknown, or unreachable Invite shows no modal — the SDK proceeds\n // as an ordinary boot (a returning Reporter's stored identity, or anonymous).\n }\n\n await bootAndMount(storedIdentity());\n return instance;\n } catch {\n // A Fixback failure must never break the host page.\n return NOOP_INSTANCE;\n }\n}\n\n/**\n * Boot the SDK and mount the launcher when — and only when — a submission would\n * be accepted for this key, origin, and Gate.\n *\n * On load the SDK first checks the page URL for an invite token\n * (`?fixback_invite=`, spec §F); when one is present and live it renders the\n * onboarding modal and defers the launcher until the tester redeems. Otherwise it\n * calls the ingest boot endpoint and mounts the launcher solely when the answer's\n * `canSubmit` is true — so a Reporter is never shown a launcher a submission would\n * be refused, and on an Invited / Internal Gate the launcher stays absent until\n * redemption. Everything is wrapped so a Fixback problem — unreachable, refused,\n * or an unexpected error — resolves to a no-op instance.\n */\nexport function init(options: InitOptions): Promise<FixbackInstance> {\n const token = typeof window !== \"undefined\" ? readInviteToken(safeHref()) : null;\n return run(options, token);\n}\n\n/**\n * Redeem an invite token explicitly, the programmatic equivalent of landing on a\n * page with `?fixback_invite=<token>`. Renders the onboarding modal, and on\n * confirm redeems, persists the `reporterId`, and mounts the launcher (spec §F).\n * Use it when the token reaches the page some way other than the URL.\n */\nexport function redeem(options: RedeemOptions): Promise<FixbackInstance> {\n const token =\n typeof options?.token === \"string\" && options.token.length > 0\n ? options.token\n : null;\n return run(options, token);\n}\n"],"x_google_ignoreList":[7],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECgBjB,GAAoB,uBAG3B,GAAS,6BAGT,GAAgE,CACpE,CAAE,MAAO,MAAO,MAAO,KAAM,EAC7B,CAAE,MAAO,cAAe,MAAO,SAAU,EACzC,CAAE,MAAO,OAAQ,MAAO,MAAO,CACjC,EAGM,GAA+D,CACnE,CAAE,KAAM,QAAS,MAAO,OAAQ,EAChC,CAAE,KAAM,MAAO,MAAO,KAAM,EAC5B,CAAE,KAAM,MAAO,MAAO,KAAM,EAC5B,CAAE,KAAM,OAAQ,MAAO,YAAa,CACtC,EAGM,GAAgB,KAwFtB,SAAS,EACP,EACA,EACA,EAAyC,CAAC,EAC1C,EAAyC,CAAC,EAChB,CAC1B,MAAM,EAAO,EAAI,cAAc,CAAG,EAClC,SAAW,CAAC,EAAM,CAAA,IAAU,OAAO,QAAQ,CAAK,EAC1C,IAAU,QAAW,EAAK,aAAa,EAAM,CAAK,EAExD,UAAW,KAAS,EAClB,EAAK,YAAY,OAAO,GAAU,SAAW,EAAI,eAAe,CAAK,EAAI,CAAK,EAEhF,OAAO,CACT,CAGA,SAAS,EACP,EACA,EACA,EAAgC,CAAC,EACjC,EAAsC,CAAC,EAC3B,CACZ,MAAM,EAAO,EAAI,gBAAgB,GAAQ,CAAG,EAC5C,SAAW,CAAC,EAAM,CAAA,IAAU,OAAO,QAAQ,CAAK,EAAG,EAAK,aAAa,EAAM,CAAK,EAChF,UAAW,KAAS,EAAU,EAAK,YAAY,CAAK,EACpD,OAAO,CACT,CAeA,SAAgB,GAAc,EAA0C,yBACtE,MAAM,GAAA,EAAM,EAAO,OAAA,MAAA,IAAA,OAAA,EAAO,SACpB,GAAA,GAAA,EAAM,EAAO,OAAA,MAAA,IAAA,OAAA,EAAO,EAAI,eAAA,MAAA,IAAA,OAAA,EAAe,OACvC,GAAA,EAAa,EAAO,cAAA,MAAA,IAAA,OAAA,EAAc,GAClC,EAAoB,CACxB,aAAA,GAAA,EAAa,EAAO,QAAA,MAAA,IAAA,OAAA,OAAA,EAAM,eAAA,MAAA,IAAA,OAAA,EAAe,GACzC,cAAA,GAAA,EAAc,EAAO,QAAA,MAAA,IAAA,OAAA,OAAA,EAAM,gBAAA,MAAA,IAAA,OAAA,EAAgB,GAC3C,oBAAA,GAAA,EAAoB,EAAO,QAAA,MAAA,IAAA,OAAA,OAAA,EAAM,sBAAA,MAAA,IAAA,OAAA,EAAsB,EACzD,EAEA,IAAI,EAA2B,KAC3B,EAAoB,KACpB,EAA+B,KAC/B,EAAsC,KACtC,EAAkC,KAClC,EAA6B,KAC7B,EAAkD,KAClD,EAAO,GACP,EAAiB,UAErB,MAAM,EAMF,CAAE,KAAM,MAAO,gBAAiB,KAAM,OAAQ,KAAM,MAAO,CAAC,EAAG,MAAO,SAAU,EAEpF,SAAS,EAAU,EAAiB,EAAwB,CACrD,IACL,EAAK,OAAO,YAAc,EAC1B,EAAK,OAAO,UAAU,OAAO,WAAY,CAAO,EAClD,CAEA,SAAS,EAAQ,EAAuB,CAEtC,GADA,EAAM,KAAO,EACT,EAAC,EACL,SAAW,CAAC,EAAO,CAAA,IAAW,EAAK,KAAM,CACvC,MAAM,EAAS,IAAU,EACzB,EAAO,UAAU,OAAO,YAAa,CAAM,EAC3C,EAAO,aAAa,eAAgB,OAAO,CAAM,CAAC,CACpD,CACF,CAGA,SAAS,EAAQ,EAAsB,CAErC,GADA,EAAO,EACH,CAAC,EAAM,OACX,MAAM,EAAU,IAAS,UACzB,EAAK,MAAM,UAAU,OAAO,aAAc,CAAO,EACjD,EAAK,UAAU,UAAU,OAAO,aAAc,IAAS,SAAS,EAChE,EAAK,aAAa,UAAU,OAAO,aAAc,IAAS,WAAW,EACrE,EAAK,UAAU,UAAU,OAAO,aAAc,IAAS,SAAS,EAChE,EAAK,QAAQ,UAAU,OAAO,YAAa,IAAS,SAAS,EAC7D,EAAK,WAAW,UAAU,OAAO,YAAa,IAAS,aAAe,IAAS,SAAS,CAC1F,CAGA,SAAS,GAAsB,CAC7B,GAAI,CAAC,EAAM,OACX,MAAM,EAAa,CAAC,CAAC,EAAM,gBACrB,EAAY,CAAC,CAAC,EAAM,OACpB,EAAY,EAAM,MAAM,OAE9B,EAAK,KAAK,UAAU,OAAO,cAAe,CAAU,EACpD,EAAK,SAAS,YAAc,EAAa,EAAM,gBAAiB,SAAW,GAE3E,EAAK,QAAQ,YAAc,GAC3B,EAAK,QAAQ,OACX,GAAM,CAAG,EACT,EAAI,eAAe,EAAa,iBAAmB,cAAc,CACnE,EACA,EAAK,WAAW,UAAU,OAAO,cAAe,GAAa,EAAY,CAAC,EAE1E,MAAM,EAAiB,CAAC,EACpB,GAAY,EAAK,KAAK,SAAS,EAC/B,GAAW,EAAK,KAAK,QAAQ,EAC7B,EAAY,GAAG,EAAK,KAAK,GAAG,CAAA,QAAiB,IAAc,EAAI,GAAK,GAAA,EAAK,EAC7E,EAAK,QAAQ,YAAc,EAAK,OAC5B,GAAG,EAAK,KAAK,KAAK,CAAA,+BAClB,oCACN,CAEA,SAAS,EAAkB,EAA+B,CACxD,GAAI,CAAC,EAAM,OACX,GAAI,CAAC,EAAS,CACZ,EAAK,UAAU,MAAM,QAAU,OAC/B,MACF,CACA,MAAM,EAAO,EAAQ,sBAAsB,EAC3C,EAAK,UAAU,MAAM,QAAU,QAC/B,EAAK,UAAU,MAAM,KAAO,GAAG,EAAK,IAAA,KACpC,EAAK,UAAU,MAAM,IAAM,GAAG,EAAK,GAAA,KACnC,EAAK,UAAU,MAAM,MAAQ,GAAG,EAAK,KAAA,KACrC,EAAK,UAAU,MAAM,OAAS,GAAG,EAAK,MAAA,IACxC,CAIA,SAAS,IAAmB,CAC1B,GAAA,MAAA,EAAQ,KAAK,EACb,EAAS,IACX,CAEA,SAAS,GAAgB,CACnB,IAAM,EAAK,UAAU,MAAM,QAAU,QACzC,GAAW,EACP,IAAS,WAAW,EAAQ,SAAS,CAC3C,CAEA,SAAS,GAAkB,CACpB,IACL,GAAkB,EAClB,EAAQ,SAAS,EACjB,EAAS,EAAK,mBAAmB,CAC/B,IAAA,EACA,QAAS,EACT,OAAS,GAAY,CACnB,EAAM,gBAAkB,GAAgB,CAAO,EAC/C,EAAQ,EACR,EAAc,CAChB,EACA,SAAU,CACZ,CAAC,EACH,CAIA,SAAS,EAAe,EAAyB,CAC/C,GAAI,CAAC,EAAM,OACX,MAAM,EAAM,EAAK,OACjB,GAAI,CAAC,EAAM,CACT,EAAI,MAAM,QAAU,OACpB,MACF,CACA,EAAI,MAAM,QAAU,QACpB,EAAI,MAAM,KAAO,GAAG,EAAK,CAAA,KACzB,EAAI,MAAM,IAAM,GAAG,EAAK,CAAA,KACxB,EAAI,MAAM,MAAQ,GAAG,EAAK,KAAA,KAC1B,EAAI,MAAM,OAAS,GAAG,EAAK,MAAA,IAC7B,CAEA,SAAS,GAA0B,CACjC,GAAA,MAAA,EAAe,KAAK,EACpB,EAAgB,IAClB,CAEA,SAAS,GAAqB,CACvB,IACL,GAAkB,EAClB,EAAe,IAAI,EACnB,EAAQ,WAAW,EACnB,EAAgB,GAAmB,CACjC,IAAA,EACA,WAAY,EACZ,WAAa,GAAS,CACpB,EAAkB,EAClB,EAAe,IAAI,EACnB,GAAU,CAAI,CAChB,EACA,SAAA,IAAgB,CACd,EAAkB,EAClB,EAAe,IAAI,EACnB,EAAQ,SAAS,CACnB,CACF,CAAC,EACH,CAIA,SAAS,EAAkB,EAAoB,CACxC,IACL,EAAK,UAAU,MAAM,KAAO,GAAG,EAAO,CAAA,KACtC,EAAK,UAAU,MAAM,IAAM,GAAG,EAAO,CAAA,KACrC,EAAK,UAAU,MAAM,MAAQ,GAAG,EAAO,KAAA,KACvC,EAAK,UAAU,MAAM,OAAS,GAAG,EAAO,MAAA,KAC1C,CAEA,SAAS,EAAY,EAAsB,CAEzC,GADA,GAAA,MAAA,EAAa,QAAQ,CAAI,EACrB,EAAC,EACL,SAAW,CAAC,EAAO,CAAA,IAAW,EAAK,UACjC,EAAO,UAAU,OAAO,YAAa,IAAU,CAAI,CAEvD,CAEA,SAAS,GAAc,EAAkC,CACnD,IAAM,EAAK,QAAQ,SAAW,EAAM,SAAW,EACrD,CAEA,SAAS,IAAwB,CAC/B,GAAA,MAAA,EAAa,KAAK,EAClB,EAAc,IAChB,CAEA,SAAS,GAAU,EAAoB,CAChC,IACL,EAAgB,EAChB,EAAkB,CAAM,EACxB,EAAQ,SAAS,EACjB,EAAc,GAAiB,CAC7B,IAAA,EACA,IAAK,EAAK,QACV,UAAW,EAAK,SAChB,aAAc,EAAM,MACpB,SAAU,EACZ,CAAC,EACD,EAAY,OAAO,EACnB,GAAc,EAAM,KAAK,EAC3B,CAEA,SAAS,IAAmB,CACtB,IACF,EAAM,MAAQ,EAAY,MAAM,EAAE,MAAM,EACpC,IAAe,EAAM,OAAS,IAEpC,GAAQ,EACR,EAAc,CAChB,CAEA,SAAS,IAAmB,CAE1B,GAAQ,EACR,EAAc,CAChB,CAEA,SAAS,IAAgB,CACvB,GAAgB,EAChB,EAAgB,KACZ,IAAS,WAAW,EAAQ,SAAS,CAC3C,CAGA,SAAS,IAA0B,CACjC,GAAW,EACX,EAAkB,EAClB,GAAgB,EAChB,EAAgB,KAChB,EAAe,IAAI,EACf,IAAM,EAAK,UAAU,MAAM,QAAU,QACrC,IAAS,WAAW,EAAQ,SAAS,CAC3C,CAIA,SAAS,IAAuB,CAC1B,IAAc,OAChB,aAAa,CAAS,EACtB,EAAY,KAEhB,CAEA,eAAe,IAAsB,CACnC,GAAI,GAAC,GAAQ,EAAM,QAAU,WAC7B,CAAA,GAAkB,EAClB,EAAM,MAAQ,UACd,EAAK,QAAQ,SAAW,GACxB,EAAK,QAAQ,YAAc,WAC3B,EAAU,GAAI,EAAK,EACnB,GAAI,aACF,MAAM,GAAY,GAAgB,CAChC,KAAM,EAAM,KACZ,QAAS,EAAK,QAAQ,MACtB,SAAA,EAAS,EAAM,mBAAA,MAAA,IAAA,OAAA,EAAmB,OAClC,QAAA,EAAQ,EAAM,UAAA,MAAA,IAAA,OAAA,EAAU,OACxB,MAAO,EAAM,MAAM,OAAS,EAAI,EAAM,MAAQ,OAC9C,KAAA,EAAK,EAAI,YAAA,MAAA,IAAA,OAAA,OAAA,EAAU,KACnB,YAAa,GAAmB,EAAK,CAAU,EAC/C,OAAA,EAAO,EAAO,UAAA,MAAA,IAAA,OAAA,OAAA,EAAQ,SAAS,CACjC,CAAC,EAIK,GAAU,GAAc,GAAW,CACvC,KAAM,EAAO,WACb,MAAO,EAAO,KAChB,CAAC,EACD,GAAI,CAAC,GAAS,CACZ,EAAM,MAAQ,OACd,EAAK,MAAM,UAAU,IAAI,SAAS,EAClC,EAAY,WAAW,GAAO,EAAa,EAC3C,MACF,CACA,MAAM,GAAU,MAAM,EAAK,YAAY,CAAE,IAAA,EAAK,IAAA,CAAI,CAAC,EAC7C,GAAa,GACf,CAAE,KAAM,GAAQ,KAAM,SAAU,cAAc,GAAa,GAAQ,IAAI,CAAA,EAAI,EAC3E,KACE,GAAS,MAAM,EAAK,aAAa,EAAO,OAAQ,CACpD,IAAK,EAAO,IACZ,SAAU,EAAO,SACjB,QAAA,GACA,WAAA,EACF,CAAC,EACG,GAAO,IACT,EAAM,MAAQ,OACd,EAAK,MAAM,UAAU,IAAI,SAAS,EAClC,EAAY,WAAW,GAAO,EAAa,IAE3C,GAAiB,EACjB,EACE,GAAO,SAAW,cACd,sCACA,uCACJ,EACF,EAEJ,MAAQ,CACN,GAAiB,EACjB,EAAU,oCAAqC,EAAI,CACrD,EACF,CAEA,SAAS,IAAyB,CAChC,EAAM,MAAQ,UACT,IACL,EAAK,QAAQ,SAAW,GACxB,EAAK,QAAQ,YAAc,OAC7B,CAIA,SAAS,IAAc,OACrB,EAAO,EAAE,EAAK,MAAO,CAAA,CAAG,EAAA,EAAoB,EAAG,CAAC,EAChD,EAAK,MAAM,QACT,qGACF,MAAM,EAAS,EAAK,aAAa,CAAE,KAAM,MAAO,CAAC,EAE3C,EAAQ,EAAI,cAAc,OAAO,EACvC,EAAM,YAAc,GACpB,EAAO,YAAY,CAAK,EAGxB,MAAM,EAAW,EAAE,EAAK,SAAU,CAAE,KAAM,SAAU,MAAO,cAAe,aAAc,OAAQ,EAAG,CAAC,GAAG,CAAC,EAClG,GAAO,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CAClD,EAAE,EAAK,OAAQ,CAAE,MAAO,eAAgB,CAAC,EACzC,EAAE,EAAK,OAAQ,CAAE,MAAO,aAAc,EAAG,CAAC,SAAS,CAAC,CACtD,CAAC,EAGG,EAAO,MAAQ,MACjB,GAAK,YACH,EAAE,EAAK,OAAQ,CAAE,MAAO,aAAc,aAAc,eAAe,EAAO,IAAA,EAAO,EAAG,CAAC,EAAO,IAAI,CAAC,CACnG,EAEF,GAAK,YAAY,CAAQ,EAGzB,MAAM,GAAO,IAAI,IACX,GAAS,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,CAAC,EACpD,SAAW,CAAE,MAAA,EAAO,MAAA,EAAA,IAAW,GAAW,CACxC,MAAM,EAAM,EAAE,EAAK,SAAU,CAC3B,KAAM,SACN,MAAO,YACP,YAAa,CACf,EAAG,CAAC,EAAK,CAAC,EACV,EAAI,iBAAiB,QAAA,IAAe,EAAQ,CAAK,CAAC,EAClD,GAAK,IAAI,EAAO,CAAG,EACnB,GAAO,YAAY,CAAG,CACxB,CAGA,MAAM,GAAW,EAAE,EAAK,OAAQ,CAAE,MAAO,gBAAiB,CAAC,EACrD,GAAU,EAAE,EAAK,OAAQ,CAAE,MAAO,oBAAqB,CAAC,EACxD,GAAO,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CAAC,GAAU,EAAO,CAAC,EAGjE,GAAU,EAAE,EAAK,WAAY,CACjC,MAAO,gBACP,YAAa,iCACb,aAAc,SAChB,CAAC,EAGK,GAAS,EAAE,EAAK,MAAO,CAAE,MAAO,eAAgB,KAAM,SAAU,YAAa,QAAS,CAAC,EACvF,GAAU,EAAE,EAAK,SAAU,CAAE,KAAM,SAAU,MAAO,gBAAiB,MAAO,qBAAsB,CAAC,EACzG,GAAQ,iBAAiB,QAAA,IAAe,CAClC,EAAM,QAAU,YAChB,IAAS,UAAW,EAAQ,EAC3B,EAAU,EACjB,CAAC,EACD,MAAM,GAAa,EAAE,EAAK,SAAU,CAClC,KAAM,SACN,MAAO,mBACP,MAAO,4BACP,aAAc,2BAChB,CAAC,EACD,GAAW,YAAY,GAAa,CAAG,CAAC,EACxC,GAAW,iBAAiB,QAAA,IAAe,CACrC,EAAM,QAAU,WACpB,EAAa,CACf,CAAC,EACD,MAAM,GAAU,EAAE,EAAK,SAAU,CAAE,KAAM,SAAU,MAAO,YAAa,EAAG,CAAC,MAAM,CAAC,EAClF,GAAQ,iBAAiB,QAAA,IAAA,CAAoB,GAAK,EAAC,EACnD,MAAM,GAAQ,EAAE,EAAK,MAAO,CAAE,MAAO,aAAc,EAAG,CAAC,GAAS,GAAY,EAAO,CAAC,EAE9E,GAAO,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CAAC,GAAQ,GAAM,GAAS,GAAQ,EAAK,CAAC,EAGpF,GAAO,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CAClD,EAAE,EAAK,MAAO,CAAE,MAAO,mBAAoB,EAAG,CAAC,GAAG,CAAC,EACnD,EAAE,EAAK,MAAO,CAAE,MAAO,mBAAoB,EAAG,CAAC,aAAa,CAAC,EAC7D,EAAE,EAAK,MAAO,CAAE,MAAO,iBAAkB,EAAG,CAAC,mCAAmC,CAAC,CACnF,CAAC,EAEK,GAAQ,EAAE,EAAK,MAAO,CAC1B,MAAO,cACP,KAAM,SACN,aAAc,kBAChB,EAAG,CAAC,GAAM,GAAM,EAAI,CAAC,EAGf,GAAY,EAAE,EAAK,MAAO,CAAE,MAAO,iBAAkB,CAAC,EAC5D,GAAU,MAAM,QAAU,OAC1B,MAAM,GAAY,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CACvD,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CAAC,4CAA4C,CAAC,EACrF,EACF,CAAC,EAGK,GAAS,EAAE,EAAK,MAAO,CAAE,MAAO,mBAAoB,CAAC,EAC3D,GAAO,MAAM,QAAU,OACvB,MAAM,GAAe,EAAE,EAAK,MAAO,CAAE,MAAO,eAAgB,EAAG,CAC7D,EAAE,EAAK,MAAO,CAAE,MAAO,mBAAoB,CAAC,EAC5C,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CAAC,yCAAyC,CAAC,EAClF,EACF,CAAC,EAGK,GAAU,EAAQ,EAAK,MAAO,CAClC,MAAO,iBACP,MAAO,OACP,OAAQ,MACV,CAAC,EACK,GAAW,EAAE,EAAK,QAAS,CAC/B,MAAO,kBACP,YAAa,SACb,aAAc,YAChB,CAAC,EACD,GAAS,MAAM,QAAU,OACzB,MAAM,GAAY,EAAE,EAAK,MAAO,CAAE,MAAO,kBAAmB,CAAC,EAEvD,GAAY,IAAI,IAChB,GAAmC,CAAC,EAC1C,SAAW,CAAE,KAAA,EAAM,MAAA,EAAA,IAAW,GAAY,CACxC,MAAM,EAAS,EAAE,EAAK,SAAU,CAC9B,KAAM,SACN,MAAO,iBACP,YAAa,EACb,MAAO,GACP,aAAc,EAChB,CAAC,EACD,EAAO,YAAY,GAAc,EAAK,CAAI,CAAC,EAC3C,EAAO,iBAAiB,QAAA,IAAe,EAAY,CAAI,CAAC,EACxD,GAAU,IAAI,EAAM,CAAM,EAC1B,GAAY,KAAK,CAAM,CACzB,CACA,MAAM,GAAU,EAAE,EAAK,SAAU,CAAE,KAAM,SAAU,MAAO,kBAAmB,MAAO,OAAQ,aAAc,MAAO,CAAC,EAClH,GAAQ,YAAY,GAAU,CAAG,CAAC,EAClC,GAAQ,iBAAiB,QAAA,IAAA,GAAA,KAAA,OAAe,EAAa,KAAK,CAAC,EAC3D,MAAM,GAAgB,EAAE,EAAK,SAAU,CAAE,KAAM,SAAU,MAAO,mBAAoB,EAAG,CAAC,QAAQ,CAAC,EACjG,GAAc,iBAAiB,QAAA,IAAe,GAAW,CAAC,EAC1D,MAAM,GAAY,EAAE,EAAK,SAAU,CAAE,KAAM,SAAU,MAAO,mBAAoB,EAAG,CAAC,QAAQ,CAAC,EAC7F,GAAU,iBAAiB,QAAA,IAAe,GAAW,CAAC,EACtD,MAAM,GAAc,EAAE,EAAK,MAAO,CAAE,MAAO,oBAAqB,EAAG,CACjE,GAAG,GACH,EAAE,EAAK,OAAQ,CAAE,MAAO,oBAAqB,CAAC,EAC9C,GACA,GACA,EACF,CAAC,EACK,GAAY,EAAE,EAAK,MAAO,CAAE,MAAO,YAAa,EAAG,CAAC,GAAW,GAAS,GAAU,EAAW,CAAC,EAEpG,EAAO,OAAO,GAAO,GAAW,GAAc,EAAS,EAEvD,EAAS,iBAAiB,QAAS,EAAK,IAExC,EAAC,EAAO,UAAA,MAAA,IAAA,OAAA,EAAU,EAAI,MAAM,YAAY,CAAI,EAC5C,EAAO,CACL,MAAA,GACA,KAAA,GACA,KAAA,GACA,SAAA,GACA,QAAA,GACA,QAAA,GACA,OAAA,GACA,QAAA,GACA,WAAA,GACA,QAAA,GACA,UAAA,GACA,UAAA,GACA,aAAA,GACA,OAAA,GACA,UAAA,GACA,QAAA,GACA,SAAA,GACA,UAAA,GACA,UAAA,GACA,QAAA,EACF,CACF,CAEA,SAAS,IAAoB,EACvB,CAAC,GAAQ,CAAC,IAAM,GAAM,CAC5B,CAEA,SAAS,IAAoB,CAE3B,GADA,GAAY,EACR,GAAC,GAAQ,CAAC,GACd,CAAA,GAAe,EACf,GAAkB,EAClB,EAAM,MAAQ,UACd,EAAM,gBAAkB,KACxB,EAAM,OAAS,KACf,EAAM,MAAQ,CAAC,EACf,EAAK,MAAM,UAAU,OAAO,SAAS,EACrC,EAAK,QAAQ,MAAQ,GACrB,GAAiB,EACjB,EAAU,GAAI,EAAK,EACnB,EAAQ,KAAK,EACb,EAAc,EACd,EAAK,MAAM,QAAU,QACrB,EAAO,GACP,GAAI,CACF,EAAK,QAAQ,MAAM,CACrB,MAAQ,CAER,EACF,CAEA,SAAS,IAAc,CACrB,GAAe,EACf,GAAkB,EACd,IAAM,EAAK,MAAM,QAAU,QAC/B,EAAO,EACT,CAEA,SAAS,IAAgB,CACvB,GAAe,EACf,GAAkB,EAClB,GAAA,MAAA,EAAM,OAAO,EACb,EAAO,KACP,EAAO,KACP,EAAO,EACT,CAEA,MAAO,CACL,KAAM,GACN,MAAA,GACA,QAAA,GACA,IAAI,QAAS,CACX,OAAO,CACT,CACF,CACF,CAGA,SAAS,GAAM,EAA4B,CACzC,OAAO,EAAE,EAAK,OAAQ,CAAE,MAAO,uBAAwB,cAAe,MAAO,EAAG,CAAC,GAAG,CAAC,CACvF,CAGA,SAAS,GAAa,EAA2B,CAC/C,OAAO,EACL,EACA,MACA,CAAE,MAAO,aAAc,MAAO,KAAM,OAAQ,KAAM,QAAS,YAAa,KAAM,OAAQ,OAAQ,eAAgB,eAAgB,MAAO,cAAe,MAAO,EAC3J,CAAC,EAAQ,EAAK,OAAQ,CAAE,EAAG,wCAAyC,CAAC,CAAC,CACxE,CACF,CAGA,SAAS,GAAU,EAA2B,CAC5C,OAAO,EACL,EACA,MACA,CAAE,MAAO,aAAc,MAAO,KAAM,OAAQ,KAAM,QAAS,YAAa,KAAM,OAAQ,OAAQ,eAAgB,eAAgB,MAAO,cAAe,MAAO,EAC3J,CAAC,EAAQ,EAAK,OAAQ,CAAE,EAAG,oCAAqC,CAAC,CAAC,CACpE,CACF,CAGA,SAAS,GAAc,EAAe,EAAsB,CAC1D,OAAI,IAAS,OACJ,EAAE,EAAK,OAAQ,CAAE,MAAO,oBAAqB,cAAe,MAAO,EAAG,CAAC,GAAG,CAAC,EAO7E,EACL,EACA,MACA,CAAE,MAAO,aAAc,MAAO,KAAM,OAAQ,KAAM,QAAS,YAAa,KAAM,OAAQ,OAAQ,eAAgB,eAAgB,MAAO,cAAe,MAAO,EAC3J,CAAC,CARD,MAAO,EAAQ,EAAK,OAAQ,CAAE,EAAG,oBAAqB,CAAC,EACvD,IAAK,EAAQ,EAAK,OAAQ,CAAE,EAAG,MAAO,EAAG,MAAO,MAAO,KAAM,OAAQ,IAAK,GAAI,GAAI,CAAC,EACnF,IAAK,EAAQ,EAAK,OAAQ,CAAE,EAAG,4BAA6B,CAAC,CAM5D,EAAM,CAAA,CAAK,CACd,CACF,CCnuBA,IAAa,GAAkB,0BAiB/B,SAAgB,GAAoB,EAAgB,EAAsB,CACxE,MAAM,EAAU,EAAO,QAAQ,OAAQ,EAAE,EACzC,OACE,EAAI,WAAW,GAAG,CAAA,cAAqB,GAAK,EAAI,WAAW,GAAG,CAAA,eAAsB,CAExF,CAoFA,IAAM,GAAiC,CAAE,SAAU,CAAC,CAAE,EAGtD,SAAS,IAAqB,CAC5B,GAAI,CACF,MAAM,EAAM,OAAO,SACnB,OAAO,EAAI,MAAQ,EAAI,UAAY,WACrC,MAAQ,CACN,MAAO,WACT,CACF,CAGA,SAAS,IAAmB,CAC1B,GAAI,CACF,OAAO,OAAO,SAAS,IACzB,MAAQ,CACN,MAAO,EACT,CACF,CAqBA,SAAS,GAAc,EAA6B,CAClD,KAAM,CAAE,QAAA,EAAS,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAU,OAAA,EAAQ,OAAA,CAAA,EAAW,EACrD,EAAqB,GAAc,EAAQ,CAC/C,IAAA,EACA,aAAc,EAAQ,YACxB,CAAC,EAED,IAAI,EAAkC,KAClC,EAAA,IAAgC,CAAC,EACrC,GAAI,EAAQ,QAAU,GAAO,eAC3B,MAAM,GAAA,EAAQ,EAAQ,SAAA,MAAA,IAAA,OAAA,EAAS,CAAC,EAK1B,EAAS,EAAI,OAAO,QACpB,GAAA,GAAA,EACJ,EAAQ,WAAA,MAAA,IAAA,OAAA,OAAA,EAAS,WAAA,MAAA,IAAA,OAAA,EAChB,OAAA,GAAA,KAAA,OAAO,EAAQ,UAAY,UAAY,EAAO,QAAU,GACrD,GAAA,GAAA,EACJ,EAAQ,WAAA,MAAA,IAAA,OAAA,OAAA,EAAS,WAAA,MAAA,IAAA,OAAA,EAChB,OAAA,GAAA,KAAA,OAAO,EAAQ,UAAY,UAAY,EAAO,QAAU,GAC3D,EAAS,GAAuB,CAC9B,QAAS,EAAM,QACf,SAAU,EAAM,SAChB,iBAAkB,EAAM,gBAC1B,CAAC,EACD,EAAgB,GAAsB,EAAQ,CAC5C,cAAe,EAAM,cACrB,UAAY,GAAQ,GAAoB,EAAQ,CAAG,EACnD,eAAA,EACA,eAAA,CACF,CAAC,CACH,CAEA,MAAM,EAAU,GAAc,CAC5B,OAAA,EACA,IAAA,EACA,SAAA,EACA,KAAM,EAAO,KACb,KAAM,EAAO,KACb,WAAY,GACZ,OAAA,EACA,OAAA,EACA,WAAY,EAAQ,WACpB,MAAO,EAAQ,KACjB,CAAC,EACK,EAAA,IAAuB,EAAQ,KAAK,EAC1C,EAAS,KAAK,iBAAiB,GAAc,CAAQ,EAOrD,IAAI,EAAA,IAAsC,CAAC,EAC3C,OAAI,EAAQ,cAAgB,KAC1B,EAAsB,GAAoB,CACxC,OAAA,EACA,IAAA,EACA,SAAA,EACA,WAAY,GACZ,OAAA,EACA,WAAY,EAAQ,WACpB,MAAO,EAAQ,KACjB,CAAC,EAAE,SAGL,IAAa,CACX,EAAS,KAAK,oBAAoB,GAAc,CAAQ,EACxD,EAAQ,QAAQ,EAChB,GAAgB,CAAQ,EACxB,EAAc,EACd,EAAoB,CACtB,CACF,CAgBA,eAAe,GACb,EACA,EAC0B,CAC1B,GAAI,WAEF,GAAI,OAAO,UAAa,YAAa,OAAO,GAE5C,MAAM,EAAA,GAAA,KAAA,OAAM,EAAS,IACrB,GAAI,OAAO,GAAQ,UAAY,EAAI,SAAW,EAAG,OAAO,GAExD,MAAM,GAAA,EAAS,EAAQ,UAAA,MAAA,IAAA,OAAA,EAAU,GAC3B,GAAA,EAAc,EAAQ,eAAA,MAAA,IAAA,OAAA,EAAe,GAAkB,EACvD,GAAA,EAAS,EAAQ,UAAA,MAAA,IAAA,OAAA,EAAU,SAAS,KAI1C,IAAI,EAAW,GACX,EAAA,IAAkC,CAAC,EACnC,EAAA,IAAgC,CAAC,EACrC,MAAM,EAA4B,CAChC,QAAA,IAAe,CACb,EAAW,GACX,EAAc,EACd,EAAA,IAAsB,CAAC,EACvB,EAAgB,EAChB,EAAA,IAAwB,CAAC,CAC3B,CACF,EAGM,EAAA,IAAuC,OAC3C,MAAM,EAAS,GAAmB,CAAG,EACrC,MAAO,CACL,eAAgB,EAAQ,eACxB,YAAA,EAAY,EAAQ,cAAA,MAAA,IAAA,OAAA,EAAA,GAAA,KAAA,OAAc,EAAQ,WAC1C,YAAA,CACF,CACF,EAGM,EAAe,MAAO,GAA4C,CACtE,MAAM,EAAS,MAAM,GAAY,EAAQ,CAAE,IAAA,EAAK,GAAG,CAAS,CAAC,EACzD,GAAY,EAAA,GAAA,MAAC,EAAQ,aACzB,EAAkB,GAAc,CAAE,QAAA,EAAS,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAU,OAAA,EAAQ,OAAA,CAAO,CAAC,EACpF,EAEA,GAAI,EAAa,CACf,MAAM,EAAS,MAAM,GAAkB,EAAQ,CAAW,EAC1D,GAAI,EAAU,OAAO,EACrB,GAAI,GAAU,EAAO,SAAW,UAAW,CACzC,MAAM,EAAS,GAAmB,CAAG,EAE/B,EAAgB,MAAO,GAA4C,CACvE,MAAM,EAAS,MAAM,GAAkB,EAAQ,CAAW,EACtD,IACJ,EAAc,EACd,EAAA,IAAsB,CAAC,EACnB,GAAU,EAAO,SAAW,YAC9B,GAAgB,EAAK,CACnB,WAAY,EAAO,WACnB,KAAM,EAAQ,KACd,MAAO,EAAQ,KACjB,CAAC,EACD,GAAiB,MAAM,EACvB,MAAM,EAAa,CACjB,eAAgB,EAAQ,eACxB,WAAY,EAAO,WACnB,YAAA,CACF,CAAC,GAKD,MAAM,EAAa,EAAe,CAAC,EAEvC,EAEM,EAAQ,GAAsB,CAClC,OAAQ,GAAW,EACnB,KAAM,EAAO,KACb,SAAU,EAAS,CAAE,KAAM,EAAO,KAAM,MAAO,EAAO,KAAM,EAAI,OAChE,OAAA,EACA,UAAY,GAAY,CACtB,EAAmB,CAAO,CAC5B,CACF,CAAC,EACD,OAAA,EAAA,IAAsB,EAAM,QAAQ,EAC7B,CACT,CAGF,CAEA,aAAM,EAAa,EAAe,CAAC,EAC5B,CACT,MAAQ,CAEN,OAAO,EACT,CACF,CAeA,SAAgB,GAAK,EAAgD,CAEnE,OAAO,GAAI,EADG,OAAO,QAAW,YAAc,GAAgB,GAAS,CAAC,EAAI,IACnD,CAC3B,CAQA,SAAgB,GAAO,EAAkD,CAKvE,OAAO,GAAI,EAHT,OAAA,GAAA,KAAA,OAAO,EAAS,QAAU,UAAY,EAAQ,MAAM,OAAS,EACzD,EAAQ,MACR,IACmB,CAC3B"}
1
+ {"version":3,"file":"fixback.umd.js","names":["isCSSImportRule","URL_RE","EventType"],"sources":["../src/boot.ts","../src/dom.ts","../src/element-picker.ts","../src/scrub.ts","../src/breadcrumbs.ts","../src/annotation.ts","../src/report.ts","../../../node_modules/.pnpm/modern-screenshot@4.7.0/node_modules/modern-screenshot/dist/index.mjs","../src/screenshot.ts","../src/auto-report-backoff.ts","../src/submit.ts","../src/version.ts","../src/error-capture.ts","../src/identity.ts","../src/invite.ts","../src/styles.ts","../src/launcher.ts","../src/onboarding-styles.ts","../src/onboarding.ts","../src/draw-surface.ts","../src/region-capture.ts","../src/overlay-styles.ts","../src/overlay.ts","../../../node_modules/.pnpm/@rrweb+record@2.1.1/node_modules/@rrweb/record/dist/record.js","../../../node_modules/.pnpm/@rrweb+types@2.1.1/node_modules/@rrweb/types/dist/types.js","../src/replay.ts","../src/init.ts"],"sourcesContent":["/**\n * The ingest **boot** wire-contract, vendored.\n *\n * The SDK deliberately does not import `@fixback/shared` — that package is\n * private and server-shaped (ticket #47). The boot request/response is small and\n * stable, so the exact slice the SDK needs is copied here. Keep it in lock-step\n * with the server: the request body accepted by `POST /api/ingest/boot`\n * (`apps/api/src/ingest/ingest.controller.ts`) and the `BootAnswer` returned by\n * `evaluateBoot` (`apps/api/src/ingest/reporter-identity.ts`).\n */\n\n/** A Project's Gate — who may submit. Mirrors the server's `ProjectGate`. */\nexport type ProjectGate = \"open\" | \"invited\" | \"internal\";\n\n/** The trust tier a Reporter holds. Mirrors the server's `ReporterTier`. */\nexport type ReporterTier = \"public\" | \"invited\" | \"internal\";\n\n/**\n * Optional identity evidence the SDK forwards to boot. None of it is a tier: the\n * server re-derives trust from this evidence and never honours a self-declared\n * tier, so the SDK does not send one.\n */\nexport interface IdentityInputs {\n readonly signedIdentity?: string;\n readonly reporterId?: string;\n readonly anonymousId?: string;\n}\n\n/** The JSON body `POST /api/ingest/boot` accepts. */\nexport interface BootRequest extends IdentityInputs {\n readonly key: string;\n}\n\n/**\n * The Project's effective console/network capture config, served on the boot answer\n * (spec #122 §L; ticket #138). Each flag is the per-project master toggle ANDed with\n * that stream's own toggle, so the SDK gates instrumentation on one boolean per\n * stream. Optional on the wire: an older server that does not send it (or a\n * malformed value) is treated as **capture on** — default-on, matching the server\n * default — and `init` options override whatever is served.\n */\nexport interface CaptureConfig {\n readonly console: boolean;\n readonly network: boolean;\n /**\n * The Project's session-replay toggle (issue #189, ADR-0024). Optional on the\n * wire: a server predating replay omits it, which — like the other streams —\n * means **capture on**.\n */\n readonly replay?: boolean;\n}\n\n/**\n * The boot answer: whether this origin is allowlisted, the Project's Gate, the\n * caller's derived tier (`null` when a presented identity was refused), whether a\n * submission would be accepted right now, and the Project's capture config. The\n * launcher shows only when `canSubmit` is true.\n */\nexport interface BootAnswer {\n readonly originAllowed: boolean;\n readonly gate: ProjectGate;\n readonly tier: ReporterTier | null;\n readonly canSubmit: boolean;\n /** The Project's console/network capture config; absent ⇒ default-on (#138). */\n readonly capture?: CaptureConfig;\n}\n\n/** Join an API base URL with the boot path, tolerating a trailing slash. */\nexport function bootEndpoint(apiUrl: string): string {\n return `${apiUrl.replace(/\\/+$/, \"\")}/api/ingest/boot`;\n}\n\n/** Narrow an unknown JSON body to a `BootAnswer` before the SDK trusts it. */\nfunction isBootAnswer(value: unknown): value is BootAnswer {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.originAllowed === \"boolean\" &&\n typeof v.canSubmit === \"boolean\" &&\n typeof v.gate === \"string\" &&\n (v.tier === null || typeof v.tier === \"string\")\n );\n}\n\n/**\n * Ask ingest whether a submission would be accepted for this key / origin / Gate.\n * Resolves to the boot answer, or `null` when Fixback could not be reached, the\n * key was refused, or the response was not a boot answer. It never throws: any\n * non-answer is treated by the caller as \"do not show the launcher\", so a Fixback\n * outage stays invisible to the host page (ticket #47: \"fails quietly\").\n *\n * The browser attaches the `Origin` header itself on this cross-origin request —\n * the server reads it to decide `originAllowed` — so the SDK neither sets nor\n * needs to set it. `fetchImpl` is injectable purely so the boot call is testable.\n */\nexport async function requestBoot(\n apiUrl: string,\n request: BootRequest,\n fetchImpl: typeof fetch = fetch,\n): Promise<BootAnswer | null> {\n let response: Response;\n try {\n response = await fetchImpl(bootEndpoint(apiUrl), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n } catch {\n return null; // network error / Fixback unreachable\n }\n\n if (!response.ok) return null; // 401 unknown key, or any other refusal\n\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n return null;\n }\n\n return isBootAnswer(body) ? body : null;\n}\n","/**\n * Small DOM helpers shared across the SDK's report surfaces.\n *\n * The SDK mounts its own host elements into the host page — the launcher and the\n * overlay panel — each tagged with a `data-fixback-*` marker attribute (the\n * element-picker's highlight lives inside the overlay's shadow, so it is covered\n * by the shadow-boundary walk below). These helpers let the picker skip the SDK's\n * own UI and let the screenshot exclude it, so a report never captures or targets\n * Fixback's chrome.\n */\n\n/** Marker attributes on the SDK's own host elements in the light DOM. */\nexport const FIXBACK_HOST_MARKERS = [\n \"data-fixback-root\",\n \"data-fixback-overlay\",\n] as const;\n\nconst HOST_SELECTOR = FIXBACK_HOST_MARKERS.map((m) => `[${m}]`).join(\",\");\n\n/**\n * Is this node itself one of the SDK's own host elements (the launcher / overlay\n * roots)? A self-only check — the screenshot's clone walk excludes a node's whole\n * subtree once the host is matched, so catching the host is enough to keep all of\n * Fixback's chrome (light DOM and its shadow tree) out of a capture.\n */\nexport function isFixbackHostElement(node: Node | null | undefined): boolean {\n return (\n node instanceof Element &&\n FIXBACK_HOST_MARKERS.some((marker) => node.hasAttribute(marker))\n );\n}\n\n/**\n * Is this node part of the SDK's own UI? Walks up parents and out through any\n * Shadow DOM boundary (via `getRootNode().host`), so a click inside the overlay's\n * shadow is recognised as Fixback's own — not a host-page element to pick.\n */\nexport function isFixbackNode(node: EventTarget | null | undefined): boolean {\n let current: Node | null = node instanceof Node ? node : null;\n while (current) {\n if (current instanceof Element) {\n for (const marker of FIXBACK_HOST_MARKERS) {\n if (current.hasAttribute(marker)) return true;\n }\n }\n const root = current.getRootNode();\n if (root instanceof ShadowRoot && root !== current) {\n current = root.host;\n continue;\n }\n current = current.parentNode;\n }\n return false;\n}\n\n/**\n * Remove the SDK's own host elements from a (cloned) subtree, so a captured\n * screenshot never contains the launcher, overlay, or picker highlight.\n */\nexport function stripFixbackNodes(root: ParentNode): void {\n for (const el of Array.from(root.querySelectorAll(HOST_SELECTOR))) {\n el.remove();\n }\n}\n","import { isFixbackNode } from \"./dom\";\nimport type { ElementRect, SelectedElement } from \"./report\";\n\n/**\n * Escape a string for use in a CSS selector, preferring the platform's\n * `CSS.escape` and falling back to a conservative backslash escape where it is\n * unavailable (older engines, some test environments).\n */\nfunction cssEscape(value: string): string {\n const api = (globalThis as { CSS?: { escape?: (v: string) => string } }).CSS;\n if (api?.escape) return api.escape(value);\n return value.replace(/[^\\w-]/g, (ch) => `\\\\${ch}`);\n}\n\n/** The 1-based position of `el` among its same-tag siblings (`:nth-of-type`). */\nfunction nthOfType(el: Element): number {\n let n = 1;\n let sib = el.previousElementSibling;\n while (sib) {\n if (sib.tagName === el.tagName) n += 1;\n sib = sib.previousElementSibling;\n }\n return n;\n}\n\n/**\n * A stable CSS selector for `el`: its own id when it has one, otherwise a path of\n * tag (with `:nth-of-type` to disambiguate same-tag siblings) climbing until it\n * reaches an ancestor with an id — the shortest anchor that still resolves.\n */\nexport function cssSelectorFor(el: Element): string {\n if (el.id) return `#${cssEscape(el.id)}`;\n\n const parts: string[] = [];\n let node: Element | null = el;\n while (node && node.tagName.toLowerCase() !== \"html\") {\n if (node.id) {\n parts.unshift(`#${cssEscape(node.id)}`);\n break;\n }\n const tag = node.tagName.toLowerCase();\n const parent: Element | null = node.parentElement;\n if (parent) {\n const sameTag = Array.from(parent.children).filter(\n (c) => c.tagName === node!.tagName,\n );\n parts.unshift(\n sameTag.length > 1 ? `${tag}:nth-of-type(${nthOfType(node)})` : tag,\n );\n } else {\n parts.unshift(tag);\n }\n node = parent;\n }\n return parts.join(\" > \");\n}\n\n/** One node's readable label: `tag`, `tag#id`, or `tag.firstClass`. */\nfunction describeNode(el: Element): string {\n const tag = el.tagName.toLowerCase();\n if (el.id) return `${tag}#${el.id}`;\n const firstClass = el.classList[0];\n return firstClass ? `${tag}.${firstClass}` : tag;\n}\n\n/** A readable ancestry path from the document root down to `el`. */\nexport function domPathFor(el: Element): string {\n const chain: string[] = [];\n let node: Element | null = el;\n while (node) {\n chain.unshift(describeNode(node));\n node = node.parentElement;\n }\n return chain.join(\" > \");\n}\n\nfunction roundedRect(el: Element): ElementRect {\n const r = el.getBoundingClientRect();\n return {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n };\n}\n\n/**\n * Describe a picked element as the Annotation ingest stores: a stable selector, a\n * readable DOM path, the tag, and the viewport bounding rect (spec MVP §B).\n */\nexport function describeElement(el: Element): SelectedElement {\n return {\n selector: cssSelectorFor(el),\n domPath: domPathFor(el),\n tag: el.tagName.toLowerCase(),\n rect: roundedRect(el),\n };\n}\n\n/** Options for {@link startElementPicker}. */\nexport interface ElementPickerOptions {\n /** Document to attach to. Defaults to the global `document`. */\n readonly doc?: Document;\n /** Called with the element being hovered (or `null` over nothing pickable). */\n readonly onHover?: (element: Element | null) => void;\n /** Called with the element the Reporter clicked to pin. */\n readonly onPick: (element: Element) => void;\n /** Called when the Reporter presses Escape to abandon the pick. */\n readonly onCancel?: () => void;\n /** Return true to skip a node (defaults to skipping the SDK's own UI). */\n readonly ignore?: (element: Element) => boolean;\n}\n\n/** A running element-picker; call {@link ElementPicker.stop} to detach it. */\nexport interface ElementPicker {\n stop(): void;\n}\n\n/**\n * Enter element-select mode: as the Reporter moves over the host page the element\n * under the pointer is reported through `onHover` (the overlay draws a highlight),\n * a click pins it through `onPick`, and Escape abandons through `onCancel`. The\n * click that pins is swallowed (prevent-default + stop-propagation) so it never\n * also activates the host page. The SDK's own UI is skipped by default, so the\n * Reporter can never pick the overlay itself.\n *\n * Listeners are attached in the capture phase so the pick is intercepted before\n * any host-page handler sees it; `stop()` (called automatically on pick/cancel)\n * detaches them all.\n */\nexport function startElementPicker(options: ElementPickerOptions): ElementPicker {\n const doc = options.doc ?? document;\n const ignore = options.ignore ?? isFixbackNode;\n let current: Element | null = null;\n let stopped = false;\n\n function resolveTarget(event: Event): Element | null {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n const deepest = path[0] ?? event.target;\n if (deepest instanceof Element) return ignore(deepest) ? null : deepest;\n return null;\n }\n\n function onOver(event: Event): void {\n if (stopped) return;\n current = resolveTarget(event);\n options.onHover?.(current);\n }\n\n function onClick(event: MouseEvent): void {\n if (stopped) return;\n const el = resolveTarget(event) ?? current;\n if (!el) return; // nothing pickable under the pointer — let the click pass\n event.preventDefault();\n event.stopPropagation();\n stop();\n options.onPick(el);\n }\n\n function onKey(event: KeyboardEvent): void {\n if (stopped) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n stop();\n options.onCancel?.();\n }\n }\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n doc.removeEventListener(\"mouseover\", onOver, true);\n doc.removeEventListener(\"click\", onClick, true);\n doc.removeEventListener(\"keydown\", onKey, true);\n current = null;\n }\n\n doc.addEventListener(\"mouseover\", onOver, true);\n doc.addEventListener(\"click\", onClick, true);\n doc.addEventListener(\"keydown\", onKey, true);\n\n return { stop };\n}\n","/**\n * The single client-side **scrub choke point** every report passes through\n * before transport (spec 0003 §C; research `sentry-error-capture-findings.md`\n * §7.4) — the SDK's `beforeSend` equivalent.\n *\n * Masking is the SDK's job, done in the browser before anything leaves the page.\n * The screenshot is masked at capture, and breadcrumbs never record a value or a\n * body at the source; `runBeforeSend` is the **last** gate over the assembled\n * report. Its default scrubbers are **on**: they strip credentials, query\n * strings, and bearer tokens from URLs, and redact obvious PII (emails, long\n * digit runs, bearer tokens) from crumb and error text. The result is then handed\n * to an optional per-project hook that can mutate it further or drop the whole\n * report by returning `null`.\n *\n * The hook is **synchronous and network-free** by contract, and both manual\n * (overlay) and automatic (error-capture) reports run through the very same\n * choke point. A project relaxes the defaults with `scrub: false`, or reshapes\n * the draft in its own hook — never a silent raw send.\n */\n\nimport type { Breadcrumb, BreadcrumbData, ConsoleArg } from \"./breadcrumbs\";\nimport type { ReportContent } from \"./report\";\n\n/** The per-project client scrub hook. Return `null` to drop the whole report. */\nexport type BeforeSend = (draft: ReportContent) => ReportContent | null;\n\n/** Options for {@link runBeforeSend}. */\nexport interface BeforeSendOptions {\n /** The per-project hook, run **after** the default scrubbers. */\n readonly hook?: BeforeSend | null;\n /** Run the built-in default scrubbers first. Defaults to `true`. */\n readonly scrub?: boolean;\n}\n\n/** A digit run at least this long is treated as sensitive (phone, card, id). */\nconst MIN_DIGIT_RUN = 7;\nconst EMAIL_RE = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi;\nconst DIGIT_RUN_RE = new RegExp(`\\\\d{${MIN_DIGIT_RUN},}`, \"g\");\nconst BEARER_RE = /\\b(bearer|token)\\s+[\\w.\\-~+/]+=*/gi;\n/** An http(s) URL embedded in free text (e.g. a console log line). */\nconst URL_IN_TEXT_RE = /\\bhttps?:\\/\\/[^\\s\"'<>]+/gi;\n\n/**\n * Redact obvious PII from free text: email addresses, `Bearer <token>` /\n * `token <value>` pairs, and long digit runs. Conservative by design — it keeps\n * the shape of the message readable while removing the sensitive spans.\n */\nexport function redactPii(text: string): string {\n if (typeof text !== \"string\" || text.length === 0) return text;\n return text\n .replace(EMAIL_RE, \"[redacted-email]\")\n .replace(BEARER_RE, (_match, keyword: string) => `${keyword} [redacted]`)\n .replace(DIGIT_RUN_RE, \"[redacted-number]\");\n}\n\n/**\n * Redact PII from the **path** portion of a URL (spec #122 §E, ticket #139):\n * emails and long digit runs in path (or fragment-route) segments — a network\n * list shows URLs prominently, so an identifier baked into a path\n * (`/users/jane@acme.app`, `/card/4111111111111111`) must not leak. Deliberately\n * narrower than {@link redactPii}: no bearer/token rule (URL credentials are\n * already stripped by {@link scrubUrl}) and it is only ever applied to the\n * post-authority remainder, so a host or port with digits is never touched.\n */\nfunction redactPathPii(pathAndBeyond: string): string {\n return pathAndBeyond\n .replace(EMAIL_RE, \"[redacted-email]\")\n .replace(DIGIT_RUN_RE, \"[redacted-number]\");\n}\n\n/**\n * Strip the sensitive parts of a URL: userinfo credentials\n * (`scheme://user:pass@host`), the entire query string, a token-bearing\n * fragment (one that carries `key=value`), and PII (emails, long digit runs) in\n * the **path segments** (#139). Plain hash routes (`#/checkout`) are kept. Works\n * on absolute and relative URLs alike, with no dependency and no throw. The host\n * (authority) is never redacted — only the path and any surviving fragment route.\n */\nexport function scrubUrl(url: string): string {\n if (typeof url !== \"string\" || url.length === 0) return url;\n let out = url;\n // Drop userinfo credentials: scheme://user:pass@host → scheme://host\n out = out.replace(/(^[a-z][a-z0-9+.-]*:\\/\\/)[^/@?#]*@/i, \"$1\");\n // Drop the query string entirely (everything from '?' up to a '#').\n out = out.replace(/\\?[^#]*/, \"\");\n // Drop a token-bearing fragment (it carries '='); keep plain hash routes.\n out = out.replace(/#.*$/, (fragment) =>\n fragment.includes(\"=\") ? \"\" : fragment,\n );\n // Redact PII in the path (and any kept fragment route), never in the authority.\n // Split off `scheme://authority` (or a protocol-relative `//authority`) so a\n // host/port that contains digits is preserved; the remainder is the path onward.\n const absolute = out.match(/^([a-z][a-z0-9+.-]*:\\/\\/[^/?#]*)([\\s\\S]*)$/i);\n if (absolute) return absolute[1] + redactPathPii(absolute[2] ?? \"\");\n const protocolRelative = out.match(/^(\\/\\/[^/?#]*)([\\s\\S]*)$/);\n if (protocolRelative) {\n return protocolRelative[1] + redactPathPii(protocolRelative[2] ?? \"\");\n }\n // A relative URL is all path — redact the whole thing.\n return redactPathPii(out);\n}\n\ntype MutableBreadcrumbData = { -readonly [K in keyof BreadcrumbData]: BreadcrumbData[K] };\ntype MutableBreadcrumb = { -readonly [K in keyof Breadcrumb]: Breadcrumb[K] };\ntype MutableContent = { -readonly [K in keyof ReportContent]: ReportContent[K] };\n\nfunction scrubCrumbData(data: BreadcrumbData): BreadcrumbData {\n const next: MutableBreadcrumbData = { ...data };\n if (typeof next.url === \"string\") next.url = scrubUrl(next.url);\n if (typeof next.from === \"string\") next.from = scrubUrl(next.from);\n if (typeof next.to === \"string\") next.to = scrubUrl(next.to);\n return next;\n}\n\n/** Scrub a crumb's free-text message: strip URL query strings, then redact PII. */\nfunction scrubMessage(message: string): string {\n return redactPii(message.replace(URL_IN_TEXT_RE, (url) => scrubUrl(url)));\n}\n\n/**\n * Scrub the string leaves of a structured console-arg value (spec #122 §C/§E) — the\n * value a `json` arg carries. Walks arrays and plain objects, applying the same\n * URL-strip + PII redaction as a crumb message to every nested string, so a value\n * logged through `console.*` is swept just like the flattened preview.\n */\nfunction scrubArgValue(value: unknown): unknown {\n if (typeof value === \"string\") return scrubMessage(value);\n if (Array.isArray(value)) return value.map(scrubArgValue);\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n out[key] = scrubArgValue(v);\n }\n return out;\n }\n return value;\n}\n\n/**\n * Scrub one structured console argument (spec #122 §C): redact PII / strip URL query\n * strings from a `string` value, from every string leaf of a `json` value, and from an\n * `error` value's `message` and `stack`. Other tags (`number`/`bool`/`null`) carry no\n * free text and pass through unchanged.\n */\nfunction scrubConsoleArg(arg: ConsoleArg): ConsoleArg {\n switch (arg.t) {\n case \"string\":\n return typeof arg.v === \"string\" ? { t: \"string\", v: scrubMessage(arg.v) } : arg;\n case \"json\":\n return { t: \"json\", v: scrubArgValue(arg.v) };\n case \"error\": {\n if (!arg.v || typeof arg.v !== \"object\") return arg;\n const v = arg.v as { message?: unknown; stack?: unknown };\n const next: Record<string, unknown> = { ...v };\n if (typeof next.message === \"string\") next.message = scrubMessage(next.message);\n if (typeof next.stack === \"string\") next.stack = scrubMessage(next.stack);\n return { t: \"error\", v: next };\n }\n default:\n return arg;\n }\n}\n\nfunction scrubCrumb(crumb: Breadcrumb): Breadcrumb {\n const next: MutableBreadcrumb = { ...crumb };\n if (typeof next.message === \"string\") next.message = scrubMessage(next.message);\n if (next.data) next.data = scrubCrumbData(next.data);\n // A rich network crumb (#139) carries its scrubbed URL at the top level — sweep it\n // again here (idempotent) so the choke point holds whether the URL rode in `data`\n // (a legacy thin crumb) or top-level, and path-PII redaction is never skipped.\n if (typeof next.url === \"string\") next.url = scrubUrl(next.url);\n // A console crumb's structured args carry the same free text as its preview — sweep\n // them too, so PII redaction holds whether a value is read from `message` or `args`.\n if (Array.isArray(next.args)) next.args = next.args.map(scrubConsoleArg);\n return next;\n}\n\n/**\n * Apply the built-in default scrubbers to a report draft: strip the page URL,\n * and scrub every crumb's URLs and redact PII from its text. The Reporter's own\n * `comment` is intentionally left untouched — it is authored on purpose, not\n * scraped. The screenshot and input values are masked elsewhere (at capture and\n * at crumb creation); this is the final URL/PII sweep.\n */\nexport function applyDefaultScrub(draft: ReportContent): ReportContent {\n const next: MutableContent = { ...draft };\n if (typeof next.url === \"string\") next.url = scrubUrl(next.url);\n if (next.trace && next.trace.length > 0) {\n next.trace = next.trace.map(scrubCrumb);\n }\n // The structured stack frames (#117) carry script URLs — sweep them again here\n // (idempotent, like the crumb URLs) so the choke point holds regardless of\n // where the frames were parsed.\n if (next.errorFrames && next.errorFrames.length > 0) {\n next.errorFrames = next.errorFrames.map((frame) => ({\n ...frame,\n file: scrubUrl(frame.file),\n }));\n }\n return next;\n}\n\n/**\n * Run the report draft through the client scrub choke point: the default\n * scrubbers first (unless `scrub` is `false`), then the optional per-project\n * hook. Returns the scrubbed (and possibly hook-mutated) draft, or `null` when\n * the hook drops the report. A hook that throws is treated as a no-op — the\n * already-scrubbed draft is kept, so a buggy hook never breaks the report path\n * nor leaks unscrubbed data.\n */\nexport function runBeforeSend(\n draft: ReportContent,\n options: BeforeSendOptions = {},\n): ReportContent | null {\n const current =\n options.scrub === false ? draft : applyDefaultScrub(draft);\n const hook = options.hook;\n if (!hook) return current;\n try {\n const result = hook(current);\n return result ?? null;\n } catch {\n return current;\n }\n}\n","/**\n * The thin trace **breadcrumb ring buffer** and its capture instrumentation\n * (spec 0003 §C; research `sentry-error-capture-findings.md` §7.5).\n *\n * A fixed-size FIFO buffer of the most recent activity — console, navigation,\n * network metadata, masked user actions, and the failing error — that rides on a\n * report as Evidence. It is trimmed exactly like Sentry (`crumbs.slice(-N)`),\n * defaults to a deliberately thin `N ≈ 30` because it ships on **every** payload,\n * and takes an optional age cap. A `beforeBreadcrumb(crumb) => crumb | null`\n * filter lets a Project mute or edit crumbs before they enter the buffer.\n *\n * Everything private is kept out **at the source**: `ui.input` records that an\n * input changed, never its value; `fetch`/`xhr` crumbs carry method + URL +\n * status only, **never** bodies; URLs are scrubbed as the crumb is built. The\n * `beforeSend` choke point (`scrub.ts`) is the final gate over the whole report.\n *\n * The SDK stays dependency-free and must never throw into the host page, so every\n * instrumentation hook is wrapped: a capture failure is swallowed and the original\n * behaviour (the real `console`, `fetch`, navigation) always runs.\n */\n\nimport { isFixbackNode } from \"./dom\";\nimport { cssSelectorFor } from \"./element-picker\";\nimport { scrubUrl } from \"./scrub\";\n\n/** Console-style severity a `console` crumb records. */\nexport type BreadcrumbLevel =\n | \"log\"\n | \"info\"\n | \"warn\"\n | \"error\"\n | \"assert\"\n | \"debug\";\n\n/** The kind of activity a crumb records. */\nexport type BreadcrumbCategory =\n | \"console\"\n | \"navigation\"\n | \"fetch\"\n | \"xhr\"\n | \"beacon\"\n | \"ui.click\"\n | \"ui.input\"\n | \"error\";\n\n/**\n * Which browser API issued a captured network request (spec #122 §D, ticket #139).\n * Every network crumb's `category` is one of these too, so a stream router and the\n * read model agree on what is a network entry.\n */\nexport type NetworkApi = \"fetch\" | \"xhr\" | \"beacon\";\n\n/**\n * A network request's failure classification (spec #122 §D, ticket #139). `ok` and\n * the HTTP status classes come from a settled response; `network-error` / `timeout`\n * / `aborted` from how a request failed; `opaque-cors` from a cross-origin response\n * whose status is unreadable. The Network tab flags every non-`ok` outcome.\n */\nexport type NetworkOutcome =\n | \"ok\"\n | \"http-4xx\"\n | \"http-5xx\"\n | \"network-error\"\n | \"timeout\"\n | \"aborted\"\n | \"opaque-cors\";\n\n/**\n * A crumb's structured detail. Deliberately narrow: there is **no** field for a\n * request/response body or an input value, so those can never be recorded.\n */\nexport interface BreadcrumbData {\n readonly url?: string;\n readonly method?: string;\n readonly status?: number;\n /** A masked CSS selector for a `ui.*` target — never its text or value. */\n readonly target?: string;\n readonly from?: string;\n readonly to?: string;\n readonly errorType?: string;\n}\n\n/**\n * The type tag on a structured console argument (spec #122 §C, decision D7). A\n * console call's arguments are preserved **type-tagged** rather than flattened to a\n * string, so an object/array argument can be inspected in the Console tab rather\n * than read as `[object Object]`: `string`/`number`/`bool`/`null` carry the value\n * directly, `json` a depth-/byte-capped JSON-safe clone, and `error` an Error's\n * `{ name, message, stack }`.\n */\nexport type ConsoleArgType =\n | \"string\"\n | \"number\"\n | \"bool\"\n | \"null\"\n | \"json\"\n | \"error\";\n\n/**\n * One structured console argument (spec #122 §C): a type tag plus a JSON-safe value.\n * `v` is always serializable — a `json` arg is depth-, breadth-, and string-capped at\n * assembly, and exotic values (bigint, symbol, function, circular refs) are rendered\n * to safe text — so a console crumb can never carry an unserializable or unbounded\n * value onto the wire.\n */\nexport interface ConsoleArg {\n readonly t: ConsoleArgType;\n readonly v: unknown;\n}\n\n/** A `file:line` source location (spec #122 §C) — where a console call was made. */\nexport interface SourceLocation {\n readonly file: string;\n readonly line: number;\n}\n\n/**\n * One entry in a trace stream. Alongside its semantic fields every entry carries a\n * stable {@link id} and a high-res monotonic {@link mono} timestamp — both stamped\n * by the buffer on `add` — so entries from the three independent streams order and\n * cross-link exactly (spec #122 §B, decision D9). `timestamp` stays epoch ms.\n */\nexport interface Breadcrumb {\n readonly category: BreadcrumbCategory;\n readonly message?: string;\n readonly level?: BreadcrumbLevel;\n /** Epoch milliseconds when the crumb was recorded. */\n readonly timestamp: number;\n /** A stable id, unique within the buffer — assigned on `add` when not already set. */\n readonly id?: string;\n /** A high-res monotonic timestamp (`performance.now()`) — assigned on `add`. */\n readonly mono?: number;\n readonly data?: BreadcrumbData;\n /**\n * For a `console` crumb (spec #122 §C): the call's arguments preserved as\n * structured, type-tagged values (see {@link ConsoleArg}), so the Console tab can\n * render each argument expandably instead of a flattened string. `message` stays\n * the one-line preview. Absent on non-console crumbs.\n */\n readonly args?: readonly ConsoleArg[];\n /**\n * For a `console` crumb (spec #122 §C): the `file:line` the call was made from,\n * parsed best-effort from the call stack. Captured only for the levels that keep a\n * source — `warn`/`error`/`assert` (ticket #159; see {@link SOURCE_CAPTURE_LEVELS}) —\n * and only when the stack yields a usable location; a chatty app's `log`/`info`/`debug`\n * omit it so the hot-page capture cost stays low. Absent on non-console crumbs.\n */\n readonly source?: SourceLocation;\n /**\n * For an auto-captured `error` crumb only (spec #122 §F): the ids of the entries\n * immediately preceding the throw — a causal pointer into the same trace, so a\n * machine-filed crash names its lead-up. Absent on every other crumb.\n */\n readonly causedBy?: readonly string[];\n /**\n * For a network crumb (`fetch` / `xhr` / `beacon`) — spec #122 §D, ticket #139.\n * The rich request metadata the Network tab renders, lifted to the top level (the\n * console-enrichment precedent) so the read model shapes each into a\n * `NetworkTraceEntry`. **No field carries a request/response body or an arbitrary\n * header** — `respSize` derives from the `content-length` response header only and\n * `contentType` from `content-type`; nothing else is read. Absent on every other crumb.\n */\n readonly api?: NetworkApi;\n /** The request method (network crumb) — e.g. `GET`, `POST`. */\n readonly method?: string;\n /** The scrubbed request URL (network crumb) — query dropped, path PII redacted. */\n readonly url?: string;\n /** The final HTTP status (network crumb), when one was known; absent on a network error/beacon. */\n readonly status?: number;\n /** The HTTP status text (network crumb), when the response carried one. */\n readonly statusText?: string;\n /** Wall-clock duration of the request in ms (network crumb) — a `performance.now()` delta. */\n readonly durationMs?: number;\n /** Request body size in bytes (network crumb) — only when trivially known (string/Blob/ArrayBuffer), never by reading a stream. */\n readonly reqSize?: number;\n /** Response body size in bytes (network crumb) — from the `content-length` response header only. */\n readonly respSize?: number;\n /** Response content type (network crumb) — the `content-type` header's media type. */\n readonly contentType?: string;\n /** The request's failure classification (network crumb) — see {@link NetworkOutcome}. */\n readonly outcome?: NetworkOutcome;\n}\n\n/**\n * The three independent trace streams (spec #122 §A, decision D6). Each is its own\n * FIFO ring with its own size budget, so a chatty stream can't evict another's\n * lead-up. Every {@link BreadcrumbCategory} maps to exactly one stream via\n * {@link streamOf}.\n */\nexport type TraceStream = \"network\" | \"console\" | \"breadcrumbs\";\n\n/**\n * Per-stream ring budgets — starting points from the grill (D6): network is the\n * chattiest, breadcrumbs the sparsest. Per-project tunable, never frozen.\n */\nexport const DEFAULT_STREAM_BUDGETS: Readonly<Record<TraceStream, number>> = {\n network: 100,\n console: 80,\n breadcrumbs: 40,\n};\n\n/**\n * The shared age cap (spec #122 §A): entries older than this are pruned from every\n * stream, whichever trims first. ~3 minutes and — unlike the thin buffer's\n * off-by-default cap — **on** by default, so an idle tab never ships stale context.\n */\nexport const DEFAULT_MAX_AGE_MS = 3 * 60 * 1000;\n\n/**\n * Console levels captured by default (spec #122 §C, decision D7): **all** of them, so\n * the Console tab is a real console and not just an error log. Eviction priority (not\n * capture) is what keeps a chatty app's `log`/`info`/`debug` from burying the signal —\n * see {@link PINNED_CONSOLE_LEVELS}.\n */\nexport const DEFAULT_CONSOLE_LEVELS: readonly BreadcrumbLevel[] = [\n \"log\",\n \"info\",\n \"warn\",\n \"error\",\n \"assert\",\n \"debug\",\n];\n\n/**\n * The console levels **pinned** against eviction (spec #122 §C, decision D7). When the\n * console stream overflows its budget, `warn`/`error`/`assert` are retained ahead of\n * `log`/`info`/`debug`, so an error is never evicted by a burst of chatter — the\n * low-priority levels fill the remainder and are dropped first.\n */\nexport const PINNED_CONSOLE_LEVELS: readonly BreadcrumbLevel[] = [\n \"warn\",\n \"error\",\n \"assert\",\n];\n\n/** Whether a console level is pinned against eviction (see {@link PINNED_CONSOLE_LEVELS}). */\nfunction isPinnedConsoleLevel(level: BreadcrumbLevel | undefined): boolean {\n return level !== undefined && PINNED_CONSOLE_LEVELS.includes(level);\n}\n\n/**\n * The console levels for which `source` (`file:line`) is captured (ticket #159).\n *\n * Capturing a call site constructs a `new Error()` to read its stack on **every** console\n * call — a measurable hot-page cost when a chatty app logs in a tight loop (spec #122's\n * \"hot-page performance budget\" open question, handed onward from the grill). The\n * spec-sanctioned mitigation (decision D7) narrows source capture to the **levels that\n * matter for debugging** — the same `warn`/`error`/`assert` that are pinned against\n * eviction — so `log`/`info`/`debug` pay no per-call stack cost and simply omit `source`.\n * Full-fidelity `source` is preserved exactly where it earns its keep: on warnings,\n * errors, and failed assertions. Per-project tunability of this set is future work; today\n * it deliberately mirrors {@link PINNED_CONSOLE_LEVELS} so \"what survives eviction\" and\n * \"what carries a call site\" stay one idea.\n */\nexport const SOURCE_CAPTURE_LEVELS: readonly BreadcrumbLevel[] =\n PINNED_CONSOLE_LEVELS;\n\n/** Whether a console level captures `source` `file:line` (see {@link SOURCE_CAPTURE_LEVELS}). */\nfunction capturesSource(level: BreadcrumbLevel): boolean {\n return SOURCE_CAPTURE_LEVELS.includes(level);\n}\n\n/**\n * Which stream a crumb's category belongs to (spec #122 §A). Network APIs\n * (`fetch` / `xhr` / `beacon`) form the network stream, `console` its own, and\n * everything else (navigation, masked UI events, the failing error) breadcrumbs.\n */\nexport function streamOf(category: string): TraceStream {\n if (category === \"console\") return \"console\";\n if (category === \"fetch\" || category === \"xhr\" || category === \"beacon\") {\n return \"network\";\n }\n return \"breadcrumbs\";\n}\n\n/** Filters or edits each crumb before it enters the buffer; `null` drops it. */\nexport type BeforeBreadcrumb = (crumb: Breadcrumb) => Breadcrumb | null;\n\n/** Configuration for {@link createBreadcrumbBuffer}. All values are optional. */\nexport interface BreadcrumbBufferConfig {\n /**\n * Per-stream size budgets (oldest drop, independently per stream). Any stream\n * omitted falls back to {@link DEFAULT_STREAM_BUDGETS}.\n */\n readonly budgets?: Partial<Record<TraceStream, number>>;\n /**\n * Shared age cap in ms: entries older than this are dropped from every stream.\n * Defaults to {@link DEFAULT_MAX_AGE_MS} (on); pass `0` (or a non-positive value)\n * to disable age pruning.\n */\n readonly maxAgeMs?: number;\n /** A per-crumb filter (mute a category, edit, or drop by returning `null`). */\n readonly beforeBreadcrumb?: BeforeBreadcrumb | null;\n /** Epoch clock source, injectable for tests. Defaults to `Date.now`. */\n readonly now?: () => number;\n /** High-res monotonic clock, injectable for tests. Defaults to `performance.now`. */\n readonly mono?: () => number;\n /** Stable id generator, injectable for tests. Defaults to a per-buffer sequence. */\n readonly nextId?: () => string;\n}\n\n/** A live trace buffer. */\nexport interface BreadcrumbBuffer {\n /** Record a crumb (subject to `beforeBreadcrumb`, id/mono stamping, size, and age trimming). */\n add(crumb: Breadcrumb): void;\n /** The current crumbs, merged across streams and ordered in time — a fresh array. */\n snapshot(): Breadcrumb[];\n /** Drop every crumb. */\n clear(): void;\n}\n\nfunction normalizeBudget(value: number | undefined, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 1) {\n return fallback;\n }\n return Math.floor(value);\n}\n\n/** The default high-res clock: `performance.now()` where available, else `Date.now`. */\nfunction defaultMono(): number {\n return typeof performance !== \"undefined\" &&\n typeof performance.now === \"function\"\n ? performance.now()\n : Date.now();\n}\n\n/** A per-buffer id factory: a short random salt + a base-36 sequence, stable once assigned. */\nfunction createIdFactory(): () => string {\n const salt = Math.random().toString(36).slice(2, 8);\n let seq = 0;\n return () => `${salt}${(seq++).toString(36)}`;\n}\n\n/** The streams, in a fixed order for a deterministic merge. */\nconst STREAMS: readonly TraceStream[] = [\"network\", \"console\", \"breadcrumbs\"];\n\n/** One held entry, tagged with its insertion order for a stable cross-stream sort. */\ninterface HeldCrumb {\n readonly crumb: Breadcrumb;\n readonly seq: number;\n}\n\n/**\n * Trim the **console** stream to its budget with eviction priority (spec #122 §C,\n * decision D7): `warn`/`error`/`assert` are pinned, so the oldest `log`/`info`/`debug`\n * entries are dropped first; a pinned entry is evicted only when dropping every\n * low-priority one still leaves the stream over budget (oldest pinned first). Survivors\n * keep their insertion order. A plain FIFO `slice(-budget)` handles every other stream.\n */\nfunction trimConsoleStream(held: HeldCrumb[], budget: number): HeldCrumb[] {\n const over = held.length - budget;\n if (over <= 0) return held;\n const drop = new Set<number>();\n // First: oldest low-priority (not pinned) entries, until enough room is freed.\n for (let i = 0; i < held.length && drop.size < over; i += 1) {\n if (!isPinnedConsoleLevel(held[i]!.crumb.level)) drop.add(i);\n }\n // Then, only if the low-priority ones weren't enough: oldest pinned entries.\n for (let i = 0; i < held.length && drop.size < over; i += 1) {\n if (!drop.has(i)) drop.add(i);\n }\n return held.filter((_, i) => !drop.has(i));\n}\n\n/**\n * Create the per-stream trace buffer (spec #122 §A/§B). It holds **three\n * independent FIFO rings** — `network`, `console`, `breadcrumbs` — each trimmed to\n * its own budget so a chatty stream never evicts another's lead-up, plus a shared\n * age cap. On `add`, a crumb passes through `beforeBreadcrumb`, is stamped with a\n * stable `id` and a high-res `mono` timestamp (and an epoch `timestamp` if it has\n * none), routed to its stream, then that stream is pruned by age and trimmed to its\n * budget. `snapshot` prunes by age again, then merges the three streams into one\n * `mono`-ordered array for transport — so the wire keeps its single `trace` field.\n */\nexport function createBreadcrumbBuffer(\n config: BreadcrumbBufferConfig = {},\n): BreadcrumbBuffer {\n const budgets: Record<TraceStream, number> = {\n network: normalizeBudget(config.budgets?.network, DEFAULT_STREAM_BUDGETS.network),\n console: normalizeBudget(config.budgets?.console, DEFAULT_STREAM_BUDGETS.console),\n breadcrumbs: normalizeBudget(\n config.budgets?.breadcrumbs,\n DEFAULT_STREAM_BUDGETS.breadcrumbs,\n ),\n };\n const maxAgeMs =\n config.maxAgeMs === undefined ? DEFAULT_MAX_AGE_MS : config.maxAgeMs;\n const beforeBreadcrumb = config.beforeBreadcrumb;\n const now = config.now ?? Date.now;\n const mono = config.mono ?? defaultMono;\n const nextId = config.nextId ?? createIdFactory();\n\n const streams: Record<TraceStream, HeldCrumb[]> = {\n network: [],\n console: [],\n breadcrumbs: [],\n };\n let seq = 0;\n\n function pruneByAge(): void {\n if (typeof maxAgeMs !== \"number\" || maxAgeMs <= 0) return;\n const cutoff = now() - maxAgeMs;\n for (const stream of STREAMS) {\n const held = streams[stream];\n if (held.length > 0) {\n streams[stream] = held.filter((h) => h.crumb.timestamp >= cutoff);\n }\n }\n }\n\n return {\n add(crumb: Breadcrumb): void {\n let entry: Breadcrumb | null = crumb;\n if (beforeBreadcrumb) {\n try {\n entry = beforeBreadcrumb(crumb);\n } catch {\n // A throwing filter must never break capture; keep the (already\n // masked) crumb rather than silently erasing the trace.\n entry = crumb;\n }\n }\n if (!entry) return;\n // Stamp a stable id + high-res mono (and an epoch timestamp if absent) so\n // every entry orders and cross-links exactly, whatever stream it lands in.\n const stamped: Breadcrumb = {\n ...entry,\n id: entry.id ?? nextId(),\n timestamp: typeof entry.timestamp === \"number\" ? entry.timestamp : now(),\n mono: typeof entry.mono === \"number\" ? entry.mono : mono(),\n };\n const stream = streamOf(stamped.category);\n streams[stream].push({ crumb: stamped, seq: seq++ });\n // Age-prune every stream first (it may reassign the array), then trim this\n // stream to its own budget — a flood here never evicts another stream.\n pruneByAge();\n const held = streams[stream];\n const budget = budgets[stream];\n if (held.length > budget) {\n streams[stream] =\n stream === \"console\"\n ? trimConsoleStream(held, budget)\n : held.slice(-budget);\n }\n },\n snapshot(): Breadcrumb[] {\n pruneByAge();\n const merged: HeldCrumb[] = [];\n for (const stream of STREAMS) merged.push(...streams[stream]);\n // Order in time by the high-res mono clock (every entry has one), with the\n // insertion sequence as a stable tiebreak so equal clocks never scramble.\n merged.sort((a, b) => {\n const am =\n typeof a.crumb.mono === \"number\" ? a.crumb.mono : a.crumb.timestamp;\n const bm =\n typeof b.crumb.mono === \"number\" ? b.crumb.mono : b.crumb.timestamp;\n return am - bm || a.seq - b.seq;\n });\n return merged.map((h) => h.crumb);\n },\n clear(): void {\n streams.network = [];\n streams.console = [];\n streams.breadcrumbs = [];\n seq = 0;\n },\n };\n}\n\n// --- Pure crumb builders -----------------------------------------------------\n\n/** Longest crumb message kept; a huge log line is truncated, never dropped. */\nconst MAX_MESSAGE_LENGTH = 300;\n\n/**\n * Longest scrubbed URL kept on a crumb (spec #122 §F): capped at assembly so an\n * over-long URL is truncated, never dropped and never allowed to bloat a report.\n */\nexport const MAX_URL_LENGTH = 2048;\n\n/**\n * Structured console argument caps (spec #122 §C/§F), all applied **at assembly** so a\n * single console crumb can never bloat a report:\n * - {@link MAX_ARG_DEPTH} bounds how deep a `json` argument is cloned (deeper nodes\n * collapse to an `[Object]`/`[Array]` marker);\n * - {@link MAX_ARG_ITEMS} bounds how many keys/elements are kept at each level;\n * - {@link MAX_ARG_STRING_LENGTH} truncates a single over-long string value;\n * - {@link MAX_CONSOLE_ARGS_BYTES} bounds the serialized size of the whole args array\n * (trailing args are dropped to fit), kept well under ingest's per-entry byte cap.\n */\nexport const MAX_ARG_DEPTH = 4;\nexport const MAX_ARG_ITEMS = 100;\nexport const MAX_ARG_STRING_LENGTH = 1024;\nexport const MAX_CONSOLE_ARGS_BYTES = 4096;\n\n/** Longest Error `stack` kept on a structured `error` arg, truncated never dropped. */\nconst MAX_ERROR_STACK_LENGTH = 2048;\n\n/** Truncate a string to `max` with an ellipsis marker; keeps the value, never drops it. */\nfunction capLength(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}…` : value;\n}\n\nfunction stringifyArg(arg: unknown): string {\n if (typeof arg === \"string\") return arg;\n if (arg instanceof Error) return `${arg.name}: ${arg.message}`;\n if (arg === null || arg === undefined) return String(arg);\n if (typeof arg === \"number\" || typeof arg === \"boolean\") return String(arg);\n try {\n return JSON.stringify(arg) ?? String(arg);\n } catch {\n return \"[object]\";\n }\n}\n\nfunction joinArgs(args: readonly unknown[]): string {\n const text = args.map(stringifyArg).join(\" \");\n return text.length > MAX_MESSAGE_LENGTH\n ? `${text.slice(0, MAX_MESSAGE_LENGTH)}…`\n : text;\n}\n\n/** An Error rendered to a structured, size-capped `{ name, message, stack? }`. */\nfunction describeErrorValue(error: Error): {\n name: string;\n message: string;\n stack?: string;\n} {\n const out: { name: string; message: string; stack?: string } = {\n name: error.name || \"Error\",\n message: capLength(String(error.message ?? \"\"), MAX_ARG_STRING_LENGTH),\n };\n if (typeof error.stack === \"string\" && error.stack.length > 0) {\n out.stack = capLength(error.stack, MAX_ERROR_STACK_LENGTH);\n }\n return out;\n}\n\n/**\n * Build a JSON-safe, depth-/breadth-/string-capped clone of a value for a `json`\n * console argument. Beyond {@link MAX_ARG_DEPTH} the node collapses to a marker;\n * at each level at most {@link MAX_ARG_ITEMS} keys/elements are kept; strings are\n * truncated to {@link MAX_ARG_STRING_LENGTH}; circular references become\n * `\"[Circular]\"`; and exotic values (bigint / symbol / function / undefined) are\n * rendered to safe text — so the result is always serializable and bounded.\n */\nfunction safeCloneValue(\n value: unknown,\n depth: number,\n seen: Set<object>,\n): unknown {\n if (value === null) return null;\n const type = typeof value;\n if (type === \"string\") return capLength(value as string, MAX_ARG_STRING_LENGTH);\n if (type === \"number\") return Number.isFinite(value as number) ? value : String(value);\n if (type === \"boolean\") return value;\n if (type === \"bigint\") return `${(value as bigint).toString()}n`;\n if (type === \"symbol\") return (value as symbol).toString();\n if (type === \"function\") return \"[Function]\";\n if (type === \"undefined\") return null;\n const obj = value as object;\n if (value instanceof Error) {\n const { name, message } = describeErrorValue(value);\n return { name, message };\n }\n if (seen.has(obj)) return \"[Circular]\";\n if (depth <= 0) return Array.isArray(value) ? \"[Array]\" : \"[Object]\";\n seen.add(obj);\n try {\n if (Array.isArray(value)) {\n const items = value\n .slice(0, MAX_ARG_ITEMS)\n .map((item) => safeCloneValue(item, depth - 1, seen));\n if (value.length > MAX_ARG_ITEMS) {\n items.push(`… ${value.length - MAX_ARG_ITEMS} more`);\n }\n return items;\n }\n const source = value as Record<string, unknown>;\n const keys = Object.keys(source);\n const out: Record<string, unknown> = {};\n for (const key of keys.slice(0, MAX_ARG_ITEMS)) {\n const child = source[key];\n // Undefined / function values JSON drops anyway — omit them for a clean clone.\n if (typeof child === \"undefined\" || typeof child === \"function\") continue;\n out[key] = safeCloneValue(child, depth - 1, seen);\n }\n if (keys.length > MAX_ARG_ITEMS) out[\"…\"] = `${keys.length - MAX_ARG_ITEMS} more`;\n return out;\n } finally {\n seen.delete(obj);\n }\n}\n\n/** Classify one console argument into a type-tagged {@link ConsoleArg} (spec #122 §C). */\nexport function toConsoleArg(value: unknown): ConsoleArg {\n if (value === null || value === undefined) return { t: \"null\", v: null };\n const type = typeof value;\n if (type === \"string\") {\n return { t: \"string\", v: capLength(value as string, MAX_ARG_STRING_LENGTH) };\n }\n if (type === \"number\") {\n return Number.isFinite(value as number)\n ? { t: \"number\", v: value }\n : { t: \"string\", v: String(value) };\n }\n if (type === \"boolean\") return { t: \"bool\", v: value };\n if (type === \"bigint\") return { t: \"string\", v: `${(value as bigint).toString()}n` };\n if (type === \"symbol\") return { t: \"string\", v: (value as symbol).toString() };\n if (type === \"function\") return { t: \"string\", v: \"[Function]\" };\n if (value instanceof Error) return { t: \"error\", v: describeErrorValue(value) };\n return { t: \"json\", v: safeCloneValue(value, MAX_ARG_DEPTH, new Set()) };\n}\n\n/** The serialized UTF-8 byte length of a value; `Infinity` when it cannot serialize. */\nfunction serializedBytes(value: unknown): number {\n try {\n const json = JSON.stringify(value) ?? \"\";\n return typeof TextEncoder !== \"undefined\"\n ? new TextEncoder().encode(json).length\n : json.length;\n } catch {\n return Number.POSITIVE_INFINITY;\n }\n}\n\n/**\n * Cap an entry's structured args to {@link MAX_CONSOLE_ARGS_BYTES} (spec #122 §F):\n * drop trailing args until the array fits, keeping the earliest (usually the format\n * string / main message); if even a single arg is over budget, keep one honest\n * placeholder rather than an unbounded value. Per-arg depth/breadth/string caps bound\n * most cases already — this is the whole-entry backstop.\n */\nfunction capConsoleArgs(args: ConsoleArg[]): ConsoleArg[] {\n if (serializedBytes(args) <= MAX_CONSOLE_ARGS_BYTES) return args;\n let out = args.slice();\n while (out.length > 1 && serializedBytes(out) > MAX_CONSOLE_ARGS_BYTES) {\n out = out.slice(0, -1);\n }\n if (out.length === 1 && serializedBytes(out) > MAX_CONSOLE_ARGS_BYTES) {\n return [{ t: \"string\", v: \"[trace: console argument omitted (too large)]\" }];\n }\n return out;\n}\n\n/**\n * A `console` crumb from a captured call's level and arguments (spec #122 §C). The\n * `message` is the one-line preview (flattened, truncated); `args` preserves each\n * argument as a structured, type-tagged, size-capped value so the Console tab can\n * render objects/errors expandably; `source` is the best-effort `file:line`, attached\n * only when the stack yielded one. Args are omitted entirely for a no-argument call.\n */\nexport function consoleCrumb(\n level: BreadcrumbLevel,\n args: readonly unknown[],\n timestamp: number,\n source?: SourceLocation,\n): Breadcrumb {\n const structured = capConsoleArgs(args.map(toConsoleArg));\n const crumb: Breadcrumb = {\n category: \"console\",\n level,\n message: joinArgs(args),\n timestamp,\n ...(structured.length > 0 ? { args: structured } : {}),\n ...(source ? { source } : {}),\n };\n return crumb;\n}\n\n/** A `navigation` crumb; both URLs are scrubbed and length-capped as the crumb is built. */\nexport function navigationCrumb(\n from: string,\n to: string,\n timestamp: number,\n): Breadcrumb {\n const fromUrl = capLength(scrubUrl(from), MAX_URL_LENGTH);\n const toUrl = capLength(scrubUrl(to), MAX_URL_LENGTH);\n return {\n category: \"navigation\",\n message: `${fromUrl} → ${toUrl}`,\n timestamp,\n data: { from: fromUrl, to: toUrl },\n };\n}\n\n/**\n * Classify an HTTP status into a {@link NetworkOutcome} (spec #122 §D). A missing or\n * `0` status is a `network-error` (a request that never got a response); otherwise\n * the 4xx/5xx classes flag failures and everything else is `ok`. Used both as the\n * fallback outcome and by the thin {@link fetchCrumb} / {@link xhrCrumb} builders.\n */\nexport function outcomeFromStatus(status: number | undefined): NetworkOutcome {\n if (typeof status !== \"number\" || status <= 0) return \"network-error\";\n if (status >= 500) return \"http-5xx\";\n if (status >= 400) return \"http-4xx\";\n return \"ok\";\n}\n\n/**\n * The trivially-known byte size of a request body (spec #122 §D) — a string's UTF-8\n * length, a `Blob`'s `.size`, or an `ArrayBuffer`/typed-array `.byteLength`. Anything\n * that would require **reading** the body (a `ReadableStream`, `FormData`, a `Request`\n * with a stream body) returns `undefined` — the \"never read the body\" line holds.\n */\nexport function trivialBodySize(body: unknown): number | undefined {\n if (typeof body === \"string\") return utf8ByteLength(body);\n if (typeof Blob !== \"undefined\" && body instanceof Blob) return body.size;\n if (typeof ArrayBuffer !== \"undefined\") {\n if (body instanceof ArrayBuffer) return body.byteLength;\n if (ArrayBuffer.isView(body)) return (body as ArrayBufferView).byteLength;\n }\n return undefined;\n}\n\nfunction utf8ByteLength(value: string): number {\n try {\n return typeof TextEncoder !== \"undefined\"\n ? new TextEncoder().encode(value).length\n : value.length;\n } catch {\n return value.length;\n }\n}\n\n/** Parse a `content-length` header into a non-negative byte count, or `undefined`. */\nexport function parseContentLength(value: string | null | undefined): number | undefined {\n if (typeof value !== \"string\") return undefined;\n const bytes = Number.parseInt(value, 10);\n return Number.isFinite(bytes) && bytes >= 0 ? bytes : undefined;\n}\n\n/** The media type from a `content-type` header (the part before any `;` parameters). */\nexport function contentTypeOf(value: string | null | undefined): string | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n const media = value.split(\";\")[0]?.trim();\n return media && media.length > 0 ? media : undefined;\n}\n\n/** The rich metadata a network crumb records (spec #122 §D) — never a body or header. */\nexport interface NetworkCrumbInput {\n readonly api: NetworkApi;\n readonly method: string;\n /** The raw request URL — scrubbed (query dropped, path PII redacted) as the crumb is built. */\n readonly url: string;\n readonly status?: number;\n readonly statusText?: string;\n readonly durationMs?: number;\n readonly reqSize?: number;\n readonly respSize?: number;\n readonly contentType?: string;\n readonly outcome: NetworkOutcome;\n}\n\n/**\n * A network crumb (`fetch` / `xhr` / `beacon`) with the rich, metadata-only fields\n * the Network tab renders (spec #122 §D, ticket #139): api, method, scrubbed URL,\n * status + statusText, duration, request/response sizes, content type, and a failure\n * outcome. The URL is scrubbed and length-capped at assembly. The shape has **no field\n * for a request/response body or an arbitrary header**, so neither can ever be\n * recorded; only a positive status, and fields that were actually supplied, ride along.\n */\nexport function networkCrumb(input: NetworkCrumbInput, timestamp: number): Breadcrumb {\n const url = capLength(scrubUrl(input.url), MAX_URL_LENGTH);\n const hasStatus = typeof input.status === \"number\" && input.status > 0;\n const statusPart = hasStatus ? ` → ${input.status}` : \"\";\n const outcomePart = input.outcome !== \"ok\" ? ` (${input.outcome})` : \"\";\n return {\n category: input.api,\n api: input.api,\n method: input.method,\n url,\n message: `${input.method} ${url}${statusPart}${outcomePart}`,\n timestamp,\n ...(hasStatus ? { status: input.status } : {}),\n ...(input.statusText ? { statusText: input.statusText } : {}),\n ...(typeof input.durationMs === \"number\" ? { durationMs: input.durationMs } : {}),\n ...(typeof input.reqSize === \"number\" ? { reqSize: input.reqSize } : {}),\n ...(typeof input.respSize === \"number\" ? { respSize: input.respSize } : {}),\n ...(input.contentType ? { contentType: input.contentType } : {}),\n outcome: input.outcome,\n };\n}\n\n/**\n * A thin `fetch` crumb from method + URL + status (outcome derived from the status).\n * The instrumentation uses {@link networkCrumb} directly to carry the full metadata;\n * this convenience builder seeds a network crumb from a status alone.\n */\nexport function fetchCrumb(\n method: string,\n url: string,\n status: number | undefined,\n timestamp: number,\n): Breadcrumb {\n return networkCrumb(\n { api: \"fetch\", method, url, status, outcome: outcomeFromStatus(status) },\n timestamp,\n );\n}\n\n/** A thin `xhr` crumb from method + URL + status (outcome derived from the status). */\nexport function xhrCrumb(\n method: string,\n url: string,\n status: number | undefined,\n timestamp: number,\n): Breadcrumb {\n return networkCrumb(\n { api: \"xhr\", method, url, status, outcome: outcomeFromStatus(status) },\n timestamp,\n );\n}\n\nfunction safeSelector(target: Element): string {\n try {\n return cssSelectorFor(target);\n } catch {\n return target.tagName ? target.tagName.toLowerCase() : \"unknown\";\n }\n}\n\n/** A `ui.click` crumb: a masked target selector only — no text or value. */\nexport function clickCrumb(target: Element, timestamp: number): Breadcrumb {\n const selector = safeSelector(target);\n return {\n category: \"ui.click\",\n message: `click ${selector}`,\n timestamp,\n data: { target: selector },\n };\n}\n\n/**\n * A `ui.input` crumb: records **that** an input changed and which field, never\n * the value typed into it. The `target` element's `.value` is never read.\n */\nexport function inputCrumb(target: Element, timestamp: number): Breadcrumb {\n const selector = safeSelector(target);\n return {\n category: \"ui.input\",\n message: `input ${selector}`,\n timestamp,\n data: { target: selector },\n };\n}\n\nfunction describeError(error: unknown): { name: string; message: string } {\n if (error instanceof Error) {\n return { name: error.name || \"Error\", message: error.message };\n }\n if (typeof error === \"string\") return { name: \"Error\", message: error };\n return { name: \"Error\", message: stringifyArg(error) };\n}\n\n/**\n * An `error` crumb for the failing exception or rejection that ends the trace. When\n * `causedBy` is given (an auto-captured error), it rides on the crumb as the causal\n * pointer to the ids of the entries immediately preceding the throw (spec #122 §F).\n */\nexport function errorCrumb(\n error: unknown,\n timestamp: number,\n causedBy?: readonly string[],\n): Breadcrumb {\n const { name, message } = describeError(error);\n const crumb: Breadcrumb = {\n category: \"error\",\n level: \"error\",\n message: message ? `${name}: ${message}` : name,\n timestamp,\n data: { errorType: name },\n };\n return causedBy && causedBy.length > 0 ? { ...crumb, causedBy } : crumb;\n}\n\n// --- Instrumentation ---------------------------------------------------------\n\n/** Detaches an installed instrumentation, restoring the original behaviour. */\nexport type Teardown = () => void;\n\ntype AnyFn = (...args: unknown[]) => unknown;\ntype ConsoleLike = Partial<Record<BreadcrumbLevel, AnyFn>>;\ntype FetchFn = (\n input: string | URL | Request,\n init?: RequestInit,\n) => Promise<Response>;\n\ninterface HistoryLike {\n pushState(data: unknown, unused: string, url?: string | URL | null): void;\n replaceState(data: unknown, unused: string, url?: string | URL | null): void;\n}\n\ninterface XhrInstance {\n status: number;\n statusText?: string;\n open(method: string, url: string | URL, ...rest: unknown[]): void;\n send(body?: unknown): void;\n getResponseHeader?(name: string): string | null;\n addEventListener(type: string, listener: () => void): void;\n removeEventListener(type: string, listener: () => void): void;\n}\ninterface XhrConstructor {\n new (): XhrInstance;\n prototype: XhrInstance;\n}\n\n/** The `navigator.sendBeacon` surface the beacon instrumentation wraps. */\nexport interface BeaconNavigator {\n sendBeacon?: (url: string | URL, data?: BodyInit | null) => boolean;\n}\n\n/** The structural window surface the instrumentation reaches into. */\nexport interface InstrumentWindow {\n fetch?: FetchFn;\n history?: HistoryLike;\n location?: { href: string };\n XMLHttpRequest?: XhrConstructor;\n navigator?: BeaconNavigator;\n addEventListener(\n type: string,\n listener: (event: Event) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n removeEventListener(\n type: string,\n listener: (event: Event) => void,\n options?: boolean | EventListenerOptions,\n ): void;\n}\n\n/** Options for {@link instrumentBreadcrumbs} and the individual installers. */\nexport interface InstrumentOptions {\n readonly win?: InstrumentWindow;\n readonly doc?: Document;\n readonly consoleObj?: ConsoleLike;\n readonly consoleLevels?: readonly BreadcrumbLevel[];\n /** Skip URLs (e.g. the SDK's own ingest calls) so they never become crumbs. */\n readonly ignoreUrl?: (url: string) => boolean;\n readonly now?: () => number;\n /**\n * High-res monotonic clock (spec #122 §D) — used to measure a request's duration as\n * a delta around the wrapped call. Defaults to `performance.now`; injectable for tests.\n */\n readonly mono?: () => number;\n /**\n * Whether to instrument the **console** stream (spec #122 §L; ticket #138).\n * Defaults to `true`; pass `false` and `console` is never wrapped, so no console\n * entry is ever recorded — the per-project toggle stops the stream at its source.\n */\n readonly captureConsole?: boolean;\n /**\n * Whether to instrument the **network** stream — `fetch` and `XHR` (spec #122 §L;\n * ticket #138). Defaults to `true`; pass `false` and neither is wrapped, so no\n * network entry is ever recorded. Navigation and masked UI events are unaffected.\n */\n readonly captureNetwork?: boolean;\n}\n\nfunction noop(): void {\n /* nothing installed */\n}\n\n/**\n * Parse a single stack line into a `{ file, line }` location, or `undefined`. Handles\n * V8 (`at fn (file:line:col)` / `at file:line:col`) and Firefox/Safari (`fn@file:line:col`)\n * frames; a query string on the asset URL is dropped (a cache-buster, or defensively a\n * token) both for parse safety and privacy.\n */\nfunction parseStackFrame(line: string): SourceLocation | undefined {\n let loc: string | undefined;\n const v8Named = line.match(/^at\\s+.+?\\s+\\((.+)\\)$/);\n if (v8Named) {\n loc = v8Named[1];\n } else {\n const v8Bare = line.match(/^at\\s+(.+)$/);\n if (v8Bare) {\n loc = v8Bare[1];\n } else {\n const at = line.indexOf(\"@\");\n if (at >= 0) loc = line.slice(at + 1);\n }\n }\n if (!loc) return undefined;\n loc = loc.replace(/\\?[^:]*/, \"\");\n const m = loc.match(/^(.*):(\\d+):\\d+$/) ?? loc.match(/^(.*):(\\d+)$/);\n if (!m) return undefined;\n const file = m[1] ?? \"\";\n const lineNo = Number(m[2]);\n if (!file || !Number.isFinite(lineNo)) return undefined;\n return { file, line: lineNo };\n}\n\n/**\n * The best-effort `file:line` a console call was made from (spec #122 §C). Parses the\n * frames of a stack, skipping `skipFrames` leading (SDK-internal) frames so the source\n * points at the host code that called `console.*`. Returns `undefined` when no frame\n * yields a usable location — the crumb then simply omits `source`.\n */\nexport function sourceFromStack(\n stack: string | undefined,\n skipFrames = 0,\n): SourceLocation | undefined {\n if (typeof stack !== \"string\" || stack.length === 0) return undefined;\n const frames: SourceLocation[] = [];\n for (const raw of stack.split(\"\\n\")) {\n const frame = parseStackFrame(raw.trim());\n if (frame) frames.push(frame);\n }\n return frames[skipFrames];\n}\n\n/**\n * Frames between `new Error()` (created inside the console wrapper) and the host caller:\n * just the wrapper frame itself. Skipping it points {@link sourceFromStack} at the app\n * code. The wrapper is called through the console object's property, so it is not a\n * direct-call inlining candidate — keeping this skip count stable.\n */\nconst CONSOLE_SOURCE_SKIP_FRAMES = 1;\n\n/** Wrap `console` methods so calls at the captured levels become crumbs. */\nexport function instrumentConsole(\n buffer: BreadcrumbBuffer,\n consoleObj: ConsoleLike,\n levels: readonly BreadcrumbLevel[],\n now: () => number,\n): Teardown {\n const restores: Teardown[] = [];\n for (const level of levels) {\n const original = consoleObj[level];\n if (typeof original !== \"function\") continue;\n // Decide once per level — not once per call — whether this level pays the\n // source-capture cost. Only the levels that matter for debugging construct a\n // `new Error()` to read the call site; the chatty log/info/debug skip it entirely\n // so a tight logging loop stays cheap (ticket #159; see SOURCE_CAPTURE_LEVELS).\n const withSource = capturesSource(level);\n const wrapper = (...args: unknown[]): unknown => {\n // Capture the call site before anything else so the wrapper is the top frame —\n // but only for the levels that keep a source (the hot-page budget, ticket #159).\n let source: SourceLocation | undefined;\n if (withSource) {\n try {\n source = sourceFromStack(new Error().stack, CONSOLE_SOURCE_SKIP_FRAMES);\n } catch {\n source = undefined;\n }\n }\n try {\n if (level === \"assert\") {\n // console.assert records only when the asserted condition is falsy.\n if (!args[0]) {\n buffer.add(consoleCrumb(\"assert\", args.slice(1), now(), source));\n }\n } else {\n buffer.add(consoleCrumb(level, args, now(), source));\n }\n } catch {\n // Capture must never throw into the host page.\n }\n return original.apply(consoleObj, args);\n };\n consoleObj[level] = wrapper;\n restores.push(() => {\n consoleObj[level] = original;\n });\n }\n return () => {\n for (const restore of restores) restore();\n };\n}\n\nfunction requestUrl(input: string | URL | Request): string {\n if (typeof input === \"string\") return input;\n if (input instanceof URL) return input.toString();\n return input.url;\n}\n\nfunction requestMethod(\n input: string | URL | Request,\n init: RequestInit | undefined,\n): string {\n const method =\n init?.method ??\n (typeof input === \"object\" && \"method\" in input ? input.method : undefined) ??\n \"GET\";\n return method.toUpperCase();\n}\n\n/** Read one response header defensively — `null` on an opaque response or any throw. */\nfunction safeResponseHeader(response: Response, name: string): string | null {\n try {\n return response.headers?.get?.(name) ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Classify a settled `fetch` response into a {@link NetworkOutcome} (spec #122 §D). An\n * opaque cross-origin response (status masked to `0`) is `opaque-cors`; otherwise the\n * outcome follows the HTTP status.\n */\nfunction classifyFetchResponse(response: Response): NetworkOutcome {\n if (response.type === \"opaque\" || response.type === \"opaqueredirect\") {\n return \"opaque-cors\";\n }\n return outcomeFromStatus(response.status);\n}\n\n/**\n * Classify a rejected `fetch` into a {@link NetworkOutcome} (spec #122 §D) by the\n * error's name: an `AbortError` is `aborted`, a `TimeoutError` (an `AbortSignal.timeout`)\n * is `timeout`, and anything else is a plain `network-error`.\n */\nfunction classifyFetchError(error: unknown): NetworkOutcome {\n const name =\n typeof error === \"object\" && error !== null && \"name\" in error\n ? String((error as { name?: unknown }).name)\n : \"\";\n if (name === \"AbortError\") return \"aborted\";\n if (name === \"TimeoutError\") return \"timeout\";\n return \"network-error\";\n}\n\n/**\n * Wrap `fetch` to record a rich network crumb on settlement (spec #122 §D, ticket\n * #139): method, scrubbed URL, status + statusText, a `performance.now()` duration,\n * request size (only when the body is trivially sized), response size (from the\n * `content-length` header only), content type, and a failure outcome. The **original**\n * outcome is returned untouched — the response is passed through **without its body\n * being read** (only two metadata headers are inspected), and a rejection is re-thrown\n * so the caller's `unhandledrejection` semantics are preserved.\n */\nexport function instrumentFetch(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n ignoreUrl: (url: string) => boolean,\n now: () => number,\n mono: () => number = defaultMono,\n): Teardown {\n const original = win.fetch;\n if (typeof original !== \"function\") return noop;\n const wrapper: FetchFn = (\n input: string | URL | Request,\n init?: RequestInit,\n ): Promise<Response> => {\n const url = requestUrl(input);\n const method = requestMethod(input, init);\n // Size only a body passed literally in `init` — never a `Request`'s stream body.\n const reqSize = trivialBodySize(init?.body);\n const started = mono();\n // Native `fetch` must run against the window, so bind the receiver rather\n // than forward whatever `this` a free call carries.\n const promise = original.call(win, input, init);\n if (ignoreUrl(url)) return promise;\n return promise.then(\n (response) => {\n try {\n buffer.add(\n networkCrumb(\n {\n api: \"fetch\",\n method,\n url,\n status: response.status || undefined,\n statusText: response.statusText || undefined,\n durationMs: Math.max(0, mono() - started),\n reqSize,\n respSize: parseContentLength(\n safeResponseHeader(response, \"content-length\"),\n ),\n contentType: contentTypeOf(\n safeResponseHeader(response, \"content-type\"),\n ),\n outcome: classifyFetchResponse(response),\n },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n return response;\n },\n (error: unknown) => {\n try {\n buffer.add(\n networkCrumb(\n {\n api: \"fetch\",\n method,\n url,\n durationMs: Math.max(0, mono() - started),\n reqSize,\n outcome: classifyFetchError(error),\n },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n throw error;\n },\n );\n };\n win.fetch = wrapper;\n return () => {\n win.fetch = original;\n };\n}\n\ninterface XhrMeta {\n __fixbackMeta?: { method: string; url: string };\n}\n\n/** Read one XHR response header defensively — `null` when unavailable or on any throw. */\nfunction safeXhrHeader(xhr: XhrInstance, name: string): string | null {\n try {\n return typeof xhr.getResponseHeader === \"function\"\n ? xhr.getResponseHeader(name)\n : null;\n } catch {\n return null;\n }\n}\n\n/** Read an XHR's `statusText` defensively — `undefined` when empty or on any throw. */\nfunction safeXhrStatusText(xhr: XhrInstance): string | undefined {\n try {\n return xhr.statusText || undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Patch `XMLHttpRequest` to record a rich network crumb when a request settles (spec\n * #122 §D, ticket #139): method, scrubbed URL, status + statusText, a `performance.now()`\n * duration, request size (only when the body is trivially sized), response size (from\n * the `content-length` header only), content type, and a failure outcome distinguished\n * by which terminal event fired (`error` / `timeout` / `abort` / `load`). The `send`\n * body argument is **never read for content** — only its trivially-known size — so a body\n * can never reach the buffer.\n */\nexport function instrumentXhr(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n ignoreUrl: (url: string) => boolean,\n now: () => number,\n mono: () => number = defaultMono,\n): Teardown {\n const ctor = win.XMLHttpRequest;\n if (typeof ctor !== \"function\") return noop;\n const proto = ctor.prototype;\n const originalOpen = proto.open;\n const originalSend = proto.send;\n\n proto.open = function (\n this: XhrInstance & XhrMeta,\n method: string,\n url: string | URL,\n ...rest: unknown[]\n ): void {\n this.__fixbackMeta = { method: String(method).toUpperCase(), url: String(url) };\n return originalOpen.call(this, method, url, ...rest);\n };\n\n proto.send = function (this: XhrInstance & XhrMeta, body?: unknown): void {\n const meta = this.__fixbackMeta;\n if (meta && !ignoreUrl(meta.url)) {\n const started = mono();\n const reqSize = trivialBodySize(body);\n // The terminal event names the outcome; `loadend` always follows exactly one of\n // load/error/timeout/abort, so by the time we record, `settled` is set.\n let settled: NetworkOutcome | undefined;\n const onLoad = (): void => {\n settled = outcomeFromStatus(this.status || undefined);\n };\n const onError = (): void => {\n settled = \"network-error\";\n };\n const onTimeout = (): void => {\n settled = \"timeout\";\n };\n const onAbort = (): void => {\n settled = \"aborted\";\n };\n // An arrow captures the request instance as `this` without aliasing it.\n const onDone = (): void => {\n try {\n buffer.add(\n networkCrumb(\n {\n api: \"xhr\",\n method: meta.method,\n url: meta.url,\n status: this.status || undefined,\n statusText: safeXhrStatusText(this),\n durationMs: Math.max(0, mono() - started),\n reqSize,\n respSize: parseContentLength(safeXhrHeader(this, \"content-length\")),\n contentType: contentTypeOf(safeXhrHeader(this, \"content-type\")),\n outcome: settled ?? outcomeFromStatus(this.status || undefined),\n },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n this.removeEventListener(\"load\", onLoad);\n this.removeEventListener(\"error\", onError);\n this.removeEventListener(\"timeout\", onTimeout);\n this.removeEventListener(\"abort\", onAbort);\n this.removeEventListener(\"loadend\", onDone);\n };\n this.addEventListener(\"load\", onLoad);\n this.addEventListener(\"error\", onError);\n this.addEventListener(\"timeout\", onTimeout);\n this.addEventListener(\"abort\", onAbort);\n this.addEventListener(\"loadend\", onDone);\n }\n return originalSend.call(this, body);\n };\n\n return () => {\n proto.open = originalOpen;\n proto.send = originalSend;\n };\n}\n\n/**\n * Wrap `navigator.sendBeacon` to record a network crumb for each beacon (spec #122 §D,\n * ticket #139). `sendBeacon` is fire-and-forget with a **synchronous boolean** return —\n * `true` when the user agent queued the beacon, `false` when it declined — so wrapping\n * must return that boolean unchanged: the original is called first and its result both\n * classifies the crumb (`ok` / `network-error`) and is returned to the caller. Only the\n * URL and the trivially-known request size are recorded (no response exists to read);\n * capture failure is swallowed and the boolean still returned, and if the original itself\n * throws we record best-effort and re-throw so the contract is preserved exactly.\n */\nexport function instrumentBeacon(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n ignoreUrl: (url: string) => boolean,\n now: () => number,\n): Teardown {\n const nav = win.navigator;\n if (!nav || typeof nav.sendBeacon !== \"function\") return noop;\n const original = nav.sendBeacon;\n const record = (url: string, data: unknown, outcome: NetworkOutcome): void => {\n if (ignoreUrl(url)) return;\n try {\n buffer.add(\n networkCrumb(\n { api: \"beacon\", method: \"POST\", url, reqSize: trivialBodySize(data), outcome },\n now(),\n ),\n );\n } catch {\n /* never throw into the host page */\n }\n };\n const wrapper = function (url: string | URL, data?: BodyInit | null): boolean {\n const target = typeof url === \"string\" ? url : String(url);\n let queued: boolean;\n try {\n queued = original.call(nav, url, data);\n } catch (error) {\n // The original threw: record a best-effort failure, then preserve semantics.\n record(target, data, \"network-error\");\n throw error;\n }\n record(target, data, queued ? \"ok\" : \"network-error\");\n return queued;\n };\n nav.sendBeacon = wrapper;\n return () => {\n nav.sendBeacon = original;\n };\n}\n\n/** Record a `navigation` crumb on `pushState`/`replaceState`/pop/hash changes. */\nexport function instrumentNavigation(\n buffer: BreadcrumbBuffer,\n win: InstrumentWindow,\n now: () => number,\n): Teardown {\n const history = win.history;\n const location = win.location;\n if (!history || !location) return noop;\n\n let last = location.href;\n const record = (to: string): void => {\n try {\n buffer.add(navigationCrumb(last, to, now()));\n } catch {\n /* never throw into the host page */\n }\n last = to;\n };\n\n const originalPush = history.pushState;\n const originalReplace = history.replaceState;\n\n history.pushState = function (\n this: HistoryLike,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n const result = originalPush.call(this, data, unused, url);\n record(location.href);\n return result;\n };\n history.replaceState = function (\n this: HistoryLike,\n data: unknown,\n unused: string,\n url?: string | URL | null,\n ): void {\n const result = originalReplace.call(this, data, unused, url);\n record(location.href);\n return result;\n };\n\n const onPopState = (): void => record(location.href);\n const onHashChange = (): void => record(location.href);\n win.addEventListener(\"popstate\", onPopState);\n win.addEventListener(\"hashchange\", onHashChange);\n\n return () => {\n history.pushState = originalPush;\n history.replaceState = originalReplace;\n win.removeEventListener(\"popstate\", onPopState);\n win.removeEventListener(\"hashchange\", onHashChange);\n };\n}\n\nfunction eventTargetElement(event: Event): Element | null {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n const deepest = path[0] ?? event.target;\n return deepest instanceof Element ? deepest : null;\n}\n\n/** Listen (capture-phase) for clicks and input changes as masked crumbs. */\nexport function instrumentUiEvents(\n buffer: BreadcrumbBuffer,\n doc: Document,\n now: () => number,\n): Teardown {\n const onClick = (event: Event): void => {\n const target = eventTargetElement(event);\n if (!target || isFixbackNode(target)) return;\n try {\n buffer.add(clickCrumb(target, now()));\n } catch {\n /* never throw into the host page */\n }\n };\n const onInput = (event: Event): void => {\n const target = eventTargetElement(event);\n if (!target || isFixbackNode(target)) return;\n try {\n buffer.add(inputCrumb(target, now()));\n } catch {\n /* never throw into the host page */\n }\n };\n doc.addEventListener(\"click\", onClick, true);\n doc.addEventListener(\"input\", onInput, true);\n return () => {\n doc.removeEventListener(\"click\", onClick, true);\n doc.removeEventListener(\"input\", onInput, true);\n };\n}\n\n/**\n * Install every capture hook onto a window/document and return a single teardown\n * that removes them all. Each hook is independent and defensive: a failure in one\n * never blocks the others, and none can throw into the host page.\n */\nexport function instrumentBreadcrumbs(\n buffer: BreadcrumbBuffer,\n options: InstrumentOptions = {},\n): Teardown {\n const win =\n options.win ?? (globalThis as unknown as InstrumentWindow | undefined);\n const doc =\n options.doc ??\n (typeof document !== \"undefined\" ? document : undefined);\n const consoleObj =\n options.consoleObj ??\n (typeof console !== \"undefined\"\n ? (console as unknown as ConsoleLike)\n : undefined);\n const levels = options.consoleLevels ?? DEFAULT_CONSOLE_LEVELS;\n const ignoreUrl = options.ignoreUrl ?? (() => false);\n const now = options.now ?? Date.now;\n const mono = options.mono ?? defaultMono;\n // Per-project capture toggles (#138): a stream is captured unless explicitly\n // turned off, so a boot config that omits it — or an older server — stays on.\n const captureConsole = options.captureConsole !== false;\n const captureNetwork = options.captureNetwork !== false;\n\n const teardowns: Teardown[] = [];\n if (consoleObj && captureConsole) {\n teardowns.push(instrumentConsole(buffer, consoleObj, levels, now));\n }\n if (win) {\n if (captureNetwork) {\n teardowns.push(instrumentFetch(buffer, win, ignoreUrl, now, mono));\n teardowns.push(instrumentXhr(buffer, win, ignoreUrl, now, mono));\n teardowns.push(instrumentBeacon(buffer, win, ignoreUrl, now));\n }\n teardowns.push(instrumentNavigation(buffer, win, now));\n }\n if (doc) {\n teardowns.push(instrumentUiEvents(buffer, doc, now));\n }\n\n return () => {\n for (const teardown of teardowns) {\n try {\n teardown();\n } catch {\n /* teardown is best-effort */\n }\n }\n };\n}\n","/**\n * The Annotation & vector-marks model (spec 0003 §B/§D).\n *\n * An Annotation is everything a Reporter marked on the page, as three\n * **composable, optional** layers over one full masked screenshot: the picked\n * `element` (from the element-picker), a drag-captured `region`, and vector\n * `marks` — arrow / box / pen / text. Marks live in the **screenshot's coordinate\n * space** (the full viewport the screenshot is rasterised at), never baked into\n * the PNG: the dashboard composites them at view time (#91).\n *\n * This module is the marks' single home — the pure types and geometry used by the\n * region-capture and draw controllers and by the overlay's Send assembly. Like the\n * rest of the SDK's wire types it is vendored (no `@fixback/shared` import); keep\n * `Annotation` in lock-step with the server's ingest contract (spec §D/§H).\n */\n\nimport type { SelectedElement } from \"./report\";\n\n/** A point in screenshot (viewport) coordinate space. */\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A rectangle in screenshot coordinates — the same shape as an element's rect. */\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** The draw tools the overlay offers, in toolbar order (spec §B, prototype). */\nexport type DrawTool = \"arrow\" | \"box\" | \"pen\" | \"text\";\n\n/** Fields shared by every vector mark. */\ninterface MarkBase {\n /** Stroke/fill colour, as a CSS colour string. */\n readonly color: string;\n}\n\n/** A directional arrow from `(x0,y0)` to its tip at `(x1,y1)`. */\nexport interface ArrowMark extends MarkBase {\n readonly type: \"arrow\";\n readonly x0: number;\n readonly y0: number;\n readonly x1: number;\n readonly y1: number;\n}\n\n/** A rectangle spanning the drag from `(x0,y0)` to `(x1,y1)`. */\nexport interface BoxMark extends MarkBase {\n readonly type: \"box\";\n readonly x0: number;\n readonly y0: number;\n readonly x1: number;\n readonly y1: number;\n}\n\n/** A freehand polyline through `points` (in order). */\nexport interface PenMark extends MarkBase {\n readonly type: \"pen\";\n readonly points: ReadonlyArray<Point>;\n}\n\n/** A text label anchored at `(x,y)` (its baseline-left, as SVG text). */\nexport interface TextMark extends MarkBase {\n readonly type: \"text\";\n readonly x: number;\n readonly y: number;\n readonly text: string;\n}\n\n/** A single vector mark, in screenshot coordinates. */\nexport type Mark = ArrowMark | BoxMark | PenMark | TextMark;\n\n/**\n * The structured Annotation carried on a report's content (spec §D): the three\n * optional layers. Every field is optional — a report may carry any subset or\n * none (a bare comment is a valid Send).\n */\nexport interface Annotation {\n readonly element?: SelectedElement;\n readonly region?: Rect;\n readonly marks?: ReadonlyArray<Mark>;\n}\n\n/**\n * The default mark colour — Signal's danger red, matching the frozen Reporter\n * prototype's draw layer (`docs/design/Fixback Reporter.dc.html`).\n */\nexport const MARK_COLOR = \"#e5484d\";\n\n/**\n * Normalise a drag from a start to an end point into a positive-extent rect\n * (top-left origin, non-negative width/height), rounded to whole pixels — the\n * screenshot is a pixel raster, so sub-pixel extents carry no meaning. Shared by\n * region-capture and the box mark.\n */\nexport function normalizeRect(x0: number, y0: number, x1: number, y1: number): Rect {\n return {\n x: Math.round(Math.min(x0, x1)),\n y: Math.round(Math.min(y0, y1)),\n width: Math.round(Math.abs(x1 - x0)),\n height: Math.round(Math.abs(y1 - y0)),\n };\n}\n\n/**\n * The three points of an arrow's head, given its line `(x0,y0)→(x1,y1)` and a head\n * length: the tip, then the two barbs splayed ±30° behind it. Pure geometry the\n * draw surface renders as a filled triangle at the arrow's tip.\n */\nexport function arrowHeadPoints(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n size = 14,\n): [Point, Point, Point] {\n const angle = Math.atan2(y1 - y0, x1 - x0);\n return [\n { x: x1, y: y1 },\n {\n x: x1 - size * Math.cos(angle - Math.PI / 6),\n y: y1 - size * Math.sin(angle - Math.PI / 6),\n },\n {\n x: x1 - size * Math.cos(angle + Math.PI / 6),\n y: y1 - size * Math.sin(angle + Math.PI / 6),\n },\n ];\n}\n\n/**\n * Assemble the structured Annotation from whatever a Reporter marked, dropping\n * empty layers: no element, no region, and an empty marks list are omitted, so the\n * result is `undefined` when nothing was marked. Marks are copied into a plain,\n * independent array so the annotation is a serialisable snapshot decoupled from the\n * live draw state.\n */\nexport function assembleAnnotation(parts: {\n readonly element?: SelectedElement | null;\n readonly region?: Rect | null;\n readonly marks?: ReadonlyArray<Mark> | null;\n}): Annotation | undefined {\n const annotation: {\n element?: SelectedElement;\n region?: Rect;\n marks?: ReadonlyArray<Mark>;\n } = {};\n if (parts.element) annotation.element = parts.element;\n if (parts.region) annotation.region = parts.region;\n if (parts.marks && parts.marks.length > 0) annotation.marks = parts.marks.slice();\n return Object.keys(annotation).length > 0 ? annotation : undefined;\n}\n","/**\n * The ingest **feedback** content wire-contract, vendored, plus the helpers that\n * assemble it from what a Reporter composed in the overlay.\n *\n * Like `boot.ts`, the SDK does not import `@fixback/shared`; the slice of the\n * submission shape it needs is copied here. Keep it in lock-step with the server:\n * the JSON `payload` part accepted by `POST /api/ingest/feedback`\n * (`apps/api/src/ingest/ingest.controller.ts` — `feedbackContentBody`) and the\n * `SubmissionContent` it parses (`apps/api/src/ingest/reporter-identity.ts`).\n */\n\nimport { assembleAnnotation, type Annotation, type Mark, type Rect } from \"./annotation\";\nimport type { Breadcrumb } from \"./breadcrumbs\";\n\n/**\n * Where a Feedback came from — a human in the overlay (`reporter`, the default) or\n * the SDK's automatic error capture (`auto`). Mirrors the server's `FEEDBACK_SOURCES`;\n * the server derives trust independently and ignores anything else the client claims.\n */\nexport type FeedbackSource = \"reporter\" | \"auto\";\n\n/** The picked element's viewport rectangle, as the server's annotation `rect`. */\nexport interface ElementRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/**\n * The picked element — the `element` layer of an {@link Annotation}: a stable CSS\n * selector, a readable DOM path, the tag, and the bounding rect. Exactly the\n * server's annotation `element` object shape.\n */\nexport interface SelectedElement {\n readonly selector: string;\n readonly domPath: string;\n readonly tag: string;\n readonly rect: ElementRect;\n}\n\n/** The capture environment recorded alongside a report. */\nexport interface CaptureEnvironment {\n readonly viewportWidth?: number;\n readonly viewportHeight?: number;\n readonly browser?: string;\n readonly sdkVersion?: string;\n /**\n * The host app's **Release** — the build identifier the builder configured at\n * `init` (#117, ADR-0024). Uploaded sourcemaps are keyed by it, so the server\n * can symbolicate this session's stack traces against the exact build that\n * produced them. Omitted when the Project doesn't set one.\n */\n readonly release?: string;\n}\n\n/**\n * One structured frame of a captured stack trace (#117, ADR-0024), top of stack\n * first — the server's `errorFrames` wire shape (mirrors `@fixback/shared`'s\n * `CapturedStackFrame` by value, per this file's vendoring rule). `file` is the\n * scrubbed script URL; `line`/`column` are 1-based as browsers report them.\n */\nexport interface CapturedFrame {\n readonly file: string;\n readonly line: number;\n readonly column: number | null;\n readonly function: string | null;\n}\n\n/** The longest release string the server accepts (mirrors `RELEASE_MAX_LENGTH`). */\nconst RELEASE_MAX_LENGTH = 100;\n\n/** Release names the server reserves (mirrors the shared release rules). */\nconst RESERVED_RELEASES = new Set([\".\", \"..\", \"latest\"]);\n\n/**\n * Validate + trim a builder-supplied release (#117, ADR-0024), mirroring the\n * server's rules by value: 1–100 visible characters, no whitespace, control\n * characters, or path separators, and not a reserved name. Returns `undefined`\n * for an invalid value — the SDK drops it (with a warning at `init`) rather than\n * shipping a value the server would discard.\n */\nexport function normaliseRelease(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length === 0 || trimmed.length > RELEASE_MAX_LENGTH) return undefined;\n if (RESERVED_RELEASES.has(trimmed)) return undefined;\n // eslint-disable-next-line no-control-regex\n if (/[\\s/\\\\\\u0000-\\u001f\\u007f]/.test(trimmed)) return undefined;\n return trimmed;\n}\n\n/**\n * The JSON content of a feedback submission — the object serialised into the\n * multipart `payload` part next to the `key` and identity evidence. Every field\n * is optional: none of it feeds the server's trust decision, so a submission may\n * carry any subset. `annotation` is the structured `{ element?, region?, marks? }`\n * (spec §D); the screenshot is a separate binary part, never part of this JSON.\n */\nexport interface ReportContent {\n readonly comment?: string;\n /**\n * The Reporter's self-provided display **name / email** (spec §F), captured in the\n * invite onboarding step and riding along with every submission so a Member sees\n * who reported an Issue. **Display only, never a trust signal** — the server derives\n * the tier from identity evidence alone and ignores these. Omitted when the Reporter\n * gave none (a Public/anonymous visitor).\n */\n readonly reporterName?: string;\n readonly reporterEmail?: string;\n readonly url?: string;\n readonly environment?: CaptureEnvironment;\n readonly annotation?: Annotation;\n /** The masked breadcrumb trace buffer that rode on this report (spec §C). */\n readonly trace?: readonly Breadcrumb[];\n /**\n * Provenance (spec §D/§E). Omitted for a manual report — the transport stamps the\n * `reporter` default on the wire; set to `auto` by the SDK's error capture.\n */\n readonly source?: FeedbackSource;\n /** For `source: auto` only — the SDK's per-session error fingerprint (spec §E). */\n readonly errorSignature?: string;\n /** For `source: auto` only — the running occurrence count within the session (spec §E). */\n readonly occurrences?: number;\n /**\n * For `source: auto` only — the captured error's parsed stack frames (#117,\n * ADR-0024), top of stack first, capped client-side. The analysis worker\n * matches them against the release's uploaded sourcemaps to write the Issue's\n * Code-area pointer.\n */\n readonly errorFrames?: readonly CapturedFrame[];\n}\n\n/**\n * What the overlay hands to {@link assembleContent} when the Reporter sends. The\n * three marking layers arrive flat (`element` / `region` / `marks`); `assembleContent`\n * folds whatever is present into the structured {@link Annotation}.\n */\nexport interface ReportDraft {\n readonly comment?: string;\n readonly element?: SelectedElement;\n readonly region?: Rect;\n readonly marks?: ReadonlyArray<Mark>;\n readonly url?: string;\n readonly environment?: CaptureEnvironment;\n readonly trace?: readonly Breadcrumb[];\n /** The Reporter's self-provided display name / email (spec §F), if the SDK holds them. */\n readonly reporterName?: string;\n readonly reporterEmail?: string;\n}\n\n/**\n * Read the capture environment off a window: the viewport size, the browser's\n * user-agent, and the SDK version. A dimension is recorded only when it is a\n * positive number (a headless/zero viewport records nothing rather than an\n * invalid `0`, which the server would reject).\n */\nexport function collectEnvironment(\n win: Window,\n sdkVersion: string,\n release?: string,\n): CaptureEnvironment {\n const env: {\n viewportWidth?: number;\n viewportHeight?: number;\n browser?: string;\n sdkVersion?: string;\n release?: string;\n } = {};\n\n const width = win.innerWidth;\n if (typeof width === \"number\" && width > 0) env.viewportWidth = Math.round(width);\n const height = win.innerHeight;\n if (typeof height === \"number\" && height > 0) {\n env.viewportHeight = Math.round(height);\n }\n\n const ua = win.navigator?.userAgent;\n if (typeof ua === \"string\" && ua.length > 0) env.browser = ua;\n\n if (sdkVersion.length > 0) env.sdkVersion = sdkVersion;\n\n // The Release, already validated at `init` (#117, ADR-0024).\n if (release && release.length > 0) env.release = release;\n\n return env;\n}\n\n/**\n * Assemble the ingest content from what the Reporter composed. Empty pieces are\n * dropped rather than sent as blanks: a whitespace-only comment, an absent\n * element, or an empty environment are simply omitted, so the payload carries\n * only what was actually provided (mirroring the server's all-optional content).\n */\nexport function assembleContent(draft: ReportDraft): ReportContent {\n const content: {\n comment?: string;\n reporterName?: string;\n reporterEmail?: string;\n url?: string;\n environment?: CaptureEnvironment;\n annotation?: Annotation;\n trace?: readonly Breadcrumb[];\n } = {};\n\n const comment = draft.comment?.trim();\n if (comment) content.comment = comment;\n\n // The Reporter's self-provided display fields ride along, trimmed; a blank is\n // dropped rather than sent, exactly as the comment is (spec §F).\n const reporterName = draft.reporterName?.trim();\n if (reporterName) content.reporterName = reporterName;\n const reporterEmail = draft.reporterEmail?.trim();\n if (reporterEmail) content.reporterEmail = reporterEmail;\n\n if (draft.url) content.url = draft.url;\n\n if (draft.environment && Object.keys(draft.environment).length > 0) {\n content.environment = draft.environment;\n }\n\n const annotation = assembleAnnotation({\n element: draft.element,\n region: draft.region,\n marks: draft.marks,\n });\n if (annotation) content.annotation = annotation;\n\n // Only a non-empty trace rides along — an empty buffer is simply omitted.\n if (draft.trace && draft.trace.length > 0) content.trace = draft.trace;\n\n return content;\n}\n","function changeJpegDpi(uint8Array, dpi) {\n uint8Array[13] = 1;\n uint8Array[14] = dpi >> 8;\n uint8Array[15] = dpi & 255;\n uint8Array[16] = dpi >> 8;\n uint8Array[17] = dpi & 255;\n return uint8Array;\n}\n\nconst _P = \"p\".charCodeAt(0);\nconst _H = \"H\".charCodeAt(0);\nconst _Y = \"Y\".charCodeAt(0);\nconst _S = \"s\".charCodeAt(0);\nlet pngDataTable;\nfunction createPngDataTable() {\n const crcTable = new Int32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;\n }\n crcTable[n] = c;\n }\n return crcTable;\n}\nfunction calcCrc(uint8Array) {\n let c = -1;\n if (!pngDataTable)\n pngDataTable = createPngDataTable();\n for (let n = 0; n < uint8Array.length; n++) {\n c = pngDataTable[(c ^ uint8Array[n]) & 255] ^ c >>> 8;\n }\n return c ^ -1;\n}\nfunction searchStartOfPhys(uint8Array) {\n const length = uint8Array.length - 1;\n for (let i = length; i >= 4; i--) {\n if (uint8Array[i - 4] === 9 && uint8Array[i - 3] === _P && uint8Array[i - 2] === _H && uint8Array[i - 1] === _Y && uint8Array[i] === _S) {\n return i - 3;\n }\n }\n return 0;\n}\nfunction changePngDpi(uint8Array, dpi, overwritepHYs = false) {\n const physChunk = new Uint8Array(13);\n dpi *= 39.3701;\n physChunk[0] = _P;\n physChunk[1] = _H;\n physChunk[2] = _Y;\n physChunk[3] = _S;\n physChunk[4] = dpi >>> 24;\n physChunk[5] = dpi >>> 16;\n physChunk[6] = dpi >>> 8;\n physChunk[7] = dpi & 255;\n physChunk[8] = physChunk[4];\n physChunk[9] = physChunk[5];\n physChunk[10] = physChunk[6];\n physChunk[11] = physChunk[7];\n physChunk[12] = 1;\n const crc = calcCrc(physChunk);\n const crcChunk = new Uint8Array(4);\n crcChunk[0] = crc >>> 24;\n crcChunk[1] = crc >>> 16;\n crcChunk[2] = crc >>> 8;\n crcChunk[3] = crc & 255;\n if (overwritepHYs) {\n const startingIndex = searchStartOfPhys(uint8Array);\n uint8Array.set(physChunk, startingIndex);\n uint8Array.set(crcChunk, startingIndex + 13);\n return uint8Array;\n } else {\n const chunkLength = new Uint8Array(4);\n chunkLength[0] = 0;\n chunkLength[1] = 0;\n chunkLength[2] = 0;\n chunkLength[3] = 9;\n const finalHeader = new Uint8Array(54);\n finalHeader.set(uint8Array, 0);\n finalHeader.set(chunkLength, 33);\n finalHeader.set(physChunk, 37);\n finalHeader.set(crcChunk, 50);\n return finalHeader;\n }\n}\nconst b64PhysSignature1 = \"AAlwSFlz\";\nconst b64PhysSignature2 = \"AAAJcEhZ\";\nconst b64PhysSignature3 = \"AAAACXBI\";\nfunction detectPhysChunkFromDataUrl(dataUrl) {\n let b64index = dataUrl.indexOf(b64PhysSignature1);\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature2);\n }\n if (b64index === -1) {\n b64index = dataUrl.indexOf(b64PhysSignature3);\n }\n return b64index;\n}\n\nconst PREFIX = \"[modern-screenshot]\";\nconst IN_BROWSER = typeof window !== \"undefined\";\nconst SUPPORT_WEB_WORKER = IN_BROWSER && \"Worker\" in window;\nconst SUPPORT_ATOB = IN_BROWSER && \"atob\" in window;\nconst SUPPORT_BTOA = IN_BROWSER && \"btoa\" in window;\nconst USER_AGENT = IN_BROWSER ? window.navigator?.userAgent : \"\";\nconst IN_CHROME = USER_AGENT.includes(\"Chrome\");\nconst IN_SAFARI = USER_AGENT.includes(\"AppleWebKit\") && !IN_CHROME;\nconst IN_FIREFOX = USER_AGENT.includes(\"Firefox\");\nconst isContext = (value) => value && \"__CONTEXT__\" in value;\nconst isCssFontFaceRule = (rule) => rule.constructor.name === \"CSSFontFaceRule\";\nconst isCSSImportRule = (rule) => rule.constructor.name === \"CSSImportRule\";\nconst isLayerBlockRule = (rule) => rule.constructor.name === \"CSSLayerBlockRule\";\nconst isElementNode = (node) => node.nodeType === 1;\nconst isSVGElementNode = (node) => typeof node.className === \"object\";\nconst isSVGImageElementNode = (node) => node.tagName === \"image\";\nconst isSVGUseElementNode = (node) => node.tagName === \"use\";\nconst isHTMLElementNode = (node) => isElementNode(node) && typeof node.style !== \"undefined\" && !isSVGElementNode(node);\nconst isCommentNode = (node) => node.nodeType === 8;\nconst isTextNode = (node) => node.nodeType === 3;\nconst isImageElement = (node) => node.tagName === \"IMG\";\nconst isVideoElement = (node) => node.tagName === \"VIDEO\";\nconst isCanvasElement = (node) => node.tagName === \"CANVAS\";\nconst isTextareaElement = (node) => node.tagName === \"TEXTAREA\";\nconst isInputElement = (node) => node.tagName === \"INPUT\";\nconst isStyleElement = (node) => node.tagName === \"STYLE\";\nconst isScriptElement = (node) => node.tagName === \"SCRIPT\";\nconst isSelectElement = (node) => node.tagName === \"SELECT\";\nconst isSlotElement = (node) => node.tagName === \"SLOT\";\nconst isIFrameElement = (node) => node.tagName === \"IFRAME\";\nconst consoleWarn = (...args) => console.warn(PREFIX, ...args);\nfunction supportWebp(ownerDocument) {\n const canvas = ownerDocument?.createElement?.(\"canvas\");\n if (canvas) {\n canvas.height = canvas.width = 1;\n }\n return Boolean(canvas) && \"toDataURL\" in canvas && Boolean(canvas.toDataURL(\"image/webp\").includes(\"image/webp\"));\n}\nconst isDataUrl = (url) => url.startsWith(\"data:\");\nfunction resolveUrl(url, baseUrl) {\n if (url.match(/^[a-z]+:\\/\\//i))\n return url;\n if (IN_BROWSER && url.match(/^\\/\\//))\n return window.location.protocol + url;\n if (url.match(/^[a-z]+:/i))\n return url;\n if (!IN_BROWSER)\n return url;\n const doc = getDocument().implementation.createHTMLDocument();\n const base = doc.createElement(\"base\");\n const a = doc.createElement(\"a\");\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl)\n base.href = baseUrl;\n a.href = url;\n return a.href;\n}\nfunction getDocument(target) {\n return (target && isElementNode(target) ? target?.ownerDocument : target) ?? window.document;\n}\nconst XMLNS = \"http://www.w3.org/2000/svg\";\nfunction createSvg(width, height, ownerDocument) {\n const svg = getDocument(ownerDocument).createElementNS(XMLNS, \"svg\");\n svg.setAttributeNS(null, \"width\", width.toString());\n svg.setAttributeNS(null, \"height\", height.toString());\n svg.setAttributeNS(null, \"viewBox\", `0 0 ${width} ${height}`);\n return svg;\n}\nfunction svgToDataUrl(svg, removeControlCharacter) {\n let xhtml = new XMLSerializer().serializeToString(svg);\n if (removeControlCharacter) {\n xhtml = xhtml.replace(/[\\u0000-\\u0008\\v\\f\\u000E-\\u001F\\uD800-\\uDFFF\\uFFFE\\uFFFF]/gu, \"\");\n }\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(xhtml)}`;\n}\nasync function canvasToBlob(canvas, type = \"image/png\", quality = 1) {\n try {\n return await new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error(\"Blob is null\"));\n }\n }, type, quality);\n });\n } catch (error) {\n if (SUPPORT_ATOB) {\n return dataUrlToBlob(canvas.toDataURL(type, quality));\n }\n throw error;\n }\n}\nfunction dataUrlToBlob(dataUrl) {\n const [header, base64] = dataUrl.split(\",\");\n const type = header.match(/data:(.+);/)?.[1] ?? void 0;\n const decoded = window.atob(base64);\n const length = decoded.length;\n const buffer = new Uint8Array(length);\n for (let i = 0; i < length; i += 1) {\n buffer[i] = decoded.charCodeAt(i);\n }\n return new Blob([buffer], { type });\n}\nfunction readBlob(blob, type) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.onabort = () => reject(new Error(`Failed read blob to ${type}`));\n if (type === \"dataUrl\") {\n reader.readAsDataURL(blob);\n } else if (type === \"arrayBuffer\") {\n reader.readAsArrayBuffer(blob);\n }\n });\n}\nconst blobToDataUrl = (blob) => readBlob(blob, \"dataUrl\");\nconst blobToArrayBuffer = (blob) => readBlob(blob, \"arrayBuffer\");\nfunction createImage(url, ownerDocument) {\n const img = getDocument(ownerDocument).createElement(\"img\");\n img.decoding = \"sync\";\n img.loading = \"eager\";\n img.src = url;\n return img;\n}\nfunction loadMedia(media, options) {\n return new Promise((resolve) => {\n const { timeout, ownerDocument, onError: userOnError, onWarn } = options ?? {};\n const node = typeof media === \"string\" ? createImage(media, getDocument(ownerDocument)) : media;\n let timer = null;\n let removeEventListeners = null;\n function onResolve() {\n resolve(node);\n timer && clearTimeout(timer);\n removeEventListeners?.();\n }\n if (timeout) {\n timer = setTimeout(onResolve, timeout);\n }\n if (isVideoElement(node)) {\n const currentSrc = node.currentSrc || node.src;\n if (!currentSrc) {\n if (node.poster) {\n return loadMedia(node.poster, options).then(resolve);\n }\n return onResolve();\n }\n if (node.readyState >= 2) {\n return onResolve();\n }\n const onLoadeddata = onResolve;\n const onError = (error) => {\n onWarn?.(\n \"Failed video load\",\n currentSrc,\n error\n );\n userOnError?.(error);\n onResolve();\n };\n removeEventListeners = () => {\n node.removeEventListener(\"loadeddata\", onLoadeddata);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"loadeddata\", onLoadeddata, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n } else {\n const currentSrc = isSVGImageElementNode(node) ? node.href.baseVal : node.currentSrc || node.src;\n if (!currentSrc) {\n return onResolve();\n }\n const onLoad = async () => {\n if (isImageElement(node) && \"decode\" in node) {\n try {\n await node.decode();\n } catch (error) {\n onWarn?.(\n \"Failed to decode image, trying to render anyway\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n }\n }\n onResolve();\n };\n const onError = (error) => {\n onWarn?.(\n \"Failed image load\",\n node.dataset.originalSrc || currentSrc,\n error\n );\n onResolve();\n };\n if (isImageElement(node) && node.complete) {\n return onLoad();\n }\n removeEventListeners = () => {\n node.removeEventListener(\"load\", onLoad);\n node.removeEventListener(\"error\", onError);\n };\n node.addEventListener(\"load\", onLoad, { once: true });\n node.addEventListener(\"error\", onError, { once: true });\n }\n });\n}\nasync function waitUntilLoad(node, options) {\n if (isHTMLElementNode(node)) {\n if (isImageElement(node) || isVideoElement(node)) {\n await loadMedia(node, options);\n } else {\n await Promise.all(\n [\"img\", \"video\"].flatMap((selectors) => {\n return Array.from(node.querySelectorAll(selectors)).map((el) => loadMedia(el, options));\n })\n );\n }\n }\n}\nconst uuid = /* @__PURE__ */ function uuid2() {\n let counter = 0;\n const random = () => `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n}();\nfunction splitFontFamily(fontFamily) {\n return fontFamily?.split(\",\").map((val) => val.trim().replace(/\"|'/g, \"\").toLowerCase()).filter(Boolean);\n}\n\nlet uid = 0;\nfunction createLogger(debug) {\n const prefix = `${PREFIX}[#${uid}]`;\n uid++;\n return {\n // eslint-disable-next-line no-console\n time: (label) => debug && console.time(`${prefix} ${label}`),\n // eslint-disable-next-line no-console\n timeEnd: (label) => debug && console.timeEnd(`${prefix} ${label}`),\n warn: (...args) => debug && consoleWarn(...args)\n };\n}\n\nfunction getDefaultRequestInit(bypassingCache) {\n return {\n cache: bypassingCache ? \"no-cache\" : \"force-cache\"\n };\n}\n\nasync function orCreateContext(node, options) {\n return isContext(node) ? node : createContext(node, { ...options, autoDestruct: true });\n}\nasync function createContext(node, options) {\n const { scale = 1, workerUrl, workerNumber = 1 } = options || {};\n const debug = Boolean(options?.debug);\n const features = options?.features ?? true;\n const ownerDocument = node.ownerDocument ?? (IN_BROWSER ? window.document : void 0);\n const ownerWindow = node.ownerDocument?.defaultView ?? (IN_BROWSER ? window : void 0);\n const requests = /* @__PURE__ */ new Map();\n const context = {\n // Options\n width: 0,\n height: 0,\n quality: 1,\n type: \"image/png\",\n scale,\n backgroundColor: null,\n style: null,\n filter: null,\n maximumCanvasSize: 0,\n timeout: 3e4,\n progress: null,\n debug,\n fetch: {\n requestInit: getDefaultRequestInit(options?.fetch?.bypassingCache),\n placeholderImage: \"data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\",\n bypassingCache: false,\n ...options?.fetch\n },\n fetchFn: null,\n font: {},\n drawImageInterval: 100,\n workerUrl: null,\n workerNumber,\n onCloneEachNode: null,\n onCloneNode: null,\n onEmbedNode: null,\n onCreateForeignObjectSvg: null,\n includeStyleProperties: null,\n autoDestruct: false,\n ...options,\n // InternalContext\n __CONTEXT__: true,\n log: createLogger(debug),\n node,\n ownerDocument,\n ownerWindow,\n dpi: scale === 1 ? null : 96 * scale,\n svgStyleElement: createStyleElement(ownerDocument),\n svgDefsElement: ownerDocument?.createElementNS(XMLNS, \"defs\"),\n svgStyles: /* @__PURE__ */ new Map(),\n defaultComputedStyles: /* @__PURE__ */ new Map(),\n workers: [\n ...Array.from({\n length: SUPPORT_WEB_WORKER && workerUrl && workerNumber ? workerNumber : 0\n })\n ].map(() => {\n try {\n const worker = new Worker(workerUrl);\n worker.onmessage = async (event) => {\n const { url, result } = event.data;\n if (result) {\n requests.get(url)?.resolve?.(result);\n } else {\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n }\n };\n worker.onmessageerror = (event) => {\n const { url } = event.data;\n requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${url}`));\n };\n return worker;\n } catch (error) {\n context.log.warn(\"Failed to new Worker\", error);\n return null;\n }\n }).filter(Boolean),\n fontFamilies: /* @__PURE__ */ new Map(),\n fontCssTexts: /* @__PURE__ */ new Map(),\n acceptOfImage: `${[\n supportWebp(ownerDocument) && \"image/webp\",\n \"image/svg+xml\",\n \"image/*\",\n \"*/*\"\n ].filter(Boolean).join(\",\")};q=0.8`,\n requests,\n drawImageCount: 0,\n tasks: [],\n features,\n isEnable: (key) => {\n if (key === \"restoreScrollPosition\") {\n return typeof features === \"boolean\" ? false : features[key] ?? false;\n }\n if (typeof features === \"boolean\") {\n return features;\n }\n return features[key] ?? true;\n },\n shadowRoots: []\n };\n context.log.time(\"wait until load\");\n await waitUntilLoad(node, { timeout: context.timeout, onWarn: context.log.warn });\n context.log.timeEnd(\"wait until load\");\n const { width, height } = resolveBoundingBox(node, context);\n context.width = width;\n context.height = height;\n return context;\n}\nfunction createStyleElement(ownerDocument) {\n if (!ownerDocument)\n return void 0;\n const style = ownerDocument.createElement(\"style\");\n const cssText = style.ownerDocument.createTextNode(`\n.______background-clip--text {\n background-clip: text;\n -webkit-background-clip: text;\n}\n`);\n style.appendChild(cssText);\n return style;\n}\nfunction resolveBoundingBox(node, context) {\n let { width, height } = context;\n if (isElementNode(node) && (!width || !height)) {\n const box = node.getBoundingClientRect();\n width = width || box.width || Number(node.getAttribute(\"width\")) || 0;\n height = height || box.height || Number(node.getAttribute(\"height\")) || 0;\n }\n return { width, height };\n}\n\nasync function imageToCanvas(image, context) {\n const {\n log,\n timeout,\n drawImageCount,\n drawImageInterval\n } = context;\n log.time(\"image to canvas\");\n const loaded = await loadMedia(image, { timeout, onWarn: context.log.warn });\n const { canvas, context2d } = createCanvas(image.ownerDocument, context);\n const drawImage = () => {\n try {\n context2d?.drawImage(loaded, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to drawImage\", error);\n }\n };\n drawImage();\n if (context.isEnable(\"fixSvgXmlDecode\")) {\n for (let i = 0; i < drawImageCount; i++) {\n await new Promise((resolve) => {\n setTimeout(() => {\n context2d?.clearRect(0, 0, canvas.width, canvas.height);\n drawImage();\n resolve();\n }, i + drawImageInterval);\n });\n }\n }\n context.drawImageCount = 0;\n log.timeEnd(\"image to canvas\");\n return canvas;\n}\nfunction createCanvas(ownerDocument, context) {\n const { width, height, scale, backgroundColor, maximumCanvasSize: max } = context;\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = Math.floor(width * scale);\n canvas.height = Math.floor(height * scale);\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n if (max) {\n if (canvas.width > max || canvas.height > max) {\n if (canvas.width > max && canvas.height > max) {\n if (canvas.width > canvas.height) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n } else if (canvas.width > max) {\n canvas.height *= max / canvas.width;\n canvas.width = max;\n } else {\n canvas.width *= max / canvas.height;\n canvas.height = max;\n }\n }\n }\n const context2d = canvas.getContext(\"2d\");\n if (context2d && backgroundColor) {\n context2d.fillStyle = backgroundColor;\n context2d.fillRect(0, 0, canvas.width, canvas.height);\n }\n return { canvas, context2d };\n}\n\nfunction cloneCanvas(canvas, context) {\n if (canvas.ownerDocument) {\n try {\n const dataURL = canvas.toDataURL();\n if (dataURL !== \"data:,\") {\n return createImage(dataURL, canvas.ownerDocument);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n }\n const cloned = canvas.cloneNode(false);\n const ctx = canvas.getContext(\"2d\");\n const clonedCtx = cloned.getContext(\"2d\");\n try {\n if (ctx && clonedCtx) {\n clonedCtx.putImageData(\n ctx.getImageData(0, 0, canvas.width, canvas.height),\n 0,\n 0\n );\n }\n return cloned;\n } catch (error) {\n context.log.warn(\"Failed to clone canvas\", error);\n }\n return cloned;\n}\n\nfunction cloneIframe(iframe, context) {\n try {\n if (iframe?.contentDocument?.documentElement) {\n return cloneNode(iframe.contentDocument.documentElement, context);\n }\n } catch (error) {\n context.log.warn(\"Failed to clone iframe\", error);\n }\n return iframe.cloneNode(false);\n}\n\nfunction cloneImage(image) {\n const cloned = image.cloneNode(false);\n if (image.currentSrc && image.currentSrc !== image.src) {\n cloned.src = image.currentSrc;\n cloned.srcset = \"\";\n }\n if (cloned.loading === \"lazy\") {\n cloned.loading = \"eager\";\n }\n return cloned;\n}\n\nasync function cloneVideo(video, context) {\n if (video.ownerDocument && !video.currentSrc && video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n const cloned = video.cloneNode(false);\n cloned.crossOrigin = \"anonymous\";\n if (video.currentSrc && video.currentSrc !== video.src) {\n cloned.src = video.currentSrc;\n }\n const ownerDocument = cloned.ownerDocument;\n if (ownerDocument) {\n let canPlay = true;\n await loadMedia(cloned, { onError: () => canPlay = false, onWarn: context.log.warn });\n if (!canPlay) {\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n cloned.currentTime = video.currentTime;\n await new Promise((resolve) => {\n cloned.addEventListener(\"seeked\", resolve, { once: true });\n });\n const canvas = ownerDocument.createElement(\"canvas\");\n canvas.width = video.offsetWidth;\n canvas.height = video.offsetHeight;\n try {\n const ctx = canvas.getContext(\"2d\");\n if (ctx)\n ctx.drawImage(cloned, 0, 0, canvas.width, canvas.height);\n } catch (error) {\n context.log.warn(\"Failed to clone video\", error);\n if (video.poster) {\n return createImage(video.poster, video.ownerDocument);\n }\n return cloned;\n }\n return cloneCanvas(canvas, context);\n }\n return cloned;\n}\n\nfunction cloneElement(node, context) {\n if (isCanvasElement(node)) {\n return cloneCanvas(node, context);\n }\n if (isIFrameElement(node)) {\n return cloneIframe(node, context);\n }\n if (isImageElement(node)) {\n return cloneImage(node);\n }\n if (isVideoElement(node)) {\n return cloneVideo(node, context);\n }\n return node.cloneNode(false);\n}\n\nfunction getSandBox(context) {\n let sandbox = context.sandbox;\n if (!sandbox) {\n const { ownerDocument } = context;\n try {\n if (ownerDocument) {\n sandbox = ownerDocument.createElement(\"iframe\");\n sandbox.id = `__SANDBOX__${uuid()}`;\n sandbox.width = \"0\";\n sandbox.height = \"0\";\n sandbox.style.visibility = \"hidden\";\n sandbox.style.position = \"fixed\";\n ownerDocument.body.appendChild(sandbox);\n sandbox.srcdoc = '<!DOCTYPE html><meta charset=\"UTF-8\"><title></title><body>';\n context.sandbox = sandbox;\n }\n } catch (error) {\n context.log.warn(\"Failed to getSandBox\", error);\n }\n }\n return sandbox;\n}\n\nconst ignoredStyles = [\n \"width\",\n \"height\",\n \"-webkit-text-fill-color\"\n];\nconst includedAttributes = [\n \"stroke\",\n \"fill\"\n];\nfunction getDefaultStyle(node, pseudoElement, context) {\n const { defaultComputedStyles } = context;\n const nodeName = node.nodeName.toLowerCase();\n const isSvgNode = isSVGElementNode(node) && nodeName !== \"svg\";\n const attributes = isSvgNode ? includedAttributes.map((name) => [name, node.getAttribute(name)]).filter(([, value]) => value !== null) : [];\n const key = [\n isSvgNode && \"svg\",\n nodeName,\n attributes.map((name, value) => `${name}=${value}`).join(\",\"),\n pseudoElement\n ].filter(Boolean).join(\":\");\n if (defaultComputedStyles.has(key))\n return defaultComputedStyles.get(key);\n const sandbox = getSandBox(context);\n const sandboxWindow = sandbox?.contentWindow;\n if (!sandboxWindow)\n return /* @__PURE__ */ new Map();\n const sandboxDocument = sandboxWindow?.document;\n let root;\n let el;\n if (isSvgNode) {\n root = sandboxDocument.createElementNS(XMLNS, \"svg\");\n el = root.ownerDocument.createElementNS(root.namespaceURI, nodeName);\n attributes.forEach(([name, value]) => {\n el.setAttributeNS(null, name, value);\n });\n root.appendChild(el);\n } else {\n root = el = sandboxDocument.createElement(nodeName);\n }\n el.textContent = \" \";\n sandboxDocument.body.appendChild(root);\n const computedStyle = sandboxWindow.getComputedStyle(el, pseudoElement);\n const styles = /* @__PURE__ */ new Map();\n for (let len = computedStyle.length, i = 0; i < len; i++) {\n const name = computedStyle.item(i);\n if (ignoredStyles.includes(name))\n continue;\n styles.set(name, computedStyle.getPropertyValue(name));\n }\n sandboxDocument.body.removeChild(root);\n defaultComputedStyles.set(key, styles);\n return styles;\n}\n\nfunction getDiffStyle(style, defaultStyle, includeStyleProperties) {\n const diffStyle = /* @__PURE__ */ new Map();\n const prefixs = [];\n const prefixTree = /* @__PURE__ */ new Map();\n if (includeStyleProperties) {\n for (const name of includeStyleProperties) {\n applyTo(name);\n }\n } else {\n for (let len = style.length, i = 0; i < len; i++) {\n const name = style.item(i);\n applyTo(name);\n }\n }\n for (let len = prefixs.length, i = 0; i < len; i++) {\n prefixTree.get(prefixs[i])?.forEach((value, name) => diffStyle.set(name, value));\n }\n function applyTo(name) {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n const subIndex = name.lastIndexOf(\"-\");\n const prefix = subIndex > -1 ? name.substring(0, subIndex) : void 0;\n if (prefix) {\n let map = prefixTree.get(prefix);\n if (!map) {\n map = /* @__PURE__ */ new Map();\n prefixTree.set(prefix, map);\n }\n map.set(name, [value, priority]);\n }\n if (defaultStyle.get(name) === value && !priority)\n return;\n if (prefix) {\n prefixs.push(prefix);\n } else {\n diffStyle.set(name, [value, priority]);\n }\n }\n return diffStyle;\n}\n\nfunction copyCssStyles(node, cloned, isRoot, context) {\n const { ownerWindow, includeStyleProperties, currentParentNodeStyle } = context;\n const clonedStyle = cloned.style;\n const computedStyle = ownerWindow.getComputedStyle(node);\n const defaultStyle = getDefaultStyle(node, null, context);\n currentParentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, includeStyleProperties);\n style.delete(\"transition-property\");\n style.delete(\"all\");\n style.delete(\"d\");\n style.delete(\"content\");\n if (isRoot) {\n style.delete(\"position\");\n style.delete(\"margin-top\");\n style.delete(\"margin-right\");\n style.delete(\"margin-bottom\");\n style.delete(\"margin-left\");\n style.delete(\"margin-block-start\");\n style.delete(\"margin-block-end\");\n style.delete(\"margin-inline-start\");\n style.delete(\"margin-inline-end\");\n style.set(\"box-sizing\", [\"border-box\", \"\"]);\n }\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n if (IN_CHROME) {\n if (!style.has(\"font-kerning\"))\n style.set(\"font-kerning\", [\"normal\", \"\"]);\n if ((style.get(\"overflow-x\")?.[0] === \"hidden\" || style.get(\"overflow-y\")?.[0] === \"hidden\") && style.get(\"text-overflow\")?.[0] === \"ellipsis\" && node.scrollWidth === node.clientWidth) {\n style.set(\"text-overflow\", [\"clip\", \"\"]);\n }\n }\n for (let len = clonedStyle.length, i = 0; i < len; i++) {\n clonedStyle.removeProperty(clonedStyle.item(i));\n }\n style.forEach(([value, priority], name) => {\n clonedStyle.setProperty(name, value, priority);\n });\n return style;\n}\n\nfunction copyInputValue(node, cloned) {\n if (isTextareaElement(node) || isInputElement(node) || isSelectElement(node)) {\n cloned.setAttribute(\"value\", node.value);\n }\n}\n\nconst pseudoClasses = [\n \"::before\",\n \"::after\"\n // '::placeholder', TODO\n];\nconst scrollbarPseudoClasses = [\n \"::-webkit-scrollbar\",\n \"::-webkit-scrollbar-button\",\n // '::-webkit-scrollbar:horizontal', TODO\n \"::-webkit-scrollbar-thumb\",\n \"::-webkit-scrollbar-track\",\n \"::-webkit-scrollbar-track-piece\",\n // '::-webkit-scrollbar:vertical', TODO\n \"::-webkit-scrollbar-corner\",\n \"::-webkit-resizer\"\n];\nfunction copyPseudoClass(node, cloned, copyScrollbar, context, addWordToFontFamilies) {\n const { ownerWindow, svgStyleElement, svgStyles, currentNodeStyle } = context;\n if (!svgStyleElement || !ownerWindow)\n return;\n function copyBy(pseudoClass) {\n const computedStyle = ownerWindow.getComputedStyle(node, pseudoClass);\n let content = computedStyle.getPropertyValue(\"content\");\n if (!content || content === \"none\")\n return;\n addWordToFontFamilies?.(content);\n content = content.replace(/(')|(\")|(counter\\(.+\\))/g, \"\");\n const klasses = [uuid()];\n const defaultStyle = getDefaultStyle(node, pseudoClass, context);\n currentNodeStyle?.forEach((_, key) => {\n defaultStyle.delete(key);\n });\n const style = getDiffStyle(computedStyle, defaultStyle, context.includeStyleProperties);\n style.delete(\"content\");\n style.delete(\"-webkit-locale\");\n if (style.get(\"background-clip\")?.[0] === \"text\") {\n cloned.classList.add(\"______background-clip--text\");\n }\n const cloneStyle = [\n `content: '${content}';`\n ];\n style.forEach(([value, priority], name) => {\n cloneStyle.push(`${name}: ${value}${priority ? \" !important\" : \"\"};`);\n });\n if (cloneStyle.length === 1)\n return;\n try {\n cloned.className = [cloned.className, ...klasses].join(\" \");\n } catch (err) {\n context.log.warn(\"Failed to copyPseudoClass\", err);\n return;\n }\n const cssText = cloneStyle.join(\"\\n \");\n let allClasses = svgStyles.get(cssText);\n if (!allClasses) {\n allClasses = [];\n svgStyles.set(cssText, allClasses);\n }\n allClasses.push(`.${klasses[0]}${pseudoClass}`);\n }\n pseudoClasses.forEach(copyBy);\n if (copyScrollbar)\n scrollbarPseudoClasses.forEach(copyBy);\n}\n\nconst excludeParentNodes = /* @__PURE__ */ new Set([\n \"symbol\"\n // test/fixtures/svg.symbol.html\n]);\nasync function appendChildNode(node, cloned, child, context, addWordToFontFamilies) {\n if (isElementNode(child) && (isStyleElement(child) || isScriptElement(child)))\n return;\n if (context.filter && !context.filter(child))\n return;\n if (excludeParentNodes.has(cloned.nodeName) || excludeParentNodes.has(child.nodeName)) {\n context.currentParentNodeStyle = void 0;\n } else {\n context.currentParentNodeStyle = context.currentNodeStyle;\n }\n const childCloned = await cloneNode(child, context, false, addWordToFontFamilies);\n if (context.isEnable(\"restoreScrollPosition\")) {\n restoreScrollPosition(node, childCloned);\n }\n cloned.appendChild(childCloned);\n}\nasync function cloneChildNodes(node, cloned, context, addWordToFontFamilies) {\n let firstChild = node.firstChild;\n if (isElementNode(node)) {\n if (node.shadowRoot) {\n firstChild = node.shadowRoot?.firstChild;\n context.shadowRoots.push(node.shadowRoot);\n }\n }\n for (let child = firstChild; child; child = child.nextSibling) {\n if (isCommentNode(child))\n continue;\n if (isElementNode(child) && isSlotElement(child) && typeof child.assignedNodes === \"function\") {\n const nodes = child.assignedNodes();\n for (let i = 0; i < nodes.length; i++) {\n await appendChildNode(node, cloned, nodes[i], context, addWordToFontFamilies);\n }\n } else {\n await appendChildNode(node, cloned, child, context, addWordToFontFamilies);\n }\n }\n}\nfunction restoreScrollPosition(node, chlidCloned) {\n if (!isHTMLElementNode(node) || !isHTMLElementNode(chlidCloned))\n return;\n const { scrollTop, scrollLeft } = node;\n if (!scrollTop && !scrollLeft) {\n return;\n }\n const { transform } = chlidCloned.style;\n const matrix = new DOMMatrix(transform);\n const { a, b, c, d } = matrix;\n matrix.a = 1;\n matrix.b = 0;\n matrix.c = 0;\n matrix.d = 1;\n matrix.translateSelf(-scrollLeft, -scrollTop);\n matrix.a = a;\n matrix.b = b;\n matrix.c = c;\n matrix.d = d;\n chlidCloned.style.transform = matrix.toString();\n}\nfunction applyCssStyleWithOptions(cloned, context) {\n const { backgroundColor, width, height, style: styles } = context;\n const clonedStyle = cloned.style;\n if (backgroundColor)\n clonedStyle.setProperty(\"background-color\", backgroundColor, \"important\");\n if (width)\n clonedStyle.setProperty(\"width\", `${width}px`, \"important\");\n if (height)\n clonedStyle.setProperty(\"height\", `${height}px`, \"important\");\n if (styles) {\n for (const name in styles) clonedStyle[name] = styles[name];\n }\n}\nconst NORMAL_ATTRIBUTE_RE = /^[\\w-:]+$/;\nasync function cloneNode(node, context, isRoot = false, addWordToFontFamilies) {\n const { ownerDocument, ownerWindow, fontFamilies, onCloneEachNode } = context;\n if (ownerDocument && isTextNode(node)) {\n if (addWordToFontFamilies && /\\S/.test(node.data)) {\n addWordToFontFamilies(node.data);\n }\n return ownerDocument.createTextNode(node.data);\n }\n if (ownerDocument && ownerWindow && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {\n const cloned2 = await cloneElement(node, context);\n if (context.isEnable(\"removeAbnormalAttributes\")) {\n const names = cloned2.getAttributeNames();\n for (let len = names.length, i = 0; i < len; i++) {\n const name = names[i];\n if (!NORMAL_ATTRIBUTE_RE.test(name)) {\n cloned2.removeAttribute(name);\n }\n }\n }\n const style = context.currentNodeStyle = copyCssStyles(node, cloned2, isRoot, context);\n if (isRoot)\n applyCssStyleWithOptions(cloned2, context);\n let copyScrollbar = false;\n if (context.isEnable(\"copyScrollbar\")) {\n const overflow = [\n style.get(\"overflow-x\")?.[0],\n style.get(\"overflow-y\")?.[0]\n ];\n copyScrollbar = overflow.includes(\"scroll\") || (overflow.includes(\"auto\") || overflow.includes(\"overlay\")) && (node.scrollHeight > node.clientHeight || node.scrollWidth > node.clientWidth);\n }\n const textTransform = style.get(\"text-transform\")?.[0];\n const families = splitFontFamily(style.get(\"font-family\")?.[0]);\n const addWordToFontFamilies2 = families ? (word) => {\n if (textTransform === \"uppercase\") {\n word = word.toUpperCase();\n } else if (textTransform === \"lowercase\") {\n word = word.toLowerCase();\n } else if (textTransform === \"capitalize\") {\n word = word[0].toUpperCase() + word.substring(1);\n }\n families.forEach((family) => {\n let fontFamily = fontFamilies.get(family);\n if (!fontFamily) {\n fontFamilies.set(family, fontFamily = /* @__PURE__ */ new Set());\n }\n word.split(\"\").forEach((text) => fontFamily.add(text));\n });\n } : void 0;\n copyPseudoClass(\n node,\n cloned2,\n copyScrollbar,\n context,\n addWordToFontFamilies2\n );\n copyInputValue(node, cloned2);\n if (!isVideoElement(node)) {\n await cloneChildNodes(\n node,\n cloned2,\n context,\n addWordToFontFamilies2\n );\n }\n await onCloneEachNode?.(cloned2);\n return cloned2;\n }\n const cloned = node.cloneNode(false);\n await cloneChildNodes(node, cloned, context);\n await onCloneEachNode?.(cloned);\n return cloned;\n}\n\nfunction destroyContext(context) {\n context.ownerDocument = void 0;\n context.ownerWindow = void 0;\n context.svgStyleElement = void 0;\n context.svgDefsElement = void 0;\n context.svgStyles.clear();\n context.defaultComputedStyles.clear();\n if (context.sandbox) {\n try {\n context.sandbox.remove();\n } catch (err) {\n context.log.warn(\"Failed to destroyContext\", err);\n }\n context.sandbox = void 0;\n }\n context.workers = [];\n context.fontFamilies.clear();\n context.fontCssTexts.clear();\n context.requests.clear();\n context.tasks = [];\n context.shadowRoots = [];\n}\n\nfunction baseFetch(options) {\n const { url, timeout, responseType, ...requestInit } = options;\n const controller = new AbortController();\n const timer = timeout ? setTimeout(() => controller.abort(), timeout) : void 0;\n return fetch(url, { signal: controller.signal, ...requestInit }).then((response) => {\n if (!response.ok) {\n throw new Error(\"Failed fetch, not 2xx response\", { cause: response });\n }\n switch (responseType) {\n case \"arrayBuffer\":\n return response.arrayBuffer();\n case \"dataUrl\":\n return response.blob().then(blobToDataUrl);\n case \"text\":\n default:\n return response.text();\n }\n }).finally(() => clearTimeout(timer));\n}\nfunction contextFetch(context, options) {\n const { url: rawUrl, requestType = \"text\", responseType = \"text\", imageDom } = options;\n let url = rawUrl;\n const {\n timeout,\n acceptOfImage,\n requests,\n fetchFn,\n fetch: {\n requestInit,\n bypassingCache,\n placeholderImage\n },\n font,\n workers,\n fontFamilies\n } = context;\n if (requestType === \"image\" && (IN_SAFARI || IN_FIREFOX)) {\n context.drawImageCount++;\n }\n let request = requests.get(rawUrl);\n if (!request) {\n if (bypassingCache) {\n if (bypassingCache instanceof RegExp && bypassingCache.test(url)) {\n url += (/\\?/.test(url) ? \"&\" : \"?\") + (/* @__PURE__ */ new Date()).getTime();\n }\n }\n const canFontMinify = requestType.startsWith(\"font\") && font && font.minify;\n const fontTexts = /* @__PURE__ */ new Set();\n if (canFontMinify) {\n const families = requestType.split(\";\")[1].split(\",\");\n families.forEach((family) => {\n if (!fontFamilies.has(family))\n return;\n fontFamilies.get(family).forEach((text) => fontTexts.add(text));\n });\n }\n const needFontMinify = canFontMinify && fontTexts.size;\n const baseFetchOptions = {\n url,\n timeout,\n responseType: needFontMinify ? \"arrayBuffer\" : responseType,\n headers: requestType === \"image\" ? { accept: acceptOfImage } : void 0,\n ...requestInit\n };\n request = {\n type: requestType,\n resolve: void 0,\n reject: void 0,\n response: null\n };\n request.response = (async () => {\n if (fetchFn && requestType === \"image\") {\n const result = await fetchFn(rawUrl);\n if (result)\n return result;\n }\n if (!IN_SAFARI && rawUrl.startsWith(\"http\") && workers.length) {\n return new Promise((resolve, reject) => {\n const worker = workers[requests.size & workers.length - 1];\n worker.postMessage({ rawUrl, ...baseFetchOptions });\n request.resolve = resolve;\n request.reject = reject;\n });\n }\n return baseFetch(baseFetchOptions);\n })().catch((error) => {\n requests.delete(rawUrl);\n if (requestType === \"image\" && placeholderImage) {\n context.log.warn(\"Failed to fetch image base64, trying to use placeholder image\", url);\n return typeof placeholderImage === \"string\" ? placeholderImage : placeholderImage(imageDom);\n }\n throw error;\n });\n requests.set(rawUrl, request);\n }\n return request.response;\n}\n\nasync function replaceCssUrlToDataUrl(cssText, baseUrl, context, isImage) {\n if (!hasCssUrl(cssText))\n return cssText;\n for (const [rawUrl, url] of parseCssUrls(cssText, baseUrl)) {\n try {\n const dataUrl = await contextFetch(\n context,\n {\n url,\n requestType: isImage ? \"image\" : \"text\",\n responseType: \"dataUrl\"\n }\n );\n cssText = cssText.replace(toRE(rawUrl), `$1${dataUrl}$3`);\n } catch (error) {\n context.log.warn(\"Failed to fetch css data url\", rawUrl, error);\n }\n }\n return cssText;\n}\nfunction hasCssUrl(cssText) {\n return /url\\((['\"]?)([^'\"]+?)\\1\\)/.test(cssText);\n}\nconst URL_RE = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nfunction parseCssUrls(cssText, baseUrl) {\n const result = [];\n cssText.replace(URL_RE, (raw, quotation, url) => {\n result.push([url, resolveUrl(url, baseUrl)]);\n return raw;\n });\n return result.filter(([url]) => !isDataUrl(url));\n}\nfunction toRE(url) {\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, \"\\\\$1\");\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, \"g\");\n}\n\nconst properties = [\n \"background-image\",\n \"border-image-source\",\n \"-webkit-border-image\",\n \"-webkit-mask-image\",\n \"list-style-image\"\n];\nfunction embedCssStyleImage(style, context) {\n return properties.map((property) => {\n const value = style.getPropertyValue(property);\n if (!value || value === \"none\") {\n return null;\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n return replaceCssUrlToDataUrl(value, null, context, true).then((newValue) => {\n if (!newValue || value === newValue)\n return;\n style.setProperty(\n property,\n newValue,\n style.getPropertyPriority(property)\n );\n });\n }).filter(Boolean);\n}\n\nfunction embedImageElement(cloned, context) {\n if (isImageElement(cloned)) {\n const originalSrc = cloned.currentSrc || cloned.src;\n if (!isDataUrl(originalSrc)) {\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.srcset = \"\";\n cloned.dataset.originalSrc = originalSrc;\n cloned.src = url || \"\";\n })\n ];\n }\n if (IN_SAFARI || IN_FIREFOX) {\n context.drawImageCount++;\n }\n } else if (isSVGElementNode(cloned) && !isDataUrl(cloned.href.baseVal)) {\n const originalSrc = cloned.href.baseVal;\n return [\n contextFetch(context, {\n url: originalSrc,\n imageDom: cloned,\n requestType: \"image\",\n responseType: \"dataUrl\"\n }).then((url) => {\n if (!url)\n return;\n cloned.dataset.originalSrc = originalSrc;\n cloned.href.baseVal = url || \"\";\n })\n ];\n }\n return [];\n}\n\nfunction embedSvgUse(cloned, context) {\n const { ownerDocument, svgDefsElement } = context;\n const href = cloned.getAttribute(\"href\") ?? cloned.getAttribute(\"xlink:href\");\n if (!href)\n return [];\n const [svgUrl, id] = href.split(\"#\");\n if (id) {\n const query = `#${id}`;\n const definition = context.shadowRoots.reduce(\n (res, root) => {\n return res ?? root.querySelector(`svg ${query}`);\n },\n ownerDocument?.querySelector(`svg ${query}`)\n );\n if (svgUrl) {\n cloned.setAttribute(\"href\", query);\n }\n if (svgDefsElement?.querySelector(query))\n return [];\n if (definition) {\n svgDefsElement?.appendChild(definition.cloneNode(true));\n return [];\n } else if (svgUrl) {\n return [\n contextFetch(context, {\n url: svgUrl,\n responseType: \"text\"\n }).then((svgData) => {\n svgDefsElement?.insertAdjacentHTML(\"beforeend\", svgData);\n })\n ];\n }\n }\n return [];\n}\n\nfunction embedNode(cloned, context) {\n const { tasks } = context;\n if (isElementNode(cloned)) {\n if (isImageElement(cloned) || isSVGImageElementNode(cloned)) {\n tasks.push(...embedImageElement(cloned, context));\n }\n if (isSVGUseElementNode(cloned)) {\n tasks.push(...embedSvgUse(cloned, context));\n }\n }\n if (isHTMLElementNode(cloned)) {\n tasks.push(...embedCssStyleImage(cloned.style, context));\n }\n cloned.childNodes.forEach((child) => {\n embedNode(child, context);\n });\n}\n\nasync function embedWebFont(clone, context) {\n const {\n ownerDocument,\n svgStyleElement,\n fontFamilies,\n fontCssTexts,\n tasks,\n font\n } = context;\n if (!ownerDocument || !svgStyleElement || !fontFamilies.size) {\n return;\n }\n if (font && font.cssText) {\n const cssText = filterPreferredFormat(font.cssText, context);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n const styleSheets = Array.from(ownerDocument.styleSheets).filter((styleSheet) => {\n try {\n return \"cssRules\" in styleSheet && Boolean(styleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(`Error while reading CSS rules from ${styleSheet.href}`, error);\n return false;\n }\n });\n const tempDoc = ownerDocument.implementation.createHTMLDocument(\"\");\n const tempStyleEl = tempDoc.createElement(\"style\");\n tempDoc.head.appendChild(tempStyleEl);\n const tempStyleSheet = tempStyleEl.sheet;\n await Promise.all(\n styleSheets.flatMap((styleSheet) => {\n return Array.from(styleSheet.cssRules).map(async (cssRule) => {\n if (isCSSImportRule(cssRule)) {\n const baseUrl = cssRule.href;\n let cssText = \"\";\n try {\n cssText = await contextFetch(context, {\n url: baseUrl,\n requestType: \"text\",\n responseType: \"text\"\n });\n } catch (error) {\n context.log.warn(`Error fetch remote css import from ${baseUrl}`, error);\n }\n const replacedCssText = cssText.replace(\n URL_RE,\n (raw, quotation, url) => raw.replace(url, resolveUrl(url, baseUrl))\n );\n for (const rule of parseCss(replacedCssText)) {\n try {\n tempStyleSheet.insertRule(rule, tempStyleSheet.cssRules.length);\n } catch (error) {\n context.log.warn(\"Error inserting rule from remote css import\", { rule, error });\n }\n }\n }\n });\n })\n );\n if (tempStyleSheet.cssRules.length)\n styleSheets.push(tempStyleSheet);\n const cssRules = [];\n styleSheets.forEach((sheet) => {\n unwrapCssLayers(sheet.cssRules, cssRules);\n });\n cssRules.filter((cssRule) => isCssFontFaceRule(cssRule) && hasCssUrl(cssRule.style.getPropertyValue(\"src\")) && splitFontFamily(cssRule.style.getPropertyValue(\"font-family\"))?.some((val) => fontFamilies.has(val))).forEach((value) => {\n const rule = value;\n const cssText = fontCssTexts.get(rule.cssText);\n if (cssText) {\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText}\n`));\n } else {\n tasks.push(\n replaceCssUrlToDataUrl(\n rule.cssText,\n rule.parentStyleSheet ? rule.parentStyleSheet.href : null,\n context\n ).then((cssText2) => {\n cssText2 = filterPreferredFormat(cssText2, context);\n fontCssTexts.set(rule.cssText, cssText2);\n svgStyleElement.appendChild(ownerDocument.createTextNode(`${cssText2}\n`));\n })\n );\n }\n });\n }\n}\nconst COMMENTS_RE = /(\\/\\*[\\s\\S]*?\\*\\/)/g;\nconst KEYFRAMES_RE = /((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})/gi;\nfunction parseCss(source) {\n if (source == null)\n return [];\n const result = [];\n let cssText = source.replace(COMMENTS_RE, \"\");\n while (true) {\n const matches = KEYFRAMES_RE.exec(cssText);\n if (!matches)\n break;\n result.push(matches[0]);\n }\n cssText = cssText.replace(KEYFRAMES_RE, \"\");\n const IMPORT_RE = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n const UNIFIED_RE = new RegExp(\n // eslint-disable-next-line\n \"((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})\",\n \"gi\"\n );\n while (true) {\n let matches = IMPORT_RE.exec(cssText);\n if (!matches) {\n matches = UNIFIED_RE.exec(cssText);\n if (!matches) {\n break;\n } else {\n IMPORT_RE.lastIndex = UNIFIED_RE.lastIndex;\n }\n } else {\n UNIFIED_RE.lastIndex = IMPORT_RE.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nconst URL_WITH_FORMAT_RE = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_RE = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction filterPreferredFormat(str, context) {\n const { font } = context;\n const preferredFormat = font ? font?.preferredFormat : void 0;\n return preferredFormat ? str.replace(FONT_SRC_RE, (match) => {\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_RE.exec(match) || [];\n if (!format)\n return \"\";\n if (format === preferredFormat)\n return `src: ${src};`;\n }\n }) : str;\n}\nfunction unwrapCssLayers(rules, out = []) {\n for (const rule of Array.from(rules)) {\n if (isLayerBlockRule(rule)) {\n out.push(...unwrapCssLayers(rule.cssRules));\n } else if (\"cssRules\" in rule) {\n unwrapCssLayers(rule.cssRules, out);\n } else {\n out.push(rule);\n }\n }\n return out;\n}\n\nconst SVG_EXTERNAL_RESOURCE_REGEX = /\\bx?link:?href\\s*=\\s*[\"'](?!data:)[^\"']+[\"']/i;\nfunction svgHasExternalResources(svg) {\n return SVG_EXTERNAL_RESOURCE_REGEX.test(svg.innerHTML);\n}\nasync function domToForeignObjectSvg(node, options) {\n const context = await orCreateContext(node, options);\n if (isElementNode(context.node) && isSVGElementNode(context.node) && !svgHasExternalResources(context.node))\n return context.node;\n const {\n ownerDocument,\n log,\n tasks,\n svgStyleElement,\n svgDefsElement,\n svgStyles,\n font,\n progress,\n autoDestruct,\n onCloneNode,\n onEmbedNode,\n onCreateForeignObjectSvg\n } = context;\n log.time(\"clone node\");\n const clone = await cloneNode(context.node, context, true);\n if (svgStyleElement && ownerDocument) {\n let allCssText = \"\";\n svgStyles.forEach((klasses, cssText) => {\n allCssText += `${klasses.join(\",\\n\")} {\n ${cssText}\n}\n`;\n });\n svgStyleElement.appendChild(ownerDocument.createTextNode(allCssText));\n }\n log.timeEnd(\"clone node\");\n await onCloneNode?.(clone);\n if (font !== false && isElementNode(clone)) {\n log.time(\"embed web font\");\n await embedWebFont(clone, context);\n log.timeEnd(\"embed web font\");\n }\n log.time(\"embed node\");\n embedNode(clone, context);\n const count = tasks.length;\n let current = 0;\n const runTask = async () => {\n while (true) {\n const task = tasks.pop();\n if (!task)\n break;\n try {\n await task;\n } catch (error) {\n context.log.warn(\"Failed to run task\", error);\n }\n progress?.(++current, count);\n }\n };\n progress?.(current, count);\n await Promise.all([...Array.from({ length: 4 })].map(runTask));\n log.timeEnd(\"embed node\");\n await onEmbedNode?.(clone);\n const svg = createForeignObjectSvg(clone, context);\n svgDefsElement && svg.insertBefore(svgDefsElement, svg.children[0]);\n svgStyleElement && svg.insertBefore(svgStyleElement, svg.children[0]);\n autoDestruct && destroyContext(context);\n await onCreateForeignObjectSvg?.(svg);\n return svg;\n}\nfunction createForeignObjectSvg(clone, context) {\n const { width, height } = context;\n const svg = createSvg(width, height, clone.ownerDocument);\n const foreignObject = svg.ownerDocument.createElementNS(svg.namespaceURI, \"foreignObject\");\n foreignObject.setAttributeNS(null, \"x\", \"0%\");\n foreignObject.setAttributeNS(null, \"y\", \"0%\");\n foreignObject.setAttributeNS(null, \"width\", \"100%\");\n foreignObject.setAttributeNS(null, \"height\", \"100%\");\n foreignObject.append(clone);\n svg.appendChild(foreignObject);\n return svg;\n}\n\nasync function domToCanvas(node, options) {\n const context = await orCreateContext(node, options);\n const svg = await domToForeignObjectSvg(context);\n const dataUrl = svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n if (!context.autoDestruct) {\n context.svgStyleElement = createStyleElement(context.ownerDocument);\n context.svgDefsElement = context.ownerDocument?.createElementNS(XMLNS, \"defs\");\n context.svgStyles.clear();\n }\n const image = createImage(dataUrl, svg.ownerDocument);\n return await imageToCanvas(image, context);\n}\n\nasync function domToBlob(node, options) {\n const context = await orCreateContext(node, options);\n const { log, type, quality, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to blob\");\n const blob = await canvasToBlob(canvas, type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi) {\n const arrayBuffer = await blobToArrayBuffer(blob.slice(0, 33));\n let uint8Array = new Uint8Array(arrayBuffer);\n if (type === \"image/png\") {\n uint8Array = changePngDpi(uint8Array, dpi);\n } else if (type === \"image/jpeg\") {\n uint8Array = changeJpegDpi(uint8Array, dpi);\n }\n log.timeEnd(\"canvas to blob\");\n return new Blob([uint8Array, blob.slice(33)], { type });\n }\n log.timeEnd(\"canvas to blob\");\n return blob;\n}\n\nasync function domToDataUrl(node, options) {\n const context = await orCreateContext(node, options);\n const { log, quality, type, dpi } = context;\n const canvas = await domToCanvas(context);\n log.time(\"canvas to data url\");\n let dataUrl = canvas.toDataURL(type, quality);\n if ([\"image/png\", \"image/jpeg\"].includes(type) && dpi && SUPPORT_ATOB && SUPPORT_BTOA) {\n const [format, body] = dataUrl.split(\",\");\n let headerLength = 0;\n let overwritepHYs = false;\n if (type === \"image/png\") {\n const b64Index = detectPhysChunkFromDataUrl(body);\n if (b64Index >= 0) {\n headerLength = Math.ceil((b64Index + 28) / 3) * 4;\n overwritepHYs = true;\n } else {\n headerLength = 33 / 3 * 4;\n }\n } else if (type === \"image/jpeg\") {\n headerLength = 18 / 3 * 4;\n }\n const stringHeader = body.substring(0, headerLength);\n const restOfData = body.substring(headerLength);\n const headerBytes = window.atob(stringHeader);\n const uint8Array = new Uint8Array(headerBytes.length);\n for (let i = 0; i < uint8Array.length; i++) {\n uint8Array[i] = headerBytes.charCodeAt(i);\n }\n const finalArray = type === \"image/png\" ? changePngDpi(uint8Array, dpi, overwritepHYs) : changeJpegDpi(uint8Array, dpi);\n const base64Header = window.btoa(String.fromCharCode(...finalArray));\n dataUrl = [format, \",\", base64Header, restOfData].join(\"\");\n }\n log.timeEnd(\"canvas to data url\");\n return dataUrl;\n}\n\nasync function domToSvg(node, options) {\n const context = await orCreateContext(node, options);\n const { width, height, ownerDocument } = context;\n const dataUrl = await domToDataUrl(context);\n const svg = createSvg(width, height, ownerDocument);\n const svgImage = svg.ownerDocument.createElementNS(svg.namespaceURI, \"image\");\n svgImage.setAttributeNS(null, \"href\", dataUrl);\n svgImage.setAttributeNS(null, \"height\", \"100%\");\n svgImage.setAttributeNS(null, \"width\", \"100%\");\n svg.appendChild(svgImage);\n return svgToDataUrl(svg, context.isEnable(\"removeControlCharacter\"));\n}\n\nasync function domToImage(node, options) {\n const context = await orCreateContext(node, options);\n const { ownerDocument, width, height, scale, type } = context;\n const url = type === \"image/svg+xml\" ? await domToSvg(context) : await domToDataUrl(context);\n const image = createImage(url, ownerDocument);\n image.width = Math.floor(width * scale);\n image.height = Math.floor(height * scale);\n image.style.width = `${width}px`;\n image.style.height = `${height}px`;\n return image;\n}\n\nasync function domToJpeg(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/jpeg\" })\n );\n}\n\nasync function domToPixel(node, options) {\n const context = await orCreateContext(node, options);\n const canvas = await domToCanvas(context);\n return canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height).data;\n}\n\nasync function domToPng(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/png\" })\n );\n}\n\nasync function domToWebp(node, options) {\n return domToDataUrl(\n await orCreateContext(node, { ...options, type: \"image/webp\" })\n );\n}\n\nexport { createContext, destroyContext, domToBlob, domToCanvas, domToDataUrl, domToForeignObjectSvg, domToImage, domToJpeg, domToPixel, domToPng, domToSvg, domToWebp, loadMedia, waitUntilLoad };\n","import { domToBlob } from \"modern-screenshot\";\n\nimport { isFixbackHostElement } from \"./dom\";\n\n/**\n * Client-side masked screenshot capture (spec MVP §E; ticket #54; ADR-0014).\n *\n * The capture is **private-by-default**: input values are masked and the SDK's own\n * UI is excluded from a *clone* of the view **before** anything is rasterised, so no\n * unmasked text and none of Fixback's chrome ever reaches the image.\n *\n * The rasterisation itself is delegated to `modern-screenshot` (ADR-0014): it clones\n * the target, inlines the page's real styles **and** its fonts and images as data\n * URIs, then draws the result through an SVG `<foreignObject>` onto a `<canvas>`.\n * That closes the fidelity gap a hand-rolled `<foreignObject>` left open — external\n * stylesheets, web fonts, and same-origin images now render — so the shot matches\n * what the Reporter saw and lines up with the annotation's viewport-space marks.\n *\n * We keep the privacy guarantee by driving it through two of its hooks: `filter`\n * drops Fixback's own host elements, and `onCloneNode` masks the clone's inputs —\n * both run on the library's internal clone, before it embeds or serialises anything,\n * so the live page is never touched and no real value reaches the raster. The backend\n * is injectable so the pipeline (and the masking-before-capture guarantee) is testable\n * without a real canvas, and it fails quietly: any problem resolves to `null` and the\n * report is simply sent without a screenshot.\n */\n\n/** The character private input content is replaced with. */\nexport const MASK_CHAR = \"•\";\n\n/** Upper bound on mask length, so a huge field doesn't produce a huge string. */\nconst MAX_MASK_LENGTH = 32;\n\n/** Input `type`s that carry no free-text private data, so are left as-is. */\nconst NON_TEXT_INPUT_TYPES = new Set([\n \"button\",\n \"submit\",\n \"reset\",\n \"checkbox\",\n \"radio\",\n \"range\",\n \"color\",\n \"file\",\n \"image\",\n \"hidden\",\n]);\n\nfunction maskString(length: number): string {\n const n = Math.min(Math.max(length, 1), MAX_MASK_LENGTH);\n return MASK_CHAR.repeat(n);\n}\n\n/**\n * Mask the private, user-entered content in a subtree: text `input` values,\n * `textarea` content, and `contenteditable` text. Developer-authored text\n * (placeholders, button labels, non-text controls) is left untouched. Operates in\n * place — call it on a *clone* of the view, never the live page.\n */\nexport function maskInputs(root: ParentNode): void {\n for (const input of Array.from(root.querySelectorAll(\"input\"))) {\n const type = (input.getAttribute(\"type\") ?? \"text\").toLowerCase();\n if (NON_TEXT_INPUT_TYPES.has(type)) continue;\n const value = input.value;\n if (!value) continue;\n const masked = maskString(value.length);\n input.value = masked;\n input.setAttribute(\"value\", masked);\n }\n\n for (const area of Array.from(root.querySelectorAll(\"textarea\"))) {\n const value = area.value || area.textContent || \"\";\n if (!value) continue;\n const masked = maskString(value.length);\n area.value = masked;\n area.textContent = masked;\n // A `<textarea>` has no `value` attribute of its own, but the raster backend\n // (modern-screenshot) mirrors the live `value` onto one when it clones. Mask\n // that too, so the un-rendered attribute can't carry the real text into the\n // serialised DOM the rasteriser consumes.\n area.setAttribute(\"value\", masked);\n }\n\n for (const editable of Array.from(\n root.querySelectorAll<HTMLElement>(\"[contenteditable]\"),\n )) {\n if (editable.getAttribute(\"contenteditable\") === \"false\") continue;\n const text = editable.textContent ?? \"\";\n if (!text.trim()) continue;\n editable.textContent = maskString(text.length);\n }\n}\n\n/** A captured screenshot: the image bytes plus its dimensions and content type. */\nexport interface Capture {\n readonly blob: Blob;\n readonly width: number;\n readonly height: number;\n readonly type: string;\n}\n\n/** Content type → screenshot file extension. */\nconst SCREENSHOT_EXTENSIONS: Readonly<Record<string, string>> = {\n \"image/png\": \"png\",\n \"image/jpeg\": \"jpg\",\n \"image/webp\": \"webp\",\n \"image/gif\": \"gif\",\n};\n\n/** The screenshot filename extension for a {@link Capture}'s content type (defaults to `png`). */\nexport function extensionFor(type: string): string {\n return SCREENSHOT_EXTENSIONS[type] ?? \"png\";\n}\n\n/** How the SDK prepares a capture: exclude Fixback's UI, mask the clone's inputs. */\ninterface CaptureHooks {\n /** Keep a node in the shot? Returns `false` for Fixback's own host elements. */\n readonly filter: (node: Node) => boolean;\n /** Mask private input content on the library's internal clone, pre-raster. */\n readonly onCloneNode: (clone: Node) => void;\n}\n\n/** Turns a DOM subtree into image bytes at a given size (injectable for tests). */\nexport type CaptureBackend = (\n target: Element,\n meta: { width: number; height: number; type: string } & CaptureHooks,\n) => Promise<Blob | null>;\n\n/** Options for {@link captureView}. */\nexport interface CaptureOptions {\n /** The element to capture. Defaults to the document element (the full view). */\n readonly target?: Element;\n readonly doc?: Document;\n readonly win?: Window;\n /** Output content type. Defaults to `image/png`. */\n readonly type?: string;\n /** Override the raster backend (the default is `modern-screenshot`). */\n readonly capture?: CaptureBackend;\n}\n\nfunction viewportExtent(\n win: Window | undefined,\n doc: Document,\n axis: \"Width\" | \"Height\",\n): number {\n const inner = win?.[`inner${axis}`];\n const client = doc.documentElement[`client${axis}`];\n const value = typeof inner === \"number\" && inner > 0 ? inner : client;\n return Math.max(1, Math.round(value || 0) || 1);\n}\n\n/** Load media + fetch remote assets timeout — bound the raster so a stuck font\n * or image can't hang the Send. Capture is best-effort: a timeout still yields\n * whatever embedded in time. */\nconst CAPTURE_TIMEOUT_MS = 6000;\n\n/**\n * The default backend: `modern-screenshot`, wired to the privacy hooks. `filter`\n * excludes Fixback's own chrome, `onCloneNode` masks the internal clone's inputs\n * before any embed/serialise, and `width`/`height` pin the raster to the viewport so\n * it shares the annotation marks' coordinate space. Any throw propagates to\n * {@link captureView}'s guard, which resolves it to `null`.\n */\nconst captureViaModernScreenshot: CaptureBackend = (target, meta) =>\n domToBlob(target, {\n width: meta.width,\n height: meta.height,\n type: meta.type,\n timeout: CAPTURE_TIMEOUT_MS,\n filter: meta.filter,\n onCloneNode: meta.onCloneNode,\n });\n\n/**\n * Capture the current view as a masked screenshot. Delegates the raster to the\n * backend ({@link captureViaModernScreenshot} by default), which excludes the SDK's\n * own UI and masks input values on its internal clone — **before** it embeds or\n * serialises anything — then returns the image bytes, or `null` if capture wasn't\n * possible.\n */\nexport async function captureView(\n options: CaptureOptions = {},\n): Promise<Capture | null> {\n try {\n const doc = options.doc ?? document;\n const win = options.win ?? doc.defaultView ?? undefined;\n const target = options.target ?? doc.documentElement;\n const type = options.type ?? \"image/png\";\n const width = viewportExtent(win, doc, \"Width\");\n const height = viewportExtent(win, doc, \"Height\");\n\n const capture = options.capture ?? captureViaModernScreenshot;\n const blob = await capture(target, {\n width,\n height,\n type,\n filter: (node) => !isFixbackHostElement(node),\n onCloneNode: (clone) => maskInputs(clone as ParentNode),\n });\n if (!blob) return null;\n return { blob, width, height, type };\n } catch {\n return null;\n }\n}\n","/**\n * Client-side backpressure for **automatic** error reports (spec 0003 §E/§H,\n * ticket #89). When ingest sheds `source: auto` load it answers `429` with a\n * `Retry-After`; the SDK honours it by holding a pause window during which further\n * `source: auto` reports are dropped without touching the network. **Manual**\n * reports — a human clicking Send — never consult this gate.\n *\n * This is the transport's counterpart to the server's per-Project token bucket\n * (`apps/api/src/ingest/auto-report-rate-limiter.ts`): one shared window per page,\n * so a 429 from one auto-report shed applies to the auto-reports that follow it.\n * The clock is injectable so the window is unit-tested deterministically, never on\n * wall time — mirroring the server limiter's `Clock`.\n */\n\n/** A source of the current time in epoch milliseconds — injectable for tests. */\nexport type Clock = () => number;\n\n/** The hold window applied when a `429` carries no usable `Retry-After` (spec §E). */\nexport const DEFAULT_RETRY_AFTER_SECONDS = 60;\n\n/**\n * Parse a `Retry-After` header into whole seconds to hold for. Handles both HTTP\n * forms — a delta-seconds integer and an HTTP-date (measured from `now`, rounded up\n * and clamped at zero) — and falls back to {@link DEFAULT_RETRY_AFTER_SECONDS} when\n * the header is absent, blank, or unparseable. Ingest sends the delta-seconds form;\n * the date form is handled for spec-completeness.\n */\nexport function parseRetryAfter(\n header: string | null | undefined,\n now: number,\n): number {\n if (header == null) return DEFAULT_RETRY_AFTER_SECONDS;\n const value = header.trim();\n if (value === \"\") return DEFAULT_RETRY_AFTER_SECONDS;\n\n if (/^\\d+$/.test(value)) {\n return Number(value);\n }\n\n const when = Date.parse(value);\n if (!Number.isNaN(when)) {\n return Math.max(0, Math.ceil((when - now) / 1000));\n }\n\n return DEFAULT_RETRY_AFTER_SECONDS;\n}\n\n/**\n * A single pause window for `source: auto` reports. `hold` opens (or extends) it\n * from a `429`'s `Retry-After`; `isPaused` reports whether it is still open. The\n * default instance in `submit.ts` is shared across a page's reports so the hold\n * persists across successive auto submissions.\n */\nexport class AutoReportBackoff {\n /** Epoch ms until which `source: auto` reports are held; `0` when clear. */\n private pausedUntil = 0;\n\n constructor(private readonly now: Clock = Date.now) {}\n\n /** Is the `source: auto` pause window currently open? */\n isPaused(): boolean {\n return this.now() < this.pausedUntil;\n }\n\n /** Whole seconds remaining in the pause window (`0` when clear). */\n retryAfterSeconds(): number {\n return Math.max(0, Math.ceil((this.pausedUntil - this.now()) / 1000));\n }\n\n /**\n * Open (or extend) the window from a `429`'s `Retry-After` value, returning the\n * seconds it will hold for. The window only ever grows — a shorter later hold\n * never clips a longer one already in effect.\n */\n hold(retryAfterHeader: string | null | undefined): number {\n const now = this.now();\n const seconds = parseRetryAfter(retryAfterHeader, now);\n const until = now + seconds * 1000;\n if (until > this.pausedUntil) this.pausedUntil = until;\n return seconds;\n }\n}\n","import { AutoReportBackoff } from \"./auto-report-backoff\";\nimport type { IdentityInputs, ReporterTier } from \"./boot\";\nimport type { FeedbackSource, ReportContent } from \"./report\";\n\n/**\n * The multipart feedback submission — the transport half of the capture loop.\n *\n * `POST /api/ingest/feedback` (spec MVP §C; tickets #50/#53) is a multipart\n * request: a single text part `payload` carrying the JSON (publishable key +\n * identity evidence + content) and optional binary parts `screenshot` and\n * `replay` (the buffered rrweb window, ADR-0024). The\n * content-type header is deliberately not set, so the runtime writes the\n * `multipart/form-data` boundary itself. Like `requestBoot`, this never throws:\n * an unreachable Fixback or a refusal is a quiet result, so a Fixback problem\n * never breaks the host page.\n *\n * The `payload` carries the full report content — the structured `annotation`\n * (element + region + marks), the masked `trace` buffer, and the `source`\n * provenance (spec §D); the `screenshot` part is the full masked PNG, never\n * region-cropped. Automatic reports (`source: auto`) additionally honour ingest's\n * `429` + `Retry-After` backpressure: while the hold window is open they are\n * dropped without touching the network. Manual reports are never gated (spec §E/§H).\n */\n\n/** The multipart field the screenshot binary is sent under (mirrors the server). */\nconst SCREENSHOT_FIELD = \"screenshot\";\n\n/**\n * The multipart field the replay window is sent under (mirrors the server). A\n * **file part**, deliberately not a field inside `payload`: rrweb events dwarf\n * the JSON payload, and multipart text fields are size-capped far below what a\n * DOM recording needs (ADR-0024).\n */\nconst REPLAY_FIELD = \"replay\";\n\n/** What ingest returns for an accepted submission (vendored server shape). */\nexport interface RecordedFeedback {\n readonly feedbackId: string;\n readonly issueId: string;\n readonly reporterId: string;\n readonly tier: ReporterTier;\n}\n\n/** The captured screenshot to attach, if any. */\nexport interface SubmitScreenshot {\n readonly blob: Blob;\n readonly filename?: string;\n}\n\n/**\n * The buffered replay window to attach, if any — the rrweb events a\n * `ReplaySnapshot` holds (replay.ts). Serialized into its own binary part.\n */\nexport interface SubmitReplay {\n readonly events: readonly unknown[];\n}\n\n/** Everything a single feedback submission carries. */\nexport interface SubmitInput {\n readonly key: string;\n readonly identity?: IdentityInputs;\n readonly content: ReportContent;\n readonly screenshot?: SubmitScreenshot | null;\n readonly replay?: SubmitReplay | null;\n}\n\n/** The outcome of a submission — never an exception. */\nexport type SubmitResult =\n | { readonly ok: true; readonly feedback: RecordedFeedback | null }\n | {\n readonly ok: false;\n readonly reason: \"unreachable\" | \"refused\";\n readonly status?: number;\n }\n | {\n /**\n * A `source: auto` report shed under ingest backpressure (spec §E/§H) — either\n * held locally because the window is still open, or answered `429` by ingest,\n * which opened/extended the window. Carries the seconds left to wait. Manual\n * reports never produce this.\n */\n readonly ok: false;\n readonly reason: \"backpressure\";\n readonly retryAfterSeconds: number;\n };\n\n/**\n * The shared `source: auto` backpressure window for the page. One instance so a\n * `429` from an auto-report holds the auto-reports that follow it; tests inject\n * their own {@link AutoReportBackoff} to isolate the clock.\n */\nconst defaultBackoff = new AutoReportBackoff();\n\n/** Join an API base URL with the feedback path, tolerating a trailing slash. */\nexport function feedbackEndpoint(apiUrl: string): string {\n return `${apiUrl.replace(/\\/+$/, \"\")}/api/ingest/feedback`;\n}\n\n/** Drop `undefined` identity fields so the payload carries only what was given. */\nfunction compactIdentity(identity: IdentityInputs | undefined): IdentityInputs {\n if (!identity) return {};\n const out: { signedIdentity?: string; reporterId?: string; anonymousId?: string } = {};\n if (identity.signedIdentity) out.signedIdentity = identity.signedIdentity;\n if (identity.reporterId) out.reporterId = identity.reporterId;\n if (identity.anonymousId) out.anonymousId = identity.anonymousId;\n return out;\n}\n\n/**\n * Submit a report to ingest. Assembles the `payload` JSON (key + identity +\n * content, with an explicit `source` stamped) and the optional full masked\n * `screenshot` file into a `FormData`, posts it, and resolves to the recorded\n * Feedback on success or a named failure otherwise.\n *\n * A `source: auto` report first consults the shared backpressure window: while it\n * is open the report is dropped without a request (spec §E/§H). Ingest's `429` +\n * `Retry-After` opens/extends that window (default 60 s if the header is absent).\n * Manual reports (`source: reporter`, the default) never consult the window and a\n * non-2xx for them stays a plain refusal. The `fetchImpl` and `backoff` seams exist\n * purely so the call is testable.\n */\nexport async function submitReport(\n apiUrl: string,\n input: SubmitInput,\n fetchImpl: typeof fetch = fetch,\n backoff: AutoReportBackoff = defaultBackoff,\n): Promise<SubmitResult> {\n const source: FeedbackSource = input.content.source ?? \"reporter\";\n const isAuto = source === \"auto\";\n\n // Client-side backpressure: shed auto-reports while the hold window is open,\n // without touching the network. Manual reports are never gated.\n if (isAuto && backoff.isPaused()) {\n return {\n ok: false,\n reason: \"backpressure\",\n retryAfterSeconds: backoff.retryAfterSeconds(),\n };\n }\n\n const payload = {\n key: input.key,\n ...compactIdentity(input.identity),\n ...input.content,\n source,\n };\n\n const form = new FormData();\n form.append(\"payload\", JSON.stringify(payload));\n if (input.screenshot?.blob) {\n form.append(\n SCREENSHOT_FIELD,\n input.screenshot.blob,\n input.screenshot.filename ?? \"screenshot.png\",\n );\n }\n if (input.replay && input.replay.events.length > 0) {\n // Serialization can throw on exotic event content; a report must still ship\n // without its replay rather than not at all.\n try {\n const json = JSON.stringify(input.replay.events);\n form.append(\n REPLAY_FIELD,\n new Blob([json], { type: \"application/json\" }),\n \"replay.json\",\n );\n } catch {\n // Ship the report without replay.\n }\n }\n\n let response: Response;\n try {\n response = await fetchImpl(feedbackEndpoint(apiUrl), {\n method: \"POST\",\n body: form,\n });\n } catch {\n return { ok: false, reason: \"unreachable\" };\n }\n\n if (!response.ok) {\n // A `429` for an auto-report is backpressure, not a refusal: open/extend the\n // hold window from `Retry-After` and report the wait. Manual reports never 429\n // here, so any non-2xx for them stays a plain refusal.\n if (isAuto && response.status === 429) {\n const retryAfterSeconds = backoff.hold(response.headers.get(\"Retry-After\"));\n return { ok: false, reason: \"backpressure\", retryAfterSeconds };\n }\n return { ok: false, reason: \"refused\", status: response.status };\n }\n\n try {\n const feedback = (await response.json()) as RecordedFeedback;\n return { ok: true, feedback };\n } catch {\n // Accepted, but the body wasn't the expected JSON — still a success.\n return { ok: true, feedback: null };\n }\n}\n","/**\n * The SDK's own version string, reported to ingest as `environment.sdkVersion`\n * (spec MVP §B/§E). Kept as an inlined constant rather than a runtime `package.json`\n * import, so the published bundle stays a single self-contained file.\n *\n * It must equal `package.json`'s `version`. Two things keep it there: the Changesets\n * `version` step syncs it automatically (`scripts/sync-sdk-version.mjs`, wired into\n * `version-packages`), and `version.test.ts` fails the build if the two ever drift —\n * so a stale dogfood version (the SDK reporting an old number on our own dashboard)\n * can't slip through. Do not hand-edit this line to a value other than\n * `package.json`'s version.\n */\nexport const SDK_VERSION = \"0.4.0\";\n","/**\n * Automatic error capture — the SDK's signature capability: **errors report\n * themselves, no prompt** (spec 0003 §E, ADR-0011; research\n * `sentry-error-capture-findings.md` §7.1–7.3, §7.6).\n *\n * Exactly **two capture-phase listeners** (`window` `error` +\n * `unhandledrejection`) turn uncaught exceptions and unhandled rejections into\n * `source: auto` Feedback (stamped `Kind = bug` server-side, ADR-0023) for the current session's Reporter — no\n * native-API monkeypatching, no library. Each firing is deduped by a per-session\n * fingerprint, rate-limited by a token-bucket burst limiter and a per-session cap,\n * scrubbed through the same `beforeSend` choke point as manual reports (§C), and\n * shipped through the same transport (which honours ingest's `429` / `Retry-After`\n * backpressure, ticket #89). `console.error` is **not** promoted — it stays\n * breadcrumb-only Evidence.\n *\n * Per-firing order (research §7.1): **`canSubmit`/Gate → dedup → rate-limit/cap →\n * `beforeSend` scrub → enqueue Feedback**. The Gate is honoured by construction:\n * `init` installs this only when boot returned `canSubmit`, so an auto-error is\n * never filed where a manual report would be refused, and it inherits the session\n * Reporter's server-derived tier.\n *\n * The whole module is defensive — every handler is wrapped so a Fixback problem\n * (or an error thrown while capturing an error) never surfaces on the host page.\n * The fingerprint/`normalize` shape and the limiter numbers are **starting points**\n * from research (ticket #92), exposed as config — tunable, not frozen.\n */\n\nimport type { IdentityInputs } from \"./boot\";\nimport {\n type Breadcrumb,\n type BreadcrumbBuffer,\n errorCrumb,\n type Teardown,\n} from \"./breadcrumbs\";\nimport type { ReporterDisplay } from \"./invite\";\nimport {\n assembleContent,\n collectEnvironment,\n type CapturedFrame,\n type ReportContent,\n} from \"./report\";\nimport type { ReplaySource } from \"./replay\";\nimport { runBeforeSend, scrubUrl, type BeforeSend } from \"./scrub\";\nimport { captureView, extensionFor, type Capture, type CaptureOptions } from \"./screenshot\";\nimport { submitReport, type SubmitInput, type SubmitResult } from \"./submit\";\nimport { SDK_VERSION } from \"./version\";\n\nexport type { Teardown };\n\n/** Burst limiter capacity — how many auto-reports may fire back-to-back (§E). */\nexport const DEFAULT_BURST_CAPACITY = 5;\n/** Burst limiter refill — one token returns every this-many ms (§E). */\nexport const DEFAULT_BURST_REFILL_MS = 2_000;\n/** Per-session ceiling on distinct auto-Feedback; beyond it, only a dropped-count (§E). */\nexport const DEFAULT_MAX_DISTINCT_AUTO = 20;\n\n/** How many top stack frames feed the fingerprint (research §7.2). */\nconst FINGERPRINT_FRAME_LIMIT = 5;\n\n/** How many preceding entries an auto-error's causal pointer names (spec #122 §F). */\nconst CAUSED_BY_LIMIT = 5;\n\n/**\n * The ids of up to the last {@link CAUSED_BY_LIMIT} entries preceding the throw, in\n * time order — the causal pointer an auto-captured error carries (spec #122 §F), so a\n * machine-filed crash names its lead-up. Entries without an id are skipped.\n */\nfunction precedingIds(entries: readonly Breadcrumb[] | undefined): string[] {\n if (!entries || entries.length === 0) return [];\n const ids: string[] = [];\n for (let i = entries.length - 1; i >= 0 && ids.length < CAUSED_BY_LIMIT; i -= 1) {\n const id = entries[i]?.id;\n if (typeof id === \"string\" && id.length > 0) ids.unshift(id);\n }\n return ids;\n}\n\n// --- Fingerprint (per-session flood-guard key, research §7.2) -----------------\n\nconst UUID_RE =\n /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;\nconst URL_RE = /\\bhttps?:\\/\\/[^\\s\"')]+/gi;\nconst HEX_0X_RE = /\\b0x[0-9a-f]+\\b/gi;\nconst HEX_RUN_RE = /\\b[0-9a-f]{8,}\\b/gi;\nconst DIGIT_RUN_RE = /\\d{4,}/g;\n\n/**\n * Collapse the volatile parts of an error message so a changing string doesn't\n * split one bug: UUIDs, URLs, `0x…` and long hex runs, and long digit runs are\n * replaced with stable placeholders. Short numbers and stable text are kept so\n * genuinely distinct bugs stay distinct. A small, dependency-free regex set —\n * tunable per ticket #92, never a frozen magic set.\n */\nexport function normalize(value: string): string {\n if (typeof value !== \"string\" || value.length === 0) return \"\";\n return value\n .replace(UUID_RE, \"<uuid>\")\n .replace(URL_RE, \"<url>\")\n .replace(HEX_0X_RE, \"<hex>\")\n .replace(HEX_RUN_RE, \"<hex>\")\n .replace(DIGIT_RUN_RE, \"<n>\")\n .trim();\n}\n\n/**\n * A dependency-free FNV-1a hash rendered in base-36. It only has to be stable and\n * well-distributed within one session (the client key is a flood guard; the server\n * does canonical cross-session clustering), so a non-cryptographic hash is right.\n */\nexport function hashString(input: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(36);\n}\n\n/** Reduce a frame location to `basename:line:col`, dropping origin and query. */\nfunction compactLocation(location: string): string {\n const noQuery = location.replace(/\\?[^:]*/, \"\");\n const lastSlash = noQuery.lastIndexOf(\"/\");\n return lastSlash >= 0 ? noQuery.slice(lastSlash + 1) : noQuery;\n}\n\n/** Parse one stack line into a compact `function@basename:line:col` frame id. */\nfunction parseFrame(line: string): string | null {\n // V8: \"at fn (loc)\" | \"at loc\"\n const v8Named = line.match(/^at\\s+(.+?)\\s+\\((.+)\\)$/);\n if (v8Named) return `${v8Named[1] ?? \"\"}@${compactLocation(v8Named[2] ?? \"\")}`;\n const v8Bare = line.match(/^at\\s+(.+)$/);\n if (v8Bare) return `@${compactLocation(v8Bare[1] ?? \"\")}`;\n // Firefox / Safari: \"fn@loc\" | \"@loc\"\n const at = line.indexOf(\"@\");\n if (at >= 0) {\n const fn = line.slice(0, at);\n return `${fn}@${compactLocation(line.slice(at + 1))}`;\n }\n return null;\n}\n\n/**\n * Extract a compact, stable signature of the top in-app frames of a stack: up to\n * {@link FINGERPRINT_FRAME_LIMIT} frames as `function@basename:line:col`, origin\n * and cache-busting query stripped so a per-deploy asset hash doesn't matter within\n * a session. Returns `\"\"` when there is no usable stack (message-only fallback).\n */\nexport function extractTopFrames(\n stack: string | undefined,\n limit = FINGERPRINT_FRAME_LIMIT,\n): string {\n if (typeof stack !== \"string\" || stack.length === 0) return \"\";\n const frames: string[] = [];\n for (const raw of stack.split(\"\\n\")) {\n const frame = parseFrame(raw.trim());\n if (frame) {\n frames.push(frame);\n if (frames.length >= limit) break;\n }\n }\n return frames.join(\" < \");\n}\n\n/** The most structured frames shipped per auto report (mirrors `MAX_CAPTURED_FRAMES`). */\nconst STRUCTURED_FRAME_LIMIT = 30;\n\n/** Split a `file:line:col` location into its parts; null when it has no line. */\nfunction parseLocation(\n location: string,\n): { file: string; line: number; column: number | null } | null {\n // The file may itself contain colons (https://…), so split from the right.\n const match = location.match(/^(.*?):(\\d+)(?::(\\d+))?$/);\n if (!match) return null;\n const file = match[1] ?? \"\";\n if (file.length === 0 || file === \"native\" || file.includes(\"<anonymous>\")) {\n return null;\n }\n const line = Number(match[2]);\n if (!Number.isFinite(line)) return null;\n const column = match[3] !== undefined ? Number(match[3]) : null;\n return { file, line, column };\n}\n\n/**\n * Extract **structured** frames from a stack for the wire (#117, ADR-0024) —\n * unlike {@link extractTopFrames} (a compact fingerprint signature that drops the\n * origin), these keep the full script URL, because server-side symbolication\n * matches it against uploaded sourcemap paths. URLs are scrubbed (query dropped,\n * PII redacted) before they leave the page; unlocatable frames (`native`,\n * `<anonymous>`, eval) are skipped; the count is capped.\n */\nexport function extractStructuredFrames(\n stack: string | undefined,\n limit = STRUCTURED_FRAME_LIMIT,\n): CapturedFrame[] {\n if (typeof stack !== \"string\" || stack.length === 0) return [];\n const frames: CapturedFrame[] = [];\n for (const raw of stack.split(\"\\n\")) {\n if (frames.length >= limit) break;\n const line = raw.trim();\n let fn: string | null = null;\n let location: string | null = null;\n // V8: \"at fn (loc)\" | \"at loc\"\n const v8Named = line.match(/^at\\s+(.+?)\\s+\\((.+)\\)$/);\n const v8Bare = v8Named ? null : line.match(/^at\\s+(.+)$/);\n const geckoAt = v8Named || v8Bare ? -1 : line.indexOf(\"@\");\n if (v8Named) {\n fn = v8Named[1] ?? null;\n location = v8Named[2] ?? null;\n } else if (v8Bare) {\n location = v8Bare[1] ?? null;\n } else if (geckoAt >= 0) {\n // Firefox / Safari: \"fn@loc\" | \"@loc\"\n fn = geckoAt > 0 ? line.slice(0, geckoAt) : null;\n location = line.slice(geckoAt + 1);\n }\n if (!location) continue;\n const parsed = parseLocation(location);\n if (!parsed) continue;\n frames.push({\n file: scrubUrl(parsed.file),\n line: parsed.line,\n column: parsed.column,\n function: fn && fn.length > 0 ? fn : null,\n });\n }\n return frames;\n}\n\n/**\n * The per-session fingerprint (research §7.2):\n * `hash(errorType + \"|\" + normalize(value) + \"|\" + topFrames)`. Stack frames\n * dominate when present; otherwise it falls back to type + normalized value.\n */\nexport function computeFingerprint(\n type: string,\n value: string,\n stack?: string,\n): string {\n return hashString(`${type}|${normalize(value)}|${extractTopFrames(stack)}`);\n}\n\n// --- Burst limiter (token bucket, research §7.3) ------------------------------\n\n/** Configuration for {@link TokenBucket}. */\nexport interface TokenBucketOptions {\n readonly capacity: number;\n readonly refillIntervalMs: number;\n /** Clock source, injectable for tests. Defaults to `Date.now`. */\n readonly now?: () => number;\n}\n\n/**\n * A token bucket: starts full at `capacity`, refills one token every\n * `refillIntervalMs`, and refuses (`take() === false`) when empty. So a fast error\n * loop that dodges dedup with distinct fingerprints still can't machine-gun ingest.\n * The clock is injectable so the window is unit-tested deterministically.\n */\nexport class TokenBucket {\n private tokens: number;\n private last: number;\n private readonly now: () => number;\n\n constructor(private readonly options: TokenBucketOptions) {\n this.now = options.now ?? Date.now;\n this.tokens = Math.max(0, options.capacity);\n this.last = this.now();\n }\n\n /** Consume a token if one is available (refilling first), else refuse. */\n take(): boolean {\n const now = this.now();\n const { capacity, refillIntervalMs } = this.options;\n if (refillIntervalMs > 0 && now > this.last) {\n const refill = Math.floor((now - this.last) / refillIntervalMs);\n if (refill > 0) {\n this.tokens = Math.min(capacity, this.tokens + refill);\n this.last += refill * refillIntervalMs;\n }\n }\n if (this.tokens >= 1) {\n this.tokens -= 1;\n return true;\n }\n return false;\n }\n}\n\n// --- Error extraction ---------------------------------------------------------\n\n/** The distilled shape a fingerprint + report is built from. */\ninterface ExtractedError {\n readonly type: string;\n readonly value: string;\n readonly stack?: string;\n /** The original throwable (Error or rejection reason) for the trace crumb. */\n readonly original: unknown;\n}\n\ninterface ErrorLike {\n name?: unknown;\n message?: unknown;\n stack?: unknown;\n}\n\nfunction asString(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (value == null) return \"\";\n try {\n return String(value);\n } catch {\n return \"\";\n }\n}\n\n/** Distil an uncaught `error` event into a fingerprint-able shape, or `null`. */\nfunction extractFromErrorEvent(event: Event): ExtractedError | null {\n const e = event as ErrorEvent & { error?: unknown };\n const error = e.error;\n if (error && typeof error === \"object\") {\n const err = error as ErrorLike;\n return {\n type: asString(err.name) || \"Error\",\n value: asString(err.message) || asString(e.message),\n stack: typeof err.stack === \"string\" ? err.stack : undefined,\n original: error,\n };\n }\n // No Error object: a message-only event (some browsers) is still capturable.\n const message = asString(e.message);\n if (message) return { type: \"Error\", value: message, original: message };\n // A resource-load error (img/script) has neither — never an uncaught exception.\n return null;\n}\n\n/** Distil an `unhandledrejection` event into a fingerprint-able shape, or `null`. */\nfunction extractFromRejectionEvent(event: Event): ExtractedError | null {\n const reason = (event as Event & { reason?: unknown }).reason;\n if (reason && typeof reason === \"object\") {\n const err = reason as ErrorLike;\n const type = asString(err.name) || \"UnhandledRejection\";\n const value = asString(err.message) || asString(reason);\n return {\n type,\n value,\n stack: typeof err.stack === \"string\" ? err.stack : undefined,\n original: reason,\n };\n }\n const value = asString(reason);\n return { type: \"UnhandledRejection\", value, original: reason ?? value };\n}\n\n// --- The capture controller ---------------------------------------------------\n\n/** Injectable collaborators, defaulted to the real implementations. */\nexport interface AutoCaptureDeps {\n readonly captureView: (options?: CaptureOptions) => Promise<Capture | null>;\n readonly submitReport: (\n apiUrl: string,\n input: SubmitInput,\n fetchImpl?: typeof fetch,\n ) => Promise<SubmitResult>;\n}\n\n/** Configuration for {@link installErrorCapture}. */\nexport interface AutoCaptureConfig {\n readonly apiUrl: string;\n readonly key: string;\n readonly identity?: IdentityInputs;\n /**\n * The Reporter's self-provided display name / email (spec §F). Carried on\n * auto-captured Feedback too, so a machine-filed crash still names whose session it\n * was — display only, never a trust signal.\n */\n readonly display?: ReporterDisplay;\n /** The window whose global handlers are installed. Defaults to `window`. */\n readonly win?: Window;\n /** The document used for capture + environment. Defaults to the window's. */\n readonly doc?: Document;\n readonly sdkVersion?: string;\n /**\n * The host app's **Release** (#117, ADR-0024) — already validated by `init`\n * (`normaliseRelease`). Stamped into every auto report's environment so the\n * server can symbolicate the captured frames against this build's sourcemaps.\n */\n readonly release?: string;\n /** The shared trace buffer; the failing error is added to it before filing. */\n readonly buffer?: BreadcrumbBuffer | null;\n /**\n * The shared replay recorder (ADR-0024); the buffered window rides on a rich\n * first report — the moment before an uncaught error is exactly what replay\n * exists to show. Light count-update flushes never re-send it.\n */\n readonly replay?: ReplaySource | null;\n /** Per-project client scrub hook, run at the `beforeSend` choke point (§C). */\n readonly beforeSend?: BeforeSend;\n /** Run the built-in default scrubbers. Defaults to `true` (private-by-default). */\n readonly scrub?: boolean;\n readonly deps?: Partial<AutoCaptureDeps>;\n /** Burst limiter capacity. Defaults to {@link DEFAULT_BURST_CAPACITY}. */\n readonly burstCapacity?: number;\n /** Burst limiter refill interval (ms). Defaults to {@link DEFAULT_BURST_REFILL_MS}. */\n readonly burstRefillMs?: number;\n /** Per-session distinct-Feedback cap. Defaults to {@link DEFAULT_MAX_DISTINCT_AUTO}. */\n readonly maxDistinct?: number;\n /** Clock source, injectable for tests. Defaults to `Date.now`. */\n readonly now?: () => number;\n}\n\n/** A per-session record of one fingerprinted error. */\ninterface AutoEntry {\n count: number;\n firstAt: number;\n lastAt: number;\n /** The occurrence count last shipped to ingest (`0` until the first send). */\n sentCount: number;\n /** The structured frames parsed from the first firing's stack (#117), if any. */\n frames: readonly CapturedFrame[];\n}\n\n/** What to include when filing — a first report is rich; a flush is a light count update. */\ninterface FileOptions {\n readonly screenshot: boolean;\n readonly trace: boolean;\n}\n\n/** A running auto-capture: its teardown, plus the local dropped-count (spec §E). */\nexport interface AutoCaptureHandle {\n /** Remove the two global handlers and the flush hooks. Safe to call repeatedly. */\n readonly destroy: Teardown;\n /**\n * Distinct auto-Feedback dropped by the burst limiter or the per-session cap —\n * the \"keep only a local dropped-count\" fallback beyond the guardrails (spec §E).\n */\n droppedCount(): number;\n}\n\nconst NOOP_HANDLE: AutoCaptureHandle = { destroy: () => {}, droppedCount: () => 0 };\n\n/**\n * Install automatic error capture on a window and return a handle whose `destroy`\n * removes every listener it added (the two global handlers plus the flush hooks).\n * The caller (`init`) installs this only after boot returned `canSubmit`, so the\n * Gate is respected and the auto-error inherits the session Reporter's tier.\n */\nexport function installErrorCapture(config: AutoCaptureConfig): AutoCaptureHandle {\n const maybeWin =\n config.win ?? (typeof window !== \"undefined\" ? window : undefined);\n if (!maybeWin) return NOOP_HANDLE;\n const win: Window = maybeWin;\n const doc: Document | undefined =\n config.doc ??\n win.document ??\n (typeof document !== \"undefined\" ? document : undefined);\n\n const now = config.now ?? Date.now;\n const sdkVersion = config.sdkVersion ?? SDK_VERSION;\n const maxDistinct = config.maxDistinct ?? DEFAULT_MAX_DISTINCT_AUTO;\n const captureViewFn = config.deps?.captureView ?? captureView;\n const submitReportFn = config.deps?.submitReport ?? submitReport;\n\n const bucket = new TokenBucket({\n capacity: config.burstCapacity ?? DEFAULT_BURST_CAPACITY,\n refillIntervalMs: config.burstRefillMs ?? DEFAULT_BURST_REFILL_MS,\n now,\n });\n\n const seen = new Map<string, AutoEntry>();\n /** Distinct auto-Feedback dropped by the burst limiter or the session cap. */\n let dropped = 0;\n\n /**\n * Build the `source: auto` content for a fingerprint at a given occurrence\n * count. No Kind rides along (ADR-0023): the server stamps a `source: auto`\n * Issue `bug` deterministically — an uncaught error proves itself.\n */\n function buildContent(fp: string, occurrences: number, opts: FileOptions): ReportContent {\n const base = assembleContent({\n url: win.location?.href,\n environment: collectEnvironment(win, sdkVersion, config.release),\n trace: opts.trace ? config.buffer?.snapshot() : undefined,\n reporterName: config.display?.name,\n reporterEmail: config.display?.email,\n });\n const frames = seen.get(fp)?.frames;\n return {\n ...base,\n source: \"auto\",\n errorSignature: fp,\n occurrences,\n // The structured frames (#117) ride with the rich first report only — a\n // flush is a light count update, like the screenshot and trace.\n ...(opts.trace && frames && frames.length > 0 ? { errorFrames: frames } : {}),\n };\n }\n\n /**\n * Assemble, scrub, (optionally) screenshot, and ship one auto-Feedback. Sets the\n * entry's `sentCount` optimistically so a concurrent flush never double-sends,\n * and rolls it back on a failed send so the flush can retry the count update. A\n * `beforeSend` that returns `null` drops the report without transport.\n */\n async function file(fp: string, occurrences: number, opts: FileOptions): Promise<void> {\n const entry = seen.get(fp);\n if (!entry) return;\n const previouslySent = entry.sentCount;\n entry.sentCount = occurrences;\n try {\n const draft = buildContent(fp, occurrences, opts);\n const content = runBeforeSend(draft, {\n hook: config.beforeSend,\n scrub: config.scrub,\n });\n if (!content) return; // dropped at the client scrub choke point — no transport.\n\n let screenshot: SubmitInput[\"screenshot\"] = null;\n if (opts.screenshot) {\n const capture = await captureViewFn({ doc, win });\n screenshot = capture\n ? { blob: capture.blob, filename: `screenshot.${extensionFor(capture.type)}` }\n : null;\n }\n\n // The buffered replay window rides with the rich first report only — the\n // trace flag marks exactly those sends (a flush is a light count update).\n const replay = opts.trace ? (config.replay?.snapshot() ?? null) : null;\n\n const result = await submitReportFn(config.apiUrl, {\n key: config.key,\n identity: config.identity,\n content,\n screenshot,\n replay,\n });\n if (!result.ok && entry.sentCount === occurrences) {\n // Held under backpressure, refused, or unreachable — let a later flush retry.\n entry.sentCount = previouslySent;\n }\n } catch {\n if (entry.sentCount === occurrences) entry.sentCount = previouslySent;\n // The error path must never throw into the host page.\n }\n }\n\n /** Handle one distilled error: dedup → burst limiter → session cap → file. */\n function handle(extracted: ExtractedError): void {\n const fp = computeFingerprint(extracted.type, extracted.value, extracted.stack);\n const existing = seen.get(fp);\n if (existing) {\n // Dedup: one Feedback per fingerprint per session; count locally, flush later.\n existing.count += 1;\n existing.lastAt = now();\n return;\n }\n if (!bucket.take()) {\n dropped += 1; // burst limiter\n return;\n }\n if (seen.size >= maxDistinct) {\n dropped += 1; // per-session cap — keep only the local dropped-count\n return;\n }\n const at = now();\n seen.set(fp, {\n count: 1,\n firstAt: at,\n lastAt: at,\n sentCount: 0,\n // Parsed once per fingerprint, from the first firing's stack (#117) — the\n // wire shape symbolication consumes, scrubbed like every captured URL.\n frames: extractStructuredFrames(extracted.stack),\n });\n // The failing error joins the trace so the lead-up and the failure both show,\n // carrying a causal pointer to the ids of the entries that preceded the throw.\n try {\n const causedBy = precedingIds(config.buffer?.snapshot());\n config.buffer?.add(errorCrumb(extracted.original, at, causedBy));\n } catch {\n /* capture must never throw into the host page */\n }\n void file(fp, 1, { screenshot: true, trace: true });\n }\n\n const onError = (event: Event): void => {\n try {\n const extracted = extractFromErrorEvent(event);\n if (extracted) handle(extracted);\n } catch {\n /* never throw into the host page */\n }\n };\n\n const onRejection = (event: Event): void => {\n try {\n const extracted = extractFromRejectionEvent(event);\n if (extracted) handle(extracted);\n } catch {\n /* never throw into the host page */\n }\n };\n\n /** Flush the final occurrence count of every fingerprint that grew since its send. */\n const flush = (): void => {\n try {\n for (const [fp, entry] of seen) {\n if (entry.count > entry.sentCount) {\n void file(fp, entry.count, { screenshot: false, trace: false });\n }\n }\n } catch {\n /* best-effort on unload */\n }\n };\n\n const onVisibility = (): void => {\n if (doc?.visibilityState === \"hidden\") flush();\n };\n\n win.addEventListener(\"error\", onError, true);\n win.addEventListener(\"unhandledrejection\", onRejection, true);\n win.addEventListener(\"pagehide\", flush);\n doc?.addEventListener(\"visibilitychange\", onVisibility);\n\n return {\n destroy: () => {\n win.removeEventListener(\"error\", onError, true);\n win.removeEventListener(\"unhandledrejection\", onRejection, true);\n win.removeEventListener(\"pagehide\", flush);\n doc?.removeEventListener(\"visibilitychange\", onVisibility);\n },\n droppedCount: () => dropped,\n };\n}\n","/**\n * The Public Reporter's stable, first-party anonymous id.\n *\n * When the host site does not supply its own identity, the SDK establishes a\n * per-browser id and persists it, so repeated boots from the same browser are one\n * Reporter (the server counts distinct Reporters by it). Persistence is\n * best-effort: if storage is unavailable (private mode, blocked cookies), we fall\n * back to an ephemeral id rather than throw — the SDK must never disturb the host\n * page.\n */\n\nconst STORAGE_KEY = \"fixback.anonymousId\";\n\n/** A random id: a UUID where the platform offers one, else a compact fallback. */\nfunction generateId(): string {\n const c: Crypto | undefined = globalThis.crypto;\n if (c && typeof c.randomUUID === \"function\") return c.randomUUID();\n return `fb-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Return this browser's anonymous id, creating and persisting one on first use. */\nexport function ensureAnonymousId(): string {\n try {\n const store = globalThis.localStorage;\n const existing = store.getItem(STORAGE_KEY);\n if (existing) return existing;\n const id = generateId();\n store.setItem(STORAGE_KEY, id);\n return id;\n } catch {\n // Storage blocked or absent — an ephemeral id keeps this boot working.\n return generateId();\n }\n}\n","/**\n * Invite redemption & reporter identity (spec §F).\n *\n * The zero-integration path for an invited tester: detect an invite token on the\n * page (`?fixback_invite=<token>`) or an explicit `redeem()` call, read the\n * Invite's public status, and — on confirmation — redeem it into a persisted\n * `reporterId` the SDK thereafter presents as an identity input.\n *\n * This module is the wire + storage half (pure enough to unit-test directly): the\n * two invite endpoints, the localStorage persistence scoped by publishable key,\n * and the URL token detection / one-time consumption. The onboarding modal is\n * `onboarding.ts`; `init` wires the two together.\n *\n * Like `boot.ts`, the wire types are a **vendored** slice of the server contract\n * (`apps/api/src/invites/invite-redemption.controller.ts`) — the SDK never imports\n * the private server package. Keep them in lock-step with that controller.\n */\n\nimport type { ReporterTier } from \"./boot\";\n\n/** The Invite's shape. Mirrors the server's `InviteKind`. */\nexport type InviteKind = \"targeted\" | \"shared\";\n\n/** The dead/unknown states a status or redeem read can resolve to. */\nexport type InviteDeadStatus = \"revoked\" | \"expired\" | \"exhausted\" | \"not_found\";\n\n/**\n * The public status of an Invite (`GET /api/invites/:token`). A live (`pending`)\n * Invite reveals the minimal facts the onboarding modal needs — the Project, the\n * Invite's shape, and the **server-derived** tier the redemption would grant; a\n * dead or unknown token reveals only its state.\n */\nexport type InviteStatusAnswer =\n | {\n readonly status: \"pending\";\n readonly projectId: string;\n readonly kind: InviteKind;\n readonly tier: ReporterTier;\n }\n | { readonly status: InviteDeadStatus };\n\n/**\n * The result of redeeming an Invite (`POST /api/invites/:token/redeem`): the\n * minted Reporter (its handle + server-derived tier + Project), or why it was\n * refused.\n */\nexport type RedeemAnswer =\n | {\n readonly status: \"redeemed\";\n readonly reporterId: string;\n readonly tier: ReporterTier;\n readonly projectId: string;\n }\n | { readonly status: InviteDeadStatus };\n\n/**\n * The self-provided display fields captured in the onboarding modal. They ride\n * along as a Reporter's chosen name / email — **never** a trust signal (the tier\n * is always server-derived, spec §F).\n */\nexport interface ReporterDisplay {\n readonly name?: string;\n readonly email?: string;\n}\n\n/** A persisted redeemed Reporter: the server handle plus the display fields. */\nexport interface StoredReporter extends ReporterDisplay {\n readonly reporterId: string;\n}\n\n/** The URL query parameter that carries an invite token. */\nexport const INVITE_QUERY_PARAM = \"fixback_invite\";\n\n/** localStorage namespace for a redeemed Reporter, scoped by publishable key. */\nconst REPORTER_STORAGE_PREFIX = \"fixback:reporter:\";\n\n// ---------------------------------------------------------------------------\n// URL token detection & one-time consumption\n// ---------------------------------------------------------------------------\n\n/**\n * Read the invite token from a page URL's `?fixback_invite=` param. Returns the\n * token, or `null` when absent, empty, or the URL cannot be parsed — never throws.\n */\nexport function readInviteToken(href: string): string | null {\n try {\n const token = new URL(href).searchParams.get(INVITE_QUERY_PARAM);\n return token && token.length > 0 ? token : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Strip the invite token from the address bar (one-time consumption, spec §F) via\n * `history.replaceState`, so a reload or a shared link cannot re-trigger — or\n * re-consume — an already-redeemed Invite. Other params, the path, and the hash\n * are preserved. Best-effort: it never throws into the host page.\n */\nexport function stripInviteToken(win: Window): void {\n try {\n const url = new URL(win.location.href);\n if (!url.searchParams.has(INVITE_QUERY_PARAM)) return;\n url.searchParams.delete(INVITE_QUERY_PARAM);\n const query = url.searchParams.toString();\n const next = `${url.pathname}${query ? `?${query}` : \"\"}${url.hash}`;\n win.history.replaceState(win.history.state, \"\", next);\n } catch {\n // Never disturb the host page over a cosmetic URL rewrite.\n }\n}\n\n// ---------------------------------------------------------------------------\n// Persistence (scoped by publishable key)\n// ---------------------------------------------------------------------------\n\nfunction reporterStorageKey(key: string): string {\n return `${REPORTER_STORAGE_PREFIX}${key}`;\n}\n\n/** The ambient localStorage, or `null` when it is absent or blocked. */\nfunction safeStorage(): Storage | null {\n try {\n return globalThis.localStorage ?? null;\n } catch {\n return null;\n }\n}\n\n/** A trimmed non-empty string, or `undefined` — so blanks are never stored. */\nfunction cleanField(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Persist a redeemed Reporter for `key`. The `reporterId` is the identity the SDK\n * presents on later boots; the display name / email ride along as chosen fields.\n * Best-effort — storage being unavailable (private mode) is never fatal.\n */\nexport function persistReporter(\n key: string,\n reporter: StoredReporter,\n store: Storage | null = safeStorage(),\n): void {\n if (!store) return;\n const name = cleanField(reporter.name);\n const email = cleanField(reporter.email);\n const payload: StoredReporter = {\n reporterId: reporter.reporterId,\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n };\n try {\n store.setItem(reporterStorageKey(key), JSON.stringify(payload));\n } catch {\n // Storage blocked or full — the redemption still succeeded in this session.\n }\n}\n\n/**\n * Read the redeemed Reporter persisted for `key`, or `null` when none is stored,\n * the record is malformed, or it carries no `reporterId`. Never throws.\n */\nexport function readStoredReporter(\n key: string,\n store: Storage | null = safeStorage(),\n): StoredReporter | null {\n if (!store) return null;\n try {\n const raw = store.getItem(reporterStorageKey(key));\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Partial<StoredReporter>;\n if (typeof parsed?.reporterId !== \"string\" || parsed.reporterId.length === 0) {\n return null;\n }\n const name = cleanField(parsed.name);\n const email = cleanField(parsed.email);\n return {\n reporterId: parsed.reporterId,\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n };\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire client\n// ---------------------------------------------------------------------------\n\n/** Join an API base URL with the invite status path, tolerating a trailing slash. */\nexport function inviteStatusEndpoint(apiUrl: string, token: string): string {\n return `${apiUrl.replace(/\\/+$/, \"\")}/api/invites/${encodeURIComponent(token)}`;\n}\n\n/** Join an API base URL with the redeem path for a token. */\nexport function redeemEndpoint(apiUrl: string, token: string): string {\n return `${inviteStatusEndpoint(apiUrl, token)}/redeem`;\n}\n\nconst DEAD_STATUSES = new Set<InviteDeadStatus>([\n \"revoked\",\n \"expired\",\n \"exhausted\",\n \"not_found\",\n]);\n\nfunction isTier(value: unknown): value is ReporterTier {\n return value === \"public\" || value === \"invited\" || value === \"internal\";\n}\n\n/** Narrow an unknown JSON body to an {@link InviteStatusAnswer}. */\nfunction isInviteStatusAnswer(value: unknown): value is InviteStatusAnswer {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n if (v.status === \"pending\") {\n return (\n typeof v.projectId === \"string\" &&\n (v.kind === \"targeted\" || v.kind === \"shared\") &&\n isTier(v.tier)\n );\n }\n return typeof v.status === \"string\" && DEAD_STATUSES.has(v.status as InviteDeadStatus);\n}\n\n/** Narrow an unknown JSON body to a {@link RedeemAnswer}. */\nfunction isRedeemAnswer(value: unknown): value is RedeemAnswer {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n if (v.status === \"redeemed\") {\n return (\n typeof v.reporterId === \"string\" &&\n typeof v.projectId === \"string\" &&\n isTier(v.tier)\n );\n }\n return typeof v.status === \"string\" && DEAD_STATUSES.has(v.status as InviteDeadStatus);\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return null;\n }\n}\n\n/**\n * Read an Invite's public status. Resolves to the answer, or `null` when Fixback\n * could not be reached or the body was not a recognised answer. The endpoint\n * answers 200 for a live or dead Invite and 404 (with a JSON body) for an unknown\n * token, so the body — not the HTTP status — is what the caller narrows on. Never\n * throws: an outage stays invisible to the host page.\n */\nexport async function fetchInviteStatus(\n apiUrl: string,\n token: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<InviteStatusAnswer | null> {\n let response: Response;\n try {\n response = await fetchImpl(inviteStatusEndpoint(apiUrl, token), {\n method: \"GET\",\n headers: { accept: \"application/json\" },\n });\n } catch {\n return null;\n }\n const body = await readJson(response);\n return isInviteStatusAnswer(body) ? body : null;\n}\n\n/**\n * Redeem an Invite by token, minting and returning a Reporter. Resolves to the\n * answer, or `null` on an unreachable API or an unrecognised body. Never throws.\n */\nexport async function redeemInviteToken(\n apiUrl: string,\n token: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<RedeemAnswer | null> {\n let response: Response;\n try {\n response = await fetchImpl(redeemEndpoint(apiUrl, token), {\n method: \"POST\",\n headers: { accept: \"application/json\" },\n });\n } catch {\n return null;\n }\n const body = await readJson(response);\n return isRedeemAnswer(body) ? body : null;\n}\n","/**\n * The launcher's isolated styles.\n *\n * These live inside the launcher's Shadow DOM (see `launcher.ts`), so nothing\n * here can reach the host page and nothing on the host page can reach in. The\n * token values are **vendored** Signal design tokens — copied from\n * `packages/ui/src/tokens.css` rather than imported, because the SDK must not\n * depend on `@fixback/ui` at runtime (ticket #47). Keep them in sync by value.\n *\n * The launcher is the prototype's polished pill (spec 0003 §A): a bottom-right\n * **Feedback** pill that **hover-peeks**, can be **tucked away** (sliding off\n * behind an edge nub, with a corner hover-zone to bring it back), a first-visit\n * **welcome toast**, and a **reduce-motion** mode that stills the pulse. Every\n * piece — pill, nub, corner zone, welcome toast — lives in this one Shadow DOM.\n *\n * Motion is driven by two host-element attributes the mount toggles:\n * `data-fb-hidden` (tucked away) and `data-fb-peeking` (peeked back on hover);\n * `data-fb-reduce-motion` (or the OS `prefers-reduced-motion`) stills it all.\n */\nexport const LAUNCHER_STYLES = `\n:host {\n /* Vendored Signal tokens (packages/ui/src/tokens.css). */\n --fb-color-accent: #2f6fed;\n --fb-color-accent-hover: #245fd0;\n --fb-color-on-emphasis: #ffffff;\n --fb-color-text: #0f1720;\n /* Inverse (dark) surface for the toasts — Signal --fb-ink-900. */\n --fb-color-surface-inverse: #0f1720;\n --fb-font-sans: \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif;\n\n display: block;\n color: var(--fb-color-text);\n font-family: var(--fb-font-sans);\n font-size: 13px;\n line-height: 1.4;\n -webkit-font-smoothing: antialiased;\n}\n\n/* The pill: Feedback button + divider + tuck control, anchored bottom-right. */\n.fb-launcher {\n position: fixed;\n right: 20px;\n bottom: 20px;\n z-index: 2;\n display: inline-flex;\n align-items: stretch;\n box-sizing: border-box;\n height: 40px;\n margin: 0;\n border-radius: 999px;\n background: var(--fb-color-accent);\n box-shadow:\n 0 6px 18px rgba(15, 23, 32, 0.16),\n 0 1px 2px rgba(15, 23, 32, 0.12);\n transform: translateX(0);\n transition:\n transform 340ms cubic-bezier(0.2, 0.8, 0.3, 1),\n background-color 120ms ease;\n}\n\n.fb-launcher:hover {\n background: var(--fb-color-accent-hover);\n}\n\n.fb-launcher__button {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n box-sizing: border-box;\n height: 100%;\n margin: 0;\n padding: 0 6px 0 16px;\n border: 0;\n background: transparent;\n color: var(--fb-color-on-emphasis);\n font-family: inherit;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.01em;\n cursor: pointer;\n}\n\n.fb-launcher__button:focus-visible,\n.fb-launcher__tuck:focus-visible {\n outline: 2px solid var(--fb-color-on-emphasis);\n outline-offset: -3px;\n border-radius: 999px;\n}\n\n.fb-launcher__icon {\n display: block;\n flex: none;\n width: 16px;\n height: 16px;\n}\n\n.fb-launcher__label {\n white-space: nowrap;\n}\n\n.fb-launcher__divider {\n width: 1px;\n margin: 9px 0;\n flex: none;\n background: rgba(255, 255, 255, 0.28);\n}\n\n.fb-launcher__tuck {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: 32px;\n height: 100%;\n padding: 0;\n border: 0;\n background: transparent;\n color: rgba(255, 255, 255, 0.82);\n cursor: pointer;\n}\n\n.fb-launcher__tuck:hover {\n color: var(--fb-color-on-emphasis);\n}\n\n.fb-launcher__tuck-icon {\n display: block;\n width: 14px;\n height: 14px;\n transition: transform 340ms cubic-bezier(0.2, 0.8, 0.3, 1);\n}\n\n/* Tucked away: mirror the chevron so it points left — back into view. */\n:host([data-fb-hidden]) .fb-launcher__tuck-icon {\n transform: scaleX(-1);\n}\n\n/* The corner hover-zone that peeks a tucked launcher back — inert until tucked,\n * so it never swallows the host page's own bottom-right clicks. */\n.fb-launcher__peekzone {\n position: fixed;\n right: 0;\n bottom: 0;\n z-index: 1;\n width: 160px;\n height: 160px;\n pointer-events: none;\n}\n\n/* The edge nub: the visible re-reveal affordance, hidden until tucked. */\n.fb-launcher__nub {\n position: fixed;\n right: 0;\n bottom: 22px;\n z-index: 2;\n width: 13px;\n height: 42px;\n border-radius: 9px 0 0 9px;\n background: var(--fb-color-accent);\n box-shadow: -6px 5px 18px rgba(47, 111, 237, 0.4);\n cursor: pointer;\n opacity: 0;\n transform: translateX(10px);\n pointer-events: none;\n transition:\n opacity 220ms ease,\n transform 220ms ease;\n}\n\n/* Tucked and not peeking: slide the pill off, reveal the nub, arm the zone. */\n:host([data-fb-hidden]:not([data-fb-peeking])) .fb-launcher {\n transform: translateX(calc(100% + 30px));\n}\n\n:host([data-fb-hidden]:not([data-fb-peeking])) .fb-launcher__nub {\n opacity: 1;\n transform: none;\n pointer-events: auto;\n}\n\n:host([data-fb-hidden]) .fb-launcher__peekzone {\n pointer-events: auto;\n}\n\n/* The first-visit welcome toast, above the pill. */\n.fb-launcher__welcome {\n position: fixed;\n right: 20px;\n bottom: 70px;\n z-index: 5;\n box-sizing: border-box;\n max-width: 210px;\n padding: 9px 13px;\n color: #fff;\n font-size: 12px;\n line-height: 1.45;\n background: var(--fb-color-surface-inverse);\n border-radius: 10px;\n box-shadow: 0 12px 30px rgba(15, 40, 70, 0.32);\n animation: fbToast 300ms ease both;\n}\n\n.fb-launcher__welcome strong {\n color: #8fc0ff;\n font-weight: 600;\n}\n\n/* The pulse that draws the eye while the welcome shows. */\n.fb-launcher--pulse {\n animation: fbPulse 1.8s ease-in-out 2;\n}\n\n@keyframes fbPulse {\n 0%,\n 100% {\n box-shadow:\n 0 6px 18px rgba(15, 23, 32, 0.16),\n 0 0 0 0 rgba(47, 111, 237, 0.45);\n }\n 50% {\n box-shadow:\n 0 6px 18px rgba(15, 23, 32, 0.16),\n 0 0 0 12px rgba(47, 111, 237, 0);\n }\n}\n\n@keyframes fbToast {\n from {\n opacity: 0;\n transform: translateY(14px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n\n/* Reduce motion — the explicit opt-in and the OS setting both still it all. */\n:host([data-fb-reduce-motion]) .fb-launcher,\n:host([data-fb-reduce-motion]) .fb-launcher__nub,\n:host([data-fb-reduce-motion]) .fb-launcher__tuck-icon {\n transition: none;\n}\n\n:host([data-fb-reduce-motion]) .fb-launcher--pulse,\n:host([data-fb-reduce-motion]) .fb-launcher__welcome {\n animation: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fb-launcher,\n .fb-launcher__nub,\n .fb-launcher__tuck-icon {\n transition: none;\n }\n .fb-launcher--pulse,\n .fb-launcher__welcome {\n animation: none;\n }\n}\n`;\n","import { LAUNCHER_STYLES } from \"./styles\";\n\n/** Marks the SDK's host element in the light DOM, so it is findable and unique. */\nexport const ROOT_ATTRIBUTE = \"data-fixback-root\";\n\n/**\n * Dispatched from the host element when the launcher is activated. The report\n * overlay this opens is wired in `init`; this event is the seam it hangs off. It\n * is `composed` so host-page listeners outside the Shadow DOM can hear it.\n */\nexport const LAUNCH_EVENT = \"fixback:launch\";\n\n/** Storage-key namespace for the first-visit welcome flag, scoped per key. */\nconst WELCOME_STORAGE_PREFIX = \"fixback:welcomed:\";\n\n/** How long the welcome toast (and its pulse) linger before self-dismissing. */\nconst WELCOME_MS = 5000;\n/** Grace period before a peeked-open launcher tucks itself back on pointer-out. */\nconst PEEK_OUT_MS = 280;\n\nconst FEEDBACK_ICON =\n '<svg class=\"fb-launcher__icon\" viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">' +\n '<path fill=\"currentColor\" d=\"M3.25 2h9.5A1.25 1.25 0 0 1 14 3.25v6.5A1.25 1.25 0 0 1 12.75 11H7.6l-3.19 2.55A.6.6 0 0 1 3.4 13.1V11h-.15A1.25 1.25 0 0 1 2 9.75v-6.5A1.25 1.25 0 0 1 3.25 2Z\"/>' +\n \"</svg>\";\n\n/**\n * The tuck control's chevron. It points **right** — the direction the pill tucks\n * away toward — and the stylesheet mirrors it to point **left** (back into view)\n * while the launcher is tucked, so the one control reads as a direction toggle.\n */\nconst TUCK_ICON =\n '<svg class=\"fb-launcher__tuck-icon\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">' +\n '<path d=\"M6 4l4 4-4 4\"/>' +\n \"</svg>\";\n\n/** Options that shape a mounted launcher. */\nexport interface LauncherOptions {\n /**\n * The Project's publishable key. Scopes the first-visit welcome flag so the\n * welcome greets once per key per browser.\n */\n readonly key?: string;\n /**\n * Still the pulse and motion. An explicit opt-in that complements the OS-level\n * `prefers-reduced-motion` (which the styles already honour on their own).\n */\n readonly reduceMotion?: boolean;\n}\n\n/** A mounted launcher and the handle needed to remove it again. */\nexport interface Launcher {\n readonly host: HTMLElement;\n /** Clears the launcher's pending timers. Called by {@link unmountLauncher}. */\n readonly dispose: () => void;\n}\n\n/**\n * Read the first-visit welcome flag and mark it seen, returning whether the\n * welcome should greet now. Never throws: when storage is unavailable (SSR,\n * sandboxed frame, blocked cookies) it greets without persisting.\n */\nfunction claimFirstVisitWelcome(win: Window | null, key: string | undefined): boolean {\n const flag = WELCOME_STORAGE_PREFIX + (key ?? \"default\");\n try {\n const storage = win?.localStorage;\n if (!storage) return true;\n if (storage.getItem(flag) === \"1\") return false;\n storage.setItem(flag, \"1\");\n return true;\n } catch {\n return true;\n }\n}\n\n/**\n * Mount the launcher into `target` (typically `document.body`). Everything the\n * launcher draws — the **Feedback** pill, its **tuck** control, the edge **nub**\n * and corner **hover-zone** that peek it back, and the first-visit **welcome**\n * toast — lives inside one open Shadow DOM, so its styles are fully isolated\n * from the host page and vice-versa. The host element is\n * fixed-positioned and out of flow, so mounting never shifts the host page's\n * layout. Only one launcher can exist at a time — an earlier one is removed first.\n *\n * Tuck/peek state is expressed as `data-fb-hidden` / `data-fb-peeking` attributes\n * on the host, which the Shadow DOM stylesheet animates; `reduceMotion` sets\n * `data-fb-reduce-motion`, which (with the OS `prefers-reduced-motion`) stills it.\n */\nexport function mountLauncher(\n target: HTMLElement,\n options: LauncherOptions = {},\n): Launcher {\n const doc = target.ownerDocument;\n const win = doc.defaultView;\n\n const previous = doc.querySelector(`[${ROOT_ATTRIBUTE}]`);\n if (previous) previous.remove();\n\n const host = doc.createElement(\"div\");\n host.setAttribute(ROOT_ATTRIBUTE, \"\");\n // Positioning is inlined on the host (not in the Shadow DOM sheet) so it holds\n // even against a hostile host-page reset, and so the launcher is anchored to\n // the viewport without ever participating in the page's flow.\n host.style.cssText =\n \"position:fixed;right:20px;bottom:20px;z-index:2147483000;margin:0;padding:0;border:0;\";\n if (options.reduceMotion) host.setAttribute(\"data-fb-reduce-motion\", \"true\");\n\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = doc.createElement(\"style\");\n style.textContent = LAUNCHER_STYLES;\n shadow.appendChild(style);\n\n // --- The pill: Feedback button + divider + tuck control ---\n const pill = doc.createElement(\"div\");\n pill.className = \"fb-launcher\";\n\n const button = doc.createElement(\"button\");\n button.type = \"button\";\n button.className = \"fb-launcher__button\";\n button.setAttribute(\"aria-haspopup\", \"dialog\");\n button.setAttribute(\"aria-label\", \"Give feedback\");\n button.innerHTML = `${FEEDBACK_ICON}<span class=\"fb-launcher__label\">Feedback</span>`;\n button.addEventListener(\"click\", () => {\n host.dispatchEvent(\n new CustomEvent(LAUNCH_EVENT, { bubbles: true, composed: true }),\n );\n });\n\n const divider = doc.createElement(\"span\");\n divider.className = \"fb-launcher__divider\";\n divider.setAttribute(\"aria-hidden\", \"true\");\n\n const tuck = doc.createElement(\"button\");\n tuck.type = \"button\";\n tuck.className = \"fb-launcher__tuck\";\n tuck.setAttribute(\"data-fb-tuck\", \"\");\n tuck.setAttribute(\"aria-label\", \"Hide feedback button\");\n tuck.title = \"Tuck away\";\n tuck.innerHTML = TUCK_ICON;\n\n pill.append(button, divider, tuck);\n\n // --- The peek chrome: corner hover-zone + edge nub ---\n const peekzone = doc.createElement(\"div\");\n peekzone.className = \"fb-launcher__peekzone\";\n peekzone.setAttribute(\"aria-hidden\", \"true\");\n\n const nub = doc.createElement(\"div\");\n nub.className = \"fb-launcher__nub\";\n nub.setAttribute(\"role\", \"button\");\n nub.setAttribute(\"tabindex\", \"0\");\n nub.setAttribute(\"aria-label\", \"Show feedback button\");\n\n shadow.append(pill, peekzone, nub);\n\n // --- Tuck / peek / welcome state ---\n let hidden = false;\n let peeking = false;\n let peekTimer: ReturnType<typeof setTimeout> | undefined;\n let welcomeTimer: ReturnType<typeof setTimeout> | undefined;\n let welcome: HTMLElement | undefined;\n\n const syncState = (): void => {\n if (hidden) host.setAttribute(\"data-fb-hidden\", \"true\");\n else host.removeAttribute(\"data-fb-hidden\");\n if (hidden && peeking) host.setAttribute(\"data-fb-peeking\", \"true\");\n else host.removeAttribute(\"data-fb-peeking\");\n // The tuck control is a toggle: label it for the direction it will move next.\n tuck.setAttribute(\n \"aria-label\",\n hidden ? \"Show feedback button\" : \"Hide feedback button\",\n );\n tuck.title = hidden ? \"Bring back\" : \"Tuck away\";\n };\n\n const dismissWelcome = (): void => {\n if (welcomeTimer !== undefined) {\n clearTimeout(welcomeTimer);\n welcomeTimer = undefined;\n }\n pill.classList.remove(\"fb-launcher--pulse\");\n welcome?.remove();\n welcome = undefined;\n };\n\n const peekIn = (): void => {\n if (peekTimer !== undefined) {\n clearTimeout(peekTimer);\n peekTimer = undefined;\n }\n if (!peeking) {\n peeking = true;\n syncState();\n }\n };\n\n const peekOut = (): void => {\n if (peekTimer !== undefined) clearTimeout(peekTimer);\n peekTimer = setTimeout(() => {\n peekTimer = undefined;\n peeking = false;\n syncState();\n }, PEEK_OUT_MS);\n };\n\n // Hovering the pill, the nub, or the corner zone all keep the launcher peeked.\n for (const el of [pill, peekzone, nub]) {\n el.addEventListener(\"mouseenter\", peekIn);\n el.addEventListener(\"mouseleave\", peekOut);\n }\n\n const showLauncher = (): void => {\n if (peekTimer !== undefined) {\n clearTimeout(peekTimer);\n peekTimer = undefined;\n }\n hidden = false;\n peeking = false;\n syncState();\n };\n\n const hideLauncher = (): void => {\n dismissWelcome();\n hidden = true;\n peeking = false;\n syncState();\n };\n\n // The tuck control toggles: it tucks the launcher away, and — once tucked and\n // peeked back into reach on hover — brings it fully back, mirroring the chevron.\n tuck.addEventListener(\"click\", () => {\n if (hidden) showLauncher();\n else hideLauncher();\n });\n\n // The nub is a real re-reveal control for pointers that can't hover (touch,\n // keyboard): clicking or Enter/Space brings the launcher fully back.\n nub.addEventListener(\"click\", showLauncher);\n nub.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" || event.key === \" \" || event.key === \"Spacebar\") {\n event.preventDefault();\n showLauncher();\n }\n });\n\n // --- First-visit welcome + its pulse ---\n if (claimFirstVisitWelcome(win, options.key)) {\n welcome = doc.createElement(\"div\");\n welcome.className = \"fb-launcher__welcome\";\n welcome.setAttribute(\"role\", \"status\");\n welcome.innerHTML =\n \"You're all set — tap <strong>Feedback</strong> any time to report something.\";\n shadow.appendChild(welcome);\n if (!options.reduceMotion) pill.classList.add(\"fb-launcher--pulse\");\n welcomeTimer = setTimeout(dismissWelcome, WELCOME_MS);\n }\n\n target.appendChild(host);\n\n const dispose = (): void => {\n if (peekTimer !== undefined) clearTimeout(peekTimer);\n if (welcomeTimer !== undefined) clearTimeout(welcomeTimer);\n };\n\n return { host, dispose };\n}\n\n/** Remove a mounted launcher. Safe to call more than once. */\nexport function unmountLauncher(launcher: Launcher): void {\n launcher.dispose();\n launcher.host.remove();\n}\n","/**\n * Styles for the invite onboarding modal (spec §F) — the Signal look of the\n * frozen Reporter prototype (`docs/design/Fixback Reporter.dc.html`), scoped to\n * the modal's own Shadow DOM so the host page is never touched and never touches\n * it. Tokens mirror `overlay-styles.ts` so launcher, overlay, and modal read as\n * one system.\n */\nexport const ONBOARDING_STYLES = `\n:host {\n --fb-color-accent: #2f6fed;\n --fb-color-accent-hover: #245fd0;\n --fb-color-on-emphasis: #ffffff;\n --fb-color-ink: #0f1720;\n --fb-color-text: #1a2530;\n --fb-color-muted: #5a6875;\n --fb-color-faint: #9aa7b2;\n --fb-color-hint: #b7c1cb;\n --fb-color-border: #dce3ea;\n --fb-color-border-soft: #e6ebf0;\n --fb-color-surface: #ffffff;\n --fb-color-card: #f6f8fa;\n --fb-color-accent-bg: #eaf1fe;\n --fb-color-success: #2f9e5b;\n --fb-font-sans: \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif;\n --fb-font-mono: \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Menlo, Consolas,\n monospace;\n all: initial;\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\n.fb-ob-backdrop {\n position: fixed;\n inset: 0;\n z-index: 2147483010;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(15, 23, 32, 0.55);\n backdrop-filter: blur(3px);\n font-family: var(--fb-font-sans);\n color: var(--fb-color-text);\n animation: fb-ob-fade 0.25s ease both;\n}\n\n.fb-ob-panel {\n width: 400px;\n max-width: 100%;\n background: var(--fb-color-surface);\n border-radius: 16px;\n box-shadow: 0 30px 70px rgba(15, 40, 70, 0.4);\n overflow: hidden;\n animation: fb-ob-pop 0.32s cubic-bezier(0.2, 0.8, 0.3, 1) both;\n}\n\n.fb-ob-head {\n padding: 22px 24px 0;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.fb-ob-mark {\n width: 22px;\n height: 22px;\n border-radius: 6px;\n background: var(--fb-color-accent);\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.fb-ob-mark::after {\n content: \"\";\n width: 7px;\n height: 7px;\n border-radius: 2px;\n background: #fff;\n}\n.fb-ob-brand { font-size: 15px; font-weight: 600; color: var(--fb-color-ink); }\n.fb-ob-chip {\n margin-left: auto;\n font-family: var(--fb-font-mono);\n font-size: 10px;\n color: #8a97a3;\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 6px;\n padding: 2px 7px;\n}\n\n.fb-ob-body { padding: 16px 24px 8px; }\n.fb-ob-title {\n font-size: 19px;\n font-weight: 700;\n color: var(--fb-color-ink);\n letter-spacing: -0.01em;\n}\n.fb-ob-lede {\n font-size: 13.5px;\n color: var(--fb-color-muted);\n line-height: 1.5;\n margin: 7px 0 0;\n}\n.fb-ob-lede strong { color: var(--fb-color-text); }\n\n.fb-ob-card {\n margin: 16px 0;\n padding: 13px 14px;\n background: var(--fb-color-card);\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.fb-ob-row { display: flex; align-items: center; gap: 10px; }\n.fb-ob-row + .fb-ob-row {\n border-top: 1px solid #eef2f6;\n padding-top: 10px;\n}\n.fb-ob-rowlabel {\n font-family: var(--fb-font-mono);\n font-size: 10px;\n color: var(--fb-color-faint);\n width: 70px;\n flex: none;\n}\n.fb-ob-site { font-size: 13px; color: var(--fb-color-text); font-weight: 500; }\n.fb-ob-tier {\n font-size: 11px;\n font-weight: 600;\n color: var(--fb-color-accent);\n background: var(--fb-color-accent-bg);\n padding: 3px 9px;\n border-radius: 6px;\n}\n.fb-ob-tiernote { font-size: 11.5px; color: #8a97a3; }\n\n.fb-ob-fieldlabel {\n display: block;\n font-family: var(--fb-font-mono);\n font-size: 10px;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--fb-color-faint);\n margin-bottom: 6px;\n}\n.fb-ob-fields { display: flex; gap: 8px; }\n.fb-ob-input {\n height: 38px;\n padding: 0 12px;\n border: 1px solid var(--fb-color-border);\n border-radius: 9px;\n font-family: inherit;\n font-size: 13px;\n color: var(--fb-color-text);\n outline: none;\n min-width: 0;\n}\n.fb-ob-input:focus { border-color: var(--fb-color-accent); }\n.fb-ob-name { flex: 1; }\n.fb-ob-email { flex: 1.3; font-family: var(--fb-font-mono); font-size: 12.5px; color: var(--fb-color-muted); }\n\n.fb-ob-privacy {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 14px;\n font-size: 11.5px;\n color: #8a97a3;\n line-height: 1.5;\n}\n.fb-ob-privacy svg { flex: none; margin-top: 1px; }\n.fb-ob-privacy strong { color: var(--fb-color-muted); }\n\n.fb-ob-foot { padding: 16px 24px 22px; }\n.fb-ob-confirm {\n width: 100%;\n height: 44px;\n border: 0;\n border-radius: 11px;\n background: var(--fb-color-accent);\n color: var(--fb-color-on-emphasis);\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n}\n.fb-ob-confirm:hover { background: var(--fb-color-accent-hover); }\n.fb-ob-confirm:disabled { opacity: 0.6; cursor: default; }\n\n@keyframes fb-ob-fade { from { opacity: 0; } to { opacity: 1; } }\n@keyframes fb-ob-pop {\n from { opacity: 0; transform: translateY(8px) scale(0.98); }\n to { opacity: 1; transform: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fb-ob-backdrop, .fb-ob-panel { animation: none; }\n}\n`;\n","/**\n * The invite onboarding modal (spec §F) — the SDK-rendered redemption screen an\n * invited tester sees when a page carries an invite token. It shows the site\n * they were invited to, the **server-derived** access tier the redemption grants,\n * a private-by-default note, and a \"Continue as\" name / email, then confirms.\n *\n * Built to the frozen Signal Reporter prototype\n * (`docs/design/Fixback Reporter.dc.html`). It mounts lazily inside its own open\n * Shadow DOM so the host page is fully isolated, and — like the launcher and\n * overlay — never throws into the host page. It renders only data the SDK\n * truthfully holds: the site's own origin and the server-derived tier. The name /\n * email are **self-provided display fields**, never a trust signal (§F).\n */\n\nimport type { ReporterTier } from \"./boot\";\nimport type { ReporterDisplay } from \"./invite\";\nimport { ONBOARDING_STYLES } from \"./onboarding-styles\";\n\n/** Marks the modal's host element in the light DOM, so it is findable and unique. */\nexport const ONBOARDING_ATTRIBUTE = \"data-fixback-onboard\";\n\n/** The access badge label for each tier (the redemption grants invited or internal). */\nconst TIER_LABEL: Record<ReporterTier, string> = {\n invited: \"Invited tester\",\n internal: \"Internal\",\n public: \"Public\",\n};\n\n/** A short, plain-language note on what the tier means for a submission. */\nconst TIER_NOTE: Record<ReporterTier, string> = {\n invited: \"reviewed before it ships\",\n internal: \"ships straight through\",\n public: \"tracked, not auto-shipped\",\n};\n\nconst SHIELD_ICON =\n '<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"#2f9e5b\" stroke-width=\"1.5\" aria-hidden=\"true\">' +\n '<path d=\"M8 1.8 13.5 4v3.5c0 3.6-2.4 5.6-5.5 6.7C4.9 13.1 2.5 11.1 2.5 7.5V4z\"/>' +\n '<path d=\"M5.8 8 7.3 9.5 10.3 6.2\"/></svg>';\n\n/** Configuration for {@link createOnboardingModal}. */\nexport interface OnboardingConfig {\n /** The site the tester was invited to — its origin (`window.location.host`). */\n readonly origin: string;\n /** The **server-derived** tier the redemption grants (from the invite status). */\n readonly tier: ReporterTier;\n /** Prefill the Continue-as fields from a previously stored display identity. */\n readonly defaults?: ReporterDisplay;\n /** Called with the self-provided display fields when the tester confirms. */\n readonly onConfirm: (display: ReporterDisplay) => void;\n /** Where to mount the modal host. Defaults to `document.body`. */\n readonly target?: HTMLElement;\n /** The document to build in. Defaults to the target's owner document. */\n readonly doc?: Document;\n}\n\n/** A mounted onboarding modal. */\nexport interface OnboardingModal {\n destroy(): void;\n readonly host: HTMLElement;\n}\n\n/** Minimal typed `createElement` helper — attributes plus string / node children. */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n props: Partial<Record<string, string>> = {},\n children: ReadonlyArray<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = doc.createElement(tag);\n for (const [name, value] of Object.entries(props)) {\n if (value !== undefined) node.setAttribute(name, value);\n }\n for (const child of children) {\n node.appendChild(typeof child === \"string\" ? doc.createTextNode(child) : child);\n }\n return node;\n}\n\n/** A trimmed, non-empty field or `undefined` — display fields are never blanks. */\nfunction field(value: string): string | undefined {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Render the onboarding modal into `target` (default `document.body`) and return a\n * handle to remove it. Confirming reads the name / email, fires `onConfirm` once\n * (further clicks are ignored while the caller redeems), and leaves teardown to\n * the caller so it can strip the token and mount the launcher first.\n */\nexport function createOnboardingModal(config: OnboardingConfig): OnboardingModal {\n const target = config.target ?? document.body;\n const doc = config.doc ?? target.ownerDocument;\n\n // Only one onboarding modal can exist at a time — an earlier one is removed\n // first, so a repeated trigger never stacks two dialogs.\n doc.querySelector(`[${ONBOARDING_ATTRIBUTE}]`)?.remove();\n\n const host = h(doc, \"div\", { [ONBOARDING_ATTRIBUTE]: \"\" });\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = doc.createElement(\"style\");\n style.textContent = ONBOARDING_STYLES;\n shadow.appendChild(style);\n\n // Header — brand + \"invite link\" chip.\n const head = h(doc, \"div\", { class: \"fb-ob-head\" }, [\n h(doc, \"span\", { class: \"fb-ob-mark\" }),\n h(doc, \"span\", { class: \"fb-ob-brand\" }, [\"Fixback\"]),\n h(doc, \"span\", { class: \"fb-ob-chip\" }, [\"invite link\"]),\n ]);\n\n // Lede — names the site by its origin (no inviter identity is fetched or shown).\n const lede = h(doc, \"p\", { class: \"fb-ob-lede\" }, [\n \"You've been invited to give feedback on \",\n h(doc, \"strong\", {}, [config.origin]),\n \". Point, mark up, send.\",\n ]);\n\n // Info card — the site and the server-derived access tier.\n const siteRow = h(doc, \"div\", { class: \"fb-ob-row\" }, [\n h(doc, \"span\", { class: \"fb-ob-rowlabel\" }, [\"SITE\"]),\n h(doc, \"span\", { class: \"fb-ob-site\" }, [config.origin]),\n ]);\n const accessRow = h(doc, \"div\", { class: \"fb-ob-row\" }, [\n h(doc, \"span\", { class: \"fb-ob-rowlabel\" }, [\"ACCESS\"]),\n h(doc, \"span\", { class: \"fb-ob-tier\" }, [TIER_LABEL[config.tier]]),\n h(doc, \"span\", { class: \"fb-ob-tiernote\" }, [TIER_NOTE[config.tier]]),\n ]);\n const card = h(doc, \"div\", { class: \"fb-ob-card\" }, [siteRow, accessRow]);\n\n // Continue-as fields.\n const nameInput = h(doc, \"input\", {\n class: \"fb-ob-input fb-ob-name\",\n type: \"text\",\n \"aria-label\": \"Name\",\n placeholder: \"Name\",\n });\n const emailInput = h(doc, \"input\", {\n class: \"fb-ob-input fb-ob-email\",\n type: \"email\",\n \"aria-label\": \"Email\",\n placeholder: \"email@example.com\",\n });\n if (config.defaults?.name) nameInput.value = config.defaults.name;\n if (config.defaults?.email) emailInput.value = config.defaults.email;\n\n const privacy = h(doc, \"div\", { class: \"fb-ob-privacy\" });\n const icon = h(doc, \"span\");\n icon.innerHTML = SHIELD_ICON;\n privacy.appendChild(icon.firstChild ?? doc.createTextNode(\"\"));\n privacy.appendChild(\n h(doc, \"span\", {}, [\n h(doc, \"strong\", {}, [\"Private by default.\"]),\n \" Anything you type is masked before it leaves your browser.\",\n ]),\n );\n\n const body = h(doc, \"div\", { class: \"fb-ob-body\" }, [\n h(doc, \"div\", { class: \"fb-ob-title\" }, [\"You're invited to give feedback\"]),\n lede,\n card,\n h(doc, \"label\", { class: \"fb-ob-fieldlabel\", for: \"fb-ob-name-input\" }, [\"Continue as\"]),\n h(doc, \"div\", { class: \"fb-ob-fields\" }, [nameInput, emailInput]),\n privacy,\n ]);\n nameInput.id = \"fb-ob-name-input\";\n\n const confirm = h(doc, \"button\", { type: \"button\", class: \"fb-ob-confirm\" }, [\n \"Start giving feedback\",\n ]);\n const foot = h(doc, \"div\", { class: \"fb-ob-foot\" }, [confirm]);\n\n const panel = h(\n doc,\n \"div\",\n { class: \"fb-ob-panel\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-label\": \"Fixback invite\" },\n [head, body, foot],\n );\n const backdrop = h(doc, \"div\", { class: \"fb-ob-backdrop\" }, [panel]);\n shadow.appendChild(backdrop);\n\n let confirmed = false;\n confirm.addEventListener(\"click\", () => {\n if (confirmed) return;\n confirmed = true;\n confirm.disabled = true;\n const display: ReporterDisplay = {\n ...(field(nameInput.value) ? { name: field(nameInput.value) } : {}),\n ...(field(emailInput.value) ? { email: field(emailInput.value) } : {}),\n };\n config.onConfirm(display);\n });\n\n target.appendChild(host);\n return {\n host,\n destroy: () => host.remove(),\n };\n}\n","/**\n * The draw surface — arrow / box / pen / text marking over the captured frame\n * (spec 0003 §B, the Reporter prototype's draw toolbar). It is the interactive\n * editor behind the overlay's draw mode: a tool, a live preview, a committed list\n * of {@link Mark}s with undo, and an SVG it renders into. Marks are recorded in\n * **screenshot (viewport) coordinates** so they compose over the full masked\n * screenshot; the overlay reads {@link DrawSurface.marks} when the Reporter\n * attaches.\n *\n * Pointer listeners are capture-phase on the document, so a stroke is intercepted\n * before the host page; a stroke that begins on interactive chrome (the toolbar,\n * the label input) is ignored so the toolbar stays clickable. The surface draws\n * nothing into the host page — only into the SVG the overlay hands it inside its\n * own Shadow DOM.\n */\n\nimport {\n arrowHeadPoints,\n MARK_COLOR,\n type ArrowMark,\n type BoxMark,\n type DrawTool,\n type Mark,\n type PenMark,\n type Point,\n} from \"./annotation\";\n\n/** A mark mid-drag — always a stroke (arrow/box/pen); text is entered via the input. */\ntype StrokePreview = ArrowMark | BoxMark | PenMark;\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/** Stroke width for every mark, in px (matches the prototype). */\nconst STROKE_WIDTH = \"3\";\n\n/** The smallest arrow/box drag that commits, in px — smaller is a stray click. */\nconst MIN_DRAG = 4;\n\n/** The label font, vendored to match the overlay's Signal sans stack. */\nconst LABEL_FONT =\n '600 16px \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\n\n/** Options for {@link startDrawSurface}. */\nexport interface DrawSurfaceOptions {\n /** Document to attach to. Defaults to the global `document`. */\n readonly doc?: Document;\n /** The (viewport-filling) SVG the surface renders committed marks + preview into. */\n readonly svg: SVGSVGElement;\n /** The inline label input the text tool shows, positions, and reads. */\n readonly textInput: HTMLInputElement;\n /** Mark colour. Defaults to {@link MARK_COLOR}. */\n readonly color?: string;\n /** Marks to seed from, so re-entering draw continues an existing annotation. */\n readonly initialMarks?: ReadonlyArray<Mark>;\n /** Notified with a fresh snapshot whenever the committed marks change. */\n readonly onChange?: (marks: ReadonlyArray<Mark>) => void;\n}\n\n/** A running draw surface. */\nexport interface DrawSurface {\n /** Switch the active tool. */\n setTool(tool: DrawTool): void;\n /** The active tool. */\n getTool(): DrawTool;\n /** Remove the most recently committed mark. */\n undo(): void;\n /** A snapshot of the committed marks, in screenshot coordinates. */\n marks(): ReadonlyArray<Mark>;\n /** Detach all listeners and hide the label input. */\n stop(): void;\n}\n\n/**\n * Begin drawing. The returned surface tracks a tool, a live preview stroke, and the\n * committed marks; `marks()` snapshots them for the overlay's Send assembly. Text\n * labels are entered through the provided input (Enter commits, Escape/blur-empty\n * discards). `stop()` detaches everything.\n */\nexport function startDrawSurface(options: DrawSurfaceOptions): DrawSurface {\n const doc = options.doc ?? document;\n const { svg, textInput } = options;\n const color = options.color ?? MARK_COLOR;\n\n let tool: DrawTool = \"arrow\";\n let committed: Mark[] = options.initialMarks ? options.initialMarks.slice() : [];\n let preview: StrokePreview | null = null;\n let drawing = false;\n let pendingText: Point | null = null;\n let stopped = false;\n\n function emitChange(): void {\n options.onChange?.(committed.slice());\n }\n\n function point(event: MouseEvent): Point {\n return { x: Math.round(event.clientX), y: Math.round(event.clientY) };\n }\n\n /** Does the event begin on interactive chrome (a button/input in the path)? */\n function hitsChrome(event: Event): boolean {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [event.target];\n for (const node of path) {\n if (node === doc) break;\n if (node instanceof Element) {\n const tag = node.tagName;\n if (tag === \"BUTTON\" || tag === \"INPUT\" || tag === \"TEXTAREA\") return true;\n }\n }\n return false;\n }\n\n function meaningful(mark: Mark): boolean {\n if (mark.type === \"pen\") return mark.points.length > 1;\n if (mark.type === \"text\") return mark.text.trim().length > 0;\n return Math.abs(mark.x1 - mark.x0) > MIN_DRAG || Math.abs(mark.y1 - mark.y0) > MIN_DRAG;\n }\n\n function onDown(event: MouseEvent): void {\n if (stopped || drawing || hitsChrome(event)) return;\n const p = point(event);\n if (tool === \"text\") {\n openText(p);\n return;\n }\n if (event.cancelable) event.preventDefault();\n drawing = true;\n preview =\n tool === \"pen\"\n ? { type: \"pen\", points: [p], color }\n : { type: tool, x0: p.x, y0: p.y, x1: p.x, y1: p.y, color };\n render();\n }\n\n function onMove(event: MouseEvent): void {\n if (stopped || !drawing || !preview) return;\n const p = point(event);\n if (preview.type === \"pen\") {\n preview = { type: \"pen\", points: [...preview.points, p], color: preview.color };\n } else {\n preview = { ...preview, x1: p.x, y1: p.y };\n }\n render();\n }\n\n function onUp(): void {\n if (stopped || !drawing) return;\n drawing = false;\n const pv = preview;\n preview = null;\n if (pv && meaningful(pv)) {\n committed = [...committed, pv];\n emitChange();\n }\n render();\n }\n\n function openText(p: Point): void {\n pendingText = p;\n textInput.value = \"\";\n textInput.style.display = \"block\";\n textInput.style.left = `${p.x}px`;\n textInput.style.top = `${p.y}px`;\n textInput.onkeydown = onTextKey;\n textInput.onblur = commitText;\n // Focus on the next tick so the current click doesn't immediately blur it.\n setTimeout(() => {\n try {\n textInput.focus();\n } catch {\n /* focus is best-effort — never throw into the host page */\n }\n }, 0);\n }\n\n function onTextKey(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n commitText();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n discardText();\n }\n }\n\n function commitText(): void {\n if (!pendingText) return;\n const text = textInput.value.trim();\n const at = pendingText;\n discardText();\n if (text.length > 0) {\n committed = [...committed, { type: \"text\", x: at.x, y: at.y, text, color }];\n emitChange();\n render();\n }\n }\n\n function discardText(): void {\n pendingText = null;\n textInput.onkeydown = null;\n textInput.onblur = null;\n textInput.value = \"\";\n textInput.style.display = \"none\";\n }\n\n function render(): void {\n while (svg.firstChild) svg.removeChild(svg.firstChild);\n for (const mark of committed) svg.appendChild(renderMark(doc, mark));\n if (preview) svg.appendChild(renderMark(doc, preview));\n }\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n doc.removeEventListener(\"mousedown\", onDown, true);\n doc.removeEventListener(\"mousemove\", onMove, true);\n doc.removeEventListener(\"mouseup\", onUp, true);\n discardText();\n }\n\n doc.addEventListener(\"mousedown\", onDown, true);\n doc.addEventListener(\"mousemove\", onMove, true);\n doc.addEventListener(\"mouseup\", onUp, true);\n render();\n\n return {\n setTool: (next) => {\n tool = next;\n },\n getTool: () => tool,\n undo: () => {\n if (committed.length === 0) return;\n committed = committed.slice(0, -1);\n emitChange();\n render();\n },\n marks: () => committed.slice(),\n stop,\n };\n}\n\n/** Build the SVG element(s) for one mark, in the mark's own coordinate space. */\nfunction renderMark(doc: Document, mark: Mark): SVGElement {\n switch (mark.type) {\n case \"box\": {\n const rect = svgEl(doc, \"rect\", {\n x: String(Math.min(mark.x0, mark.x1)),\n y: String(Math.min(mark.y0, mark.y1)),\n width: String(Math.abs(mark.x1 - mark.x0)),\n height: String(Math.abs(mark.y1 - mark.y0)),\n rx: \"2\",\n fill: \"none\",\n stroke: mark.color,\n \"stroke-width\": STROKE_WIDTH,\n });\n return rect;\n }\n case \"pen\": {\n return svgEl(doc, \"polyline\", {\n points: mark.points.map((p) => `${p.x},${p.y}`).join(\" \"),\n fill: \"none\",\n stroke: mark.color,\n \"stroke-width\": STROKE_WIDTH,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n });\n }\n case \"text\": {\n const text = svgEl(doc, \"text\", {\n x: String(mark.x),\n y: String(mark.y),\n fill: mark.color,\n style: `font:${LABEL_FONT}`,\n });\n text.textContent = mark.text;\n return text;\n }\n case \"arrow\": {\n const group = svgEl(doc, \"g\", {});\n group.appendChild(\n svgEl(doc, \"line\", {\n x1: String(mark.x0),\n y1: String(mark.y0),\n x2: String(mark.x1),\n y2: String(mark.y1),\n stroke: mark.color,\n \"stroke-width\": STROKE_WIDTH,\n \"stroke-linecap\": \"round\",\n }),\n );\n const head = arrowHeadPoints(mark.x0, mark.y0, mark.x1, mark.y1);\n group.appendChild(\n svgEl(doc, \"polygon\", {\n points: head.map((p) => `${p.x},${p.y}`).join(\" \"),\n fill: mark.color,\n }),\n );\n return group;\n }\n }\n}\n\n/** Create a namespaced SVG element with the given attributes. */\nfunction svgEl(\n doc: Document,\n tag: string,\n attrs: Record<string, string>,\n): SVGElement {\n const node = doc.createElementNS(SVG_NS, tag) as SVGElement;\n for (const [name, value] of Object.entries(attrs)) node.setAttribute(name, value);\n return node;\n}\n","/**\n * Region-capture — drag a rectangle over the page to focus the report on one area\n * (spec 0003 §B, the Reporter prototype's capture layer). It produces a `region`\n * rect in screenshot (viewport) coordinates; Escape or a too-small drag abandons\n * it. One of the overlay's three composable, optional marking layers, alongside\n * element-pick and draw.\n *\n * Listeners are attached in the **capture phase** so the drag is intercepted before\n * any host-page handler sees it. It is armed deliberately — the overlay lays a\n * full-screen capture layer over the page (and hides the panel) while it runs — so\n * it captures whatever the Reporter drags, its own layer included. Purely a producer\n * of a `Rect`: it draws nothing; the overlay renders the live selection box from\n * `onProgress`.\n */\n\nimport { normalizeRect, type Rect } from \"./annotation\";\n\n/** Options for {@link startRegionCapture}. */\nexport interface RegionCaptureOptions {\n /** Document to attach to. Defaults to the global `document`. */\n readonly doc?: Document;\n /** Called on each drag update with the current rect (to draw a selection box). */\n readonly onProgress?: (rect: Rect) => void;\n /** Called with the captured rect when the drag ends large enough to keep. */\n readonly onComplete: (rect: Rect) => void;\n /** Called when the capture is abandoned (Escape, or a drag below the floor). */\n readonly onCancel?: () => void;\n /** Minimum width and height, in px, to count as a capture. Defaults to 12. */\n readonly minSize?: number;\n}\n\n/** A running region-capture; call {@link RegionCapture.stop} to detach it. */\nexport interface RegionCapture {\n stop(): void;\n}\n\n/** The smallest drag that counts as a region (matches the prototype's 12px floor). */\nconst DEFAULT_MIN_SIZE = 12;\n\n/**\n * Enter region-capture mode: the next drag on the host page draws out a rectangle,\n * reported live through `onProgress` and committed through `onComplete` on release\n * (when it clears the size floor). Escape, or a drag too small to be meaningful,\n * calls `onCancel`. `stop()` (called automatically on complete/cancel) detaches all\n * listeners.\n */\nexport function startRegionCapture(options: RegionCaptureOptions): RegionCapture {\n const doc = options.doc ?? document;\n const minSize = options.minSize ?? DEFAULT_MIN_SIZE;\n let start: { x: number; y: number } | null = null;\n let stopped = false;\n\n function onDown(event: MouseEvent): void {\n if (stopped || start) return;\n start = { x: event.clientX, y: event.clientY };\n if (event.cancelable) event.preventDefault();\n }\n\n function onMove(event: MouseEvent): void {\n if (stopped || !start) return;\n options.onProgress?.(normalizeRect(start.x, start.y, event.clientX, event.clientY));\n }\n\n function onUp(event: MouseEvent): void {\n if (stopped || !start) return;\n const rect = normalizeRect(start.x, start.y, event.clientX, event.clientY);\n start = null;\n stop();\n if (rect.width < minSize || rect.height < minSize) {\n options.onCancel?.();\n return;\n }\n options.onComplete(rect);\n }\n\n function onKey(event: KeyboardEvent): void {\n if (stopped) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n stop();\n options.onCancel?.();\n }\n }\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n doc.removeEventListener(\"mousedown\", onDown, true);\n doc.removeEventListener(\"mousemove\", onMove, true);\n doc.removeEventListener(\"mouseup\", onUp, true);\n doc.removeEventListener(\"keydown\", onKey, true);\n start = null;\n }\n\n doc.addEventListener(\"mousedown\", onDown, true);\n doc.addEventListener(\"mousemove\", onMove, true);\n doc.addEventListener(\"mouseup\", onUp, true);\n doc.addEventListener(\"keydown\", onKey, true);\n\n return { stop };\n}\n","/**\n * The report overlay's isolated styles, built to the frozen Signal Reporter\n * overlay (`docs/design/Fixback Visual Identity.dc.html`, badge `1d`). Like the\n * launcher's styles these live inside the overlay's Shadow DOM, so nothing here\n * reaches the host page and nothing on the host page reaches in. Token values are\n * vendored Signal tokens (copied from `packages/ui/src/tokens.css`, not imported —\n * the SDK must not depend on `@fixback/ui` at runtime). Keep them in sync by value.\n */\nexport const OVERLAY_STYLES = `\n:host {\n --fb-color-accent: #2f6fed;\n --fb-color-accent-hover: #245fd0;\n --fb-color-on-emphasis: #ffffff;\n --fb-color-ink: #0f1720;\n --fb-color-text: #1a2530;\n --fb-color-muted: #5a6875;\n --fb-color-faint: #9aa7b2;\n --fb-color-border: #e0e6ec;\n --fb-color-border-soft: #e6ebf0;\n --fb-color-surface: #ffffff;\n --fb-color-bug: #e5484d;\n --fb-color-bug-bg: #fdecec;\n --fb-color-impr: #2f6fed;\n --fb-color-impr-bg: #eaf1fe;\n --fb-color-success: #2f9e5b;\n --fb-font-sans: \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif;\n --fb-font-mono: \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Menlo, Consolas,\n monospace;\n\n display: block;\n color: var(--fb-color-text);\n font-family: var(--fb-font-sans);\n font-size: 13px;\n line-height: 1.45;\n -webkit-font-smoothing: antialiased;\n}\n\n* { box-sizing: border-box; }\n\n.fb-ov-panel {\n width: 300px;\n max-width: calc(100vw - 40px);\n background: var(--fb-color-surface);\n border: 1px solid var(--fb-color-border);\n border-radius: 13px;\n box-shadow: 0 18px 44px rgba(20, 40, 70, 0.2);\n overflow: hidden;\n}\n\n.fb-ov-head {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 12px 14px;\n border-bottom: 1px solid var(--fb-color-border-soft);\n}\n.fb-ov-mark-sq {\n width: 13px;\n height: 13px;\n border-radius: 4px;\n background: var(--fb-color-accent);\n flex: none;\n}\n.fb-ov-brand { font-size: 14px; font-weight: 600; color: var(--fb-color-ink); }\n.fb-ov-tier {\n flex: none;\n font-family: var(--fb-font-mono);\n font-size: 9.5px;\n color: var(--fb-color-faint);\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 5px;\n padding: 1px 6px;\n}\n.fb-ov-close {\n margin-left: auto;\n border: 0;\n background: none;\n color: var(--fb-color-faint);\n font-size: 16px;\n line-height: 1;\n padding: 2px 4px;\n cursor: pointer;\n border-radius: 6px;\n}\n.fb-ov-close:hover { color: var(--fb-color-muted); background: #f4f7fa; }\n\n.fb-ov-mark {\n margin: 12px 14px 10px;\n min-height: 52px;\n border-radius: 9px;\n border: 1px solid var(--fb-color-border-soft);\n background: repeating-linear-gradient(135deg, #f4f7fa, #f4f7fa 7px, #eaeff4 7px, #eaeff4 14px);\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n gap: 6px;\n padding: 10px 12px;\n}\n.fb-ov-selector {\n display: none;\n max-width: 100%;\n font-family: var(--fb-font-mono);\n font-size: 10px;\n color: var(--fb-color-on-emphasis);\n background: var(--fb-color-accent);\n padding: 3px 8px;\n border-radius: 5px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.fb-ov-mark.has-element .fb-ov-selector { display: inline-block; }\n.fb-ov-mark-caption { font-size: 10px; color: var(--fb-color-faint); font-family: var(--fb-font-mono); }\n\n.fb-ov-comment {\n display: block;\n width: calc(100% - 28px);\n margin: 0 14px 10px;\n min-height: 62px;\n resize: vertical;\n font-family: inherit;\n font-size: 13px;\n color: var(--fb-color-text);\n border: 1px solid var(--fb-color-border-soft);\n border-radius: 9px;\n padding: 10px 11px;\n}\n.fb-ov-comment::placeholder { color: var(--fb-color-faint); }\n.fb-ov-comment:focus-visible { outline: 2px solid var(--fb-color-accent); outline-offset: 1px; }\n\n.fb-ov-status { padding: 0 14px; font-size: 11px; min-height: 0; }\n.fb-ov-status.is-error { color: var(--fb-color-bug); }\n\n.fb-ov-tools { display: flex; align-items: center; gap: 7px; padding: 8px 14px 14px; }\n.fb-ov-pickbtn,\n.fb-ov-capturebtn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n font-size: 12px;\n color: var(--fb-color-muted);\n background: var(--fb-color-surface);\n border: 1px solid var(--fb-color-border);\n border-radius: 8px;\n padding: 8px 11px;\n cursor: pointer;\n}\n.fb-ov-capturebtn { padding: 8px 9px; }\n.fb-ov-pickbtn:hover,\n.fb-ov-capturebtn:hover { border-color: #cfd8e2; }\n.fb-ov-pickbtn.is-active,\n.fb-ov-capturebtn.is-active,\n.fb-ov-capturebtn.is-attached {\n color: var(--fb-color-accent);\n border-color: var(--fb-color-accent);\n background: var(--fb-color-impr-bg);\n}\n.fb-ov-pickbtn__glyph { font-size: 14px; line-height: 1; }\n.fb-ov-icon { display: block; }\n\n.fb-ov-send {\n margin-left: auto;\n font-family: inherit;\n font-size: 13px;\n font-weight: 600;\n color: var(--fb-color-on-emphasis);\n background: var(--fb-color-accent);\n border: 0;\n border-radius: 8px;\n padding: 9px 18px;\n cursor: pointer;\n}\n.fb-ov-send:hover { background: var(--fb-color-accent-hover); }\n.fb-ov-send:disabled { opacity: 0.6; cursor: default; }\n\n.fb-ov-done { display: none; padding: 24px 18px; text-align: center; }\n.fb-ov-panel.is-sent .fb-ov-form { display: none; }\n.fb-ov-panel.is-sent .fb-ov-done { display: block; }\n.fb-ov-done__check {\n width: 40px; height: 40px; margin: 0 auto 12px;\n border-radius: 50%;\n background: #e7f6ee; color: var(--fb-color-success);\n display: flex; align-items: center; justify-content: center;\n font-size: 20px; font-weight: 700;\n}\n.fb-ov-done__title { font-size: 15px; font-weight: 600; color: var(--fb-color-ink); }\n.fb-ov-done__sub { font-size: 12px; color: var(--fb-color-muted); margin-top: 4px; }\n\n/* The panel is hidden while any full-screen marking layer is active. */\n.fb-ov-panel.is-marking { visibility: hidden; }\n\n.fb-ov-pick,\n.fb-ov-capture,\n.fb-ov-draw { position: fixed; inset: 0; z-index: 2147483002; display: none; }\n.fb-ov-pick.is-visible,\n.fb-ov-capture.is-visible,\n.fb-ov-draw.is-visible { display: block; }\n\n/* Element-pick highlight layer — visual only, never intercepts host events. */\n.fb-ov-pick { pointer-events: none; }\n.fb-ov-highlight {\n position: absolute;\n border: 2px dashed var(--fb-color-accent);\n border-radius: 6px;\n box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.14);\n transition: all 60ms ease;\n}\n.fb-ov-hint {\n position: absolute;\n top: 16px;\n left: 50%;\n transform: translateX(-50%);\n font-family: var(--fb-font-mono);\n font-size: 11px;\n color: var(--fb-color-on-emphasis);\n background: var(--fb-color-ink);\n padding: 6px 12px;\n border-radius: 7px;\n box-shadow: 0 8px 20px rgba(20, 40, 70, 0.25);\n}\n\n/* Region-capture layer — a dim wash with a live selection box. */\n.fb-ov-capture { cursor: crosshair; }\n.fb-ov-capture-dim { position: absolute; inset: 0; background: rgba(15, 23, 32, 0.28); }\n.fb-ov-capture-sel {\n position: absolute;\n border: 2px solid var(--fb-color-accent);\n border-radius: 4px;\n box-shadow: 0 0 0 100vmax rgba(15, 23, 32, 0.32);\n}\n\n/* Draw layer — the mark SVG, the region frame, the label input, and the toolbar. */\n.fb-ov-draw-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }\n.fb-ov-draw-frame {\n position: absolute;\n border: 1px solid rgba(47, 111, 237, 0.5);\n border-radius: 4px;\n box-shadow: 0 0 0 100vmax rgba(15, 23, 32, 0.18);\n pointer-events: none;\n}\n.fb-ov-draw-text {\n position: absolute;\n display: none;\n font-family: var(--fb-font-sans);\n font-size: 15px;\n font-weight: 600;\n color: var(--fb-color-bug);\n background: rgba(255, 255, 255, 0.92);\n border: 1px dashed var(--fb-color-bug);\n border-radius: 4px;\n padding: 2px 6px;\n outline: none;\n z-index: 3;\n}\n.fb-ov-draw-toolbar {\n position: fixed;\n left: 50%;\n bottom: 26px;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 5px;\n background: var(--fb-color-ink);\n border-radius: 12px;\n padding: 7px;\n box-shadow: 0 16px 40px rgba(15, 40, 70, 0.4);\n}\n.fb-ov-drawtool {\n width: 34px;\n height: 34px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #c4ccd4;\n cursor: pointer;\n font-family: inherit;\n}\n.fb-ov-drawtool:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }\n.fb-ov-drawtool.is-active { background: var(--fb-color-accent); color: var(--fb-color-on-emphasis); }\n.fb-ov-drawtool__t { font-weight: 700; font-size: 14px; line-height: 1; }\n.fb-ov-draw-divider { width: 1px; height: 22px; background: #2a343e; margin: 0 3px; }\n.fb-ov-draw-undo {\n width: 34px;\n height: 34px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #c4ccd4;\n cursor: pointer;\n}\n.fb-ov-draw-undo:hover:not(:disabled) { background: rgba(255, 255, 255, 0.08); color: #fff; }\n.fb-ov-draw-undo:disabled { opacity: 0.4; cursor: default; }\n.fb-ov-draw-cancel {\n height: 34px;\n padding: 0 12px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: var(--fb-color-faint);\n font-family: inherit;\n font-size: 12.5px;\n cursor: pointer;\n}\n.fb-ov-draw-cancel:hover { color: #fff; }\n.fb-ov-draw-attach {\n height: 34px;\n padding: 0 15px;\n border: 0;\n border-radius: 8px;\n background: var(--fb-color-accent);\n color: var(--fb-color-on-emphasis);\n font-family: inherit;\n font-size: 12.5px;\n font-weight: 600;\n cursor: pointer;\n}\n.fb-ov-draw-attach:hover { background: var(--fb-color-accent-hover); }\n\n@media (prefers-reduced-motion: reduce) {\n .fb-ov-highlight { transition: none; }\n}\n`;\n","import type { DrawTool, Mark, Rect } from \"./annotation\";\nimport type { IdentityInputs, ProjectGate, ReporterTier } from \"./boot\";\nimport type { Breadcrumb } from \"./breadcrumbs\";\nimport type { ReporterDisplay } from \"./invite\";\nimport { startDrawSurface, type DrawSurface } from \"./draw-surface\";\nimport {\n describeElement,\n startElementPicker,\n type ElementPicker,\n type ElementPickerOptions,\n} from \"./element-picker\";\nimport {\n assembleContent,\n collectEnvironment,\n type SelectedElement,\n} from \"./report\";\nimport { startRegionCapture, type RegionCapture } from \"./region-capture\";\nimport { OVERLAY_STYLES } from \"./overlay-styles\";\nimport type { ReplaySnapshot, ReplaySource } from \"./replay\";\nimport { runBeforeSend, type BeforeSend } from \"./scrub\";\nimport { captureView, extensionFor, type Capture, type CaptureOptions } from \"./screenshot\";\nimport { submitReport, type SubmitInput, type SubmitResult } from \"./submit\";\nimport { SDK_VERSION } from \"./version\";\n\n/** Marks the overlay's host element in the light DOM (skipped by capture/picker). */\nexport const OVERLAY_ATTRIBUTE = \"data-fixback-overlay\";\n\n/** The SVG namespace, for the draw surface's mark layer. */\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/** The draw tools, in toolbar order (spec §B, the Reporter prototype). */\nconst DRAW_TOOLS: ReadonlyArray<{ tool: DrawTool; label: string }> = [\n { tool: \"arrow\", label: \"Arrow\" },\n { tool: \"box\", label: \"Box\" },\n { tool: \"pen\", label: \"Pen\" },\n { tool: \"text\", label: \"Text label\" },\n];\n\n/** How long the confirmation shows before the overlay closes itself. */\nconst AUTO_CLOSE_MS = 1800;\n\ntype CaptureViewFn = (options?: CaptureOptions) => Promise<Capture | null>;\ntype SubmitReportFn = (\n apiUrl: string,\n input: SubmitInput,\n fetchImpl?: typeof fetch,\n) => Promise<SubmitResult>;\ntype StartPickerFn = (options: ElementPickerOptions) => ElementPicker;\n\n/** Injectable collaborators, defaulted to the real implementations. */\nexport interface OverlayDeps {\n readonly captureView: CaptureViewFn;\n readonly submitReport: SubmitReportFn;\n readonly startElementPicker: StartPickerFn;\n}\n\n/** A read-only view of the trace buffer the overlay attaches to a report. */\nexport interface BreadcrumbSource {\n snapshot(): readonly Breadcrumb[];\n}\n\n/** Configuration for {@link createOverlay}. */\nexport interface OverlayConfig {\n readonly apiUrl: string;\n readonly key: string;\n readonly identity?: IdentityInputs;\n /**\n * The Project's Gate, forwarded verbatim from the boot answer. Reserved for\n * Gate-aware launcher / redemption behaviour (spec §A/§F); the overlay itself\n * does not read it yet, but `init` plumbs it through here (ticket #85 / §G).\n */\n readonly gate?: ProjectGate;\n /**\n * The Reporter's **server-derived** trust tier from the boot answer, or `null`\n * when a presented identity was refused. Rendered as a **display-only** chip in\n * the overlay header (spec §G) — never a trust signal, never read for a decision,\n * and never sent back to the server. When `null`/absent no tier is asserted.\n */\n readonly tier?: ReporterTier | null;\n readonly sdkVersion?: string;\n /** The host app's Release (#117, ADR-0024), validated by `init`; rides in the environment. */\n readonly release?: string;\n /**\n * The Reporter's self-provided display name / email (spec §F), when the SDK holds\n * them (from a redemption in this session or a prior one). They ride along with the\n * report so a Member sees who filed it — display only, never a trust signal.\n */\n readonly display?: ReporterDisplay;\n /** Where to mount the overlay host. Defaults to `document.body`. */\n readonly target?: HTMLElement;\n readonly doc?: Document;\n readonly win?: Window;\n readonly deps?: Partial<OverlayDeps>;\n /** The trace buffer whose snapshot rides on each report (spec §C). */\n readonly buffer?: BreadcrumbSource | null;\n /** The replay recorder whose buffered window rides on each report (ADR-0024). */\n readonly replay?: ReplaySource | null;\n /** Per-project client scrub hook, run at the `beforeSend` choke point. */\n readonly beforeSend?: BeforeSend;\n /** Run the built-in default scrubbers. Defaults to `true` (private-by-default). */\n readonly scrub?: boolean;\n}\n\n/** A mounted overlay the launcher opens. */\nexport interface OverlayController {\n open(): void;\n close(): void;\n destroy(): void;\n readonly isOpen: boolean;\n}\n\n/** Which full-screen marking mode is active, if any. */\ntype MarkMode = \"compose\" | \"picking\" | \"capturing\" | \"drawing\";\n\ninterface Refs {\n readonly panel: HTMLElement;\n readonly mark: HTMLElement;\n readonly selector: HTMLElement;\n readonly caption: HTMLElement;\n readonly comment: HTMLTextAreaElement;\n readonly status: HTMLElement;\n readonly pickBtn: HTMLButtonElement;\n readonly captureBtn: HTMLButtonElement;\n readonly sendBtn: HTMLButtonElement;\n readonly highlight: HTMLElement;\n readonly pickLayer: HTMLElement;\n readonly captureLayer: HTMLElement;\n readonly selBox: HTMLElement;\n readonly drawLayer: HTMLElement;\n readonly drawSvg: SVGSVGElement;\n readonly drawText: HTMLInputElement;\n readonly drawFrame: HTMLElement;\n readonly drawTools: Map<DrawTool, HTMLButtonElement>;\n readonly undoBtn: HTMLButtonElement;\n}\n\nfunction h<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n props: Partial<Record<string, string>> = {},\n children: ReadonlyArray<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = doc.createElement(tag);\n for (const [name, value] of Object.entries(props)) {\n if (value !== undefined) node.setAttribute(name, value);\n }\n for (const child of children) {\n node.appendChild(typeof child === \"string\" ? doc.createTextNode(child) : child);\n }\n return node;\n}\n\n/** Create a namespaced SVG element with attributes and optional SVG children. */\nfunction svgNode(\n doc: Document,\n tag: string,\n attrs: Record<string, string> = {},\n children: ReadonlyArray<SVGElement> = [],\n): SVGElement {\n const node = doc.createElementNS(SVG_NS, tag) as SVGElement;\n for (const [name, value] of Object.entries(attrs)) node.setAttribute(name, value);\n for (const child of children) node.appendChild(child);\n return node;\n}\n\n/**\n * Create the report overlay — the on-page panel a Reporter files a report from,\n * built to the frozen Signal Reporter prototype (`docs/design/Fixback Reporter.dc.html`).\n * It mounts lazily inside its own Shadow DOM (isolated from the host page, and\n * marked so the screenshot and element-picker skip it), opens on the launcher's\n * `fixback:launch` seam, and offers three **composable, optional** marking layers\n * over one full masked screenshot (spec §B): **element-pick**, **region-capture**\n * (drag), and **draw** (arrow / box / pen / text, with undo / cancel / attach). On\n * Send it captures the masked screenshot, assembles the structured Annotation\n * (`{ element?, region?, marks? }`, spec §D — marks stay vector, never baked into\n * the PNG), and submits to ingest — showing a confirmation on success and failing\n * quietly otherwise.\n */\nexport function createOverlay(config: OverlayConfig): OverlayController {\n const doc = config.doc ?? document;\n const win = config.win ?? doc.defaultView ?? window;\n const sdkVersion = config.sdkVersion ?? SDK_VERSION;\n const deps: OverlayDeps = {\n captureView: config.deps?.captureView ?? captureView,\n submitReport: config.deps?.submitReport ?? submitReport,\n startElementPicker: config.deps?.startElementPicker ?? startElementPicker,\n };\n\n let host: HTMLElement | null = null;\n let refs: Refs | null = null;\n let picker: ElementPicker | null = null;\n let regionCapture: RegionCapture | null = null;\n let drawSurface: DrawSurface | null = null;\n let pendingRegion: Rect | null = null;\n let autoClose: ReturnType<typeof setTimeout> | null = null;\n let open = false;\n /**\n * The replay window frozen when the overlay opened (ADR-0024): the recorder\n * keeps rotating its buckets while the Reporter composes, so the window that\n * ships is the lead-up to *opening* the overlay — the bug — not to Send.\n */\n let openedReplay: ReplaySnapshot | null = null;\n let mode: MarkMode = \"compose\";\n\n const state: {\n selectedElement: SelectedElement | null;\n region: Rect | null;\n marks: Mark[];\n phase: \"compose\" | \"sending\" | \"sent\";\n } = { selectedElement: null, region: null, marks: [], phase: \"compose\" };\n\n function setStatus(message: string, isError: boolean): void {\n if (!refs) return;\n refs.status.textContent = message;\n refs.status.classList.toggle(\"is-error\", isError);\n }\n\n /** Show exactly one full-screen marking layer, hiding the panel while it runs. */\n function setMode(next: MarkMode): void {\n mode = next;\n if (!refs) return;\n const marking = next !== \"compose\";\n refs.panel.classList.toggle(\"is-marking\", marking);\n refs.pickLayer.classList.toggle(\"is-visible\", next === \"picking\");\n refs.captureLayer.classList.toggle(\"is-visible\", next === \"capturing\");\n refs.drawLayer.classList.toggle(\"is-visible\", next === \"drawing\");\n refs.pickBtn.classList.toggle(\"is-active\", next === \"picking\");\n refs.captureBtn.classList.toggle(\"is-active\", next === \"capturing\" || next === \"drawing\");\n }\n\n /** Reflect the current marking state in the compose panel's mark region. */\n function renderMarking(): void {\n if (!refs) return;\n const hasElement = !!state.selectedElement;\n const hasRegion = !!state.region;\n const markCount = state.marks.length;\n\n refs.mark.classList.toggle(\"has-element\", hasElement);\n refs.selector.textContent = hasElement ? state.selectedElement!.selector : \"\";\n\n refs.pickBtn.textContent = \"\";\n refs.pickBtn.append(\n glyph(doc),\n doc.createTextNode(hasElement ? \"Change element\" : \"Pick element\"),\n );\n refs.captureBtn.classList.toggle(\"is-attached\", hasRegion || markCount > 0);\n\n const bits: string[] = [];\n if (hasElement) bits.push(\"Element\");\n if (hasRegion) bits.push(\"Region\");\n if (markCount > 0) bits.push(`${markCount} mark${markCount === 1 ? \"\" : \"s\"}`);\n refs.caption.textContent = bits.length\n ? `${bits.join(\" · \")} · masked screenshot on Send`\n : \"Masked screenshot attached on Send\";\n }\n\n function positionHighlight(element: Element | null): void {\n if (!refs) return;\n if (!element) {\n refs.highlight.style.display = \"none\";\n return;\n }\n const rect = element.getBoundingClientRect();\n refs.highlight.style.display = \"block\";\n refs.highlight.style.left = `${rect.left}px`;\n refs.highlight.style.top = `${rect.top}px`;\n refs.highlight.style.width = `${rect.width}px`;\n refs.highlight.style.height = `${rect.height}px`;\n }\n\n // ---- element-pick -------------------------------------------------------\n\n function stopPicker(): void {\n picker?.stop();\n picker = null;\n }\n\n function endPick(): void {\n if (refs) refs.highlight.style.display = \"none\";\n stopPicker();\n if (mode === \"picking\") setMode(\"compose\");\n }\n\n function beginPick(): void {\n if (!refs) return;\n closeMarkingModes();\n setMode(\"picking\");\n picker = deps.startElementPicker({\n doc,\n onHover: positionHighlight,\n onPick: (element) => {\n state.selectedElement = describeElement(element);\n endPick();\n renderMarking();\n },\n onCancel: endPick,\n });\n }\n\n // ---- region-capture -----------------------------------------------------\n\n function positionSelBox(rect: Rect | null): void {\n if (!refs) return;\n const box = refs.selBox;\n if (!rect) {\n box.style.display = \"none\";\n return;\n }\n box.style.display = \"block\";\n box.style.left = `${rect.x}px`;\n box.style.top = `${rect.y}px`;\n box.style.width = `${rect.width}px`;\n box.style.height = `${rect.height}px`;\n }\n\n function stopRegionCapture(): void {\n regionCapture?.stop();\n regionCapture = null;\n }\n\n function beginCapture(): void {\n if (!refs) return;\n closeMarkingModes();\n positionSelBox(null);\n setMode(\"capturing\");\n regionCapture = startRegionCapture({\n doc,\n onProgress: positionSelBox,\n onComplete: (rect) => {\n stopRegionCapture();\n positionSelBox(null);\n beginDraw(rect);\n },\n onCancel: () => {\n stopRegionCapture();\n positionSelBox(null);\n setMode(\"compose\");\n },\n });\n }\n\n // ---- draw ---------------------------------------------------------------\n\n function positionDrawFrame(region: Rect): void {\n if (!refs) return;\n refs.drawFrame.style.left = `${region.x}px`;\n refs.drawFrame.style.top = `${region.y}px`;\n refs.drawFrame.style.width = `${region.width}px`;\n refs.drawFrame.style.height = `${region.height}px`;\n }\n\n function setDrawTool(tool: DrawTool): void {\n drawSurface?.setTool(tool);\n if (!refs) return;\n for (const [value, button] of refs.drawTools) {\n button.classList.toggle(\"is-active\", value === tool);\n }\n }\n\n function onMarksChange(marks: ReadonlyArray<Mark>): void {\n if (refs) refs.undoBtn.disabled = marks.length === 0;\n }\n\n function stopDrawSurface(): void {\n drawSurface?.stop();\n drawSurface = null;\n }\n\n function beginDraw(region: Rect): void {\n if (!refs) return;\n pendingRegion = region;\n positionDrawFrame(region);\n setMode(\"drawing\");\n drawSurface = startDrawSurface({\n doc,\n svg: refs.drawSvg,\n textInput: refs.drawText,\n initialMarks: state.marks,\n onChange: onMarksChange,\n });\n setDrawTool(\"arrow\");\n onMarksChange(state.marks);\n }\n\n function attachDraw(): void {\n if (drawSurface) {\n state.marks = drawSurface.marks().slice();\n if (pendingRegion) state.region = pendingRegion;\n }\n endDraw();\n renderMarking();\n }\n\n function cancelDraw(): void {\n // Discard the in-flight capture; previously attached marking is untouched.\n endDraw();\n renderMarking();\n }\n\n function endDraw(): void {\n stopDrawSurface();\n pendingRegion = null;\n if (mode === \"drawing\") setMode(\"compose\");\n }\n\n /** Tear down any active marking mode (before starting another, or on close). */\n function closeMarkingModes(): void {\n stopPicker();\n stopRegionCapture();\n stopDrawSurface();\n pendingRegion = null;\n positionSelBox(null);\n if (refs) refs.highlight.style.display = \"none\";\n if (mode !== \"compose\") setMode(\"compose\");\n }\n\n // ---- send ---------------------------------------------------------------\n\n function clearAutoClose(): void {\n if (autoClose !== null) {\n clearTimeout(autoClose);\n autoClose = null;\n }\n }\n\n async function send(): Promise<void> {\n if (!refs || state.phase === \"sending\") return;\n closeMarkingModes();\n state.phase = \"sending\";\n refs.sendBtn.disabled = true;\n refs.sendBtn.textContent = \"Sending…\";\n setStatus(\"\", false);\n try {\n const assembled = assembleContent({\n comment: refs.comment.value,\n element: state.selectedElement ?? undefined,\n region: state.region ?? undefined,\n marks: state.marks.length > 0 ? state.marks : undefined,\n url: win.location?.href,\n environment: collectEnvironment(win, sdkVersion, config.release),\n trace: config.buffer?.snapshot(),\n reporterName: config.display?.name,\n reporterEmail: config.display?.email,\n });\n // The single client-side scrub choke point (spec §C): default scrubbers +\n // the per-project hook run before transport; a `null` result drops the\n // report entirely.\n const content = runBeforeSend(assembled, {\n hook: config.beforeSend,\n scrub: config.scrub,\n });\n if (!content) {\n state.phase = \"sent\";\n refs.panel.classList.add(\"is-sent\");\n autoClose = setTimeout(close, AUTO_CLOSE_MS);\n return;\n }\n const capture = await deps.captureView({ doc, win });\n const screenshot = capture\n ? { blob: capture.blob, filename: `screenshot.${extensionFor(capture.type)}` }\n : null;\n // The buffered replay window rides as its own part (ADR-0024) — the one\n // frozen when the overlay opened (the lead-up to the bug), falling back to\n // a fresh snapshot only if open-time capture produced nothing. It is read\n // after the scrub hook accepted the report — a dropped report sends nothing.\n const replay = openedReplay ?? config.replay?.snapshot() ?? null;\n const result = await deps.submitReport(config.apiUrl, {\n key: config.key,\n identity: config.identity,\n content,\n screenshot,\n replay,\n });\n if (result.ok) {\n state.phase = \"sent\";\n refs.panel.classList.add(\"is-sent\");\n autoClose = setTimeout(close, AUTO_CLOSE_MS);\n } else {\n resetSendControl();\n setStatus(\n result.reason === \"unreachable\"\n ? \"Couldn't reach Fixback — try again.\"\n : \"Fixback couldn't accept this report.\",\n true,\n );\n }\n } catch {\n resetSendControl();\n setStatus(\"Something went wrong — try again.\", true);\n }\n }\n\n function resetSendControl(): void {\n state.phase = \"compose\";\n if (!refs) return;\n refs.sendBtn.disabled = false;\n refs.sendBtn.textContent = \"Send\";\n }\n\n // ---- build --------------------------------------------------------------\n\n function build(): void {\n host = h(doc, \"div\", { [OVERLAY_ATTRIBUTE]: \"\" });\n host.style.cssText =\n \"position:fixed;right:20px;bottom:84px;z-index:2147483001;margin:0;padding:0;border:0;display:none;\";\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = doc.createElement(\"style\");\n style.textContent = OVERLAY_STYLES;\n shadow.appendChild(style);\n\n // Header\n const closeBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-close\", \"aria-label\": \"Close\" }, [\"✕\"]);\n const head = h(doc, \"div\", { class: \"fb-ov-head\" }, [\n h(doc, \"span\", { class: \"fb-ov-mark-sq\" }),\n h(doc, \"span\", { class: \"fb-ov-brand\" }, [\"Fixback\"]),\n ]);\n // Display-only trust tier chip — present only when boot derived a tier. It\n // reflects the server-derived value verbatim; the client never asserts trust.\n if (config.tier != null) {\n head.appendChild(\n h(doc, \"span\", { class: \"fb-ov-tier\", \"aria-label\": `Trust tier: ${config.tier}` }, [config.tier]),\n );\n }\n head.appendChild(closeBtn);\n\n // Annotation / screenshot marking region\n const selector = h(doc, \"span\", { class: \"fb-ov-selector\" });\n const caption = h(doc, \"span\", { class: \"fb-ov-mark-caption\" });\n const mark = h(doc, \"div\", { class: \"fb-ov-mark\" }, [selector, caption]);\n\n // Comment\n const comment = h(doc, \"textarea\", {\n class: \"fb-ov-comment\",\n placeholder: \"Describe what you saw or want…\",\n \"aria-label\": \"Comment\",\n });\n\n // Status + tools\n const status = h(doc, \"div\", { class: \"fb-ov-status\", role: \"status\", \"aria-live\": \"polite\" });\n const pickBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-pickbtn\", title: \"Point at an element\" });\n pickBtn.addEventListener(\"click\", () => {\n if (state.phase === \"sending\") return;\n if (mode === \"picking\") endPick();\n else beginPick();\n });\n const captureBtn = h(doc, \"button\", {\n type: \"button\",\n class: \"fb-ov-capturebtn\",\n title: \"Capture a region and draw\",\n \"aria-label\": \"Capture a region and draw\",\n });\n captureBtn.appendChild(captureGlyph(doc));\n captureBtn.addEventListener(\"click\", () => {\n if (state.phase === \"sending\") return;\n beginCapture();\n });\n const sendBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-send\" }, [\"Send\"]);\n sendBtn.addEventListener(\"click\", () => void send());\n const tools = h(doc, \"div\", { class: \"fb-ov-tools\" }, [pickBtn, captureBtn, sendBtn]);\n\n const form = h(doc, \"div\", { class: \"fb-ov-form\" }, [mark, comment, status, tools]);\n\n // Confirmation\n const done = h(doc, \"div\", { class: \"fb-ov-done\" }, [\n h(doc, \"div\", { class: \"fb-ov-done__check\" }, [\"✓\"]),\n h(doc, \"div\", { class: \"fb-ov-done__title\" }, [\"Report sent\"]),\n h(doc, \"div\", { class: \"fb-ov-done__sub\" }, [\"Thanks — the team can see it now.\"]),\n ]);\n\n const panel = h(doc, \"div\", {\n class: \"fb-ov-panel\",\n role: \"dialog\",\n \"aria-label\": \"Fixback feedback\",\n }, [head, form, done]);\n\n // Element-pick highlight layer (visual only; never intercepts host events)\n const highlight = h(doc, \"div\", { class: \"fb-ov-highlight\" });\n highlight.style.display = \"none\";\n const pickLayer = h(doc, \"div\", { class: \"fb-ov-pick\" }, [\n h(doc, \"div\", { class: \"fb-ov-hint\" }, [\"Click the element you mean · Esc to cancel\"]),\n highlight,\n ]);\n\n // Region-capture layer (a dim + a live selection box)\n const selBox = h(doc, \"div\", { class: \"fb-ov-capture-sel\" });\n selBox.style.display = \"none\";\n const captureLayer = h(doc, \"div\", { class: \"fb-ov-capture\" }, [\n h(doc, \"div\", { class: \"fb-ov-capture-dim\" }),\n h(doc, \"div\", { class: \"fb-ov-hint\" }, [\"Drag to capture an area · Esc to cancel\"]),\n selBox,\n ]);\n\n // Draw layer: the mark SVG, the label input, the region frame, and the toolbar.\n const drawSvg = svgNode(doc, \"svg\", {\n class: \"fb-ov-draw-svg\",\n width: \"100%\",\n height: \"100%\",\n }) as SVGSVGElement;\n const drawText = h(doc, \"input\", {\n class: \"fb-ov-draw-text\",\n placeholder: \"label…\",\n \"aria-label\": \"Mark label\",\n });\n drawText.style.display = \"none\";\n const drawFrame = h(doc, \"div\", { class: \"fb-ov-draw-frame\" });\n\n const drawTools = new Map<DrawTool, HTMLButtonElement>();\n const toolButtons: HTMLButtonElement[] = [];\n for (const { tool, label } of DRAW_TOOLS) {\n const button = h(doc, \"button\", {\n type: \"button\",\n class: \"fb-ov-drawtool\",\n \"data-tool\": tool,\n title: label,\n \"aria-label\": label,\n });\n button.appendChild(drawToolGlyph(doc, tool));\n button.addEventListener(\"click\", () => setDrawTool(tool));\n drawTools.set(tool, button);\n toolButtons.push(button);\n }\n const undoBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-draw-undo\", title: \"Undo\", \"aria-label\": \"Undo\" });\n undoBtn.appendChild(undoGlyph(doc));\n undoBtn.addEventListener(\"click\", () => drawSurface?.undo());\n const cancelDrawBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-draw-cancel\" }, [\"Cancel\"]);\n cancelDrawBtn.addEventListener(\"click\", () => cancelDraw());\n const attachBtn = h(doc, \"button\", { type: \"button\", class: \"fb-ov-draw-attach\" }, [\"Attach\"]);\n attachBtn.addEventListener(\"click\", () => attachDraw());\n const drawToolbar = h(doc, \"div\", { class: \"fb-ov-draw-toolbar\" }, [\n ...toolButtons,\n h(doc, \"span\", { class: \"fb-ov-draw-divider\" }),\n undoBtn,\n cancelDrawBtn,\n attachBtn,\n ]);\n const drawLayer = h(doc, \"div\", { class: \"fb-ov-draw\" }, [drawFrame, drawSvg, drawText, drawToolbar]);\n\n shadow.append(panel, pickLayer, captureLayer, drawLayer);\n\n closeBtn.addEventListener(\"click\", close);\n\n (config.target ?? doc.body).appendChild(host);\n refs = {\n panel,\n mark,\n selector,\n caption,\n comment,\n status,\n pickBtn,\n captureBtn,\n sendBtn,\n highlight,\n pickLayer,\n captureLayer,\n selBox,\n drawLayer,\n drawSvg,\n drawText,\n drawFrame,\n drawTools,\n undoBtn,\n };\n }\n\n function ensureBuilt(): void {\n if (!host || !refs) build();\n }\n\n function openOverlay(): void {\n ensureBuilt();\n if (!host || !refs) return;\n clearAutoClose();\n closeMarkingModes();\n // Freeze the replay window NOW (ADR-0024): opening the overlay is the\n // moment closest to the bug, and the recorder's buckets keep rotating while\n // the Reporter composes — a snapshot at Send would show the composition,\n // not the lead-up. The SDK's own chrome is blocked from the recording\n // either way; this pins *when* the window ends.\n openedReplay = config.replay?.snapshot() ?? null;\n state.phase = \"compose\";\n state.selectedElement = null;\n state.region = null;\n state.marks = [];\n refs.panel.classList.remove(\"is-sent\");\n refs.comment.value = \"\";\n resetSendControl();\n setStatus(\"\", false);\n renderMarking();\n host.style.display = \"block\";\n open = true;\n try {\n refs.comment.focus();\n } catch {\n /* focus is best-effort — never let it throw into the host page */\n }\n }\n\n function close(): void {\n clearAutoClose();\n closeMarkingModes();\n if (host) host.style.display = \"none\";\n open = false;\n openedReplay = null;\n }\n\n function destroy(): void {\n clearAutoClose();\n closeMarkingModes();\n host?.remove();\n host = null;\n refs = null;\n open = false;\n }\n\n return {\n open: openOverlay,\n close,\n destroy,\n get isOpen() {\n return open;\n },\n };\n}\n\n/** The crosshair glyph on the element-pick control (matches the `⌖` in the prototype). */\nfunction glyph(doc: Document): HTMLElement {\n return h(doc, \"span\", { class: \"fb-ov-pickbtn__glyph\", \"aria-hidden\": \"true\" }, [\"⌖\"]);\n}\n\n/** The frame glyph on the region-capture control (matches the prototype's crop icon). */\nfunction captureGlyph(doc: Document): SVGElement {\n return svgNode(\n doc,\n \"svg\",\n { class: \"fb-ov-icon\", width: \"14\", height: \"14\", viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.5\", \"aria-hidden\": \"true\" },\n [svgNode(doc, \"path\", { d: \"M2 5V2h3M14 5V2h-3M2 11v3h3M14 11v3h-3\" })],\n );\n}\n\n/** The undo glyph on the draw toolbar. */\nfunction undoGlyph(doc: Document): SVGElement {\n return svgNode(\n doc,\n \"svg\",\n { class: \"fb-ov-icon\", width: \"15\", height: \"15\", viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.6\", \"aria-hidden\": \"true\" },\n [svgNode(doc, \"path\", { d: \"M6 4 3 7l3 3M3 7h6a4 4 0 0 1 0 8H7\" })],\n );\n}\n\n/** The per-tool glyph on the draw toolbar (matches the prototype's icons). */\nfunction drawToolGlyph(doc: Document, tool: DrawTool): Node {\n if (tool === \"text\") {\n return h(doc, \"span\", { class: \"fb-ov-drawtool__t\", \"aria-hidden\": \"true\" }, [\"T\"]);\n }\n const paths: Record<Exclude<DrawTool, \"text\">, SVGElement> = {\n arrow: svgNode(doc, \"path\", { d: \"M3 13 13 3M7 3h6v6\" }),\n box: svgNode(doc, \"rect\", { x: \"2.5\", y: \"3.5\", width: \"11\", height: \"9\", rx: \"1\" }),\n pen: svgNode(doc, \"path\", { d: \"M3 13l1-3 6-6 2 2-6 6-3 1Z\" }),\n };\n return svgNode(\n doc,\n \"svg\",\n { class: \"fb-ov-icon\", width: \"15\", height: \"15\", viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.6\", \"aria-hidden\": \"true\" },\n [paths[tool]],\n );\n}\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar _a;\nvar EventType = /* @__PURE__ */ ((EventType2) => {\n EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n EventType2[EventType2[\"Asset\"] = 7] = \"Asset\";\n return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n return PointerTypes2;\n})(PointerTypes || {});\nvar CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {\n CanvasContext2[CanvasContext2[\"2D\"] = 0] = \"2D\";\n CanvasContext2[CanvasContext2[\"WebGL\"] = 1] = \"WebGL\";\n CanvasContext2[CanvasContext2[\"WebGL2\"] = 2] = \"WebGL2\";\n return CanvasContext2;\n})(CanvasContext || {});\nvar MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {\n MediaInteractions2[MediaInteractions2[\"Play\"] = 0] = \"Play\";\n MediaInteractions2[MediaInteractions2[\"Pause\"] = 1] = \"Pause\";\n MediaInteractions2[MediaInteractions2[\"Seeked\"] = 2] = \"Seeked\";\n MediaInteractions2[MediaInteractions2[\"VolumeChange\"] = 3] = \"VolumeChange\";\n MediaInteractions2[MediaInteractions2[\"RateChange\"] = 4] = \"RateChange\";\n return MediaInteractions2;\n})(MediaInteractions || {});\nvar NodeType = /* @__PURE__ */ ((NodeType2) => {\n NodeType2[NodeType2[\"Document\"] = 0] = \"Document\";\n NodeType2[NodeType2[\"DocumentType\"] = 1] = \"DocumentType\";\n NodeType2[NodeType2[\"Element\"] = 2] = \"Element\";\n NodeType2[NodeType2[\"Text\"] = 3] = \"Text\";\n NodeType2[NodeType2[\"CDATA\"] = 4] = \"CDATA\";\n NodeType2[NodeType2[\"Comment\"] = 5] = \"Comment\";\n return NodeType2;\n})(NodeType || {});\nconst testableAccessors = {\n Node: [\n \"childNodes\",\n \"parentNode\",\n \"parentElement\",\n \"textContent\",\n \"ownerDocument\"\n ],\n ShadowRoot: [\"host\", \"styleSheets\"],\n Element: [\"shadowRoot\", \"querySelector\", \"querySelectorAll\"],\n MutationObserver: []\n};\nconst testableMethods = {\n Node: [\"contains\", \"getRootNode\"],\n ShadowRoot: [\"getSelection\"],\n Element: [],\n MutationObserver: [\"constructor\"]\n};\nconst untaintedBasePrototype = {};\nconst untaintedBaseIframeCleanup = {};\nconst isAngularZonePresent = () => {\n return !!globalThis.Zone;\n};\nfunction getUntaintedPrototype(key) {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key];\n const defaultObj = globalThis[key];\n const defaultPrototype = defaultObj.prototype;\n const accessorNames = key in testableAccessors ? testableAccessors[key] : void 0;\n const isUntaintedAccessors = Boolean(\n accessorNames && // @ts-expect-error 2345\n accessorNames.every(\n (accessor) => {\n var _a2, _b;\n return Boolean(\n (_b = (_a2 = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a2.get) == null ? void 0 : _b.toString().includes(\"[native code]\")\n );\n }\n )\n );\n const methodNames = key in testableMethods ? testableMethods[key] : void 0;\n const isUntaintedMethods = Boolean(\n methodNames && methodNames.every(\n // @ts-expect-error 2345\n (method) => {\n var _a2;\n return typeof defaultPrototype[method] === \"function\" && ((_a2 = defaultPrototype[method]) == null ? void 0 : _a2.toString().includes(\"[native code]\"));\n }\n )\n );\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype;\n return defaultObj.prototype;\n }\n try {\n const iframeEl = document.createElement(\"iframe\");\n iframeEl.style.display = \"none\";\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype;\n const untaintedObject = win[key].prototype;\n if (!untaintedObject) {\n iframeEl.remove();\n return defaultPrototype;\n }\n const ua = navigator.userAgent;\n if (ua.includes(\"Safari\") && !ua.includes(\"Chrome\")) {\n iframeEl.classList.add(\"rr-block\");\n iframeEl.setAttribute(\"__rrwebUntaintedMutationObserver\", \"\");\n untaintedBaseIframeCleanup[key] = () => iframeEl.remove();\n } else {\n iframeEl.remove();\n }\n return untaintedBasePrototype[key] = untaintedObject;\n } catch {\n return defaultPrototype;\n }\n}\nconst untaintedAccessorCache = {};\nfunction getUntaintedAccessor(key, instance, accessor) {\n var _a2;\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance\n );\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedAccessor = (_a2 = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor\n )) == null ? void 0 : _a2.get;\n if (!untaintedAccessor) return instance[accessor];\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n return untaintedAccessor.call(instance);\n}\nconst untaintedMethodCache = {};\nfunction getUntaintedMethod(key, instance, method) {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance\n );\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n if (typeof untaintedMethod !== \"function\") return instance[method];\n untaintedMethodCache[cacheKey] = untaintedMethod;\n return untaintedMethod.bind(instance);\n}\nfunction ownerDocument(n) {\n return getUntaintedAccessor(\"Node\", n, \"ownerDocument\");\n}\nfunction childNodes(n) {\n return getUntaintedAccessor(\"Node\", n, \"childNodes\");\n}\nfunction parentNode(n) {\n return getUntaintedAccessor(\"Node\", n, \"parentNode\");\n}\nfunction parentElement(n) {\n return getUntaintedAccessor(\"Node\", n, \"parentElement\");\n}\nfunction textContent(n) {\n return getUntaintedAccessor(\"Node\", n, \"textContent\");\n}\nfunction contains(n, other) {\n return getUntaintedMethod(\"Node\", n, \"contains\")(other);\n}\nfunction getRootNode(n) {\n return getUntaintedMethod(\"Node\", n, \"getRootNode\")();\n}\nfunction host(n) {\n if (!n || !(\"host\" in n)) return null;\n return getUntaintedAccessor(\"ShadowRoot\", n, \"host\");\n}\nfunction styleSheets(n) {\n return n.styleSheets;\n}\nfunction shadowRoot(n) {\n if (!n || !(\"shadowRoot\" in n)) return null;\n return getUntaintedAccessor(\"Element\", n, \"shadowRoot\");\n}\nfunction querySelector(n, selectors) {\n return getUntaintedAccessor(\"Element\", n, \"querySelector\")(selectors);\n}\nfunction querySelectorAll(n, selectors) {\n return getUntaintedAccessor(\"Element\", n, \"querySelectorAll\")(selectors);\n}\nfunction mutationObserverCtor() {\n return [\n getUntaintedPrototype(\"MutationObserver\").constructor,\n untaintedBaseIframeCleanup[\"MutationObserver\"] ?? (() => {\n })\n ];\n}\nlet nowTimestamp = Date.now;\nif (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {\n nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();\n}\nfunction patch(source, name, replacement) {\n try {\n if (!(name in source)) {\n return () => {\n };\n }\n const original = source[name];\n const wrapped = replacement(original);\n if (typeof wrapped === \"function\") {\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original\n }\n });\n }\n source[name] = wrapped;\n return () => {\n source[name] = original;\n };\n } catch {\n return () => {\n };\n }\n}\nconst index = {\n ownerDocument,\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n nowTimestamp,\n mutationObserverCtor,\n patch\n};\nfunction isElement(n) {\n return n.nodeType === n.ELEMENT_NODE;\n}\nfunction isShadowRoot(n) {\n const hostEl = (\n // anchor and textarea elements also have a `host` property\n // but only shadow roots have a `mode` property\n n && \"host\" in n && \"mode\" in n && index.host(n) || null\n );\n return Boolean(\n hostEl && \"shadowRoot\" in hostEl && index.shadowRoot(hostEl) === n\n );\n}\nfunction isNativeShadowDom(shadowRoot2) {\n return Object.prototype.toString.call(shadowRoot2) === \"[object ShadowRoot]\";\n}\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\n if (cssText.includes(\" background-clip: text;\") && !cssText.includes(\" -webkit-background-clip: text;\")) {\n cssText = cssText.replace(\n /\\sbackground-clip:\\s*text;/g,\n \" -webkit-background-clip: text; background-clip: text;\"\n );\n }\n return cssText;\n}\nfunction escapeImportStatement(rule) {\n const { cssText } = rule;\n if (cssText.split('\"').length < 3) return cssText;\n const statement = [\"@import\", `url(${JSON.stringify(rule.href)})`];\n if (rule.layerName === \"\") {\n statement.push(`layer`);\n } else if (rule.layerName) {\n statement.push(`layer(${rule.layerName})`);\n }\n if (rule.supportsText) {\n statement.push(`supports(${rule.supportsText})`);\n }\n if (rule.media.length) {\n statement.push(rule.media.mediaText);\n }\n return statement.join(\" \") + \";\";\n}\nfunction stringifyStylesheet(s) {\n try {\n const rules = s.rules || s.cssRules;\n if (!rules) {\n return null;\n }\n let sheetHref = s.href;\n if (!sheetHref && s.ownerNode) {\n sheetHref = s.ownerNode.baseURI;\n }\n const stringifiedRules = Array.from(\n rules,\n (rule) => stringifyRule(rule, sheetHref)\n ).join(\"\");\n return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);\n } catch (error) {\n return null;\n }\n}\nfunction stringifyRule(rule, sheetHref) {\n if (isCSSImportRule(rule)) {\n let importStringified;\n try {\n importStringified = // for same-origin stylesheets,\n // we can access the imported stylesheet rules directly\n stringifyStylesheet(rule.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement\n escapeImportStatement(rule);\n } catch (error) {\n importStringified = rule.cssText;\n }\n if (rule.styleSheet.href) {\n return absolutifyURLs(importStringified, rule.styleSheet.href);\n }\n return importStringified;\n } else {\n let ruleStringified = rule.cssText;\n if (isCSSStyleRule(rule) && rule.selectorText.includes(\":\")) {\n ruleStringified = fixSafariColons(ruleStringified);\n }\n if (sheetHref) {\n return absolutifyURLs(ruleStringified, sheetHref);\n }\n return ruleStringified;\n }\n}\nfunction fixSafariColons(cssStringified) {\n const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\n return cssStringified.replace(regex, \"$1\\\\$2\");\n}\nfunction isCSSImportRule(rule) {\n return \"styleSheet\" in rule;\n}\nfunction isCSSStyleRule(rule) {\n return \"selectorText\" in rule;\n}\nclass Mirror {\n constructor() {\n __publicField(this, \"idNodeMap\", /* @__PURE__ */ new Map());\n __publicField(this, \"nodeMetaMap\", /* @__PURE__ */ new WeakMap());\n }\n getId(n) {\n var _a2;\n if (!n) return -1;\n const id = (_a2 = this.getMeta(n)) == null ? void 0 : _a2.id;\n return id ?? -1;\n }\n getNode(id) {\n return this.idNodeMap.get(id) || null;\n }\n getIds() {\n return Array.from(this.idNodeMap.keys());\n }\n getMeta(n) {\n return this.nodeMetaMap.get(n) || null;\n }\n // removes the node from idNodeMap\n // doesn't remove the node from nodeMetaMap\n removeNodeFromMap(n) {\n const id = this.getId(n);\n this.idNodeMap.delete(id);\n if (n.childNodes) {\n n.childNodes.forEach(\n (childNode) => this.removeNodeFromMap(childNode)\n );\n }\n }\n has(id) {\n return this.idNodeMap.has(id);\n }\n hasNode(node) {\n return this.nodeMetaMap.has(node);\n }\n add(n, meta) {\n const id = meta.id;\n this.idNodeMap.set(id, n);\n this.nodeMetaMap.set(n, meta);\n }\n replace(id, n) {\n const oldNode = this.getNode(id);\n if (oldNode) {\n const meta = this.nodeMetaMap.get(oldNode);\n if (meta) this.nodeMetaMap.set(n, meta);\n }\n this.idNodeMap.set(id, n);\n }\n reset() {\n this.idNodeMap = /* @__PURE__ */ new Map();\n this.nodeMetaMap = /* @__PURE__ */ new WeakMap();\n }\n}\nfunction createMirror() {\n return new Mirror();\n}\nfunction maskInputValue({\n element,\n maskInputOptions,\n tagName,\n type,\n value,\n maskInputFn\n}) {\n let text = value || \"\";\n const actualType = type && toLowerCase(type);\n if (maskInputOptions[tagName.toLowerCase()] || actualType && maskInputOptions[actualType]) {\n if (maskInputFn) {\n text = maskInputFn(text, element);\n } else {\n text = \"*\".repeat(text.length);\n }\n }\n return text;\n}\nfunction toLowerCase(str) {\n return str.toLowerCase();\n}\nconst ORIGINAL_ATTRIBUTE_NAME = \"__rrweb_original__\";\nfunction is2DCanvasBlank(canvas) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return true;\n const chunkSize = 50;\n for (let x = 0; x < canvas.width; x += chunkSize) {\n for (let y = 0; y < canvas.height; y += chunkSize) {\n const getImageData = ctx.getImageData;\n const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData ? getImageData[ORIGINAL_ATTRIBUTE_NAME] : getImageData;\n const pixelBuffer = new Uint32Array(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n originalGetImageData.call(\n ctx,\n x,\n y,\n Math.min(chunkSize, canvas.width - x),\n Math.min(chunkSize, canvas.height - y)\n ).data.buffer\n );\n if (pixelBuffer.some((pixel) => pixel !== 0)) return false;\n }\n }\n return true;\n}\nfunction getInputType(element) {\n const type = element.type;\n return element.hasAttribute(\"data-rr-is-password\") ? \"password\" : type ? (\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n toLowerCase(type)\n ) : null;\n}\nfunction extractFileExtension(path, baseURL) {\n let url;\n try {\n url = new URL(path, baseURL ?? window.location.href);\n } catch (err) {\n return null;\n }\n const regex = /\\.([0-9a-z]+)(?:$)/i;\n const match = url.pathname.match(regex);\n return (match == null ? void 0 : match[1]) ?? null;\n}\nfunction extractOrigin(url) {\n let origin = \"\";\n if (url.indexOf(\"//\") > -1) {\n origin = url.split(\"/\").slice(0, 3).join(\"/\");\n } else {\n origin = url.split(\"/\")[0];\n }\n origin = origin.split(\"?\")[0];\n return origin;\n}\nconst URL_IN_CSS_REF = /url\\((?:(')([^']*)'|(\")(.*?)\"|([^)]*))\\)/gm;\nconst URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\\/\\//i;\nconst URL_WWW_MATCH = /^www\\..*/i;\nconst DATA_URI = /^(data:)([^,]*),(.*)/i;\nfunction absolutifyURLs(cssText, href) {\n return (cssText || \"\").replace(\n URL_IN_CSS_REF,\n (origin, quote1, path1, quote2, path2, path3) => {\n const filePath = path1 || path2 || path3;\n const maybeQuote = quote1 || quote2 || \"\";\n if (!filePath) {\n return origin;\n }\n if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {\n return `url(${maybeQuote}${filePath}${maybeQuote})`;\n }\n if (DATA_URI.test(filePath)) {\n return `url(${maybeQuote}${filePath}${maybeQuote})`;\n }\n if (filePath[0] === \"/\") {\n return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;\n }\n const filePathNoHash = filePath.split(\"#\")[0];\n const maybeHash = filePath.substring(filePathNoHash.length);\n const stack = href.split(\"#\")[0].split(\"/\");\n const parts = filePathNoHash.split(\"/\");\n stack.pop();\n for (const part of parts) {\n if (part === \".\") {\n continue;\n } else if (part === \"..\") {\n stack.pop();\n } else {\n stack.push(part);\n }\n }\n return `url(${maybeQuote}${stack.join(\"/\")}${maybeHash}${maybeQuote})`;\n }\n );\n}\nfunction normalizeCssString(cssText, _testNoPxNorm = false) {\n if (_testNoPxNorm) {\n return cssText.replace(/(\\/\\*[^*]*\\*\\/)|[\\s;]/g, \"\");\n } else {\n return cssText.replace(/(\\/\\*[^*]*\\*\\/)|[\\s;]/g, \"\").replace(/0px/g, \"0\");\n }\n}\nfunction splitCssText(cssText, style, _testNoPxNorm = false) {\n const childNodes2 = Array.from(style.childNodes);\n const splits = [];\n let iterCount = 0;\n if (childNodes2.length > 1 && cssText && typeof cssText === \"string\") {\n let cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);\n const normFactor = cssTextNorm.length / cssText.length;\n for (let i = 1; i < childNodes2.length; i++) {\n if (childNodes2[i].textContent && typeof childNodes2[i].textContent === \"string\") {\n const textContentNorm = normalizeCssString(\n childNodes2[i].textContent,\n _testNoPxNorm\n );\n const jLimit = 100;\n let j = 3;\n for (; j < textContentNorm.length; j++) {\n if (\n // keep consuming css identifiers (to get a decent chunk more quickly)\n textContentNorm[j].match(/[a-zA-Z0-9]/) || // substring needs to be unique to this section\n textContentNorm.indexOf(textContentNorm.substring(0, j), 1) !== -1\n ) {\n continue;\n }\n break;\n }\n for (; j < textContentNorm.length; j++) {\n let startSubstring = textContentNorm.substring(0, j);\n let cssNormSplits = cssTextNorm.split(startSubstring);\n let splitNorm = -1;\n if (cssNormSplits.length === 2) {\n splitNorm = cssNormSplits[0].length;\n } else if (cssNormSplits.length > 2 && cssNormSplits[0] === \"\" && childNodes2[i - 1].textContent !== \"\") {\n splitNorm = cssTextNorm.indexOf(startSubstring, 1);\n } else if (cssNormSplits.length === 1) {\n startSubstring = startSubstring.substring(\n 0,\n startSubstring.length - 1\n );\n cssNormSplits = cssTextNorm.split(startSubstring);\n if (cssNormSplits.length <= 1) {\n splits.push(cssText);\n return splits;\n }\n j = jLimit + 1;\n } else if (j === textContentNorm.length - 1) {\n splitNorm = cssTextNorm.indexOf(startSubstring);\n }\n if (cssNormSplits.length >= 2 && j > jLimit) {\n const prevTextContent = childNodes2[i - 1].textContent;\n if (prevTextContent && typeof prevTextContent === \"string\") {\n const prevMinLength = normalizeCssString(prevTextContent).length;\n splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);\n }\n if (splitNorm === -1) {\n splitNorm = cssNormSplits[0].length;\n }\n }\n if (splitNorm !== -1) {\n let k = Math.floor(splitNorm / normFactor);\n for (; k > 0 && k < cssText.length; ) {\n iterCount += 1;\n if (iterCount > 50 * childNodes2.length) {\n splits.push(cssText);\n return splits;\n }\n const normPart = normalizeCssString(\n cssText.substring(0, k),\n _testNoPxNorm\n );\n if (normPart.length === splitNorm) {\n splits.push(cssText.substring(0, k));\n cssText = cssText.substring(k);\n cssTextNorm = cssTextNorm.substring(splitNorm);\n break;\n } else if (normPart.length < splitNorm) {\n k += Math.max(\n 1,\n Math.floor((splitNorm - normPart.length) / normFactor)\n );\n } else {\n k -= Math.max(\n 1,\n Math.floor((normPart.length - splitNorm) * normFactor)\n );\n }\n }\n break;\n }\n }\n }\n }\n }\n splits.push(cssText);\n return splits;\n}\nfunction markCssSplits(cssText, style) {\n return splitCssText(cssText, style).join(\"/* rr_split */\");\n}\nlet _id = 1;\nconst tagNameRegex = new RegExp(\"[^a-z0-9-_:]\");\nconst IGNORED_NODE = -2;\nfunction genId() {\n return _id++;\n}\nfunction getValidTagName(element) {\n if (element instanceof HTMLFormElement) {\n return \"form\";\n }\n const processedTagName = toLowerCase(element.tagName);\n if (tagNameRegex.test(processedTagName)) {\n return \"div\";\n }\n return processedTagName;\n}\nlet canvasService;\nlet canvasCtx;\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\n if (attributeValue.trim() === \"\") {\n return attributeValue;\n }\n let pos = 0;\n function collectCharacters(regEx) {\n let chars2;\n const match = regEx.exec(attributeValue.substring(pos));\n if (match) {\n chars2 = match[0];\n pos += chars2.length;\n return chars2;\n }\n return \"\";\n }\n const output = [];\n while (true) {\n collectCharacters(SRCSET_COMMAS_OR_SPACES);\n if (pos >= attributeValue.length) {\n break;\n }\n let url = collectCharacters(SRCSET_NOT_SPACES);\n if (url.slice(-1) === \",\") {\n url = absoluteToDoc(doc, url.substring(0, url.length - 1));\n output.push(url);\n } else {\n let descriptorsStr = \"\";\n url = absoluteToDoc(doc, url);\n let inParens = false;\n while (true) {\n const c = attributeValue.charAt(pos);\n if (c === \"\") {\n output.push((url + descriptorsStr).trim());\n break;\n } else if (!inParens) {\n if (c === \",\") {\n pos += 1;\n output.push((url + descriptorsStr).trim());\n break;\n } else if (c === \"(\") {\n inParens = true;\n }\n } else {\n if (c === \")\") {\n inParens = false;\n }\n }\n descriptorsStr += c;\n pos += 1;\n }\n }\n }\n return output.join(\", \");\n}\nconst cachedDocument = /* @__PURE__ */ new WeakMap();\nfunction absoluteToDoc(doc, attributeValue) {\n if (!attributeValue || attributeValue.trim() === \"\") {\n return attributeValue;\n }\n return getHref(doc, attributeValue);\n}\nfunction isSVGElement(el) {\n return Boolean(el.tagName === \"svg\" || el.ownerSVGElement);\n}\nfunction getHref(doc, customHref) {\n let a = cachedDocument.get(doc);\n if (!a) {\n a = doc.createElement(\"a\");\n cachedDocument.set(doc, a);\n }\n if (!customHref) {\n customHref = \"\";\n } else if (customHref.startsWith(\"blob:\") || customHref.startsWith(\"data:\")) {\n return customHref;\n }\n a.setAttribute(\"href\", customHref);\n return a.href;\n}\nfunction transformAttribute(doc, tagName, name, value) {\n if (!value) {\n return value;\n }\n if (name === \"src\" || name === \"href\" && !(tagName === \"use\" && value[0] === \"#\")) {\n return absoluteToDoc(doc, value);\n } else if (name === \"xlink:href\" && value[0] !== \"#\") {\n return absoluteToDoc(doc, value);\n } else if (name === \"background\" && [\"table\", \"td\", \"th\"].includes(tagName)) {\n return absoluteToDoc(doc, value);\n } else if (name === \"srcset\") {\n return getAbsoluteSrcsetString(doc, value);\n } else if (name === \"style\") {\n return absolutifyURLs(value, getHref(doc));\n } else if (tagName === \"object\" && name === \"data\") {\n return absoluteToDoc(doc, value);\n }\n return value;\n}\nfunction ignoreAttribute(tagName, name, _value) {\n return [\"video\", \"audio\"].includes(tagName) && name === \"autoplay\";\n}\nfunction _isBlockedElement(element, blockClass, blockSelector) {\n try {\n if (typeof blockClass === \"string\") {\n if (element.classList.contains(blockClass)) {\n return true;\n }\n } else {\n for (let eIndex = element.classList.length; eIndex--; ) {\n const className = element.classList[eIndex];\n if (blockClass.test(className)) {\n return true;\n }\n }\n }\n if (blockSelector) {\n return element.matches(blockSelector);\n }\n } catch (e) {\n }\n return false;\n}\nfunction classMatchesRegex(node, regex, checkAncestors) {\n if (!node) return false;\n if (node.nodeType !== node.ELEMENT_NODE) {\n if (!checkAncestors) return false;\n return classMatchesRegex(index.parentNode(node), regex, checkAncestors);\n }\n for (let eIndex = node.classList.length; eIndex--; ) {\n const className = node.classList[eIndex];\n if (regex.test(className)) {\n return true;\n }\n }\n if (!checkAncestors) return false;\n return classMatchesRegex(index.parentNode(node), regex, checkAncestors);\n}\nfunction needMaskingText(node, maskTextClass, maskTextSelector, checkAncestors) {\n let el;\n if (isElement(node)) {\n el = node;\n if (!index.childNodes(el).length) {\n return false;\n }\n } else if (index.parentElement(node) === null) {\n return false;\n } else {\n el = index.parentElement(node);\n }\n try {\n if (typeof maskTextClass === \"string\") {\n if (checkAncestors) {\n if (el.closest(`.${maskTextClass}`)) return true;\n } else {\n if (el.classList.contains(maskTextClass)) return true;\n }\n } else {\n if (classMatchesRegex(el, maskTextClass, checkAncestors)) return true;\n }\n if (maskTextSelector) {\n if (checkAncestors) {\n if (el.closest(maskTextSelector)) return true;\n } else {\n if (el.matches(maskTextSelector)) return true;\n }\n }\n } catch (e) {\n }\n return false;\n}\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\n const win = iframeEl.contentWindow;\n if (!win) {\n return;\n }\n let fired = false;\n let readyState;\n try {\n readyState = win.document.readyState;\n } catch (error) {\n return;\n }\n if (readyState !== \"complete\") {\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, iframeLoadTimeout);\n iframeEl.addEventListener(\"load\", () => {\n clearTimeout(timer);\n fired = true;\n listener();\n });\n return;\n }\n const blankUrl = \"about:blank\";\n if (win.location.href !== blankUrl || iframeEl.src === blankUrl || iframeEl.src === \"\") {\n setTimeout(listener, 0);\n return iframeEl.addEventListener(\"load\", listener);\n }\n iframeEl.addEventListener(\"load\", listener);\n}\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\n let fired = false;\n let styleSheetLoaded;\n try {\n styleSheetLoaded = link.sheet;\n } catch (error) {\n return;\n }\n if (styleSheetLoaded) return;\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, styleSheetLoadTimeout);\n link.addEventListener(\"load\", () => {\n clearTimeout(timer);\n fired = true;\n listener();\n });\n}\nfunction serializeNode(n, options) {\n const {\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n needsMask,\n inlineStylesheet,\n maskInputOptions = {},\n maskTextFn,\n maskInputFn,\n dataURLOptions = {},\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement = false,\n cssCaptured = false\n } = options;\n const rootId = getRootId(doc, mirror2);\n switch (n.nodeType) {\n case n.DOCUMENT_NODE:\n if (n.compatMode !== \"CSS1Compat\") {\n return {\n type: NodeType.Document,\n childNodes: [],\n compatMode: n.compatMode\n // probably \"BackCompat\"\n };\n } else {\n return {\n type: NodeType.Document,\n childNodes: []\n };\n }\n case n.DOCUMENT_TYPE_NODE:\n return {\n type: NodeType.DocumentType,\n name: n.name,\n publicId: n.publicId,\n systemId: n.systemId,\n rootId\n };\n case n.ELEMENT_NODE:\n return serializeElementNode(n, {\n doc,\n blockClass,\n blockSelector,\n inlineStylesheet,\n maskInputOptions,\n maskInputFn,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement,\n rootId\n });\n case n.TEXT_NODE:\n return serializeTextNode(n, {\n doc,\n needsMask,\n maskTextFn,\n rootId,\n cssCaptured\n });\n case n.CDATA_SECTION_NODE:\n return {\n type: NodeType.CDATA,\n textContent: \"\",\n rootId\n };\n case n.COMMENT_NODE:\n return {\n type: NodeType.Comment,\n textContent: index.textContent(n) || \"\",\n rootId\n };\n default:\n return false;\n }\n}\nfunction getRootId(doc, mirror2) {\n if (!mirror2.hasNode(doc)) return void 0;\n const docId = mirror2.getId(doc);\n return docId === 1 ? void 0 : docId;\n}\nfunction serializeTextNode(n, options) {\n const { needsMask, maskTextFn, rootId, cssCaptured } = options;\n const parent = index.parentNode(n);\n const parentTagName = parent && parent.tagName;\n let textContent2 = \"\";\n const isStyle = parentTagName === \"STYLE\" ? true : void 0;\n const isScript = parentTagName === \"SCRIPT\" ? true : void 0;\n if (isScript) {\n textContent2 = \"SCRIPT_PLACEHOLDER\";\n } else if (!cssCaptured) {\n textContent2 = index.textContent(n);\n if (isStyle && textContent2) {\n textContent2 = absolutifyURLs(textContent2, getHref(options.doc));\n }\n }\n if (!isStyle && !isScript && textContent2 && needsMask) {\n textContent2 = maskTextFn ? maskTextFn(textContent2, index.parentElement(n)) : textContent2.replace(/[\\S]/g, \"*\");\n }\n return {\n type: NodeType.Text,\n textContent: textContent2 || \"\",\n rootId\n };\n}\nfunction serializeElementNode(n, options) {\n const {\n doc,\n blockClass,\n blockSelector,\n inlineStylesheet,\n maskInputOptions = {},\n maskInputFn,\n dataURLOptions = {},\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement = false,\n rootId\n } = options;\n const needBlock = _isBlockedElement(n, blockClass, blockSelector);\n const tagName = getValidTagName(n);\n let attributes = {};\n const len = n.attributes.length;\n for (let i = 0; i < len; i++) {\n const attr = n.attributes[i];\n if (!ignoreAttribute(tagName, attr.name, attr.value)) {\n attributes[attr.name] = transformAttribute(\n doc,\n tagName,\n toLowerCase(attr.name),\n attr.value\n );\n }\n }\n if (tagName === \"link\" && inlineStylesheet) {\n const stylesheet = Array.from(doc.styleSheets).find((s) => {\n return s.href === n.href;\n });\n let cssText = null;\n if (stylesheet) {\n cssText = stringifyStylesheet(stylesheet);\n }\n if (cssText) {\n delete attributes.rel;\n delete attributes.href;\n attributes._cssText = cssText;\n }\n }\n if (tagName === \"style\" && n.sheet) {\n let cssText = stringifyStylesheet(\n n.sheet\n );\n if (cssText) {\n if (n.childNodes.length > 1) {\n cssText = markCssSplits(cssText, n);\n }\n attributes._cssText = cssText;\n }\n }\n if ([\"input\", \"textarea\", \"select\"].includes(tagName)) {\n const value = n.value;\n const checked = n.checked;\n if (attributes.type !== \"radio\" && attributes.type !== \"checkbox\" && attributes.type !== \"submit\" && attributes.type !== \"button\" && value) {\n attributes.value = maskInputValue({\n element: n,\n type: getInputType(n),\n tagName,\n value,\n maskInputOptions,\n maskInputFn\n });\n } else if (checked) {\n attributes.checked = checked;\n }\n }\n if (tagName === \"option\") {\n if (n.selected && !maskInputOptions[\"select\"]) {\n attributes.selected = true;\n } else {\n delete attributes.selected;\n }\n }\n if (tagName === \"dialog\" && n.open) {\n attributes.rr_open_mode = n.matches(\"dialog:modal\") ? \"modal\" : \"non-modal\";\n }\n if (tagName === \"canvas\" && recordCanvas) {\n if (n.__context === \"2d\") {\n if (!is2DCanvasBlank(n)) {\n attributes.rr_dataURL = n.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n }\n } else if (!(\"__context\" in n)) {\n const canvasDataURL = n.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n const blankCanvas = doc.createElement(\"canvas\");\n blankCanvas.width = n.width;\n blankCanvas.height = n.height;\n const blankCanvasDataURL = blankCanvas.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n if (canvasDataURL !== blankCanvasDataURL) {\n attributes.rr_dataURL = canvasDataURL;\n }\n }\n }\n if (tagName === \"img\" && inlineImages) {\n if (!canvasService) {\n canvasService = doc.createElement(\"canvas\");\n canvasCtx = canvasService.getContext(\"2d\");\n }\n const image = n;\n const imageSrc = image.currentSrc || image.getAttribute(\"src\") || \"<unknown-src>\";\n const priorCrossOrigin = image.crossOrigin;\n const recordInlineImage = () => {\n image.removeEventListener(\"load\", recordInlineImage);\n try {\n canvasService.width = image.naturalWidth;\n canvasService.height = image.naturalHeight;\n canvasCtx.drawImage(image, 0, 0);\n attributes.rr_dataURL = canvasService.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n } catch (err) {\n if (image.crossOrigin !== \"anonymous\") {\n image.crossOrigin = \"anonymous\";\n if (image.complete && image.naturalWidth !== 0)\n recordInlineImage();\n else image.addEventListener(\"load\", recordInlineImage);\n return;\n } else {\n console.warn(\n `Cannot inline img src=${imageSrc}! Error: ${err}`\n );\n }\n }\n if (image.crossOrigin === \"anonymous\") {\n priorCrossOrigin ? attributes.crossOrigin = priorCrossOrigin : image.removeAttribute(\"crossorigin\");\n }\n };\n if (image.complete && image.naturalWidth !== 0) recordInlineImage();\n else image.addEventListener(\"load\", recordInlineImage);\n }\n if ([\"audio\", \"video\"].includes(tagName)) {\n const mediaAttributes = attributes;\n mediaAttributes.rr_mediaState = n.paused ? \"paused\" : \"played\";\n mediaAttributes.rr_mediaCurrentTime = n.currentTime;\n mediaAttributes.rr_mediaPlaybackRate = n.playbackRate;\n mediaAttributes.rr_mediaMuted = n.muted;\n mediaAttributes.rr_mediaLoop = n.loop;\n mediaAttributes.rr_mediaVolume = n.volume;\n }\n if (!newlyAddedElement) {\n if (n.scrollLeft) {\n attributes.rr_scrollLeft = n.scrollLeft;\n }\n if (n.scrollTop) {\n attributes.rr_scrollTop = n.scrollTop;\n }\n }\n if (needBlock) {\n const { width, height } = n.getBoundingClientRect();\n attributes = {\n class: attributes.class,\n rr_width: `${width}px`,\n rr_height: `${height}px`\n };\n }\n if (tagName === \"iframe\" && !keepIframeSrcFn(attributes.src)) {\n if (!n.contentDocument) {\n attributes.rr_src = attributes.src;\n }\n delete attributes.src;\n }\n let isCustomElement;\n try {\n if (customElements.get(tagName)) isCustomElement = true;\n } catch (e) {\n }\n return {\n type: NodeType.Element,\n tagName,\n attributes,\n childNodes: [],\n isSVG: isSVGElement(n) || void 0,\n needBlock,\n rootId,\n isCustom: isCustomElement\n };\n}\nfunction lowerIfExists(maybeAttr) {\n if (maybeAttr === void 0 || maybeAttr === null) {\n return \"\";\n } else {\n return maybeAttr.toLowerCase();\n }\n}\nfunction slimDOMDefaults(_slimDOMOptions) {\n if (_slimDOMOptions === true || _slimDOMOptions === \"all\") {\n return {\n script: true,\n comment: true,\n headFavicon: true,\n headWhitespace: true,\n headMetaSocial: true,\n headMetaRobots: true,\n headMetaHttpEquiv: true,\n headMetaVerification: true,\n // the following are off for slimDOMOptions === true,\n // as they destroy some (hidden) info:\n headMetaAuthorship: _slimDOMOptions === \"all\",\n headMetaDescKeywords: _slimDOMOptions === \"all\",\n headTitleMutations: _slimDOMOptions === \"all\"\n };\n } else if (_slimDOMOptions) {\n return _slimDOMOptions;\n }\n return {};\n}\nfunction slimDOMExcluded(sn, slimDOMOptions) {\n if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\n return true;\n } else if (sn.type === NodeType.Element) {\n if (slimDOMOptions.script && // script tag\n (sn.tagName === \"script\" || // (module)preload link\n sn.tagName === \"link\" && (sn.attributes.rel === \"preload\" && sn.attributes.as === \"script\" || sn.attributes.rel === \"modulepreload\") || // prefetch link\n sn.tagName === \"link\" && sn.attributes.rel === \"prefetch\" && typeof sn.attributes.href === \"string\" && extractFileExtension(sn.attributes.href) === \"js\")) {\n return true;\n } else if (slimDOMOptions.headFavicon && (sn.tagName === \"link\" && sn.attributes.rel === \"shortcut icon\" || sn.tagName === \"meta\" && (lowerIfExists(sn.attributes.name).match(\n /^msapplication-tile(image|color)$/\n ) || lowerIfExists(sn.attributes.name) === \"application-name\" || lowerIfExists(sn.attributes.rel) === \"icon\" || lowerIfExists(sn.attributes.rel) === \"apple-touch-icon\" || lowerIfExists(sn.attributes.rel) === \"shortcut icon\"))) {\n return true;\n } else if (sn.tagName === \"meta\") {\n if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\n return true;\n } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)\n lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === \"pinterest\")) {\n return true;\n } else if (slimDOMOptions.headMetaRobots && (lowerIfExists(sn.attributes.name) === \"robots\" || lowerIfExists(sn.attributes.name) === \"googlebot\" || lowerIfExists(sn.attributes.name) === \"bingbot\")) {\n return true;\n } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes[\"http-equiv\"] !== void 0) {\n return true;\n } else if (slimDOMOptions.headMetaAuthorship && (lowerIfExists(sn.attributes.name) === \"author\" || lowerIfExists(sn.attributes.name) === \"generator\" || lowerIfExists(sn.attributes.name) === \"framework\" || lowerIfExists(sn.attributes.name) === \"publisher\" || lowerIfExists(sn.attributes.name) === \"progid\" || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {\n return true;\n } else if (slimDOMOptions.headMetaVerification && (lowerIfExists(sn.attributes.name) === \"google-site-verification\" || lowerIfExists(sn.attributes.name) === \"yandex-verification\" || lowerIfExists(sn.attributes.name) === \"csrf-token\" || lowerIfExists(sn.attributes.name) === \"p:domain_verify\" || lowerIfExists(sn.attributes.name) === \"verify-v1\" || lowerIfExists(sn.attributes.name) === \"verification\" || lowerIfExists(sn.attributes.name) === \"shopify-checkout-api-token\")) {\n return true;\n }\n }\n }\n return false;\n}\nfunction serializeNodeWithId(n, options) {\n const {\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n skipChild = false,\n inlineStylesheet = true,\n maskInputOptions = {},\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions = {},\n inlineImages = false,\n recordCanvas = false,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout = 5e3,\n onStylesheetLoad,\n stylesheetLoadTimeout = 5e3,\n keepIframeSrcFn = () => false,\n newlyAddedElement = false,\n cssCaptured = false\n } = options;\n let { needsMask } = options;\n let { preserveWhiteSpace = true } = options;\n if (!needsMask) {\n const checkAncestors = needsMask === void 0;\n needsMask = needMaskingText(\n n,\n maskTextClass,\n maskTextSelector,\n checkAncestors\n );\n }\n const _serializedNode = serializeNode(n, {\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n needsMask,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement,\n cssCaptured\n });\n if (!_serializedNode) {\n console.warn(n, \"not serialized\");\n return null;\n }\n let id;\n if (mirror2.hasNode(n)) {\n id = mirror2.getId(n);\n } else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType.Text && !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, \"\").length) {\n id = IGNORED_NODE;\n } else {\n id = genId();\n }\n const serializedNode = Object.assign(_serializedNode, { id });\n mirror2.add(n, serializedNode);\n if (id === IGNORED_NODE) {\n return null;\n }\n if (onSerialize) {\n onSerialize(n);\n }\n let recordChild = !skipChild;\n if (serializedNode.type === NodeType.Element) {\n recordChild = recordChild && !serializedNode.needBlock;\n delete serializedNode.needBlock;\n const shadowRootEl = index.shadowRoot(n);\n if (shadowRootEl && isNativeShadowDom(shadowRootEl))\n serializedNode.isShadowHost = true;\n }\n if ((serializedNode.type === NodeType.Document || serializedNode.type === NodeType.Element) && recordChild) {\n if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType.Element && serializedNode.tagName === \"head\") {\n preserveWhiteSpace = false;\n }\n const bypassOptions = {\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n cssCaptured: false\n };\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"textarea\" && serializedNode.attributes.value !== void 0) ;\n else {\n if (serializedNode.type === NodeType.Element && serializedNode.attributes._cssText !== void 0 && typeof serializedNode.attributes._cssText === \"string\") {\n bypassOptions.cssCaptured = true;\n }\n for (const childN of Array.from(index.childNodes(n))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n let shadowRootEl = null;\n if (isElement(n) && (shadowRootEl = index.shadowRoot(n))) {\n for (const childN of Array.from(index.childNodes(shadowRootEl))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n isNativeShadowDom(shadowRootEl) && (serializedChildNode.isShadow = true);\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n }\n const parent = index.parentNode(n);\n if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {\n serializedNode.isShadow = true;\n }\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"iframe\") {\n onceIframeLoaded(\n n,\n () => {\n const iframeDoc = n.contentDocument;\n if (iframeDoc && onIframeLoad) {\n const serializedIframeNode = serializeNodeWithId(iframeDoc, {\n doc: iframeDoc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn\n });\n if (serializedIframeNode) {\n onIframeLoad(\n n,\n serializedIframeNode\n );\n }\n }\n },\n iframeLoadTimeout\n );\n }\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"link\" && typeof serializedNode.attributes.rel === \"string\" && (serializedNode.attributes.rel === \"stylesheet\" || serializedNode.attributes.rel === \"preload\" && typeof serializedNode.attributes.href === \"string\" && extractFileExtension(serializedNode.attributes.href) === \"css\")) {\n onceStylesheetLoaded(\n n,\n () => {\n if (onStylesheetLoad) {\n const serializedLinkNode = serializeNodeWithId(n, {\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn\n });\n if (serializedLinkNode) {\n onStylesheetLoad(\n n,\n serializedLinkNode\n );\n }\n }\n },\n stylesheetLoadTimeout\n );\n }\n return serializedNode;\n}\nfunction snapshot(n, options) {\n const {\n mirror: mirror2 = new Mirror(),\n blockClass = \"rr-block\",\n blockSelector = null,\n maskTextClass = \"rr-mask\",\n maskTextSelector = null,\n inlineStylesheet = true,\n inlineImages = false,\n recordCanvas = false,\n maskAllInputs = false,\n maskTextFn,\n maskInputFn,\n slimDOM = false,\n dataURLOptions,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn = () => false\n } = options;\n const maskInputOptions = maskAllInputs === true ? {\n color: true,\n date: true,\n \"datetime-local\": true,\n email: true,\n month: true,\n number: true,\n range: true,\n search: true,\n tel: true,\n text: true,\n time: true,\n url: true,\n week: true,\n textarea: true,\n select: true,\n password: true\n } : maskAllInputs === false ? {\n password: true\n } : maskAllInputs;\n const slimDOMOptions = slimDOMDefaults(slimDOM);\n return serializeNodeWithId(n, {\n doc: n,\n mirror: mirror2,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n newlyAddedElement: false\n });\n}\nclass BaseRRNode {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any\n constructor(..._args) {\n __publicField(this, \"parentElement\", null);\n __publicField(this, \"parentNode\", null);\n __publicField(this, \"ownerDocument\");\n __publicField(this, \"firstChild\", null);\n __publicField(this, \"lastChild\", null);\n __publicField(this, \"previousSibling\", null);\n __publicField(this, \"nextSibling\", null);\n __publicField(this, \"ELEMENT_NODE\", 1);\n __publicField(this, \"TEXT_NODE\", 3);\n // corresponding nodeType value of standard HTML Node\n __publicField(this, \"nodeType\");\n __publicField(this, \"nodeName\");\n __publicField(this, \"RRNodeType\");\n }\n get childNodes() {\n const childNodes2 = [];\n let childIterator = this.firstChild;\n while (childIterator) {\n childNodes2.push(childIterator);\n childIterator = childIterator.nextSibling;\n }\n return childNodes2;\n }\n contains(node) {\n if (!(node instanceof BaseRRNode)) return false;\n else if (node.ownerDocument !== this.ownerDocument) return false;\n else if (node === this) return true;\n while (node.parentNode) {\n if (node.parentNode === this) return true;\n node = node.parentNode;\n }\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n appendChild(_newChild) {\n throw new Error(\n `RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n insertBefore(_newChild, _refChild) {\n throw new Error(\n `RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n removeChild(_node) {\n throw new Error(\n `RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n toString() {\n return \"RRNode\";\n }\n}\nfunction on(type, fn, target = document) {\n const options = { capture: true, passive: true };\n target.addEventListener(type, fn, options);\n return () => target.removeEventListener(type, fn, options);\n}\nconst DEPARTED_MIRROR_ACCESS_WARNING = \"Please stop import mirror directly. Instead of that,\\r\\nnow you can use replayer.getMirror() to access the mirror instance of a replayer,\\r\\nor you can use record.mirror to access the mirror instance during recording.\";\nlet _mirror = {\n map: {},\n getId() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n return -1;\n },\n getNode() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n return null;\n },\n removeNodeFromMap() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n },\n has() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n return false;\n },\n reset() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n }\n};\nif (typeof window !== \"undefined\" && window.Proxy && window.Reflect) {\n _mirror = new Proxy(_mirror, {\n get(target, prop, receiver) {\n if (prop === \"map\") {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n }\n return Reflect.get(target, prop, receiver);\n }\n });\n}\nfunction throttle(func, wait, options = {}) {\n let timeout = null;\n let previous = 0;\n return function(...args) {\n const now = Date.now();\n if (!previous && options.leading === false) {\n previous = now;\n }\n const remaining = wait - (now - previous);\n const context = this;\n if (remaining <= 0 || remaining > wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n func.apply(context, args);\n } else if (!timeout && options.trailing !== false) {\n timeout = setTimeout(() => {\n previous = options.leading === false ? 0 : Date.now();\n timeout = null;\n func.apply(context, args);\n }, remaining);\n }\n };\n}\nfunction hookSetter(target, key, d, isRevoked, win = window) {\n const original = win.Object.getOwnPropertyDescriptor(target, key);\n win.Object.defineProperty(\n target,\n key,\n isRevoked ? d : {\n set(value) {\n setTimeout(() => {\n d.set.call(this, value);\n }, 0);\n if (original && original.set) {\n original.set.call(this, value);\n }\n }\n }\n );\n return () => hookSetter(target, key, original || {}, true);\n}\nfunction getWindowScroll(win) {\n var _a2, _b, _c, _d;\n const doc = win.document;\n return {\n left: doc.scrollingElement ? doc.scrollingElement.scrollLeft : win.pageXOffset !== void 0 ? win.pageXOffset : doc.documentElement.scrollLeft || (doc == null ? void 0 : doc.body) && ((_a2 = index.parentElement(doc.body)) == null ? void 0 : _a2.scrollLeft) || ((_b = doc == null ? void 0 : doc.body) == null ? void 0 : _b.scrollLeft) || 0,\n top: doc.scrollingElement ? doc.scrollingElement.scrollTop : win.pageYOffset !== void 0 ? win.pageYOffset : (doc == null ? void 0 : doc.documentElement.scrollTop) || (doc == null ? void 0 : doc.body) && ((_c = index.parentElement(doc.body)) == null ? void 0 : _c.scrollTop) || ((_d = doc == null ? void 0 : doc.body) == null ? void 0 : _d.scrollTop) || 0\n };\n}\nfunction getWindowHeight() {\n return window.innerHeight || document.documentElement && document.documentElement.clientHeight || document.body && document.body.clientHeight;\n}\nfunction getWindowWidth() {\n return window.innerWidth || document.documentElement && document.documentElement.clientWidth || document.body && document.body.clientWidth;\n}\nfunction closestElementOfNode(node) {\n if (!node) {\n return null;\n }\n const el = node.nodeType === node.ELEMENT_NODE ? node : index.parentElement(node);\n return el;\n}\nfunction isBlocked(node, blockClass, blockSelector, checkAncestors) {\n if (!node) {\n return false;\n }\n const el = closestElementOfNode(node);\n if (!el) {\n return false;\n }\n try {\n if (typeof blockClass === \"string\") {\n if (el.classList.contains(blockClass)) return true;\n if (checkAncestors && el.closest(\".\" + blockClass) !== null) return true;\n } else {\n if (classMatchesRegex(el, blockClass, checkAncestors)) return true;\n }\n } catch (e) {\n }\n if (blockSelector) {\n if (el.matches(blockSelector)) return true;\n if (checkAncestors && el.closest(blockSelector) !== null) return true;\n }\n return false;\n}\nfunction isSerialized(n, mirror2) {\n return mirror2.getId(n) !== -1;\n}\nfunction isIgnored(n, mirror2, slimDOMOptions) {\n if (n.tagName === \"TITLE\" && slimDOMOptions.headTitleMutations) {\n return true;\n }\n return mirror2.getId(n) === IGNORED_NODE;\n}\nfunction isAncestorRemoved(target, mirror2) {\n if (isShadowRoot(target)) {\n return false;\n }\n const id = mirror2.getId(target);\n if (!mirror2.has(id)) {\n return true;\n }\n const parent = index.parentNode(target);\n if (parent && parent.nodeType === target.DOCUMENT_NODE) {\n return false;\n }\n if (!parent) {\n return true;\n }\n return isAncestorRemoved(parent, mirror2);\n}\nfunction legacy_isTouchEvent(event) {\n return Boolean(event.changedTouches);\n}\nfunction polyfill(win = window) {\n if (\"NodeList\" in win && !win.NodeList.prototype.forEach) {\n win.NodeList.prototype.forEach = Array.prototype.forEach;\n }\n if (\"DOMTokenList\" in win && !win.DOMTokenList.prototype.forEach) {\n win.DOMTokenList.prototype.forEach = Array.prototype.forEach;\n }\n}\nfunction isSerializedIframe(n, mirror2) {\n return Boolean(n.nodeName === \"IFRAME\" && mirror2.getMeta(n));\n}\nfunction isSerializedStylesheet(n, mirror2) {\n return Boolean(\n n.nodeName === \"LINK\" && n.nodeType === n.ELEMENT_NODE && n.getAttribute && n.getAttribute(\"rel\") === \"stylesheet\" && mirror2.getMeta(n)\n );\n}\nfunction hasShadowRoot(n) {\n if (!n) return false;\n if (n instanceof BaseRRNode && \"shadowRoot\" in n) {\n return Boolean(n.shadowRoot);\n }\n return Boolean(index.shadowRoot(n));\n}\nclass StyleSheetMirror {\n constructor() {\n __publicField(this, \"id\", 1);\n __publicField(this, \"styleIDMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"idStyleMap\", /* @__PURE__ */ new Map());\n }\n getId(stylesheet) {\n return this.styleIDMap.get(stylesheet) ?? -1;\n }\n has(stylesheet) {\n return this.styleIDMap.has(stylesheet);\n }\n /**\n * @returns If the stylesheet is in the mirror, returns the id of the stylesheet. If not, return the new assigned id.\n */\n add(stylesheet, id) {\n if (this.has(stylesheet)) return this.getId(stylesheet);\n let newId;\n if (id === void 0) {\n newId = this.id++;\n } else newId = id;\n this.styleIDMap.set(stylesheet, newId);\n this.idStyleMap.set(newId, stylesheet);\n return newId;\n }\n getStyle(id) {\n return this.idStyleMap.get(id) || null;\n }\n reset() {\n this.styleIDMap = /* @__PURE__ */ new WeakMap();\n this.idStyleMap = /* @__PURE__ */ new Map();\n this.id = 1;\n }\n generateId() {\n return this.id++;\n }\n}\nfunction getShadowHost(n) {\n var _a2;\n let shadowHost = null;\n if (\"getRootNode\" in n && ((_a2 = index.getRootNode(n)) == null ? void 0 : _a2.nodeType) === Node.DOCUMENT_FRAGMENT_NODE && index.host(index.getRootNode(n)))\n shadowHost = index.host(index.getRootNode(n));\n return shadowHost;\n}\nfunction getRootShadowHost(n) {\n let rootShadowHost = n;\n let shadowHost;\n while (shadowHost = getShadowHost(rootShadowHost))\n rootShadowHost = shadowHost;\n return rootShadowHost;\n}\nfunction shadowHostInDom(n) {\n const doc = index.ownerDocument(n);\n if (!doc) return false;\n const shadowHost = getRootShadowHost(n);\n return index.contains(doc, shadowHost);\n}\nfunction inDom(n) {\n const doc = index.ownerDocument(n);\n if (!doc) return false;\n return index.contains(doc, n) || shadowHostInDom(n);\n}\nfunction isNodeInLinkedList(n) {\n return \"__ln\" in n;\n}\nclass DoubleLinkedList {\n constructor() {\n __publicField(this, \"length\", 0);\n __publicField(this, \"head\", null);\n __publicField(this, \"tail\", null);\n }\n get(position) {\n if (position >= this.length) {\n throw new Error(\"Position outside of list range\");\n }\n let current = this.head;\n for (let index2 = 0; index2 < position; index2++) {\n current = (current == null ? void 0 : current.next) || null;\n }\n return current;\n }\n addNode(n) {\n const node = {\n value: n,\n previous: null,\n next: null\n };\n n.__ln = node;\n if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {\n const current = n.previousSibling.__ln.next;\n node.next = current;\n node.previous = n.previousSibling.__ln;\n n.previousSibling.__ln.next = node;\n if (current) {\n current.previous = node;\n }\n } else if (n.nextSibling && isNodeInLinkedList(n.nextSibling) && n.nextSibling.__ln.previous) {\n const current = n.nextSibling.__ln.previous;\n node.previous = current;\n node.next = n.nextSibling.__ln;\n n.nextSibling.__ln.previous = node;\n if (current) {\n current.next = node;\n }\n } else {\n if (this.head) {\n this.head.previous = node;\n }\n node.next = this.head;\n this.head = node;\n }\n if (node.next === null) {\n this.tail = node;\n }\n this.length++;\n }\n removeNode(n) {\n const current = n.__ln;\n if (!this.head) {\n return;\n }\n if (!current.previous) {\n this.head = current.next;\n if (this.head) {\n this.head.previous = null;\n } else {\n this.tail = null;\n }\n } else {\n current.previous.next = current.next;\n if (current.next) {\n current.next.previous = current.previous;\n } else {\n this.tail = current.previous;\n }\n }\n if (n.__ln) {\n delete n.__ln;\n }\n this.length--;\n }\n}\nconst moveKey = (id, parentId) => `${id}@${parentId}`;\nclass MutationBuffer {\n constructor() {\n __publicField(this, \"frozen\", false);\n __publicField(this, \"locked\", false);\n __publicField(this, \"texts\", []);\n __publicField(this, \"attributes\", []);\n __publicField(this, \"attributeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"removes\", []);\n __publicField(this, \"mapRemoves\", []);\n __publicField(this, \"movedMap\", {});\n /**\n * the browser MutationObserver emits multiple mutations after\n * a delay for performance reasons, making tracing added nodes hard\n * in our `processMutations` callback function.\n * For example, if we append an element el_1 into body, and then append\n * another element el_2 into el_1, these two mutations may be passed to the\n * callback function together when the two operations were done.\n * Generally we need to trace child nodes of newly added nodes, but in this\n * case if we count el_2 as el_1's child node in the first mutation record,\n * then we will count el_2 again in the second mutation record which was\n * duplicated.\n * To avoid of duplicate counting added nodes, we use a Set to store\n * added nodes and its child nodes during iterate mutation records. Then\n * collect added nodes from the Set which have no duplicate copy. But\n * this also causes newly added nodes will not be serialized with id ASAP,\n * which means all the id related calculation should be lazy too.\n */\n __publicField(this, \"addedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"movedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"droppedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"removesSubTreeCache\", /* @__PURE__ */ new Set());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"blockClass\");\n __publicField(this, \"blockSelector\");\n __publicField(this, \"maskTextClass\");\n __publicField(this, \"maskTextSelector\");\n __publicField(this, \"inlineStylesheet\");\n __publicField(this, \"maskInputOptions\");\n __publicField(this, \"maskTextFn\");\n __publicField(this, \"maskInputFn\");\n __publicField(this, \"keepIframeSrcFn\");\n __publicField(this, \"recordCanvas\");\n __publicField(this, \"inlineImages\");\n __publicField(this, \"slimDOMOptions\");\n __publicField(this, \"dataURLOptions\");\n __publicField(this, \"doc\");\n __publicField(this, \"mirror\");\n __publicField(this, \"iframeManager\");\n __publicField(this, \"stylesheetManager\");\n __publicField(this, \"shadowDomManager\");\n __publicField(this, \"canvasManager\");\n __publicField(this, \"processedNodeManager\");\n __publicField(this, \"unattachedDoc\");\n __publicField(this, \"processMutations\", (mutations) => {\n mutations.forEach(this.processMutation);\n this.emit();\n });\n __publicField(this, \"emit\", () => {\n if (this.frozen || this.locked) {\n return;\n }\n const adds = [];\n const addedIds = /* @__PURE__ */ new Set();\n const addList = new DoubleLinkedList();\n const getNextId = (n) => {\n let ns = n;\n let nextId = IGNORED_NODE;\n while (nextId === IGNORED_NODE) {\n ns = ns && ns.nextSibling;\n nextId = ns && this.mirror.getId(ns);\n }\n return nextId;\n };\n const pushAdd = (n) => {\n const parent = index.parentNode(n);\n if (!parent || !inDom(n)) {\n return;\n }\n let cssCaptured = false;\n if (n.nodeType === Node.TEXT_NODE) {\n const parentTag = parent.tagName;\n if (parentTag === \"TEXTAREA\") {\n return;\n } else if (parentTag === \"STYLE\" && this.addedSet.has(parent)) {\n cssCaptured = true;\n }\n }\n const parentId = isShadowRoot(parent) ? this.mirror.getId(getShadowHost(n)) : this.mirror.getId(parent);\n const nextId = getNextId(n);\n if (parentId === -1 || nextId === -1) {\n return addList.addNode(n);\n }\n const sn = serializeNodeWithId(n, {\n doc: this.doc,\n mirror: this.mirror,\n blockClass: this.blockClass,\n blockSelector: this.blockSelector,\n maskTextClass: this.maskTextClass,\n maskTextSelector: this.maskTextSelector,\n skipChild: true,\n newlyAddedElement: true,\n inlineStylesheet: this.inlineStylesheet,\n maskInputOptions: this.maskInputOptions,\n maskTextFn: this.maskTextFn,\n maskInputFn: this.maskInputFn,\n slimDOMOptions: this.slimDOMOptions,\n dataURLOptions: this.dataURLOptions,\n recordCanvas: this.recordCanvas,\n inlineImages: this.inlineImages,\n onSerialize: (currentN) => {\n if (isSerializedIframe(currentN, this.mirror)) {\n this.iframeManager.addIframe(currentN);\n }\n if (isSerializedStylesheet(currentN, this.mirror)) {\n this.stylesheetManager.trackLinkElement(\n currentN\n );\n }\n if (hasShadowRoot(n)) {\n this.shadowDomManager.addShadowRoot(index.shadowRoot(n), this.doc);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n this.iframeManager.attachIframe(iframe, childSn);\n this.shadowDomManager.observeAttachShadow(iframe);\n },\n onStylesheetLoad: (link, childSn) => {\n this.stylesheetManager.attachLinkElement(link, childSn);\n },\n cssCaptured\n });\n if (sn) {\n adds.push({\n parentId,\n nextId,\n node: sn\n });\n addedIds.add(sn.id);\n }\n };\n while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift());\n }\n for (const n of this.movedSet) {\n if (isParentRemoved(this.removesSubTreeCache, n, this.mirror) && !this.movedSet.has(index.parentNode(n))) {\n continue;\n }\n pushAdd(n);\n }\n for (const n of this.addedSet) {\n if (!isAncestorInSet(this.droppedSet, n) && !isParentRemoved(this.removesSubTreeCache, n, this.mirror)) {\n pushAdd(n);\n } else if (isAncestorInSet(this.movedSet, n)) {\n pushAdd(n);\n } else {\n this.droppedSet.add(n);\n }\n }\n let candidate = null;\n while (addList.length) {\n let node = null;\n if (candidate) {\n const parentId = this.mirror.getId(index.parentNode(candidate.value));\n const nextId = getNextId(candidate.value);\n if (parentId !== -1 && nextId !== -1) {\n node = candidate;\n }\n }\n if (!node) {\n let tailNode = addList.tail;\n while (tailNode) {\n const _node = tailNode;\n tailNode = tailNode.previous;\n if (_node) {\n const parentId = this.mirror.getId(index.parentNode(_node.value));\n const nextId = getNextId(_node.value);\n if (nextId === -1) continue;\n else if (parentId !== -1) {\n node = _node;\n break;\n } else {\n const unhandledNode = _node.value;\n const parent = index.parentNode(unhandledNode);\n if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n const shadowHost = index.host(parent);\n const parentId2 = this.mirror.getId(shadowHost);\n if (parentId2 !== -1) {\n node = _node;\n break;\n }\n }\n }\n }\n }\n }\n if (!node) {\n while (addList.head) {\n addList.removeNode(addList.head.value);\n }\n break;\n }\n candidate = node.previous;\n addList.removeNode(node.value);\n pushAdd(node.value);\n }\n const payload = {\n texts: this.texts.map((text) => {\n const n = text.node;\n const parent = index.parentNode(n);\n if (parent && parent.tagName === \"TEXTAREA\") {\n this.genTextAreaValueMutation(parent);\n }\n return {\n id: this.mirror.getId(n),\n value: text.value\n };\n }).filter((text) => !addedIds.has(text.id)).filter((text) => this.mirror.has(text.id)),\n attributes: this.attributes.map((attribute) => {\n const { attributes } = attribute;\n if (typeof attributes.style === \"string\") {\n const diffAsStr = JSON.stringify(attribute.styleDiff);\n const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);\n if (diffAsStr.length < attributes.style.length) {\n if ((diffAsStr + unchangedAsStr).split(\"var(\").length === attributes.style.split(\"var(\").length) {\n attributes.style = attribute.styleDiff;\n }\n }\n }\n return {\n id: this.mirror.getId(attribute.node),\n attributes\n };\n }).filter((attribute) => !addedIds.has(attribute.id)).filter((attribute) => this.mirror.has(attribute.id)),\n removes: this.removes,\n adds\n };\n if (!payload.texts.length && !payload.attributes.length && !payload.removes.length && !payload.adds.length) {\n return;\n }\n this.texts = [];\n this.attributes = [];\n this.attributeMap = /* @__PURE__ */ new WeakMap();\n this.removes = [];\n this.addedSet = /* @__PURE__ */ new Set();\n this.movedSet = /* @__PURE__ */ new Set();\n this.droppedSet = /* @__PURE__ */ new Set();\n this.removesSubTreeCache = /* @__PURE__ */ new Set();\n this.movedMap = {};\n this.mutationCb(payload);\n });\n __publicField(this, \"genTextAreaValueMutation\", (textarea) => {\n let item = this.attributeMap.get(textarea);\n if (!item) {\n item = {\n node: textarea,\n attributes: {},\n styleDiff: {},\n _unchangedStyles: {}\n };\n this.attributes.push(item);\n this.attributeMap.set(textarea, item);\n }\n const value = Array.from(\n index.childNodes(textarea),\n (cn) => index.textContent(cn) || \"\"\n ).join(\"\");\n item.attributes.value = maskInputValue({\n element: textarea,\n maskInputOptions: this.maskInputOptions,\n tagName: textarea.tagName,\n type: getInputType(textarea),\n value,\n maskInputFn: this.maskInputFn\n });\n });\n __publicField(this, \"processMutation\", (m) => {\n if (isIgnored(m.target, this.mirror, this.slimDOMOptions)) {\n return;\n }\n switch (m.type) {\n case \"characterData\": {\n const value = index.textContent(m.target);\n if (!isBlocked(m.target, this.blockClass, this.blockSelector, false) && value !== m.oldValue) {\n this.texts.push({\n value: needMaskingText(\n m.target,\n this.maskTextClass,\n this.maskTextSelector,\n true\n // checkAncestors\n ) && value ? this.maskTextFn ? this.maskTextFn(value, closestElementOfNode(m.target)) : value.replace(/[\\S]/g, \"*\") : value,\n node: m.target\n });\n }\n break;\n }\n case \"attributes\": {\n const target = m.target;\n let attributeName = m.attributeName;\n let value = m.target.getAttribute(attributeName);\n if (attributeName === \"value\") {\n const type = getInputType(target);\n value = maskInputValue({\n element: target,\n maskInputOptions: this.maskInputOptions,\n tagName: target.tagName,\n type,\n value,\n maskInputFn: this.maskInputFn\n });\n }\n if (isBlocked(m.target, this.blockClass, this.blockSelector, false) || value === m.oldValue) {\n return;\n }\n let item = this.attributeMap.get(m.target);\n if (target.tagName === \"IFRAME\" && attributeName === \"src\" && !this.keepIframeSrcFn(value)) {\n if (!target.contentDocument) {\n attributeName = \"rr_src\";\n } else {\n return;\n }\n }\n if (!item) {\n item = {\n node: m.target,\n attributes: {},\n styleDiff: {},\n _unchangedStyles: {}\n };\n this.attributes.push(item);\n this.attributeMap.set(m.target, item);\n }\n if (attributeName === \"type\" && target.tagName === \"INPUT\" && (m.oldValue || \"\").toLowerCase() === \"password\") {\n target.setAttribute(\"data-rr-is-password\", \"true\");\n }\n if (!ignoreAttribute(target.tagName, attributeName)) {\n item.attributes[attributeName] = transformAttribute(\n this.doc,\n toLowerCase(target.tagName),\n toLowerCase(attributeName),\n value\n );\n if (attributeName === \"style\") {\n if (!this.unattachedDoc) {\n try {\n this.unattachedDoc = document.implementation.createHTMLDocument();\n } catch (e) {\n this.unattachedDoc = this.doc;\n }\n }\n const old = this.unattachedDoc.createElement(\"span\");\n if (m.oldValue) {\n old.setAttribute(\"style\", m.oldValue);\n }\n for (const pname of Array.from(target.style)) {\n const newValue = target.style.getPropertyValue(pname);\n const newPriority = target.style.getPropertyPriority(pname);\n if (newValue !== old.style.getPropertyValue(pname) || newPriority !== old.style.getPropertyPriority(pname)) {\n if (newPriority === \"\") {\n item.styleDiff[pname] = newValue;\n } else {\n item.styleDiff[pname] = [newValue, newPriority];\n }\n } else {\n item._unchangedStyles[pname] = [newValue, newPriority];\n }\n }\n for (const pname of Array.from(old.style)) {\n if (target.style.getPropertyValue(pname) === \"\") {\n item.styleDiff[pname] = false;\n }\n }\n } else if (attributeName === \"open\" && target.tagName === \"DIALOG\") {\n if (target.matches(\"dialog:modal\")) {\n item.attributes[\"rr_open_mode\"] = \"modal\";\n } else {\n item.attributes[\"rr_open_mode\"] = \"non-modal\";\n }\n }\n }\n break;\n }\n case \"childList\": {\n if (isBlocked(m.target, this.blockClass, this.blockSelector, true))\n return;\n if (m.target.tagName === \"TEXTAREA\") {\n this.genTextAreaValueMutation(m.target);\n return;\n }\n m.addedNodes.forEach((n) => this.genAdds(n, m.target));\n m.removedNodes.forEach((n) => {\n const nodeId = this.mirror.getId(n);\n const parentId = isShadowRoot(m.target) ? this.mirror.getId(index.host(m.target)) : this.mirror.getId(m.target);\n if (isBlocked(m.target, this.blockClass, this.blockSelector, false) || isIgnored(n, this.mirror, this.slimDOMOptions) || !isSerialized(n, this.mirror)) {\n return;\n }\n if (this.addedSet.has(n)) {\n deepDelete(this.addedSet, n);\n this.droppedSet.add(n);\n } else if (this.addedSet.has(m.target) && nodeId === -1) ;\n else if (isAncestorRemoved(m.target, this.mirror)) ;\n else if (this.movedSet.has(n) && this.movedMap[moveKey(nodeId, parentId)]) {\n deepDelete(this.movedSet, n);\n } else {\n this.removes.push({\n parentId,\n id: nodeId,\n isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target) ? true : void 0\n });\n processRemoves(n, this.removesSubTreeCache);\n }\n this.mapRemoves.push(n);\n });\n break;\n }\n }\n });\n /**\n * Make sure you check if `n`'s parent is blocked before calling this function\n * */\n __publicField(this, \"genAdds\", (n, target) => {\n if (this.processedNodeManager.inOtherBuffer(n, this)) return;\n if (this.addedSet.has(n) || this.movedSet.has(n)) return;\n if (this.mirror.hasNode(n)) {\n if (isIgnored(n, this.mirror, this.slimDOMOptions)) {\n return;\n }\n this.movedSet.add(n);\n let targetId = null;\n if (target && this.mirror.hasNode(target)) {\n targetId = this.mirror.getId(target);\n }\n if (targetId && targetId !== -1) {\n this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;\n }\n } else {\n this.addedSet.add(n);\n this.droppedSet.delete(n);\n }\n if (!isBlocked(n, this.blockClass, this.blockSelector, false)) {\n index.childNodes(n).forEach((childN) => this.genAdds(childN));\n if (hasShadowRoot(n)) {\n index.childNodes(index.shadowRoot(n)).forEach((childN) => {\n this.processedNodeManager.add(childN, this);\n this.genAdds(childN, n);\n });\n }\n }\n });\n }\n init(options) {\n [\n \"mutationCb\",\n \"blockClass\",\n \"blockSelector\",\n \"maskTextClass\",\n \"maskTextSelector\",\n \"inlineStylesheet\",\n \"maskInputOptions\",\n \"maskTextFn\",\n \"maskInputFn\",\n \"keepIframeSrcFn\",\n \"recordCanvas\",\n \"inlineImages\",\n \"slimDOMOptions\",\n \"dataURLOptions\",\n \"doc\",\n \"mirror\",\n \"iframeManager\",\n \"stylesheetManager\",\n \"shadowDomManager\",\n \"canvasManager\",\n \"processedNodeManager\"\n ].forEach((key) => {\n this[key] = options[key];\n });\n }\n freeze() {\n this.frozen = true;\n this.canvasManager.freeze();\n }\n unfreeze() {\n this.frozen = false;\n this.canvasManager.unfreeze();\n this.emit();\n }\n isFrozen() {\n return this.frozen;\n }\n lock() {\n this.locked = true;\n this.canvasManager.lock();\n }\n unlock() {\n this.locked = false;\n this.canvasManager.unlock();\n this.emit();\n }\n reset() {\n this.shadowDomManager.reset();\n this.canvasManager.reset();\n }\n}\nfunction deepDelete(addsSet, n) {\n addsSet.delete(n);\n index.childNodes(n).forEach((childN) => deepDelete(addsSet, childN));\n}\nfunction processRemoves(n, cache) {\n const queue = [n];\n while (queue.length) {\n const next = queue.pop();\n if (cache.has(next)) continue;\n cache.add(next);\n index.childNodes(next).forEach((n2) => queue.push(n2));\n }\n return;\n}\nfunction isParentRemoved(removes, n, mirror2) {\n if (removes.size === 0) return false;\n return _isParentRemoved(removes, n);\n}\nfunction _isParentRemoved(removes, n, _mirror2) {\n const node = index.parentNode(n);\n if (!node) return false;\n return removes.has(node);\n}\nfunction isAncestorInSet(set, n) {\n if (set.size === 0) return false;\n return _isAncestorInSet(set, n);\n}\nfunction _isAncestorInSet(set, n) {\n const parent = index.parentNode(n);\n if (!parent) {\n return false;\n }\n if (set.has(parent)) {\n return true;\n }\n return _isAncestorInSet(set, parent);\n}\nlet errorHandler;\nfunction registerErrorHandler(handler) {\n errorHandler = handler;\n}\nfunction unregisterErrorHandler() {\n errorHandler = void 0;\n}\nconst callbackWrapper = (cb) => {\n if (!errorHandler) {\n return cb;\n }\n const rrwebWrapped = (...rest) => {\n try {\n return cb(...rest);\n } catch (error) {\n if (errorHandler && errorHandler(error) === true) {\n return;\n }\n throw error;\n }\n };\n return rrwebWrapped;\n};\nconst mutationBuffers = [];\nfunction getEventTarget(event) {\n try {\n if (\"composedPath\" in event) {\n const path = event.composedPath();\n if (path.length) {\n return path[0];\n }\n } else if (\"path\" in event && event.path.length) {\n return event.path[0];\n }\n } catch {\n }\n return event && event.target;\n}\nfunction initMutationObserver(options, rootEl) {\n const mutationBuffer = new MutationBuffer();\n mutationBuffers.push(mutationBuffer);\n mutationBuffer.init(options);\n const [ObserverCtor, iframeCleanup] = mutationObserverCtor();\n const observer = new ObserverCtor(\n callbackWrapper(mutationBuffer.processMutations.bind(mutationBuffer))\n );\n observer.observe(rootEl, {\n attributes: true,\n attributeOldValue: true,\n characterData: true,\n characterDataOldValue: true,\n childList: true,\n subtree: true\n });\n return [observer, iframeCleanup];\n}\nfunction initMoveObserver({\n mousemoveCb,\n sampling,\n doc,\n mirror: mirror2\n}) {\n if (sampling.mousemove === false) {\n return () => {\n };\n }\n const threshold = typeof sampling.mousemove === \"number\" ? sampling.mousemove : 50;\n const callbackThreshold = typeof sampling.mousemoveCallback === \"number\" ? sampling.mousemoveCallback : 500;\n let positions = [];\n let timeBaseline;\n const wrappedCb = throttle(\n callbackWrapper(\n (source) => {\n const totalOffset = Date.now() - timeBaseline;\n mousemoveCb(\n positions.map((p) => {\n p.timeOffset -= totalOffset;\n return p;\n }),\n source\n );\n positions = [];\n timeBaseline = null;\n }\n ),\n callbackThreshold\n );\n const updatePosition = callbackWrapper(\n throttle(\n callbackWrapper((evt) => {\n const target = getEventTarget(evt);\n const { clientX, clientY } = legacy_isTouchEvent(evt) ? evt.changedTouches[0] : evt;\n if (!timeBaseline) {\n timeBaseline = nowTimestamp();\n }\n positions.push({\n x: clientX,\n y: clientY,\n id: mirror2.getId(target),\n timeOffset: nowTimestamp() - timeBaseline\n });\n wrappedCb(\n typeof DragEvent !== \"undefined\" && evt instanceof DragEvent ? IncrementalSource.Drag : evt instanceof MouseEvent ? IncrementalSource.MouseMove : IncrementalSource.TouchMove\n );\n }),\n threshold,\n {\n trailing: false\n }\n )\n );\n const handlers = [\n on(\"mousemove\", updatePosition, doc),\n on(\"touchmove\", updatePosition, doc),\n on(\"drag\", updatePosition, doc)\n ];\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initMouseInteractionObserver({\n mouseInteractionCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n sampling\n}) {\n if (sampling.mouseInteraction === false) {\n return () => {\n };\n }\n const disableMap = sampling.mouseInteraction === true || sampling.mouseInteraction === void 0 ? {} : sampling.mouseInteraction;\n const handlers = [];\n let currentPointerType = null;\n const getHandler = (eventKey) => {\n return (event) => {\n const target = getEventTarget(event);\n if (isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n let pointerType = null;\n let thisEventKey = eventKey;\n if (\"pointerType\" in event) {\n switch (event.pointerType) {\n case \"mouse\":\n pointerType = PointerTypes.Mouse;\n break;\n case \"touch\":\n pointerType = PointerTypes.Touch;\n break;\n case \"pen\":\n pointerType = PointerTypes.Pen;\n break;\n }\n if (pointerType === PointerTypes.Touch) {\n if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {\n thisEventKey = \"TouchStart\";\n } else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {\n thisEventKey = \"TouchEnd\";\n }\n } else if (pointerType === PointerTypes.Pen) ;\n } else if (legacy_isTouchEvent(event)) {\n pointerType = PointerTypes.Touch;\n }\n if (pointerType !== null) {\n currentPointerType = pointerType;\n if (thisEventKey.startsWith(\"Touch\") && pointerType === PointerTypes.Touch || thisEventKey.startsWith(\"Mouse\") && pointerType === PointerTypes.Mouse) {\n pointerType = null;\n }\n } else if (MouseInteractions[eventKey] === MouseInteractions.Click) {\n pointerType = currentPointerType;\n currentPointerType = null;\n }\n const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;\n if (!e) {\n return;\n }\n const id = mirror2.getId(target);\n const { clientX, clientY } = e;\n callbackWrapper(mouseInteractionCb)({\n type: MouseInteractions[thisEventKey],\n id,\n x: clientX,\n y: clientY,\n ...pointerType !== null && { pointerType }\n });\n };\n };\n Object.keys(MouseInteractions).filter(\n (key) => Number.isNaN(Number(key)) && !key.endsWith(\"_Departed\") && disableMap[key] !== false\n ).forEach((eventKey) => {\n let eventName = toLowerCase(eventKey);\n const handler = getHandler(eventKey);\n if (window.PointerEvent) {\n switch (MouseInteractions[eventKey]) {\n case MouseInteractions.MouseDown:\n case MouseInteractions.MouseUp:\n eventName = eventName.replace(\n \"mouse\",\n \"pointer\"\n );\n break;\n case MouseInteractions.TouchStart:\n case MouseInteractions.TouchEnd:\n return;\n }\n }\n handlers.push(on(eventName, handler, doc));\n });\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initScrollObserver({\n scrollCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n sampling\n}) {\n const updatePosition = callbackWrapper(\n throttle(\n callbackWrapper((evt) => {\n const target = getEventTarget(evt);\n if (!target || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n const id = mirror2.getId(target);\n if (target === doc && doc.defaultView) {\n const scrollLeftTop = getWindowScroll(doc.defaultView);\n scrollCb({\n id,\n x: scrollLeftTop.left,\n y: scrollLeftTop.top\n });\n } else {\n scrollCb({\n id,\n x: target.scrollLeft,\n y: target.scrollTop\n });\n }\n }),\n sampling.scroll || 100\n )\n );\n return on(\"scroll\", updatePosition, doc);\n}\nfunction initViewportResizeObserver({ viewportResizeCb }, { win }) {\n let lastH = -1;\n let lastW = -1;\n const updateDimension = callbackWrapper(\n throttle(\n callbackWrapper(() => {\n const height = getWindowHeight();\n const width = getWindowWidth();\n if (lastH !== height || lastW !== width) {\n viewportResizeCb({\n width: Number(width),\n height: Number(height)\n });\n lastH = height;\n lastW = width;\n }\n }),\n 200\n )\n );\n return on(\"resize\", updateDimension, win);\n}\nconst INPUT_TAGS = [\"INPUT\", \"TEXTAREA\", \"SELECT\"];\nconst lastInputValueMap = /* @__PURE__ */ new WeakMap();\nfunction initInputObserver({\n inputCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n ignoreClass,\n ignoreSelector,\n maskInputOptions,\n maskInputFn,\n sampling,\n userTriggeredOnInput\n}) {\n function eventHandler(event) {\n let target = getEventTarget(event);\n const userTriggered = event.isTrusted;\n const tagName = target && target.tagName;\n if (target && tagName === \"OPTION\") {\n target = index.parentElement(target);\n }\n if (!target || !tagName || INPUT_TAGS.indexOf(tagName) < 0 || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n if (target.classList.contains(ignoreClass) || ignoreSelector && target.matches(ignoreSelector)) {\n return;\n }\n let text = target.value;\n let isChecked = false;\n const type = getInputType(target) || \"\";\n if (type === \"radio\" || type === \"checkbox\") {\n isChecked = target.checked;\n } else if (maskInputOptions[tagName.toLowerCase()] || maskInputOptions[type]) {\n text = maskInputValue({\n element: target,\n maskInputOptions,\n tagName,\n type,\n value: text,\n maskInputFn\n });\n }\n cbWithDedup(\n target,\n userTriggeredOnInput ? { text, isChecked, userTriggered } : { text, isChecked }\n );\n const name = target.name;\n if (type === \"radio\" && name && isChecked) {\n doc.querySelectorAll(`input[type=\"radio\"][name=\"${name}\"]`).forEach((el) => {\n if (el !== target) {\n const text2 = el.value;\n cbWithDedup(\n el,\n userTriggeredOnInput ? { text: text2, isChecked: !isChecked, userTriggered: false } : { text: text2, isChecked: !isChecked }\n );\n }\n });\n }\n }\n function cbWithDedup(target, v) {\n const lastInputValue = lastInputValueMap.get(target);\n if (!lastInputValue || lastInputValue.text !== v.text || lastInputValue.isChecked !== v.isChecked) {\n lastInputValueMap.set(target, v);\n const id = mirror2.getId(target);\n callbackWrapper(inputCb)({\n ...v,\n id\n });\n }\n }\n const events = sampling.input === \"last\" ? [\"change\"] : [\"input\", \"change\"];\n const handlers = events.map(\n (eventName) => on(eventName, callbackWrapper(eventHandler), doc)\n );\n const currentWindow = doc.defaultView;\n if (!currentWindow) {\n return () => {\n handlers.forEach((h) => h());\n };\n }\n const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(\n currentWindow.HTMLInputElement.prototype,\n \"value\"\n );\n const hookProperties = [\n [currentWindow.HTMLInputElement.prototype, \"value\"],\n [currentWindow.HTMLInputElement.prototype, \"checked\"],\n [currentWindow.HTMLSelectElement.prototype, \"value\"],\n [currentWindow.HTMLTextAreaElement.prototype, \"value\"],\n // Some UI library use selectedIndex to set select value\n [currentWindow.HTMLSelectElement.prototype, \"selectedIndex\"],\n [currentWindow.HTMLOptionElement.prototype, \"selected\"]\n ];\n if (propertyDescriptor && propertyDescriptor.set) {\n handlers.push(\n ...hookProperties.map(\n (p) => hookSetter(\n p[0],\n p[1],\n {\n set() {\n callbackWrapper(eventHandler)({\n target: this,\n isTrusted: false\n // userTriggered to false as this could well be programmatic\n });\n }\n },\n false,\n currentWindow\n )\n )\n );\n }\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction getNestedCSSRulePositions(rule) {\n const positions = [];\n function recurse(childRule, pos) {\n if (hasNestedCSSRule(\"CSSGroupingRule\") && childRule.parentRule instanceof CSSGroupingRule || hasNestedCSSRule(\"CSSMediaRule\") && childRule.parentRule instanceof CSSMediaRule || hasNestedCSSRule(\"CSSSupportsRule\") && childRule.parentRule instanceof CSSSupportsRule || hasNestedCSSRule(\"CSSConditionRule\") && childRule.parentRule instanceof CSSConditionRule) {\n const rules = Array.from(\n childRule.parentRule.cssRules\n );\n const index2 = rules.indexOf(childRule);\n pos.unshift(index2);\n return recurse(childRule.parentRule, pos);\n } else if (childRule.parentStyleSheet) {\n const rules = Array.from(childRule.parentStyleSheet.cssRules);\n const index2 = rules.indexOf(childRule);\n pos.unshift(index2);\n }\n return pos;\n }\n return recurse(rule, positions);\n}\nfunction getIdAndStyleId(sheet, mirror2, styleMirror) {\n let id, styleId;\n if (!sheet) return {};\n if (sheet.ownerNode) id = mirror2.getId(sheet.ownerNode);\n else styleId = styleMirror.getId(sheet);\n return {\n styleId,\n id\n };\n}\nfunction initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetManager }, { win }) {\n if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {\n return () => {\n };\n }\n const insertRule = win.CSSStyleSheet.prototype.insertRule;\n win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [rule, index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n adds: [{ rule, index: index2 }]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n win.CSSStyleSheet.prototype.addRule = function(selector, styleBlock, index2 = this.cssRules.length) {\n const rule = `${selector} { ${styleBlock} }`;\n return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule, index2]);\n };\n const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [{ index: index2 }]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n win.CSSStyleSheet.prototype.removeRule = function(index2) {\n return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);\n };\n let replace;\n if (win.CSSStyleSheet.prototype.replace) {\n replace = win.CSSStyleSheet.prototype.replace;\n win.CSSStyleSheet.prototype.replace = new Proxy(replace, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [text] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n replace: text\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n }\n let replaceSync;\n if (win.CSSStyleSheet.prototype.replaceSync) {\n replaceSync = win.CSSStyleSheet.prototype.replaceSync;\n win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [text] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n replaceSync: text\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n }\n const supportedNestedCSSRuleTypes = {};\n if (canMonkeyPatchNestedCSSRule(\"CSSGroupingRule\")) {\n supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;\n } else {\n if (canMonkeyPatchNestedCSSRule(\"CSSMediaRule\")) {\n supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;\n }\n if (canMonkeyPatchNestedCSSRule(\"CSSConditionRule\")) {\n supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;\n }\n if (canMonkeyPatchNestedCSSRule(\"CSSSupportsRule\")) {\n supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;\n }\n }\n const unmodifiedFunctions = {};\n Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n unmodifiedFunctions[typeKey] = {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n insertRule: type.prototype.insertRule,\n // eslint-disable-next-line @typescript-eslint/unbound-method\n deleteRule: type.prototype.deleteRule\n };\n type.prototype.insertRule = new Proxy(\n unmodifiedFunctions[typeKey].insertRule,\n {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [rule, index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n adds: [\n {\n rule,\n index: [\n ...getNestedCSSRulePositions(thisArg),\n index2 || 0\n // defaults to 0\n ]\n }\n ]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n }\n );\n type.prototype.deleteRule = new Proxy(\n unmodifiedFunctions[typeKey].deleteRule,\n {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [\n { index: [...getNestedCSSRulePositions(thisArg), index2] }\n ]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n }\n );\n });\n return callbackWrapper(() => {\n win.CSSStyleSheet.prototype.insertRule = insertRule;\n win.CSSStyleSheet.prototype.deleteRule = deleteRule;\n replace && (win.CSSStyleSheet.prototype.replace = replace);\n replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);\n Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;\n type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;\n });\n });\n}\nfunction initAdoptedStyleSheetObserver({\n mirror: mirror2,\n stylesheetManager\n}, host2) {\n var _a2, _b, _c;\n let hostId = null;\n if (host2.nodeName === \"#document\") hostId = mirror2.getId(host2);\n else hostId = mirror2.getId(index.host(host2));\n const patchTarget = host2.nodeName === \"#document\" ? (_a2 = host2.defaultView) == null ? void 0 : _a2.Document : (_c = (_b = host2.ownerDocument) == null ? void 0 : _b.defaultView) == null ? void 0 : _c.ShadowRoot;\n const originalPropertyDescriptor = (patchTarget == null ? void 0 : patchTarget.prototype) ? Object.getOwnPropertyDescriptor(\n patchTarget == null ? void 0 : patchTarget.prototype,\n \"adoptedStyleSheets\"\n ) : void 0;\n if (hostId === null || hostId === -1 || !patchTarget || !originalPropertyDescriptor)\n return () => {\n };\n Object.defineProperty(host2, \"adoptedStyleSheets\", {\n configurable: originalPropertyDescriptor.configurable,\n enumerable: originalPropertyDescriptor.enumerable,\n get() {\n var _a3;\n return (_a3 = originalPropertyDescriptor.get) == null ? void 0 : _a3.call(this);\n },\n set(sheets) {\n var _a3;\n const result = (_a3 = originalPropertyDescriptor.set) == null ? void 0 : _a3.call(this, sheets);\n if (hostId !== null && hostId !== -1) {\n try {\n stylesheetManager.adoptStyleSheets(sheets, hostId);\n } catch (e) {\n }\n }\n return result;\n }\n });\n return callbackWrapper(() => {\n Object.defineProperty(host2, \"adoptedStyleSheets\", {\n configurable: originalPropertyDescriptor.configurable,\n enumerable: originalPropertyDescriptor.enumerable,\n // eslint-disable-next-line @typescript-eslint/unbound-method\n get: originalPropertyDescriptor.get,\n // eslint-disable-next-line @typescript-eslint/unbound-method\n set: originalPropertyDescriptor.set\n });\n });\n}\nfunction initStyleDeclarationObserver({\n styleDeclarationCb,\n mirror: mirror2,\n ignoreCSSAttributes,\n stylesheetManager\n}, { win }) {\n const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n var _a2;\n const [property, value, priority] = argumentsList;\n if (ignoreCSSAttributes.has(property)) {\n return setProperty.apply(thisArg, [property, value, priority]);\n }\n const { id, styleId } = getIdAndStyleId(\n (_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleDeclarationCb({\n id,\n styleId,\n set: {\n property,\n value,\n priority\n },\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n index: getNestedCSSRulePositions(thisArg.parentRule)\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n var _a2;\n const [property] = argumentsList;\n if (ignoreCSSAttributes.has(property)) {\n return removeProperty.apply(thisArg, [property]);\n }\n const { id, styleId } = getIdAndStyleId(\n (_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleDeclarationCb({\n id,\n styleId,\n remove: {\n property\n },\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n index: getNestedCSSRulePositions(thisArg.parentRule)\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n return callbackWrapper(() => {\n win.CSSStyleDeclaration.prototype.setProperty = setProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\n });\n}\nfunction initMediaInteractionObserver({\n mediaInteractionCb,\n blockClass,\n blockSelector,\n mirror: mirror2,\n sampling,\n doc\n}) {\n const handler = callbackWrapper(\n (type) => throttle(\n callbackWrapper((event) => {\n const target = getEventTarget(event);\n if (!target || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n const { currentTime, volume, muted, playbackRate, loop } = target;\n mediaInteractionCb({\n type,\n id: mirror2.getId(target),\n currentTime,\n volume,\n muted,\n playbackRate,\n loop\n });\n }),\n sampling.media || 500\n )\n );\n const handlers = [\n on(\"play\", handler(MediaInteractions.Play), doc),\n on(\"pause\", handler(MediaInteractions.Pause), doc),\n on(\"seeked\", handler(MediaInteractions.Seeked), doc),\n on(\"volumechange\", handler(MediaInteractions.VolumeChange), doc),\n on(\"ratechange\", handler(MediaInteractions.RateChange), doc)\n ];\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initFontObserver({ fontCb, doc }) {\n const win = doc.defaultView;\n if (!win) {\n return () => {\n };\n }\n const handlers = [];\n const fontMap = /* @__PURE__ */ new WeakMap();\n const originalFontFace = win.FontFace;\n win.FontFace = function FontFace(family, source, descriptors) {\n const fontFace = new originalFontFace(family, source, descriptors);\n fontMap.set(fontFace, {\n family,\n buffer: typeof source !== \"string\",\n descriptors,\n fontSource: typeof source === \"string\" ? source : JSON.stringify(Array.from(new Uint8Array(source)))\n });\n return fontFace;\n };\n const restoreHandler = patch(\n doc.fonts,\n \"add\",\n function(original) {\n return function(fontFace) {\n setTimeout(\n callbackWrapper(() => {\n const p = fontMap.get(fontFace);\n if (p) {\n fontCb(p);\n fontMap.delete(fontFace);\n }\n }),\n 0\n );\n return original.apply(this, [fontFace]);\n };\n }\n );\n handlers.push(() => {\n win.FontFace = originalFontFace;\n });\n handlers.push(restoreHandler);\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initSelectionObserver(param) {\n const { doc, mirror: mirror2, blockClass, blockSelector, selectionCb } = param;\n let collapsed = true;\n const updateSelection = callbackWrapper(() => {\n const selection = doc.getSelection();\n if (!selection || collapsed && (selection == null ? void 0 : selection.isCollapsed)) return;\n collapsed = selection.isCollapsed || false;\n const ranges = [];\n const count = selection.rangeCount || 0;\n for (let i = 0; i < count; i++) {\n const range = selection.getRangeAt(i);\n const { startContainer, startOffset, endContainer, endOffset } = range;\n const blocked = isBlocked(startContainer, blockClass, blockSelector, true) || isBlocked(endContainer, blockClass, blockSelector, true);\n if (blocked) continue;\n ranges.push({\n start: mirror2.getId(startContainer),\n startOffset,\n end: mirror2.getId(endContainer),\n endOffset\n });\n }\n selectionCb({ ranges });\n });\n updateSelection();\n return on(\"selectionchange\", updateSelection);\n}\nfunction initCustomElementObserver({\n doc,\n customElementCb\n}) {\n const win = doc.defaultView;\n if (!win || !win.customElements) return () => {\n };\n const restoreHandler = patch(\n win.customElements,\n \"define\",\n function(original) {\n return function(name, constructor, options) {\n try {\n customElementCb({\n define: {\n name\n }\n });\n } catch (e) {\n console.warn(`Custom element callback failed for ${name}`);\n }\n return original.apply(this, [name, constructor, options]);\n };\n }\n );\n return restoreHandler;\n}\nfunction mergeHooks(o, hooks) {\n const {\n mutationCb,\n mousemoveCb,\n mouseInteractionCb,\n scrollCb,\n viewportResizeCb,\n inputCb,\n mediaInteractionCb,\n styleSheetRuleCb,\n styleDeclarationCb,\n canvasMutationCb,\n fontCb,\n selectionCb,\n customElementCb\n } = o;\n o.mutationCb = (...p) => {\n if (hooks.mutation) {\n hooks.mutation(...p);\n }\n mutationCb(...p);\n };\n o.mousemoveCb = (...p) => {\n if (hooks.mousemove) {\n hooks.mousemove(...p);\n }\n mousemoveCb(...p);\n };\n o.mouseInteractionCb = (...p) => {\n if (hooks.mouseInteraction) {\n hooks.mouseInteraction(...p);\n }\n mouseInteractionCb(...p);\n };\n o.scrollCb = (...p) => {\n if (hooks.scroll) {\n hooks.scroll(...p);\n }\n scrollCb(...p);\n };\n o.viewportResizeCb = (...p) => {\n if (hooks.viewportResize) {\n hooks.viewportResize(...p);\n }\n viewportResizeCb(...p);\n };\n o.inputCb = (...p) => {\n if (hooks.input) {\n hooks.input(...p);\n }\n inputCb(...p);\n };\n o.mediaInteractionCb = (...p) => {\n if (hooks.mediaInteaction) {\n hooks.mediaInteaction(...p);\n }\n mediaInteractionCb(...p);\n };\n o.styleSheetRuleCb = (...p) => {\n if (hooks.styleSheetRule) {\n hooks.styleSheetRule(...p);\n }\n styleSheetRuleCb(...p);\n };\n o.styleDeclarationCb = (...p) => {\n if (hooks.styleDeclaration) {\n hooks.styleDeclaration(...p);\n }\n styleDeclarationCb(...p);\n };\n o.canvasMutationCb = (...p) => {\n if (hooks.canvasMutation) {\n hooks.canvasMutation(...p);\n }\n canvasMutationCb(...p);\n };\n o.fontCb = (...p) => {\n if (hooks.font) {\n hooks.font(...p);\n }\n fontCb(...p);\n };\n o.selectionCb = (...p) => {\n if (hooks.selection) {\n hooks.selection(...p);\n }\n selectionCb(...p);\n };\n o.customElementCb = (...c) => {\n if (hooks.customElement) {\n hooks.customElement(...c);\n }\n customElementCb(...c);\n };\n}\nfunction initObservers(o, hooks = {}) {\n const currentWindow = o.doc.defaultView;\n if (!currentWindow) {\n return () => {\n };\n }\n mergeHooks(o, hooks);\n let mutationObserver;\n let cleanupMutationIframe = () => {\n };\n if (o.recordDOM) {\n [mutationObserver, cleanupMutationIframe] = initMutationObserver(o, o.doc);\n }\n const mousemoveHandler = initMoveObserver(o);\n const mouseInteractionHandler = initMouseInteractionObserver(o);\n const scrollHandler = initScrollObserver(o);\n const viewportResizeHandler = initViewportResizeObserver(o, {\n win: currentWindow\n });\n const inputHandler = initInputObserver(o);\n const mediaInteractionHandler = initMediaInteractionObserver(o);\n let styleSheetObserver = () => {\n };\n let adoptedStyleSheetObserver = () => {\n };\n let styleDeclarationObserver = () => {\n };\n let fontObserver = () => {\n };\n if (o.recordDOM) {\n styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });\n adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);\n styleDeclarationObserver = initStyleDeclarationObserver(o, {\n win: currentWindow\n });\n if (o.collectFonts) {\n fontObserver = initFontObserver(o);\n }\n }\n const selectionObserver = initSelectionObserver(o);\n const customElementObserver = initCustomElementObserver(o);\n const pluginHandlers = [];\n for (const plugin of o.plugins) {\n pluginHandlers.push(\n plugin.observer(plugin.callback, currentWindow, plugin.options)\n );\n }\n return callbackWrapper(() => {\n mutationBuffers.forEach((b) => b.reset());\n mutationObserver == null ? void 0 : mutationObserver.disconnect();\n cleanupMutationIframe();\n mousemoveHandler();\n mouseInteractionHandler();\n scrollHandler();\n viewportResizeHandler();\n inputHandler();\n mediaInteractionHandler();\n styleSheetObserver();\n adoptedStyleSheetObserver();\n styleDeclarationObserver();\n fontObserver();\n selectionObserver();\n customElementObserver();\n pluginHandlers.forEach((h) => h());\n });\n}\nfunction hasNestedCSSRule(prop) {\n return typeof window[prop] !== \"undefined\";\n}\nfunction canMonkeyPatchNestedCSSRule(prop) {\n return Boolean(\n typeof window[prop] !== \"undefined\" && // Note: Generally, this check _shouldn't_ be necessary\n // However, in some scenarios (e.g. jsdom) this can sometimes fail, so we check for it here\n window[prop].prototype && \"insertRule\" in window[prop].prototype && \"deleteRule\" in window[prop].prototype\n );\n}\nclass CrossOriginIframeMirror {\n constructor(generateIdFn) {\n __publicField(this, \"iframeIdToRemoteIdMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"iframeRemoteIdToIdMap\", /* @__PURE__ */ new WeakMap());\n this.generateIdFn = generateIdFn;\n }\n getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {\n const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);\n let id = idToRemoteIdMap.get(remoteId);\n if (!id) {\n id = this.generateIdFn();\n idToRemoteIdMap.set(remoteId, id);\n remoteIdToIdMap.set(id, remoteId);\n }\n return id;\n }\n getIds(iframe, remoteId) {\n const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n return remoteId.map(\n (id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap)\n );\n }\n getRemoteId(iframe, id, map) {\n const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);\n if (typeof id !== \"number\") return id;\n const remoteId = remoteIdToIdMap.get(id);\n if (!remoteId) return -1;\n return remoteId;\n }\n getRemoteIds(iframe, ids) {\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));\n }\n reset(iframe) {\n if (!iframe) {\n this.iframeIdToRemoteIdMap = /* @__PURE__ */ new WeakMap();\n this.iframeRemoteIdToIdMap = /* @__PURE__ */ new WeakMap();\n return;\n }\n this.iframeIdToRemoteIdMap.delete(iframe);\n this.iframeRemoteIdToIdMap.delete(iframe);\n }\n getIdToRemoteIdMap(iframe) {\n let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);\n if (!idToRemoteIdMap) {\n idToRemoteIdMap = /* @__PURE__ */ new Map();\n this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);\n }\n return idToRemoteIdMap;\n }\n getRemoteIdToIdMap(iframe) {\n let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);\n if (!remoteIdToIdMap) {\n remoteIdToIdMap = /* @__PURE__ */ new Map();\n this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);\n }\n return remoteIdToIdMap;\n }\n}\nclass IframeManager {\n constructor(options) {\n __publicField(this, \"iframes\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"crossOriginIframeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"crossOriginIframeMirror\", new CrossOriginIframeMirror(genId));\n __publicField(this, \"crossOriginIframeStyleMirror\");\n __publicField(this, \"crossOriginIframeRootIdMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"mirror\");\n __publicField(this, \"mutationCb\");\n __publicField(this, \"wrappedEmit\");\n __publicField(this, \"loadListener\");\n __publicField(this, \"stylesheetManager\");\n __publicField(this, \"recordCrossOriginIframes\");\n this.mutationCb = options.mutationCb;\n this.wrappedEmit = options.wrappedEmit;\n this.stylesheetManager = options.stylesheetManager;\n this.recordCrossOriginIframes = options.recordCrossOriginIframes;\n this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(\n this.stylesheetManager.styleMirror.generateId.bind(\n this.stylesheetManager.styleMirror\n )\n );\n this.mirror = options.mirror;\n if (this.recordCrossOriginIframes) {\n window.addEventListener(\"message\", this.handleMessage.bind(this));\n }\n }\n addIframe(iframeEl) {\n this.iframes.set(iframeEl, true);\n if (iframeEl.contentWindow)\n this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);\n }\n addLoadListener(cb) {\n this.loadListener = cb;\n }\n attachIframe(iframeEl, childSn) {\n var _a2, _b;\n this.mutationCb({\n adds: [\n {\n parentId: this.mirror.getId(iframeEl),\n nextId: null,\n node: childSn\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n });\n if (this.recordCrossOriginIframes)\n (_a2 = iframeEl.contentWindow) == null ? void 0 : _a2.addEventListener(\n \"message\",\n this.handleMessage.bind(this)\n );\n (_b = this.loadListener) == null ? void 0 : _b.call(this, iframeEl);\n if (iframeEl.contentDocument && iframeEl.contentDocument.adoptedStyleSheets && iframeEl.contentDocument.adoptedStyleSheets.length > 0)\n this.stylesheetManager.adoptStyleSheets(\n iframeEl.contentDocument.adoptedStyleSheets,\n this.mirror.getId(iframeEl.contentDocument)\n );\n }\n handleMessage(message) {\n const crossOriginMessageEvent = message;\n if (crossOriginMessageEvent.data.type !== \"rrweb\" || // To filter out the rrweb messages which are forwarded by some sites.\n crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)\n return;\n const iframeSourceWindow = message.source;\n if (!iframeSourceWindow) return;\n const iframeEl = this.crossOriginIframeMap.get(message.source);\n if (!iframeEl) return;\n const transformedEvent = this.transformCrossOriginEvent(\n iframeEl,\n crossOriginMessageEvent.data.event\n );\n if (transformedEvent)\n this.wrappedEmit(\n transformedEvent,\n crossOriginMessageEvent.data.isCheckout\n );\n }\n transformCrossOriginEvent(iframeEl, e) {\n var _a2;\n switch (e.type) {\n case EventType.FullSnapshot: {\n this.crossOriginIframeMirror.reset(iframeEl);\n this.crossOriginIframeStyleMirror.reset(iframeEl);\n this.replaceIdOnNode(e.data.node, iframeEl);\n const rootId = e.data.node.id;\n this.crossOriginIframeRootIdMap.set(iframeEl, rootId);\n this.patchRootIdOnNode(e.data.node, rootId);\n return {\n timestamp: e.timestamp,\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n adds: [\n {\n parentId: this.mirror.getId(iframeEl),\n nextId: null,\n node: e.data.node\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n }\n };\n }\n case EventType.Meta:\n case EventType.Load:\n case EventType.DomContentLoaded: {\n return false;\n }\n case EventType.Plugin: {\n return e;\n }\n case EventType.Custom: {\n this.replaceIds(\n e.data.payload,\n iframeEl,\n [\"id\", \"parentId\", \"previousId\", \"nextId\"]\n );\n return e;\n }\n case EventType.IncrementalSnapshot: {\n switch (e.data.source) {\n case IncrementalSource.Mutation: {\n e.data.adds.forEach((n) => {\n this.replaceIds(n, iframeEl, [\n \"parentId\",\n \"nextId\",\n \"previousId\"\n ]);\n this.replaceIdOnNode(n.node, iframeEl);\n const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);\n rootId && this.patchRootIdOnNode(n.node, rootId);\n });\n e.data.removes.forEach((n) => {\n this.replaceIds(n, iframeEl, [\"parentId\", \"id\"]);\n });\n e.data.attributes.forEach((n) => {\n this.replaceIds(n, iframeEl, [\"id\"]);\n });\n e.data.texts.forEach((n) => {\n this.replaceIds(n, iframeEl, [\"id\"]);\n });\n return e;\n }\n case IncrementalSource.Drag:\n case IncrementalSource.TouchMove:\n case IncrementalSource.MouseMove: {\n e.data.positions.forEach((p) => {\n this.replaceIds(p, iframeEl, [\"id\"]);\n });\n return e;\n }\n case IncrementalSource.ViewportResize: {\n return false;\n }\n case IncrementalSource.MediaInteraction:\n case IncrementalSource.MouseInteraction:\n case IncrementalSource.Scroll:\n case IncrementalSource.CanvasMutation:\n case IncrementalSource.Input: {\n this.replaceIds(e.data, iframeEl, [\"id\"]);\n return e;\n }\n case IncrementalSource.StyleSheetRule:\n case IncrementalSource.StyleDeclaration: {\n this.replaceIds(e.data, iframeEl, [\"id\"]);\n this.replaceStyleIds(e.data, iframeEl, [\"styleId\"]);\n return e;\n }\n case IncrementalSource.Font: {\n return e;\n }\n case IncrementalSource.Selection: {\n e.data.ranges.forEach((range) => {\n this.replaceIds(range, iframeEl, [\"start\", \"end\"]);\n });\n return e;\n }\n case IncrementalSource.AdoptedStyleSheet: {\n this.replaceIds(e.data, iframeEl, [\"id\"]);\n this.replaceStyleIds(e.data, iframeEl, [\"styleIds\"]);\n (_a2 = e.data.styles) == null ? void 0 : _a2.forEach((style) => {\n this.replaceStyleIds(style, iframeEl, [\"styleId\"]);\n });\n return e;\n }\n }\n }\n }\n return false;\n }\n replace(iframeMirror, obj, iframeEl, keys) {\n for (const key of keys) {\n if (!Array.isArray(obj[key]) && typeof obj[key] !== \"number\") continue;\n if (Array.isArray(obj[key])) {\n obj[key] = iframeMirror.getIds(\n iframeEl,\n obj[key]\n );\n } else {\n obj[key] = iframeMirror.getId(iframeEl, obj[key]);\n }\n }\n return obj;\n }\n replaceIds(obj, iframeEl, keys) {\n return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);\n }\n replaceStyleIds(obj, iframeEl, keys) {\n return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);\n }\n replaceIdOnNode(node, iframeEl) {\n this.replaceIds(node, iframeEl, [\"id\", \"rootId\"]);\n if (\"childNodes\" in node) {\n node.childNodes.forEach((child) => {\n this.replaceIdOnNode(child, iframeEl);\n });\n }\n }\n patchRootIdOnNode(node, rootId) {\n if (node.type !== NodeType.Document && !node.rootId) node.rootId = rootId;\n if (\"childNodes\" in node) {\n node.childNodes.forEach((child) => {\n this.patchRootIdOnNode(child, rootId);\n });\n }\n }\n}\nclass ShadowDomManager {\n constructor(options) {\n __publicField(this, \"shadowDoms\", /* @__PURE__ */ new WeakSet());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"scrollCb\");\n __publicField(this, \"bypassOptions\");\n __publicField(this, \"mirror\");\n __publicField(this, \"restoreHandlers\", []);\n this.mutationCb = options.mutationCb;\n this.scrollCb = options.scrollCb;\n this.bypassOptions = options.bypassOptions;\n this.mirror = options.mirror;\n this.init();\n }\n init() {\n this.reset();\n this.patchAttachShadow(Element, document);\n }\n addShadowRoot(shadowRoot2, doc) {\n if (!isNativeShadowDom(shadowRoot2)) return;\n if (this.shadowDoms.has(shadowRoot2)) return;\n this.shadowDoms.add(shadowRoot2);\n const [observer] = initMutationObserver(\n {\n ...this.bypassOptions,\n doc,\n mutationCb: this.mutationCb,\n mirror: this.mirror,\n shadowDomManager: this\n },\n shadowRoot2\n );\n this.restoreHandlers.push(() => observer.disconnect());\n this.restoreHandlers.push(\n initScrollObserver({\n ...this.bypassOptions,\n scrollCb: this.scrollCb,\n // https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813\n // scroll is not allowed to pass the boundary, so we need to listen the shadow document\n doc: shadowRoot2,\n mirror: this.mirror\n })\n );\n setTimeout(() => {\n if (shadowRoot2.adoptedStyleSheets && shadowRoot2.adoptedStyleSheets.length > 0)\n this.bypassOptions.stylesheetManager.adoptStyleSheets(\n shadowRoot2.adoptedStyleSheets,\n this.mirror.getId(index.host(shadowRoot2))\n );\n this.restoreHandlers.push(\n initAdoptedStyleSheetObserver(\n {\n mirror: this.mirror,\n stylesheetManager: this.bypassOptions.stylesheetManager\n },\n shadowRoot2\n )\n );\n }, 0);\n }\n /**\n * Monkey patch 'attachShadow' of an IFrameElement to observe newly added shadow doms.\n */\n observeAttachShadow(iframeElement) {\n if (!iframeElement.contentWindow || !iframeElement.contentDocument) return;\n this.patchAttachShadow(\n iframeElement.contentWindow.Element,\n iframeElement.contentDocument\n );\n }\n /**\n * Patch 'attachShadow' to observe newly added shadow doms.\n */\n patchAttachShadow(element, doc) {\n const manager = this;\n this.restoreHandlers.push(\n patch(\n element.prototype,\n \"attachShadow\",\n function(original) {\n return function(option) {\n const sRoot = original.call(this, option);\n const shadowRootEl = index.shadowRoot(this);\n if (shadowRootEl && inDom(this))\n manager.addShadowRoot(shadowRootEl, doc);\n return sRoot;\n };\n }\n )\n );\n }\n reset() {\n this.restoreHandlers.forEach((handler) => {\n try {\n handler();\n } catch (e) {\n }\n });\n this.restoreHandlers = [];\n this.shadowDoms = /* @__PURE__ */ new WeakSet();\n }\n}\nvar chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar lookup = typeof Uint8Array === \"undefined\" ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n}\nvar encode = function(arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = \"\";\n for (i = 0; i < len; i += 3) {\n base64 += chars[bytes[i] >> 2];\n base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64 += chars[bytes[i + 2] & 63];\n }\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + \"=\";\n } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + \"==\";\n }\n return base64;\n};\nconst canvasVarMap = /* @__PURE__ */ new Map();\nfunction variableListFor(ctx, ctor) {\n let contextMap = canvasVarMap.get(ctx);\n if (!contextMap) {\n contextMap = /* @__PURE__ */ new Map();\n canvasVarMap.set(ctx, contextMap);\n }\n if (!contextMap.has(ctor)) {\n contextMap.set(ctor, []);\n }\n return contextMap.get(ctor);\n}\nconst saveWebGLVar = (value, win, ctx) => {\n if (!value || !(isInstanceOfWebGLObject(value, win) || typeof value === \"object\"))\n return;\n const name = value.constructor.name;\n const list = variableListFor(ctx, name);\n let index2 = list.indexOf(value);\n if (index2 === -1) {\n index2 = list.length;\n list.push(value);\n }\n return index2;\n};\nfunction serializeArg(value, win, ctx) {\n if (value instanceof Array) {\n return value.map((arg) => serializeArg(arg, win, ctx));\n } else if (value === null) {\n return value;\n } else if (value instanceof Float32Array || value instanceof Float64Array || value instanceof Int32Array || value instanceof Uint32Array || value instanceof Uint8Array || value instanceof Uint16Array || value instanceof Int16Array || value instanceof Int8Array || value instanceof Uint8ClampedArray) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [Object.values(value)]\n };\n } else if (\n // SharedArrayBuffer disabled on most browsers due to spectre.\n // More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/SharedArrayBuffer\n // value instanceof SharedArrayBuffer ||\n value instanceof ArrayBuffer\n ) {\n const name = value.constructor.name;\n const base64 = encode(value);\n return {\n rr_type: name,\n base64\n };\n } else if (value instanceof DataView) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [\n serializeArg(value.buffer, win, ctx),\n value.byteOffset,\n value.byteLength\n ]\n };\n } else if (value instanceof HTMLImageElement) {\n const name = value.constructor.name;\n const { src } = value;\n return {\n rr_type: name,\n src\n };\n } else if (value instanceof HTMLCanvasElement) {\n const name = \"HTMLImageElement\";\n const src = value.toDataURL();\n return {\n rr_type: name,\n src\n };\n } else if (value instanceof ImageData) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [serializeArg(value.data, win, ctx), value.width, value.height]\n };\n } else if (isInstanceOfWebGLObject(value, win) || typeof value === \"object\") {\n const name = value.constructor.name;\n const index2 = saveWebGLVar(value, win, ctx);\n return {\n rr_type: name,\n index: index2\n };\n }\n return value;\n}\nconst serializeArgs = (args, win, ctx) => {\n return args.map((arg) => serializeArg(arg, win, ctx));\n};\nconst isInstanceOfWebGLObject = (value, win) => {\n const webGLConstructorNames = [\n \"WebGLActiveInfo\",\n \"WebGLBuffer\",\n \"WebGLFramebuffer\",\n \"WebGLProgram\",\n \"WebGLRenderbuffer\",\n \"WebGLShader\",\n \"WebGLShaderPrecisionFormat\",\n \"WebGLTexture\",\n \"WebGLUniformLocation\",\n \"WebGLVertexArrayObject\",\n // In old Chrome versions, value won't be an instanceof WebGLVertexArrayObject.\n \"WebGLVertexArrayObjectOES\"\n ];\n const supportedWebGLConstructorNames = webGLConstructorNames.filter(\n (name) => typeof win[name] === \"function\"\n );\n return Boolean(\n supportedWebGLConstructorNames.find(\n (name) => value instanceof win[name]\n )\n );\n};\nfunction initCanvas2DMutationObserver(cb, win, blockClass, blockSelector) {\n const handlers = [];\n const props2D = Object.getOwnPropertyNames(\n win.CanvasRenderingContext2D.prototype\n );\n for (const prop of props2D) {\n try {\n if (typeof win.CanvasRenderingContext2D.prototype[prop] !== \"function\") {\n continue;\n }\n const restoreHandler = patch(\n win.CanvasRenderingContext2D.prototype,\n prop,\n function(original) {\n return function(...args) {\n if (!isBlocked(this.canvas, blockClass, blockSelector, true)) {\n setTimeout(() => {\n const recordArgs = serializeArgs(args, win, this);\n cb(this.canvas, {\n type: CanvasContext[\"2D\"],\n property: prop,\n args: recordArgs\n });\n }, 0);\n }\n return original.apply(this, args);\n };\n }\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter(\n win.CanvasRenderingContext2D.prototype,\n prop,\n {\n set(v) {\n cb(this.canvas, {\n type: CanvasContext[\"2D\"],\n property: prop,\n args: [v],\n setter: true\n });\n }\n }\n );\n handlers.push(hookHandler);\n }\n }\n return () => {\n handlers.forEach((h) => h());\n };\n}\nfunction getNormalizedContextName(contextType) {\n return contextType === \"experimental-webgl\" ? \"webgl\" : contextType;\n}\nfunction initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {\n const handlers = [];\n try {\n const restoreHandler = patch(\n win.HTMLCanvasElement.prototype,\n \"getContext\",\n function(original) {\n return function(contextType, ...args) {\n if (!isBlocked(this, blockClass, blockSelector, true)) {\n const ctxName = getNormalizedContextName(contextType);\n if (!(\"__context\" in this)) this.__context = ctxName;\n if (setPreserveDrawingBufferToTrue && [\"webgl\", \"webgl2\"].includes(ctxName)) {\n if (args[0] && typeof args[0] === \"object\") {\n const contextAttributes = args[0];\n if (!contextAttributes.preserveDrawingBuffer) {\n contextAttributes.preserveDrawingBuffer = true;\n }\n } else {\n args.splice(0, 1, {\n preserveDrawingBuffer: true\n });\n }\n }\n }\n return original.apply(this, [contextType, ...args]);\n };\n }\n );\n handlers.push(restoreHandler);\n } catch {\n console.error(\"failed to patch HTMLCanvasElement.prototype.getContext\");\n }\n return () => {\n handlers.forEach((h) => h());\n };\n}\nfunction patchGLPrototype(prototype, type, cb, blockClass, blockSelector, win) {\n const handlers = [];\n const props = Object.getOwnPropertyNames(prototype);\n for (const prop of props) {\n if (\n //prop.startsWith('get') || // e.g. getProgramParameter, but too risky\n [\n \"isContextLost\",\n \"canvas\",\n \"drawingBufferWidth\",\n \"drawingBufferHeight\"\n ].includes(prop)\n ) {\n continue;\n }\n try {\n if (typeof prototype[prop] !== \"function\") {\n continue;\n }\n const restoreHandler = patch(\n prototype,\n prop,\n function(original) {\n return function(...args) {\n const result = original.apply(this, args);\n saveWebGLVar(result, win, this);\n if (\"tagName\" in this.canvas && !isBlocked(this.canvas, blockClass, blockSelector, true)) {\n const recordArgs = serializeArgs(args, win, this);\n const mutation = {\n type,\n property: prop,\n args: recordArgs\n };\n cb(this.canvas, mutation);\n }\n return result;\n };\n }\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter(prototype, prop, {\n set(v) {\n cb(this.canvas, {\n type,\n property: prop,\n args: [v],\n setter: true\n });\n }\n });\n handlers.push(hookHandler);\n }\n }\n return handlers;\n}\nfunction initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector) {\n const handlers = [];\n if (typeof win.WebGLRenderingContext !== \"undefined\") {\n handlers.push(\n ...patchGLPrototype(\n win.WebGLRenderingContext.prototype,\n CanvasContext.WebGL,\n cb,\n blockClass,\n blockSelector,\n win\n )\n );\n }\n if (typeof win.WebGL2RenderingContext !== \"undefined\") {\n handlers.push(\n ...patchGLPrototype(\n win.WebGL2RenderingContext.prototype,\n CanvasContext.WebGL2,\n cb,\n blockClass,\n blockSelector,\n win\n )\n );\n }\n return () => {\n handlers.forEach((h) => h());\n };\n}\nconst jsContent = '(function() {\\n \"use strict\";\\n var chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\\n var lookup = typeof Uint8Array === \"undefined\" ? [] : new Uint8Array(256);\\n for (var i = 0; i < chars.length; i++) {\\n lookup[chars.charCodeAt(i)] = i;\\n }\\n var encode = function(arraybuffer) {\\n var bytes = new Uint8Array(arraybuffer), i2, len = bytes.length, base64 = \"\";\\n for (i2 = 0; i2 < len; i2 += 3) {\\n base64 += chars[bytes[i2] >> 2];\\n base64 += chars[(bytes[i2] & 3) << 4 | bytes[i2 + 1] >> 4];\\n base64 += chars[(bytes[i2 + 1] & 15) << 2 | bytes[i2 + 2] >> 6];\\n base64 += chars[bytes[i2 + 2] & 63];\\n }\\n if (len % 3 === 2) {\\n base64 = base64.substring(0, base64.length - 1) + \"=\";\\n } else if (len % 3 === 1) {\\n base64 = base64.substring(0, base64.length - 2) + \"==\";\\n }\\n return base64;\\n };\\n const lastBlobMap = /* @__PURE__ */ new Map();\\n const transparentBlobMap = /* @__PURE__ */ new Map();\\n async function getTransparentBlobFor(width, height, dataURLOptions) {\\n const id = `${width}-${height}`;\\n if (\"OffscreenCanvas\" in globalThis) {\\n if (transparentBlobMap.has(id)) return transparentBlobMap.get(id);\\n const offscreen = new OffscreenCanvas(width, height);\\n offscreen.getContext(\"2d\");\\n const blob = await offscreen.convertToBlob(dataURLOptions);\\n const arrayBuffer = await blob.arrayBuffer();\\n const base64 = encode(arrayBuffer);\\n transparentBlobMap.set(id, base64);\\n return base64;\\n } else {\\n return \"\";\\n }\\n }\\n const worker = self;\\n worker.onmessage = async function(e) {\\n if (\"OffscreenCanvas\" in globalThis) {\\n const { id, bitmap, width, height, dataURLOptions } = e.data;\\n const transparentBase64 = getTransparentBlobFor(\\n width,\\n height,\\n dataURLOptions\\n );\\n const offscreen = new OffscreenCanvas(width, height);\\n const ctx = offscreen.getContext(\"2d\");\\n ctx.drawImage(bitmap, 0, 0);\\n bitmap.close();\\n const blob = await offscreen.convertToBlob(dataURLOptions);\\n const type = blob.type;\\n const arrayBuffer = await blob.arrayBuffer();\\n const base64 = encode(arrayBuffer);\\n if (!lastBlobMap.has(id) && await transparentBase64 === base64) {\\n lastBlobMap.set(id, base64);\\n return worker.postMessage({ id });\\n }\\n if (lastBlobMap.get(id) === base64) return worker.postMessage({ id });\\n worker.postMessage({\\n id,\\n type,\\n base64,\\n width,\\n height\\n });\\n lastBlobMap.set(id, base64);\\n } else {\\n return worker.postMessage({ id: e.data.id });\\n }\\n };\\n})();\\n//# sourceMappingURL=image-bitmap-data-url-worker-IJpC7g_b.js.map\\n';\nconst blob = typeof self !== \"undefined\" && self.Blob && new Blob([jsContent], { type: \"text/javascript;charset=utf-8\" });\nfunction WorkerWrapper(options) {\n let objURL;\n try {\n objURL = blob && (self.URL || self.webkitURL).createObjectURL(blob);\n if (!objURL) throw \"\";\n const worker = new Worker(objURL, {\n name: options == null ? void 0 : options.name\n });\n worker.addEventListener(\"error\", () => {\n (self.URL || self.webkitURL).revokeObjectURL(objURL);\n });\n return worker;\n } catch (e) {\n return new Worker(\n \"data:text/javascript;charset=utf-8,\" + encodeURIComponent(jsContent),\n {\n name: options == null ? void 0 : options.name\n }\n );\n } finally {\n objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);\n }\n}\nclass CanvasManager {\n constructor(options) {\n __publicField(this, \"pendingCanvasMutations\", /* @__PURE__ */ new Map());\n __publicField(this, \"rafStamps\", { latestId: 0, invokeId: null });\n __publicField(this, \"mirror\");\n __publicField(this, \"mutationCb\");\n __publicField(this, \"resetObservers\");\n __publicField(this, \"frozen\", false);\n __publicField(this, \"locked\", false);\n __publicField(this, \"processMutation\", (target, mutation) => {\n const newFrame = this.rafStamps.invokeId && this.rafStamps.latestId !== this.rafStamps.invokeId;\n if (newFrame || !this.rafStamps.invokeId)\n this.rafStamps.invokeId = this.rafStamps.latestId;\n if (!this.pendingCanvasMutations.has(target)) {\n this.pendingCanvasMutations.set(target, []);\n }\n this.pendingCanvasMutations.get(target).push(mutation);\n });\n const {\n sampling = \"all\",\n win,\n blockClass,\n blockSelector,\n recordCanvas,\n dataURLOptions\n } = options;\n this.mutationCb = options.mutationCb;\n this.mirror = options.mirror;\n if (recordCanvas && sampling === \"all\")\n this.initCanvasMutationObserver(win, blockClass, blockSelector);\n if (recordCanvas && typeof sampling === \"number\")\n this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {\n dataURLOptions\n });\n }\n reset() {\n this.pendingCanvasMutations.clear();\n this.resetObservers && this.resetObservers();\n }\n freeze() {\n this.frozen = true;\n }\n unfreeze() {\n this.frozen = false;\n }\n lock() {\n this.locked = true;\n }\n unlock() {\n this.locked = false;\n }\n initCanvasFPSObserver(fps, win, blockClass, blockSelector, options) {\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n true\n );\n const snapshotInProgressMap = /* @__PURE__ */ new Map();\n const worker = new WorkerWrapper();\n worker.onmessage = (e) => {\n const { id } = e.data;\n snapshotInProgressMap.set(id, false);\n if (!(\"base64\" in e.data)) return;\n const { base64, type, width, height } = e.data;\n this.mutationCb({\n id,\n type: CanvasContext[\"2D\"],\n commands: [\n {\n property: \"clearRect\",\n // wipe canvas\n args: [0, 0, width, height]\n },\n {\n property: \"drawImage\",\n // draws (semi-transparent) image\n args: [\n {\n rr_type: \"ImageBitmap\",\n args: [\n {\n rr_type: \"Blob\",\n data: [{ rr_type: \"ArrayBuffer\", base64 }],\n type\n }\n ]\n },\n 0,\n 0\n ]\n }\n ]\n });\n };\n const timeBetweenSnapshots = 1e3 / fps;\n let lastSnapshotTime = 0;\n let rafId;\n const getCanvas = () => {\n const matchedCanvas = [];\n win.document.querySelectorAll(\"canvas\").forEach((canvas) => {\n if (!isBlocked(canvas, blockClass, blockSelector, true)) {\n matchedCanvas.push(canvas);\n }\n });\n return matchedCanvas;\n };\n const takeCanvasSnapshots = (timestamp) => {\n if (lastSnapshotTime && timestamp - lastSnapshotTime < timeBetweenSnapshots) {\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n return;\n }\n lastSnapshotTime = timestamp;\n getCanvas().forEach(async (canvas) => {\n var _a2;\n const id = this.mirror.getId(canvas);\n if (snapshotInProgressMap.get(id)) return;\n if (canvas.width === 0 || canvas.height === 0) return;\n snapshotInProgressMap.set(id, true);\n if ([\"webgl\", \"webgl2\"].includes(canvas.__context)) {\n const context = canvas.getContext(canvas.__context);\n if (((_a2 = context == null ? void 0 : context.getContextAttributes()) == null ? void 0 : _a2.preserveDrawingBuffer) === false) {\n context.clear(context.COLOR_BUFFER_BIT);\n }\n }\n const bitmap = await createImageBitmap(canvas);\n worker.postMessage(\n {\n id,\n bitmap,\n width: canvas.width,\n height: canvas.height,\n dataURLOptions: options.dataURLOptions\n },\n [bitmap]\n );\n });\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n };\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n this.resetObservers = () => {\n canvasContextReset();\n cancelAnimationFrame(rafId);\n };\n }\n initCanvasMutationObserver(win, blockClass, blockSelector) {\n this.startRAFTimestamping();\n this.startPendingCanvasMutationFlusher();\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n false\n );\n const canvas2DReset = initCanvas2DMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector\n );\n const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector\n );\n this.resetObservers = () => {\n canvasContextReset();\n canvas2DReset();\n canvasWebGL1and2Reset();\n };\n }\n startPendingCanvasMutationFlusher() {\n requestAnimationFrame(() => this.flushPendingCanvasMutations());\n }\n startRAFTimestamping() {\n const setLatestRAFTimestamp = (timestamp) => {\n this.rafStamps.latestId = timestamp;\n requestAnimationFrame(setLatestRAFTimestamp);\n };\n requestAnimationFrame(setLatestRAFTimestamp);\n }\n flushPendingCanvasMutations() {\n this.pendingCanvasMutations.forEach(\n (_values, canvas) => {\n const id = this.mirror.getId(canvas);\n this.flushPendingCanvasMutationFor(canvas, id);\n }\n );\n requestAnimationFrame(() => this.flushPendingCanvasMutations());\n }\n flushPendingCanvasMutationFor(canvas, id) {\n if (this.frozen || this.locked) {\n return;\n }\n const valuesWithType = this.pendingCanvasMutations.get(canvas);\n if (!valuesWithType || id === -1) return;\n const values = valuesWithType.map((value) => {\n const { type: type2, ...rest } = value;\n return rest;\n });\n const { type } = valuesWithType[0];\n this.mutationCb({ id, type, commands: values });\n this.pendingCanvasMutations.delete(canvas);\n }\n}\nclass StylesheetManager {\n constructor(options) {\n __publicField(this, \"trackedLinkElements\", /* @__PURE__ */ new WeakSet());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"adoptedStyleSheetCb\");\n __publicField(this, \"styleMirror\", new StyleSheetMirror());\n this.mutationCb = options.mutationCb;\n this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;\n }\n attachLinkElement(linkEl, childSn) {\n if (\"_cssText\" in childSn.attributes)\n this.mutationCb({\n adds: [],\n removes: [],\n texts: [],\n attributes: [\n {\n id: childSn.id,\n attributes: childSn.attributes\n }\n ]\n });\n this.trackLinkElement(linkEl);\n }\n trackLinkElement(linkEl) {\n if (this.trackedLinkElements.has(linkEl)) return;\n this.trackedLinkElements.add(linkEl);\n this.trackStylesheetInLinkElement(linkEl);\n }\n adoptStyleSheets(sheets, hostId) {\n if (sheets.length === 0) return;\n const adoptedStyleSheetData = {\n id: hostId,\n styleIds: []\n };\n const styles = [];\n for (const sheet of sheets) {\n let styleId;\n if (!this.styleMirror.has(sheet)) {\n styleId = this.styleMirror.add(sheet);\n styles.push({\n styleId,\n rules: Array.from(sheet.rules || CSSRule, (r, index2) => ({\n rule: stringifyRule(r, sheet.href),\n index: index2\n }))\n });\n } else styleId = this.styleMirror.getId(sheet);\n adoptedStyleSheetData.styleIds.push(styleId);\n }\n if (styles.length > 0) adoptedStyleSheetData.styles = styles;\n this.adoptedStyleSheetCb(adoptedStyleSheetData);\n }\n reset() {\n this.styleMirror.reset();\n this.trackedLinkElements = /* @__PURE__ */ new WeakSet();\n }\n // TODO: take snapshot on stylesheet reload by applying event listener\n trackStylesheetInLinkElement(_linkEl) {\n }\n}\nclass ProcessedNodeManager {\n constructor() {\n __publicField(this, \"nodeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"active\", false);\n }\n inOtherBuffer(node, thisBuffer) {\n const buffers = this.nodeMap.get(node);\n return buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer);\n }\n add(node, buffer) {\n if (!this.active) {\n this.active = true;\n requestAnimationFrame(() => {\n this.nodeMap = /* @__PURE__ */ new WeakMap();\n this.active = false;\n });\n }\n this.nodeMap.set(node, (this.nodeMap.get(node) || /* @__PURE__ */ new Set()).add(buffer));\n }\n destroy() {\n }\n}\nlet wrappedEmit;\nlet takeFullSnapshot;\nlet canvasManager;\nlet recording = false;\ntry {\n if (Array.from([1], (x) => x * 2)[0] !== 2) {\n const cleanFrame = document.createElement(\"iframe\");\n document.body.appendChild(cleanFrame);\n Array.from = ((_a = cleanFrame.contentWindow) == null ? void 0 : _a.Array.from) || Array.from;\n document.body.removeChild(cleanFrame);\n }\n} catch (err) {\n console.debug(\"Unable to override Array.from\", err);\n}\nconst mirror = createMirror();\nfunction record(options = {}) {\n const {\n emit,\n checkoutEveryNms,\n checkoutEveryNth,\n blockClass = \"rr-block\",\n blockSelector = null,\n ignoreClass = \"rr-ignore\",\n ignoreSelector = null,\n maskTextClass = \"rr-mask\",\n maskTextSelector = null,\n inlineStylesheet = true,\n maskAllInputs,\n maskInputOptions: _maskInputOptions,\n slimDOMOptions: _slimDOMOptions,\n maskInputFn,\n maskTextFn,\n hooks,\n packFn,\n sampling = {},\n dataURLOptions = {},\n mousemoveWait,\n recordDOM = true,\n recordCanvas = false,\n recordCrossOriginIframes = false,\n recordAfter = options.recordAfter === \"DOMContentLoaded\" ? options.recordAfter : \"load\",\n userTriggeredOnInput = false,\n collectFonts = false,\n inlineImages = false,\n plugins,\n keepIframeSrcFn = () => false,\n ignoreCSSAttributes = /* @__PURE__ */ new Set([]),\n errorHandler: errorHandler2\n } = options;\n registerErrorHandler(errorHandler2);\n const inEmittingFrame = recordCrossOriginIframes ? window.parent === window : true;\n let passEmitsToParent = false;\n if (!inEmittingFrame) {\n try {\n if (window.parent.document) {\n passEmitsToParent = false;\n }\n } catch (e) {\n passEmitsToParent = true;\n }\n }\n if (inEmittingFrame && !emit) {\n throw new Error(\"emit function is required\");\n }\n if (!inEmittingFrame && !passEmitsToParent) {\n return () => {\n };\n }\n if (mousemoveWait !== void 0 && sampling.mousemove === void 0) {\n sampling.mousemove = mousemoveWait;\n }\n mirror.reset();\n const maskInputOptions = maskAllInputs === true ? {\n color: true,\n date: true,\n \"datetime-local\": true,\n email: true,\n month: true,\n number: true,\n range: true,\n search: true,\n tel: true,\n text: true,\n time: true,\n url: true,\n week: true,\n textarea: true,\n select: true,\n password: true\n } : _maskInputOptions !== void 0 ? _maskInputOptions : { password: true };\n const slimDOMOptions = slimDOMDefaults(_slimDOMOptions);\n polyfill();\n let lastFullSnapshotEvent;\n let incrementalSnapshotCount = 0;\n const eventProcessor = (e) => {\n for (const plugin of plugins || []) {\n if (plugin.eventProcessor) {\n e = plugin.eventProcessor(e);\n }\n }\n if (packFn && // Disable packing events which will be emitted to parent frames.\n !passEmitsToParent) {\n e = packFn(e);\n }\n return e;\n };\n wrappedEmit = (r, isCheckout) => {\n var _a2;\n const e = r;\n e.timestamp = nowTimestamp();\n if (((_a2 = mutationBuffers[0]) == null ? void 0 : _a2.isFrozen()) && e.type !== EventType.FullSnapshot && !(e.type === EventType.IncrementalSnapshot && e.data.source === IncrementalSource.Mutation)) {\n mutationBuffers.forEach((buf) => buf.unfreeze());\n }\n if (inEmittingFrame) {\n emit == null ? void 0 : emit(eventProcessor(e), isCheckout);\n } else if (passEmitsToParent) {\n const message = {\n type: \"rrweb\",\n event: eventProcessor(e),\n origin: window.location.origin,\n isCheckout\n };\n window.parent.postMessage(message, \"*\");\n }\n if (e.type === EventType.FullSnapshot) {\n lastFullSnapshotEvent = e;\n incrementalSnapshotCount = 0;\n } else if (e.type === EventType.IncrementalSnapshot) {\n if (e.data.source === IncrementalSource.Mutation && e.data.isAttachIframe) {\n return;\n }\n incrementalSnapshotCount++;\n const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;\n const exceedTime = checkoutEveryNms && e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;\n if (exceedCount || exceedTime) {\n takeFullSnapshot(true);\n }\n }\n };\n const wrappedMutationEmit = (m) => {\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n ...m\n }\n });\n };\n const wrappedScrollEmit = (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Scroll,\n ...p\n }\n });\n const wrappedCanvasMutationEmit = (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CanvasMutation,\n ...p\n }\n });\n const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.AdoptedStyleSheet,\n ...a\n }\n });\n const stylesheetManager = new StylesheetManager({\n mutationCb: wrappedMutationEmit,\n adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit\n });\n const iframeManager = new IframeManager({\n mirror,\n mutationCb: wrappedMutationEmit,\n stylesheetManager,\n recordCrossOriginIframes,\n wrappedEmit\n });\n for (const plugin of plugins || []) {\n if (plugin.getMirror)\n plugin.getMirror({\n nodeMirror: mirror,\n crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,\n crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror\n });\n }\n const processedNodeManager = new ProcessedNodeManager();\n canvasManager = new CanvasManager({\n recordCanvas,\n mutationCb: wrappedCanvasMutationEmit,\n win: window,\n blockClass,\n blockSelector,\n mirror,\n sampling: sampling.canvas,\n dataURLOptions\n });\n const shadowDomManager = new ShadowDomManager({\n mutationCb: wrappedMutationEmit,\n scrollCb: wrappedScrollEmit,\n bypassOptions: {\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n inlineStylesheet,\n maskInputOptions,\n dataURLOptions,\n maskTextFn,\n maskInputFn,\n recordCanvas,\n inlineImages,\n sampling,\n slimDOMOptions,\n iframeManager,\n stylesheetManager,\n canvasManager,\n keepIframeSrcFn,\n processedNodeManager\n },\n mirror\n });\n takeFullSnapshot = (isCheckout = false) => {\n if (!recordDOM) {\n return;\n }\n wrappedEmit(\n {\n type: EventType.Meta,\n data: {\n href: window.location.href,\n width: getWindowWidth(),\n height: getWindowHeight()\n }\n },\n isCheckout\n );\n stylesheetManager.reset();\n shadowDomManager.init();\n mutationBuffers.forEach((buf) => buf.lock());\n const node = snapshot(document, {\n mirror,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n inlineStylesheet,\n maskAllInputs: maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOM: slimDOMOptions,\n dataURLOptions,\n recordCanvas,\n inlineImages,\n onSerialize: (n) => {\n if (isSerializedIframe(n, mirror)) {\n iframeManager.addIframe(n);\n }\n if (isSerializedStylesheet(n, mirror)) {\n stylesheetManager.trackLinkElement(n);\n }\n if (hasShadowRoot(n)) {\n shadowDomManager.addShadowRoot(index.shadowRoot(n), document);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n iframeManager.attachIframe(iframe, childSn);\n shadowDomManager.observeAttachShadow(iframe);\n },\n onStylesheetLoad: (linkEl, childSn) => {\n stylesheetManager.attachLinkElement(linkEl, childSn);\n },\n keepIframeSrcFn\n });\n if (!node) {\n return console.warn(\"Failed to snapshot the document\");\n }\n wrappedEmit(\n {\n type: EventType.FullSnapshot,\n data: {\n node,\n initialOffset: getWindowScroll(window)\n }\n },\n isCheckout\n );\n mutationBuffers.forEach((buf) => buf.unlock());\n if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)\n stylesheetManager.adoptStyleSheets(\n document.adoptedStyleSheets,\n mirror.getId(document)\n );\n };\n try {\n const handlers = [];\n const observe = (doc) => {\n var _a2;\n return callbackWrapper(initObservers)(\n {\n mutationCb: wrappedMutationEmit,\n mousemoveCb: (positions, source) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source,\n positions\n }\n }),\n mouseInteractionCb: (d) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MouseInteraction,\n ...d\n }\n }),\n scrollCb: wrappedScrollEmit,\n viewportResizeCb: (d) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.ViewportResize,\n ...d\n }\n }),\n inputCb: (v) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Input,\n ...v\n }\n }),\n mediaInteractionCb: (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MediaInteraction,\n ...p\n }\n }),\n styleSheetRuleCb: (r) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleSheetRule,\n ...r\n }\n }),\n styleDeclarationCb: (r) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleDeclaration,\n ...r\n }\n }),\n canvasMutationCb: wrappedCanvasMutationEmit,\n fontCb: (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Font,\n ...p\n }\n }),\n selectionCb: (p) => {\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Selection,\n ...p\n }\n });\n },\n customElementCb: (c) => {\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CustomElement,\n ...c\n }\n });\n },\n blockClass,\n ignoreClass,\n ignoreSelector,\n maskTextClass,\n maskTextSelector,\n maskInputOptions,\n inlineStylesheet,\n sampling,\n recordDOM,\n recordCanvas,\n inlineImages,\n userTriggeredOnInput,\n collectFonts,\n doc,\n maskInputFn,\n maskTextFn,\n keepIframeSrcFn,\n blockSelector,\n slimDOMOptions,\n dataURLOptions,\n mirror,\n iframeManager,\n stylesheetManager,\n shadowDomManager,\n processedNodeManager,\n canvasManager,\n ignoreCSSAttributes,\n plugins: ((_a2 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a2.map((p) => ({\n observer: p.observer,\n options: p.options,\n callback: (payload) => wrappedEmit({\n type: EventType.Plugin,\n data: {\n plugin: p.name,\n payload\n }\n })\n }))) || []\n },\n hooks\n );\n };\n iframeManager.addLoadListener((iframeEl) => {\n try {\n handlers.push(observe(iframeEl.contentDocument));\n } catch (error) {\n console.warn(error);\n }\n });\n const init = () => {\n takeFullSnapshot();\n handlers.push(observe(document));\n recording = true;\n };\n if ([\"interactive\", \"complete\"].includes(document.readyState)) {\n init();\n } else {\n handlers.push(\n on(\"DOMContentLoaded\", () => {\n wrappedEmit({\n type: EventType.DomContentLoaded,\n data: {}\n });\n if (recordAfter === \"DOMContentLoaded\") init();\n })\n );\n handlers.push(\n on(\n \"load\",\n () => {\n wrappedEmit({\n type: EventType.Load,\n data: {}\n });\n if (recordAfter === \"load\") init();\n },\n window\n )\n );\n }\n return () => {\n handlers.forEach((handler) => {\n try {\n handler();\n } catch (error) {\n const msg = String(error).toLowerCase();\n if (!msg.includes(\"cross-origin\")) {\n console.warn(error);\n }\n }\n });\n processedNodeManager.destroy();\n recording = false;\n unregisterErrorHandler();\n };\n } catch (error) {\n console.warn(error);\n }\n}\nrecord.addCustomEvent = (tag, payload) => {\n if (!recording) {\n throw new Error(\"please add custom event after start recording\");\n }\n wrappedEmit({\n type: EventType.Custom,\n data: {\n tag,\n payload\n }\n });\n};\nrecord.freezePage = () => {\n mutationBuffers.forEach((buf) => buf.freeze());\n};\nrecord.takeFullSnapshot = (isCheckout) => {\n if (!recording) {\n throw new Error(\"please take full snapshot after start recording\");\n }\n takeFullSnapshot(isCheckout);\n};\nrecord.mirror = mirror;\nexport {\n record\n};\n//# sourceMappingURL=record.js.map\n","var EventType = /* @__PURE__ */ ((EventType2) => {\n EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n EventType2[EventType2[\"Asset\"] = 7] = \"Asset\";\n return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n return PointerTypes2;\n})(PointerTypes || {});\nvar CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {\n CanvasContext2[CanvasContext2[\"2D\"] = 0] = \"2D\";\n CanvasContext2[CanvasContext2[\"WebGL\"] = 1] = \"WebGL\";\n CanvasContext2[CanvasContext2[\"WebGL2\"] = 2] = \"WebGL2\";\n return CanvasContext2;\n})(CanvasContext || {});\nvar MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {\n MediaInteractions2[MediaInteractions2[\"Play\"] = 0] = \"Play\";\n MediaInteractions2[MediaInteractions2[\"Pause\"] = 1] = \"Pause\";\n MediaInteractions2[MediaInteractions2[\"Seeked\"] = 2] = \"Seeked\";\n MediaInteractions2[MediaInteractions2[\"VolumeChange\"] = 3] = \"VolumeChange\";\n MediaInteractions2[MediaInteractions2[\"RateChange\"] = 4] = \"RateChange\";\n return MediaInteractions2;\n})(MediaInteractions || {});\nvar ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {\n ReplayerEvents2[\"Start\"] = \"start\";\n ReplayerEvents2[\"Pause\"] = \"pause\";\n ReplayerEvents2[\"Resume\"] = \"resume\";\n ReplayerEvents2[\"Resize\"] = \"resize\";\n ReplayerEvents2[\"Finish\"] = \"finish\";\n ReplayerEvents2[\"FullsnapshotRebuilded\"] = \"fullsnapshot-rebuilded\";\n ReplayerEvents2[\"LoadStylesheetStart\"] = \"load-stylesheet-start\";\n ReplayerEvents2[\"LoadStylesheetEnd\"] = \"load-stylesheet-end\";\n ReplayerEvents2[\"SkipStart\"] = \"skip-start\";\n ReplayerEvents2[\"SkipEnd\"] = \"skip-end\";\n ReplayerEvents2[\"MouseInteraction\"] = \"mouse-interaction\";\n ReplayerEvents2[\"EventCast\"] = \"event-cast\";\n ReplayerEvents2[\"CustomEvent\"] = \"custom-event\";\n ReplayerEvents2[\"Flush\"] = \"flush\";\n ReplayerEvents2[\"StateChange\"] = \"state-change\";\n ReplayerEvents2[\"PlayBack\"] = \"play-back\";\n ReplayerEvents2[\"Destroy\"] = \"destroy\";\n return ReplayerEvents2;\n})(ReplayerEvents || {});\nvar NodeType = /* @__PURE__ */ ((NodeType2) => {\n NodeType2[NodeType2[\"Document\"] = 0] = \"Document\";\n NodeType2[NodeType2[\"DocumentType\"] = 1] = \"DocumentType\";\n NodeType2[NodeType2[\"Element\"] = 2] = \"Element\";\n NodeType2[NodeType2[\"Text\"] = 3] = \"Text\";\n NodeType2[NodeType2[\"CDATA\"] = 4] = \"CDATA\";\n NodeType2[NodeType2[\"Comment\"] = 5] = \"Comment\";\n return NodeType2;\n})(NodeType || {});\nexport {\n CanvasContext,\n EventType,\n IncrementalSource,\n MediaInteractions,\n MouseInteractions,\n NodeType,\n PointerTypes,\n ReplayerEvents\n};\n//# sourceMappingURL=types.js.map\n","import { record } from \"@rrweb/record\";\nimport { EventType, type eventWithTime } from \"@rrweb/types\";\n\n/**\n * Buffered session replay — the rrweb capture half of issue #189 (ADR-0024).\n *\n * The recorder runs continuously from mount (\"the moment before matters\",\n * VISION principle 4) but never streams: rrweb events accumulate in **two\n * checkout-delimited buckets**, and every {@link REPLAY_CHECKOUT_MS} rrweb takes\n * a fresh full DOM snapshot (a \"checkout\") that rotates the buckets. A report's\n * {@link ReplayRecorder.snapshot} is the concatenation of both buckets, so it\n * always starts at a full snapshot and carries between one and two checkout\n * intervals of lead-up — the bounded-window posture the Trace already follows,\n * never an unbounded full-session stream.\n *\n * Masking is applied by rrweb **at serialization time, inside the page** — the\n * same client-side, private-by-default boundary as the screenshot and the Trace\n * (spec 0003 §C, VISION §5): every input is masked (`maskAllInputs`) and, by\n * default, **all text** is masked (`maskTextSelector: \"*\"`), so the recording\n * that leaves the browser carries layout and interaction, not content. A\n * Project that accepts the trade-off can narrow the text mask via\n * {@link ReplayOptions.maskTextSelector} (rrweb 2.1 has no per-element unmask\n * selector, so narrowing the mask selector is the escape hatch). The SDK's own\n * chrome — launcher and overlay hosts — is blocked from the recording entirely,\n * mirroring how the screenshot strips it.\n */\n\n/**\n * How often rrweb takes a checkout full snapshot, which is also the bucket\n * rotation period: a snapshot carries 1–2 of these intervals of lead-up\n * (30–60 s), Sentry's buffered-replay ballpark.\n */\nexport const REPLAY_CHECKOUT_MS = 30_000;\n\n/**\n * The SDK's own host elements (dom.ts markers), excluded from the recording the\n * way the screenshot's clone walk strips them.\n */\nexport const FIXBACK_BLOCK_SELECTOR = \"[data-fixback-root],[data-fixback-overlay]\";\n\n/**\n * Media elements blocked from the recording by default (Sentry's `blockAllMedia`\n * posture, adopted): text masking cannot redact what an image shows, so media\n * renders as a same-size placeholder in replay unless a Project opts out via\n * {@link ReplayOptions.blockMedia}.\n */\nexport const FIXBACK_MEDIA_SELECTOR =\n \"img,image,svg,video,object,picture,embed,map,audio\";\n\n/** Tuning for the replay recorder. All optional; the defaults are the contract. */\nexport interface ReplayOptions {\n /**\n * Mask **all** text content (default `true`, private-by-default). `false`\n * records text in the clear — inputs stay masked regardless.\n */\n readonly maskText?: boolean;\n /**\n * Which elements' text rrweb masks when {@link maskText} is on. Defaults to\n * `\"*\"` (everything); narrow it to unmask known-safe regions.\n */\n readonly maskTextSelector?: string;\n /**\n * Block media content — images, video, audio, SVG — from the recording\n * (default `true`, {@link FIXBACK_MEDIA_SELECTOR}): what a picture shows\n * cannot be text-masked, so media is a placeholder in replay. `false` records\n * it (an internal/beta Project trading privacy for fidelity, VISION §5).\n */\n readonly blockMedia?: boolean;\n /** Extra elements to exclude from the recording, alongside the SDK's own chrome. */\n readonly blockSelector?: string;\n}\n\n/** One rrweb event as recorded; the wire payload is an array of these. */\nexport type ReplayEvent = eventWithTime;\n\n/** The buffered window a report ships: rrweb events starting at a full snapshot. */\nexport interface ReplaySnapshot {\n readonly events: readonly ReplayEvent[];\n}\n\n/** A read-only view of the recorder the report surfaces attach from. */\nexport interface ReplaySource {\n /** The current buffered window, or `null` when nothing replayable exists. */\n snapshot(): ReplaySnapshot | null;\n}\n\n/** A running replay recorder. */\nexport interface ReplayRecorder extends ReplaySource {\n /** Stop recording and release the buffers. Safe to call more than once. */\n stop(): void;\n}\n\n/** The slice of rrweb's record options the recorder sets. */\nexport interface ReplayRecordOptions {\n readonly emit: (event: ReplayEvent, isCheckout?: boolean) => void;\n readonly checkoutEveryNms?: number;\n readonly maskAllInputs?: boolean;\n readonly maskTextSelector?: string;\n readonly blockSelector?: string;\n readonly slimDOMOptions?: \"all\";\n}\n\n/**\n * The slice of rrweb's `record` the recorder consumes; injectable for tests.\n * (A concrete signature — rrweb's own is generic, which mocks can't satisfy.)\n */\nexport type RecordFn = (options: ReplayRecordOptions) => (() => void) | undefined;\n\n/** A recorder that never records — what a failed start degrades to. */\nconst NOOP_RECORDER: ReplayRecorder = { snapshot: () => null, stop: () => {} };\n\n/**\n * Start the buffered replay recorder. Never throws: an rrweb failure (an exotic\n * DOM, an unsupported environment) degrades to a recorder whose `snapshot()` is\n * `null`, so a Fixback problem never surfaces on the host page and a report\n * simply ships without replay.\n */\nexport function startReplayRecorder(\n options: ReplayOptions = {},\n recordFn: RecordFn = record as RecordFn,\n): ReplayRecorder {\n /** Events since the last checkout (`cur`) and the full interval before it (`prev`). */\n let prev: ReplayEvent[] = [];\n let cur: ReplayEvent[] = [];\n /**\n * A checkout arrives as a burst of consecutive `isCheckout` events (meta +\n * full snapshot); rotate the buckets once per burst, on its first event.\n */\n let inCheckout = false;\n\n const maskText = options.maskText !== false;\n const blockParts = [\n FIXBACK_BLOCK_SELECTOR,\n ...(options.blockMedia !== false ? [FIXBACK_MEDIA_SELECTOR] : []),\n ...(options.blockSelector ? [options.blockSelector] : []),\n ];\n const blockSelector = blockParts.join(\",\");\n\n let stopFn: (() => void) | undefined;\n try {\n stopFn = recordFn({\n emit: (event: ReplayEvent, isCheckout?: boolean) => {\n if (isCheckout && !inCheckout) {\n prev = cur;\n cur = [];\n }\n inCheckout = isCheckout === true;\n cur.push(event);\n },\n checkoutEveryNms: REPLAY_CHECKOUT_MS,\n maskAllInputs: true,\n ...(maskText ? { maskTextSelector: options.maskTextSelector ?? \"*\" } : {}),\n blockSelector,\n // Strip script tags, comments, and head noise from the snapshot — replay\n // re-executes nothing, so they are dead weight on every payload.\n slimDOMOptions: \"all\",\n });\n } catch {\n stopFn = undefined;\n }\n if (typeof stopFn !== \"function\") return NOOP_RECORDER;\n const stopRecord = stopFn;\n\n let running = true;\n return {\n snapshot() {\n if (!running) return null;\n const events = [...prev, ...cur];\n // Replay needs a full snapshot to rebuild from; without one (recording\n // just started, or rrweb never produced it) there is nothing to watch.\n if (!events.some((event) => event.type === EventType.FullSnapshot)) return null;\n return { events };\n },\n stop() {\n if (!running) return;\n running = false;\n try {\n stopRecord();\n } catch {\n // Teardown must never throw into the host page.\n }\n prev = [];\n cur = [];\n },\n };\n}\n","import { type BootAnswer, type IdentityInputs, requestBoot } from \"./boot\";\nimport {\n createBreadcrumbBuffer,\n instrumentBreadcrumbs,\n type BeforeBreadcrumb,\n type BreadcrumbBuffer,\n type BreadcrumbLevel,\n type Teardown,\n type TraceStream,\n} from \"./breadcrumbs\";\nimport { installErrorCapture } from \"./error-capture\";\nimport { ensureAnonymousId } from \"./identity\";\nimport {\n fetchInviteStatus,\n persistReporter,\n readInviteToken,\n readStoredReporter,\n redeemInviteToken,\n type ReporterDisplay,\n stripInviteToken,\n} from \"./invite\";\nimport { LAUNCH_EVENT, type Launcher, mountLauncher, unmountLauncher } from \"./launcher\";\nimport { createOnboardingModal } from \"./onboarding\";\nimport { createOverlay } from \"./overlay\";\nimport {\n startReplayRecorder,\n type ReplayOptions,\n type ReplayRecorder,\n} from \"./replay\";\nimport { normaliseRelease } from \"./report\";\nimport type { BeforeSend } from \"./scrub\";\nimport { SDK_VERSION } from \"./version\";\n\n/**\n * The hosted Fixback API origin the SDK talks to by default. A self-hosted or\n * local deployment overrides it with `apiUrl` (the dashboard's install snippet\n * pre-fills the right value for the Project).\n */\nexport const DEFAULT_API_URL = \"https://api.fixback.dev\";\n\n/**\n * Does `url` address one of the SDK's **own** API endpoints? Every request the SDK\n * issues lives under two namespaces beneath the API origin: `/api/ingest/*` — boot\n * (`bootEndpoint`, boot.ts) and feedback (`feedbackEndpoint`, submit.ts) — and\n * `/api/invites/*` (`inviteStatusEndpoint` / `redeemEndpoint`, invite.ts).\n *\n * The trace's network capture ignores **only** these, never the whole origin. That\n * distinction matters when the instrumented app and the Fixback API share an origin — a\n * self-hosted deployment, or Fixback running its own SDK on its own dashboard — where\n * ignoring the origin wholesale would swallow all of the app's own requests and leave the\n * Network tab empty. When the app and the API sit on different origins (the common case)\n * this matches nothing extra, since the app's origin is never `apiUrl`. `url` is the raw\n * request URL — absolute for every call the SDK makes — so a prefix test over the\n * normalised origin is exact.\n */\nexport function isFixbackApiRequest(apiUrl: string, url: string): boolean {\n const apiBase = apiUrl.replace(/\\/+$/, \"\");\n return (\n url.startsWith(`${apiBase}/api/ingest/`) || url.startsWith(`${apiBase}/api/invites/`)\n );\n}\n\n/**\n * Trace buffer tuning (spec #122 §A). These are configurable **starting points**\n * from the grill — three per-stream ring budgets (network ≈ 100 / console ≈ 80 /\n * breadcrumbs ≈ 40), a shared age cap (~3 min, on), and **all** console levels\n * captured (eviction priority, not capture, keeps warn/error above the chatter) —\n * never frozen magic numbers. Pass `false` for {@link InitOptions.trace} to disable\n * capture entirely.\n */\nexport interface TraceOptions {\n /**\n * Per-stream ring budgets (network / console / breadcrumbs); each stream evicts\n * independently, so a chatty stream can't drop another's lead-up. Any stream\n * omitted uses its default.\n */\n readonly budgets?: Partial<Record<TraceStream, number>>;\n /** Shared age cap in ms. Defaults to ~3 min (on); pass `0` to disable age pruning. */\n readonly maxAgeMs?: number;\n /** Console levels captured. Defaults to **all** levels (log/info/warn/error/assert/debug). */\n readonly consoleLevels?: readonly BreadcrumbLevel[];\n /** Per-crumb filter: mute a category, edit a crumb, or drop it (`null`). */\n readonly beforeBreadcrumb?: BeforeBreadcrumb;\n}\n\n/** Options for {@link init}. Only `key` is required. */\nexport interface InitOptions extends IdentityInputs {\n /** The Project's **publishable** key — an identifier that ships in the page. */\n readonly key: string;\n /** The Fixback API origin. Defaults to {@link DEFAULT_API_URL}. */\n readonly apiUrl?: string;\n /** Where to mount the launcher. Defaults to `document.body`. */\n readonly target?: HTMLElement;\n /**\n * Still the launcher's pulse and motion. An explicit opt-in that complements\n * the visitor's OS-level `prefers-reduced-motion`, which the launcher already\n * honours on its own.\n */\n readonly reduceMotion?: boolean;\n /**\n * The synchronous, network-free client scrub hook every report passes through\n * before transport (spec §C). Mutate the draft to scrub further, or return\n * `null` to drop the report. Runs after the default scrubbers.\n */\n readonly beforeSend?: BeforeSend;\n /** Run the built-in default scrubbers. Defaults to `true` (private-by-default). */\n readonly scrub?: boolean;\n /** Trace buffer tuning, or `false` to turn the buffer off entirely. */\n readonly trace?: TraceOptions | false;\n /**\n * Buffered session-replay tuning (issue #189, ADR-0024) — masking defaults on:\n * all inputs, all text, SDK chrome blocked — or `false` to turn the recorder\n * off entirely regardless of the served config.\n */\n readonly replay?: ReplayOptions | false;\n /**\n * The dev-side override of the Project's server-served capture config (spec #122\n * §L; ticket #138). Capture is **default-on** and normally governed per-project\n * from the dashboard, surfaced on the boot answer; set a stream here to override\n * what the server serves for it — `{ network: false }` turns network capture off\n * even where the Project leaves it on, and a stream left unset follows the served\n * config. Independent of {@link trace} `false`, which turns the whole buffer off,\n * and of {@link replay} `false`, which turns the recorder off.\n */\n readonly capture?: {\n readonly console?: boolean;\n readonly network?: boolean;\n readonly replay?: boolean;\n };\n /**\n * Automatic error capture — the SDK files uncaught exceptions / unhandled\n * rejections as `source: auto` Feedback with no prompt (spec §E, ADR-0011).\n * **Default-on across all Gates**; set `false` for the per-project toggle that\n * turns it off. It is gated by boot's `canSubmit` either way, so an auto-error is\n * never filed where a manual report would be refused.\n */\n readonly autoCapture?: boolean;\n /**\n * The host app's **Release** — a build identifier (a git SHA, a semver, a\n * `name@version`) stamped into every submission's environment (#117,\n * ADR-0024). Set it to the same value the build uploaded sourcemaps under\n * (`npx fixback sourcemaps upload --release <v>`), and auto-captured errors\n * gain a symbolicated **code-area pointer** on their Issues. Optional: without\n * it (or without uploaded sourcemaps) everything behaves exactly as before.\n * An invalid value (whitespace, slashes, over 100 chars) is ignored with a\n * console warning.\n */\n readonly release?: string;\n}\n\n/**\n * Options for {@link redeem} — the explicit form of the `?fixback_invite=` URL\n * detection {@link init} performs. Identical to {@link InitOptions} plus the\n * `token` to redeem (the value the invite link carried).\n */\nexport interface RedeemOptions extends InitOptions {\n /** The invite token to redeem — the `?fixback_invite=` value from the link. */\n readonly token: string;\n}\n\n/** A running SDK instance. */\nexport interface FixbackInstance {\n /** Remove the launcher and release its DOM. Safe to call more than once. */\n destroy(): void;\n}\n\nconst NOOP_INSTANCE: FixbackInstance = { destroy() {} };\n\n/** The host site's origin (for the onboarding modal); never throws. */\nfunction originHost(): string {\n try {\n const loc = window.location;\n return loc.host || loc.hostname || \"this site\";\n } catch {\n return \"this site\";\n }\n}\n\n/** The current page URL, or `\"\"` when it cannot be read; never throws. */\nfunction safeHref(): string {\n try {\n return window.location.href;\n } catch {\n return \"\";\n }\n}\n\n/** Context for mounting the launcher + overlay + trace once boot says yes. */\ninterface MountContext {\n readonly options: InitOptions;\n readonly apiUrl: string;\n readonly key: string;\n readonly identity: IdentityInputs;\n /**\n * The Reporter's self-provided display name / email (spec §F), when the SDK holds\n * them. Rides into the overlay and auto-capture so every submission names who filed\n * it — display only, never a trust signal.\n */\n readonly display?: ReporterDisplay;\n readonly target: HTMLElement;\n readonly answer: BootAnswer;\n}\n\n/**\n * Mount the launcher and the report overlay it opens, the thin trace buffer\n * (spec §C), and automatic error capture (spec §E). Returns a teardown that removes\n * them all. The boot answer's `gate` + `tier` ride into the overlay (no second\n * call): `tier` drives the display-only header chip (§G), `gate` is reserved for\n * Gate-aware behaviour. The overlay and the auto-capture handlers carry the resolved\n * identity, so both a filed report and an auto-captured error are attributed to the\n * very Reporter boot recognised.\n */\nfunction mountReporter(ctx: MountContext): Teardown {\n const { options, apiUrl, key, identity, display, target, answer } = ctx;\n // The host app's Release (#117, ADR-0024), validated once here: an invalid\n // value is dropped with a warning (never shipped for the server to discard,\n // and never a reason to refuse to mount — capture must not break on config).\n const release = options.release ? normaliseRelease(options.release) : undefined;\n if (options.release && !release) {\n console.warn(\n `[fixback] ignoring invalid release ${JSON.stringify(options.release)} — ` +\n \"use 1-100 visible characters with no whitespace or slashes (e.g. a git SHA or semver).\",\n );\n }\n const launcher: Launcher = mountLauncher(target, {\n key,\n reduceMotion: options.reduceMotion,\n });\n\n let buffer: BreadcrumbBuffer | null = null;\n let teardownTrace: Teardown = () => {};\n if (options.trace !== false) {\n const trace = options.trace ?? {};\n // Effective per-stream capture (#138): start from what boot served (default-on\n // when the server omits it or a value is not a boolean), then let an explicit\n // `init` option override that stream. Turning a stream off means it is never\n // instrumented, so no entry of that kind ever reaches the wire.\n const served = ctx.answer.capture;\n const captureConsole =\n options.capture?.console ??\n (typeof served?.console === \"boolean\" ? served.console : true);\n const captureNetwork =\n options.capture?.network ??\n (typeof served?.network === \"boolean\" ? served.network : true);\n buffer = createBreadcrumbBuffer({\n budgets: trace.budgets,\n maxAgeMs: trace.maxAgeMs,\n beforeBreadcrumb: trace.beforeBreadcrumb,\n });\n teardownTrace = instrumentBreadcrumbs(buffer, {\n consoleLevels: trace.consoleLevels,\n ignoreUrl: (url) => isFixbackApiRequest(apiUrl, url),\n captureConsole,\n captureNetwork,\n });\n }\n\n // Buffered session replay (issue #189, ADR-0024): same gating shape as the\n // trace streams — the served per-project toggle (default-on), overridable from\n // `capture.replay`, with `replay: false` turning the recorder off outright.\n let replay: ReplayRecorder | null = null;\n if (options.replay !== false) {\n const served = ctx.answer.capture;\n const captureReplay =\n options.capture?.replay ??\n (typeof served?.replay === \"boolean\" ? served.replay : true);\n if (captureReplay) {\n replay = startReplayRecorder(options.replay ?? {});\n }\n }\n\n const overlay = createOverlay({\n apiUrl,\n key,\n identity,\n display,\n gate: answer.gate,\n tier: answer.tier,\n sdkVersion: SDK_VERSION,\n release,\n target,\n buffer,\n replay,\n beforeSend: options.beforeSend,\n scrub: options.scrub,\n });\n const onLaunch = (): void => overlay.open();\n launcher.host.addEventListener(LAUNCH_EVENT, onLaunch);\n\n // Automatic error capture (spec §E, ADR-0011): two global handlers file uncaught\n // errors as `source: auto` Feedback for this session's Reporter, with no prompt.\n // Default-on; `autoCapture: false` is the per-project toggle. Reaching here means\n // boot already returned `canSubmit`, so the Gate is respected and the auto-error\n // inherits the very tier boot derived — a Public crash stays tracked-not-shipped.\n let teardownAutoCapture: Teardown = () => {};\n if (options.autoCapture !== false) {\n teardownAutoCapture = installErrorCapture({\n apiUrl,\n key,\n identity,\n display,\n sdkVersion: SDK_VERSION,\n release,\n buffer,\n replay,\n beforeSend: options.beforeSend,\n scrub: options.scrub,\n }).destroy;\n }\n\n return () => {\n launcher.host.removeEventListener(LAUNCH_EVENT, onLaunch);\n overlay.destroy();\n unmountLauncher(launcher);\n teardownTrace();\n replay?.stop();\n teardownAutoCapture();\n };\n}\n\n/**\n * The shared boot + identity flow behind {@link init} and {@link redeem}.\n *\n * When an invite `token` is present and its Invite is live, the SDK renders the\n * onboarding modal (spec §F) instead of mounting immediately; on confirm it\n * redeems the Invite, persists the returned `reporterId` (scoped by publishable\n * key), strips the token from the URL (one-time consumption), and only then boots\n * with that identity and mounts the launcher. With no token — or a dead one — it\n * boots with any previously stored `reporterId` (a returning invited tester) or\n * an anonymous id, and mounts solely when boot's `canSubmit` is true. So on an\n * Invited / Internal Gate the launcher is absent until redemption, while an Open\n * Gate shows it to an anonymous visitor. Everything is wrapped so a Fixback\n * problem resolves to a no-op instance and never surfaces on the host page.\n */\nasync function run(\n options: InitOptions,\n inviteToken: string | null,\n): Promise<FixbackInstance> {\n try {\n // No DOM (server-side render, worker) — nothing to mount.\n if (typeof document === \"undefined\") return NOOP_INSTANCE;\n\n const key = options?.key;\n if (typeof key !== \"string\" || key.length === 0) return NOOP_INSTANCE;\n\n const apiUrl = options.apiUrl ?? DEFAULT_API_URL;\n const anonymousId = options.anonymousId ?? ensureAnonymousId();\n const target = options.target ?? document.body;\n\n // The launcher / overlay and the modal mount at different times (the modal\n // now, the launcher after redemption). `destroy()` tears down whichever exist.\n let disposed = false;\n let teardownMounted: Teardown = () => {};\n let teardownModal: Teardown = () => {};\n const instance: FixbackInstance = {\n destroy: () => {\n disposed = true;\n teardownModal();\n teardownModal = () => {};\n teardownMounted();\n teardownMounted = () => {};\n },\n };\n\n /** The identity to present when there is no fresh redemption to honour. */\n const storedIdentity = (): IdentityInputs => {\n const stored = readStoredReporter(key);\n return {\n signedIdentity: options.signedIdentity,\n reporterId: options.reporterId ?? stored?.reporterId,\n anonymousId,\n };\n };\n\n /**\n * The display name / email to present alongside a returning Reporter's stored\n * identity (spec §F) — read from the same persisted record `storedIdentity` uses,\n * so a report from a returning invited tester still names them. `undefined` when\n * nothing was stored (an anonymous visitor names no one).\n */\n const storedDisplay = (): ReporterDisplay | undefined => {\n const stored = readStoredReporter(key);\n if (!stored) return undefined;\n const display: ReporterDisplay = {\n ...(stored.name ? { name: stored.name } : {}),\n ...(stored.email ? { email: stored.email } : {}),\n };\n return display.name || display.email ? display : undefined;\n };\n\n /** Boot with a resolved identity and mount the launcher when accepted. */\n const bootAndMount = async (\n identity: IdentityInputs,\n display?: ReporterDisplay,\n ): Promise<void> => {\n const answer = await requestBoot(apiUrl, { key, ...identity });\n if (disposed || !answer?.canSubmit) return;\n teardownMounted = mountReporter({\n options,\n apiUrl,\n key,\n identity,\n display,\n target,\n answer,\n });\n };\n\n if (inviteToken) {\n const status = await fetchInviteStatus(apiUrl, inviteToken);\n if (disposed) return instance;\n if (status && status.status === \"pending\") {\n const stored = readStoredReporter(key);\n\n const confirmRedeem = async (display: ReporterDisplay): Promise<void> => {\n const result = await redeemInviteToken(apiUrl, inviteToken);\n if (disposed) return;\n teardownModal();\n teardownModal = () => {};\n if (result && result.status === \"redeemed\") {\n persistReporter(key, {\n reporterId: result.reporterId,\n name: display.name,\n email: display.email,\n });\n stripInviteToken(window);\n await bootAndMount(\n {\n signedIdentity: options.signedIdentity,\n reporterId: result.reporterId,\n anonymousId,\n },\n // The name / email the tester just entered ride along with their reports.\n display.name || display.email ? display : undefined,\n );\n } else {\n // The Invite died between reading its status and redeeming it (a\n // race, or an already-spent shared link) — fall back to whatever\n // identity we already hold; on a gated Project that means no launcher.\n await bootAndMount(storedIdentity(), storedDisplay());\n }\n };\n\n const modal = createOnboardingModal({\n origin: originHost(),\n tier: status.tier,\n defaults: stored ? { name: stored.name, email: stored.email } : undefined,\n target,\n onConfirm: (display) => {\n void confirmRedeem(display);\n },\n });\n teardownModal = () => modal.destroy();\n return instance;\n }\n // A dead, unknown, or unreachable Invite shows no modal — the SDK proceeds\n // as an ordinary boot (a returning Reporter's stored identity, or anonymous).\n }\n\n await bootAndMount(storedIdentity(), storedDisplay());\n return instance;\n } catch {\n // A Fixback failure must never break the host page.\n return NOOP_INSTANCE;\n }\n}\n\n/**\n * Boot the SDK and mount the launcher when — and only when — a submission would\n * be accepted for this key, origin, and Gate.\n *\n * On load the SDK first checks the page URL for an invite token\n * (`?fixback_invite=`, spec §F); when one is present and live it renders the\n * onboarding modal and defers the launcher until the tester redeems. Otherwise it\n * calls the ingest boot endpoint and mounts the launcher solely when the answer's\n * `canSubmit` is true — so a Reporter is never shown a launcher a submission would\n * be refused, and on an Invited / Internal Gate the launcher stays absent until\n * redemption. Everything is wrapped so a Fixback problem — unreachable, refused,\n * or an unexpected error — resolves to a no-op instance.\n */\nexport function init(options: InitOptions): Promise<FixbackInstance> {\n const token = typeof window !== \"undefined\" ? readInviteToken(safeHref()) : null;\n return run(options, token);\n}\n\n/**\n * Redeem an invite token explicitly, the programmatic equivalent of landing on a\n * page with `?fixback_invite=<token>`. Renders the onboarding modal, and on\n * confirm redeems, persists the `reporterId`, and mounts the launcher (spec §F).\n * Use it when the token reaches the page some way other than the URL.\n */\nexport function redeem(options: RedeemOptions): Promise<FixbackInstance> {\n const token =\n typeof options?.token === \"string\" && options.token.length > 0\n ? options.token\n : null;\n return run(options, token);\n}\n"],"x_google_ignoreList":[7,23,24],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECiBjB,GAAoB,uBAG3B,GAAS,6BAGT,GAA+D,CACnE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"}