@typecaast/capture 0.0.8 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-MJRHEKPU.js → chunk-4JQY5NEW.js} +112 -13
- package/dist/chunk-4JQY5NEW.js.map +1 -0
- package/dist/{chunk-2UORYZUZ.js → chunk-TBLY4L5G.js} +21 -4
- package/dist/chunk-TBLY4L5G.js.map +1 -0
- package/dist/{distill-kGI5Nt9q.d.cts → distill-CVvHwBKY.d.cts} +17 -0
- package/dist/{distill-DviDU75P.d.ts → distill-Cs7bOU8G.d.ts} +17 -0
- package/dist/draft.cjs +19 -2
- package/dist/draft.cjs.map +1 -1
- package/dist/draft.d.cts +6 -0
- package/dist/draft.d.ts +6 -0
- package/dist/draft.js +1 -1
- package/dist/import-page.cjs +109 -10
- package/dist/import-page.cjs.map +1 -1
- package/dist/import-page.d.cts +1 -1
- package/dist/import-page.d.ts +1 -1
- package/dist/import-page.js +1 -1
- package/dist/index.cjs +226 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -6
- package/dist/index.d.ts +71 -6
- package/dist/index.js +99 -152
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-2UORYZUZ.js.map +0 -1
- package/dist/chunk-MJRHEKPU.js.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sanitize.ts","../src/draft.ts","../src/tokens.ts","../src/distill.ts","../src/template-skin.tsx","../src/merge.ts"],"names":["createDOMPurify","z","getWindow","useRef","useState","useLayoutEffect","createPortal","jsx","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["import createDOMPurify from \"dompurify\";\n\n/**\n * Allowlist sanitizer for captured / imported HTML+CSS (PLAN §10). Captured\n * markup is **untrusted** — it can carry scripts, event handlers, hostile\n * `url(javascript:)` CSS, `data:text/html` payloads, and framed content. We do\n * not roll our own: the heavy lifting is a maintained, audited sanitizer\n * (DOMPurify), wrapped here with a strict allowlist and a CSS scrubber, and the\n * `TemplateSkinAdapter` *additionally* renders in a shadow root so a sanitizer\n * miss still can't reach the host page. Defense in depth, not a single gate.\n */\n\ninterface WindowLike {\n document: Document;\n}\n\n/** Tags we keep — pure presentational/structural HTML. No scripts, forms, media. */\nconst ALLOWED_TAGS = [\n \"div\",\n \"span\",\n \"p\",\n \"a\",\n \"b\",\n \"strong\",\n \"i\",\n \"em\",\n \"u\",\n \"s\",\n \"small\",\n \"sub\",\n \"sup\",\n \"br\",\n \"hr\",\n \"ul\",\n \"ol\",\n \"li\",\n \"img\",\n \"svg\",\n \"path\",\n \"g\",\n \"circle\",\n \"rect\",\n \"line\",\n \"polyline\",\n \"polygon\",\n \"ellipse\",\n \"defs\",\n \"use\",\n \"title\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"time\",\n \"header\",\n \"footer\",\n \"section\",\n \"article\",\n \"aside\",\n \"nav\",\n \"figure\",\n \"figcaption\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"td\",\n \"th\",\n];\n\n/**\n * Attributes we keep. `data-*` is dropped via `ALLOW_DATA_ATTR: false`, with the\n * single exception of our own `data-tc-slot` marker, which is re-allowed via\n * `ADD_ATTR` below so the slot contract survives a re-sanitize.\n */\nconst ALLOWED_ATTR = [\n \"class\",\n \"style\",\n \"role\",\n \"alt\",\n \"src\",\n \"srcset\",\n \"width\",\n \"height\",\n \"dir\",\n \"title\",\n \"viewbox\",\n \"fill\",\n \"stroke\",\n \"stroke-width\",\n \"d\",\n \"points\",\n \"cx\",\n \"cy\",\n \"r\",\n \"x\",\n \"y\",\n \"x1\",\n \"x2\",\n \"y1\",\n \"y2\",\n \"rx\",\n \"ry\",\n \"transform\",\n \"xmlns\",\n \"href\",\n];\n\n/**\n * Strip CSS-level code execution and exfiltration vectors from a style string\n * (inline `style=\"\"` or a stylesheet body). Inline styles survive sanitize, so\n * this is where `expression()`, `url(javascript:)`, `@import`, `behavior:`, and\n * non-image `data:` URLs are removed.\n */\nexport function scrubCss(css: string): string {\n let out = css;\n // Hostile functions / properties.\n out = out.replace(/expression\\s*\\(/gi, \"/*blocked*/(\");\n out = out.replace(/-moz-binding\\s*:/gi, \"/*blocked*/:\");\n out = out.replace(/behavior\\s*:/gi, \"/*blocked*/:\");\n out = out.replace(/@import[^;]*;?/gi, \"/*blocked-import*/\");\n // url(...) targets: block scripting protocols and non-image data URLs.\n out = out.replace(/url\\(\\s*(['\"]?)([^)'\"]*)\\1\\s*\\)/gi, (whole, _q, uri) => {\n const u = String(uri).trim().toLowerCase();\n const blocked =\n u.startsWith(\"javascript:\") ||\n u.startsWith(\"vbscript:\") ||\n (u.startsWith(\"data:\") && !u.startsWith(\"data:image/\"));\n return blocked ? \"none\" : whole;\n });\n // Bare scripting protocols anywhere in the declaration.\n out = out.replace(/javascript:/gi, \"blocked:\");\n out = out.replace(/vbscript:/gi, \"blocked:\");\n return out;\n}\n\nfunction getWindow(win?: WindowLike): WindowLike {\n if (win) return win;\n if (typeof window !== \"undefined\") return window as unknown as WindowLike;\n throw new Error(\n \"sanitizeHtml requires a DOM window — pass { window } in non-browser environments.\",\n );\n}\n\nlet hooked: unknown = null;\n\ntype PurifyWindow = Parameters<typeof createDOMPurify>[0];\n\nfunction purifierFor(win: WindowLike): ReturnType<typeof createDOMPurify> {\n const purify = createDOMPurify(win as unknown as PurifyWindow);\n // Install hooks once per purifier instance.\n if (hooked !== purify) {\n purify.addHook(\"afterSanitizeAttributes\", (node) => {\n const el = node as Element;\n // Scrub inline styles for CSS hazards.\n const style = el.getAttribute?.(\"style\");\n if (style) el.setAttribute(\"style\", scrubCss(style));\n // Enforce image-only data: URLs on src.\n const src = el.getAttribute?.(\"src\");\n if (src) {\n const u = src.trim().toLowerCase();\n if (u.startsWith(\"data:\") && !u.startsWith(\"data:image/\")) {\n el.removeAttribute(\"src\");\n }\n }\n // Force links inert and safe — no navigation out of a simulation.\n if (el.tagName === \"A\") {\n el.removeAttribute(\"href\");\n el.setAttribute(\"role\", \"link\");\n }\n // target=_blank/opener hygiene (belt-and-braces; href already removed).\n if (el.getAttribute?.(\"target\")) el.removeAttribute(\"target\");\n });\n hooked = purify;\n }\n return purify;\n}\n\nexport interface SanitizeOptions {\n /** DOM window to use (required in Node; defaults to global `window`). */\n window?: WindowLike;\n}\n\n/**\n * Sanitize an untrusted HTML string to the capture allowlist. Returns inert,\n * presentational HTML safe to parse and slot-ify. Always pair with shadow-DOM\n * isolation at render time (`TemplateSkinAdapter`).\n */\nexport function sanitizeHtml(html: string, opts: SanitizeOptions = {}): string {\n const win = getWindow(opts.window);\n const purify = purifierFor(win);\n return purify.sanitize(html, {\n ALLOWED_TAGS,\n ALLOWED_ATTR,\n // Keep our slot marker even though data-* is otherwise dropped.\n ADD_ATTR: [\"data-tc-slot\"],\n ALLOW_DATA_ATTR: false,\n ALLOW_ARIA_ATTR: true,\n FORBID_TAGS: [\n \"script\",\n \"style\",\n \"iframe\",\n \"object\",\n \"embed\",\n \"form\",\n \"input\",\n \"button\",\n \"textarea\",\n \"select\",\n \"link\",\n \"meta\",\n \"base\",\n \"video\",\n \"audio\",\n \"source\",\n ],\n FORBID_ATTR: [\"srcdoc\", \"formaction\", \"xlink:href\"],\n }) as string;\n}\n","import { z } from \"zod\";\n\n/**\n * A `SkinDraft` is what the distiller emits from a captured chat UI: sanitized,\n * slotted HTML templates (with inline styles), extracted design tokens, and a\n * detection report describing what was auto-identified vs. what still needs a\n * human pass (PLAN §10). A draft is *not* a finished skin — `scaffold-skin`\n * turns one into an editable template-skin package, and the capture quality bar\n * (§10) decides whether it ships as a skin or stays \"draft only\".\n *\n * Slot tokens are double-brace placeholders the `TemplateSkinAdapter` fills:\n * frame: `{{messages}}` — where the message list mounts\n * message: `{{author}}` `{{avatar}}` `{{body}}` `{{time}}`\n * composer: `{{composer}}`\n * typing: `{{author}}`\n */\n\nexport const SLOT_TOKENS = {\n messages: \"{{messages}}\",\n author: \"{{author}}\",\n avatar: \"{{avatar}}\",\n body: \"{{body}}\",\n time: \"{{time}}\",\n composer: \"{{composer}}\",\n} as const;\n\nexport type SlotName = \"frame\" | \"message\" | \"composer\" | \"typing\";\n\n/** Per-slot detection outcome — drives the quality-bar metric (§10). */\nexport const slotReportSchema = z.object({\n /** Whether this region was found at all. */\n found: z.boolean(),\n /** Which inner slots were auto-detected (e.g. `[\"author\",\"body\"]`). */\n detected: z.array(z.string()),\n /** Heuristic confidence 0..1 for the auto-detection. */\n confidence: z.number().min(0).max(1),\n});\nexport type SlotReport = z.infer<typeof slotReportSchema>;\n\nconst tokenSetSchema = z.object({\n colors: z.record(z.string(), z.string()),\n fonts: z.record(z.string(), z.string()).optional(),\n space: z.record(z.string(), z.string()).optional(),\n radius: z.record(z.string(), z.string()).optional(),\n});\n\nexport const skinDraftSchema = z.object({\n version: z.literal(1),\n meta: z.object({\n /** Human label, defaulted from the source title/host. */\n name: z.string(),\n /** Source page URL, when known (informational only). */\n sourceUrl: z.string().optional(),\n /** Theme the capture was taken under, when known. */\n theme: z.enum([\"light\", \"dark\"]).optional(),\n /** Suggested canvas from the captured element's box. */\n canvas: z\n .object({ width: z.number().int(), height: z.number().int() })\n .optional(),\n }),\n /**\n * Slotted, sanitized HTML per region. Elements carry inline `style`\n * attributes; `css` holds anything inline styles can't express.\n */\n slots: z.object({\n frame: z.string().optional(),\n message: z.string().optional(),\n composer: z.string().optional(),\n typing: z.string().optional(),\n }),\n /** Best-effort extra CSS (pseudo-elements, keyframes) — may be empty. */\n css: z.string(),\n /** Extracted design tokens (best effort) — the primary/captured theme. */\n tokens: tokenSetSchema,\n /**\n * Dark-theme tokens from a paired capture (M5.7 double-capture flow). When\n * present, the skin supports both themes and switches CSS vars by theme.\n */\n darkTokens: tokenSetSchema.optional(),\n /** Detection report per region. */\n detection: z.object({\n frame: slotReportSchema,\n message: slotReportSchema,\n composer: slotReportSchema,\n typing: slotReportSchema,\n }),\n /** Human-readable warnings (hidden content dropped, slots missing, …). */\n warnings: z.array(z.string()),\n});\n\nexport type SkinDraft = z.infer<typeof skinDraftSchema>;\n\n/** Overall slot-detection ratio used by the §10 quality bar (0..1). */\nexport function detectionScore(draft: SkinDraft): number {\n // The five core slots: message-row found, author, avatar, body, composer.\n const checks = [\n draft.detection.message.detected.includes(\"body\"),\n draft.detection.message.detected.includes(\"author\"),\n draft.detection.message.detected.includes(\"avatar\"),\n draft.detection.message.detected.includes(\"time\"),\n draft.detection.composer.found,\n ];\n return checks.filter(Boolean).length / checks.length;\n}\n","/**\n * Best-effort design-token extraction from the inline styles of a distilled\n * tree (PLAN §10). This is a starting palette for the skin author to rename and\n * curate — not an authoritative theme. We pull distinct colors (most-frequent\n * first), font families, border radii, and padding scales.\n */\n\ninterface Tokens {\n colors: Record<string, string>;\n fonts?: Record<string, string>;\n space?: Record<string, string>;\n radius?: Record<string, string>;\n}\n\nfunction parseStyle(style: string): Map<string, string> {\n const m = new Map<string, string>();\n for (const decl of style.split(\";\")) {\n const idx = decl.indexOf(\":\");\n if (idx === -1) continue;\n const prop = decl.slice(0, idx).trim().toLowerCase();\n const val = decl.slice(idx + 1).trim();\n if (prop && val) m.set(prop, val);\n }\n return m;\n}\n\nconst COLOR_RE = /(#[0-9a-f]{3,8}\\b|rgba?\\([^)]*\\)|hsla?\\([^)]*\\))/gi;\n\nexport function extractTokens(root: Element): Tokens {\n const colorFreq = new Map<string, number>();\n const fonts = new Set<string>();\n const radii = new Set<string>();\n const spaces = new Set<string>();\n\n const bump = (raw: string) => {\n const v = raw.trim();\n if (!v || v === \"transparent\" || v === \"inherit\" || v === \"currentcolor\")\n return;\n colorFreq.set(v, (colorFreq.get(v) ?? 0) + 1);\n };\n\n for (const el of [root, ...root.querySelectorAll(\"*\")]) {\n const style = el.getAttribute(\"style\");\n if (!style) continue;\n const decls = parseStyle(style);\n for (const [prop, val] of decls) {\n if (prop === \"color\" || prop.startsWith(\"background\")) {\n const matches = val.match(COLOR_RE);\n if (matches) for (const c of matches) bump(c);\n }\n if (prop === \"font-family\") fonts.add(val);\n if (prop === \"border-radius\") radii.add(val);\n if (prop === \"padding\" || prop === \"gap\") spaces.add(val);\n }\n }\n\n const colors: Record<string, string> = {};\n [...colorFreq.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 12)\n .forEach(([c], i) => {\n colors[`color-${i + 1}`] = c;\n });\n\n const out: Tokens = { colors };\n if (fonts.size) {\n out.fonts = {};\n [...fonts].slice(0, 4).forEach((f, i) => {\n out.fonts![`font-${i + 1}`] = f;\n });\n }\n if (radii.size) {\n out.radius = {};\n [...radii].slice(0, 6).forEach((r, i) => {\n out.radius![`radius-${i + 1}`] = r;\n });\n }\n if (spaces.size) {\n out.space = {};\n [...spaces].slice(0, 8).forEach((s, i) => {\n out.space![`space-${i + 1}`] = s;\n });\n }\n return out;\n}\n","import { sanitizeHtml } from \"./sanitize.js\";\nimport { extractTokens } from \"./tokens.js\";\nimport type { SkinDraft, SlotReport } from \"./draft.js\";\n\n/**\n * The distiller (PLAN §10): given a chat-UI subtree, produce a sanitized,\n * slotted `SkinDraft`. The pipeline is\n *\n * clone → inline computed styles (live capture) → drop hidden/`data-*` →\n * sanitize (allowlist) → find the repeating message row → slot-ify\n * (author/avatar/body/time) → carve the frame chrome → find the composer →\n * extract tokens → report.\n *\n * Capture gets you ~80% of the way; the emitted `detection` report and\n * `warnings` tell the author exactly what to confirm by hand (the §10 quality\n * bar treats anything below the bar as \"draft only\", never a finished skin).\n * The function is DOM-agnostic — the extension passes a live element, the\n * saved-page importer passes a jsdom element.\n */\n\ninterface WindowLike {\n document: Document;\n getComputedStyle?: (el: Element) => CSSStyleDeclaration;\n}\n\nexport interface DistillOptions {\n /** DOM window (defaults to global `window`). Required in Node. */\n window?: WindowLike;\n /** Display name for the draft. */\n name?: string;\n sourceUrl?: string;\n theme?: \"light\" | \"dark\";\n /**\n * Inline computed styles from the live page so fidelity survives losing the\n * cascade. Off for saved-page import (the source CSS comes inline already).\n */\n inlineComputedStyles?: boolean;\n}\n\n/** The slot-marker attribute the `TemplateSkinAdapter` keys off. */\nexport const SLOT_ATTR = \"data-tc-slot\";\n\n/** Computed properties worth inlining — look, not frozen layout geometry. */\nconst INLINE_PROPS = [\n \"color\",\n \"background-color\",\n \"background\",\n \"font-family\",\n \"font-size\",\n \"font-weight\",\n \"font-style\",\n \"line-height\",\n \"letter-spacing\",\n \"text-align\",\n \"text-transform\",\n \"border\",\n \"border-radius\",\n \"padding\",\n \"margin\",\n \"gap\",\n \"display\",\n \"flex-direction\",\n \"align-items\",\n \"justify-content\",\n \"box-shadow\",\n \"opacity\",\n];\n\nconst HIDDEN_CLASS_RE = /\\b(sr-only|visually-hidden|hidden)\\b/;\n\nfunction getWindow(win?: WindowLike): WindowLike {\n if (win) return win;\n if (typeof window !== \"undefined\") return window as unknown as WindowLike;\n throw new Error(\"distill requires a DOM window — pass { window } in Node.\");\n}\n\nfunction isHidden(el: Element, win: WindowLike): boolean {\n if (el.getAttribute(\"aria-hidden\") === \"true\") return true;\n if (el.hasAttribute(\"hidden\")) return true;\n const cls = el.getAttribute(\"class\") ?? \"\";\n if (HIDDEN_CLASS_RE.test(cls)) return true;\n const inline = (el.getAttribute(\"style\") ?? \"\").toLowerCase();\n if (/display\\s*:\\s*none/.test(inline)) return true;\n if (/visibility\\s*:\\s*hidden/.test(inline)) return true;\n const cs = win.getComputedStyle?.(el);\n if (cs) {\n if (cs.display === \"none\") return true;\n if (cs.visibility === \"hidden\") return true;\n }\n return false;\n}\n\nfunction inlineStyles(orig: Element, clone: Element, win: WindowLike): void {\n const cs = win.getComputedStyle?.(orig);\n if (!cs) return;\n const decls: string[] = [];\n for (const prop of INLINE_PROPS) {\n const v = cs.getPropertyValue(prop);\n if (v && v !== \"none\" && v !== \"normal\" && v.trim() !== \"\")\n decls.push(`${prop}: ${v}`);\n }\n if (decls.length) clone.setAttribute(\"style\", decls.join(\"; \"));\n}\n\n/** Recursively inline styles + drop hidden nodes, walking orig/clone in step. */\nfunction pruneAndInline(\n orig: Element,\n clone: Element,\n win: WindowLike,\n inline: boolean,\n dropped: { count: number },\n): void {\n if (inline) inlineStyles(orig, clone, win);\n // Strip data-* (defense-in-depth; sanitize also does this later).\n for (const attr of [...clone.attributes]) {\n if (attr.name.startsWith(\"data-\")) clone.removeAttribute(attr.name);\n }\n const origKids = [...orig.children];\n const cloneKids = [...clone.children];\n const remove: Element[] = [];\n for (let i = 0; i < origKids.length; i++) {\n const o = origKids[i];\n const c = cloneKids[i];\n if (!o || !c) continue;\n if (isHidden(o, win)) {\n remove.push(c);\n dropped.count++;\n continue;\n }\n pruneAndInline(o, c, win, inline, dropped);\n }\n for (const c of remove) c.remove();\n}\n\n/** A structural signature for grouping repeated rows. */\nfunction signature(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const classes = (el.getAttribute(\"class\") ?? \"\")\n .split(/\\s+/)\n .filter(Boolean)\n .sort()\n .join(\".\");\n const kidTags = [...el.children]\n .map((c) => c.tagName.toLowerCase())\n .join(\",\");\n return `${tag}|${classes}|${kidTags}`;\n}\n\ninterface RepeatPick {\n container: Element;\n rows: Element[];\n}\n\n/** Find the container whose children are the most-repeated similar rows. */\nfunction findRepeatingRows(root: Element): RepeatPick | null {\n let best: RepeatPick | null = null;\n let bestScore = 0;\n const visit = (el: Element) => {\n const groups = new Map<string, Element[]>();\n for (const child of el.children) {\n const sig = signature(child);\n const arr = groups.get(sig) ?? [];\n arr.push(child);\n groups.set(sig, arr);\n }\n for (const rows of groups.values()) {\n if (rows.length < 2) continue;\n // Score: repetition count weighted by how much text the rows carry, so\n // a list of message bubbles beats e.g. a repeated row of icon buttons.\n const textLen = rows.reduce(\n (n, r) => n + (r.textContent ?? \"\").trim().length,\n 0,\n );\n const score = rows.length * 10 + Math.min(textLen, 400);\n if (score > bestScore) {\n bestScore = score;\n best = { container: el, rows };\n }\n }\n for (const child of el.children) visit(child);\n };\n visit(root);\n return best;\n}\n\nconst AUTHOR_RE =\n /\\b(name|author|sender|user|handle|username|display-?name)\\b/i;\nconst AVATAR_RE = /\\b(avatar|photo|userpic|profile-?pic|pic|gravatar)\\b/i;\nconst TIME_RE = /\\b(time|timestamp|date|ago|sent-?at)\\b/i;\nconst BODY_RE = /\\b(body|text|content|message|bubble|markdown|prose)\\b/i;\nconst TIME_TEXT_RE =\n /^\\s*(\\d{1,2}:\\d{2}(\\s?[ap]\\.?m\\.?)?|\\d+\\s*(m|min|h|hr|d|days?|hours?|minutes?)( ago)?|yesterday|today)\\s*$/i;\n\nfunction classOf(el: Element): string {\n return el.getAttribute(\"class\") ?? \"\";\n}\n\nfunction markSlot(el: Element, slot: string, token: string): void {\n el.setAttribute(SLOT_ATTR, slot);\n el.textContent = token;\n}\n\n/** Identify and mark author/avatar/body/time inside a representative row. */\nfunction slotifyRow(row: Element): {\n html: string;\n detected: string[];\n} {\n const detected: string[] = [];\n const all = [...row.querySelectorAll(\"*\")];\n\n // Avatar: an <img> or an element whose class names it.\n let avatar =\n row.querySelector(\"img\") ??\n all.find((e) => AVATAR_RE.test(classOf(e))) ??\n null;\n if (avatar) {\n // Convert an <img> avatar into a styled container we can fill.\n if (avatar.tagName === \"IMG\") {\n const div = row.ownerDocument.createElement(\"div\");\n const cls = classOf(avatar);\n if (cls) div.setAttribute(\"class\", cls);\n const st = avatar.getAttribute(\"style\");\n if (st) div.setAttribute(\"style\", st);\n avatar.replaceWith(div);\n avatar = div;\n }\n markSlot(avatar, \"avatar\", \"{{avatar}}\");\n detected.push(\"avatar\");\n }\n\n // Author: a named element, else the first short bold-ish text run.\n let author = all.find(\n (e) =>\n e !== avatar &&\n AUTHOR_RE.test(classOf(e)) &&\n (e.textContent ?? \"\").trim(),\n );\n if (!author) {\n author = all.find((e) => {\n if (e === avatar || e.getAttribute(SLOT_ATTR)) return false;\n const t = (e.textContent ?? \"\").trim();\n const fw = (e.getAttribute(\"style\") ?? \"\").match(\n /font-weight:\\s*(\\d+|bold)/i,\n );\n const bold =\n e.tagName === \"B\" ||\n e.tagName === \"STRONG\" ||\n (fw ? fw[1] === \"bold\" || Number(fw[1]) >= 600 : false);\n return bold && t.length > 0 && t.length < 40;\n });\n }\n if (author && !author.getAttribute(SLOT_ATTR)) {\n markSlot(author, \"author\", \"{{author}}\");\n detected.push(\"author\");\n }\n\n // Time: a <time>, a named element, or an element whose text reads as a time.\n const time =\n row.querySelector(\"time\") ??\n all.find((e) => !e.getAttribute(SLOT_ATTR) && TIME_RE.test(classOf(e))) ??\n all.find(\n (e) =>\n !e.getAttribute(SLOT_ATTR) &&\n e.children.length === 0 &&\n TIME_TEXT_RE.test((e.textContent ?? \"\").trim()),\n );\n if (time && !time.getAttribute(SLOT_ATTR)) {\n markSlot(time, \"time\", \"{{time}}\");\n detected.push(\"time\");\n }\n\n // Body: the remaining element with the most text (or a named one). Never an\n // ancestor of an already-marked slot, or filling it would wipe author/time.\n const named = all.find(\n (e) =>\n !e.getAttribute(SLOT_ATTR) &&\n !e.querySelector(`[${SLOT_ATTR}]`) &&\n BODY_RE.test(classOf(e)),\n );\n let body = named ?? null;\n if (!body) {\n let bestLen = -1;\n for (const e of all) {\n if (e.getAttribute(SLOT_ATTR)) continue;\n if (e.querySelector(`[${SLOT_ATTR}]`)) continue; // don't pick an ancestor of a slot\n const t = (e.textContent ?? \"\").trim();\n if (t.length > bestLen) {\n bestLen = t.length;\n body = e;\n }\n }\n }\n if (body && !body.getAttribute(SLOT_ATTR)) {\n markSlot(body, \"body\", \"{{body}}\");\n detected.push(\"body\");\n } else if (!body) {\n // Fall back: slot the row itself.\n markSlot(row, \"body\", \"{{body}}\");\n detected.push(\"body\");\n }\n\n return { html: row.outerHTML, detected };\n}\n\nconst COMPOSER_RE =\n /\\b(composer|compose|reply|message-?box|message-?input|input-?box|textbox|editor|prompt)\\b/i;\n\nfunction findComposer(root: Element, exclude: Element): Element | null {\n const candidates = [...root.querySelectorAll(\"*\")].filter(\n (e) => !exclude.contains(e) && !e.contains(exclude),\n );\n return (\n candidates.find((e) => e.getAttribute(\"role\") === \"textbox\") ??\n candidates.find((e) => e.hasAttribute(\"contenteditable\")) ??\n candidates.find((e) => COMPOSER_RE.test(classOf(e))) ??\n null\n );\n}\n\nfunction emptyReport(): SlotReport {\n return { found: false, detected: [], confidence: 0 };\n}\n\nexport function distill(root: Element, opts: DistillOptions = {}): SkinDraft {\n const win = getWindow(opts.window);\n const doc = win.document;\n const warnings: string[] = [];\n\n // 1. Clone, inline styles, drop hidden + data-*.\n const clone = root.cloneNode(true) as Element;\n const dropped = { count: 0 };\n pruneAndInline(root, clone, win, opts.inlineComputedStyles ?? false, dropped);\n if (dropped.count > 0)\n warnings.push(\n `Dropped ${dropped.count} hidden element(s) from the capture.`,\n );\n\n // 2. Sanitize (allowlist) and re-parse.\n const safe = sanitizeHtml(clone.outerHTML, { window: win });\n const host = doc.createElement(\"div\");\n host.innerHTML = safe;\n const frameRoot = (host.firstElementChild as Element | null) ?? host;\n\n // 3. Find the repeating message row.\n const pick = findRepeatingRows(frameRoot);\n const detection = {\n frame: emptyReport(),\n message: emptyReport(),\n composer: emptyReport(),\n typing: emptyReport(),\n };\n\n let messageHtml: string | undefined;\n let frameHtml: string | undefined;\n let composerHtml: string | undefined;\n\n if (pick) {\n // 4. Slot-ify a representative row.\n const sample = (pick.rows[0] as Element).cloneNode(true) as Element;\n const slotted = slotifyRow(sample);\n messageHtml = slotted.html;\n detection.message = {\n found: true,\n detected: slotted.detected,\n confidence: Math.min(1, slotted.detected.length / 4),\n };\n\n // 5. Carve the frame: replace the message list with a {{messages}} slot.\n const slot = doc.createElement(\"div\");\n slot.setAttribute(SLOT_ATTR, \"messages\");\n slot.textContent = \"{{messages}}\";\n const listCls = classOf(pick.container);\n if (listCls) slot.setAttribute(\"class\", `${listCls} tc-messages`);\n const containerClone = pick.container.cloneNode(false) as Element;\n // Preserve the list container's own styling, but it now holds only the slot.\n if (containerClone.getAttribute(\"style\"))\n slot.setAttribute(\n \"style\",\n containerClone.getAttribute(\"style\") as string,\n );\n // Build the frame by replacing the container subtree with the slot.\n const frameClone = frameRoot.cloneNode(true) as Element;\n const path = pathTo(frameRoot, pick.container);\n const targetInClone = path ? nodeAtPath(frameClone, path) : null;\n if (targetInClone && targetInClone.parentElement) {\n targetInClone.replaceWith(slot);\n frameHtml = frameClone.outerHTML;\n detection.frame = { found: true, detected: [\"messages\"], confidence: 1 };\n } else {\n // The list *is* the root; frame is just the slot.\n frameHtml = slot.outerHTML;\n detection.frame = {\n found: true,\n detected: [\"messages\"],\n confidence: 0.5,\n };\n warnings.push(\n \"Message list is the captured root; no surrounding chrome was found.\",\n );\n }\n\n // 6. Composer (outside the message list).\n const composer = findComposer(frameRoot, pick.container);\n if (composer) {\n const c = composer.cloneNode(true) as Element;\n c.setAttribute(SLOT_ATTR, \"composer\");\n c.removeAttribute(\"contenteditable\");\n c.textContent = \"{{composer}}\";\n composerHtml = c.outerHTML;\n detection.composer = {\n found: true,\n detected: [\"composer\"],\n confidence: 1,\n };\n } else {\n warnings.push(\n \"No composer detected — add one by hand if the skin needs it.\",\n );\n }\n } else {\n warnings.push(\n \"No repeating message row found — capture a tighter subtree around the thread.\",\n );\n }\n\n // 7. Tokens.\n const tokens = extractTokens(frameRoot);\n\n // 8. Canvas suggestion from the captured box (best effort).\n let canvas: { width: number; height: number } | undefined;\n const rect = (\n root as Element & { getBoundingClientRect?: () => DOMRect }\n ).getBoundingClientRect?.();\n if (rect && rect.width > 0 && rect.height > 0) {\n canvas = { width: Math.round(rect.width), height: Math.round(rect.height) };\n }\n\n return {\n version: 1,\n meta: {\n name: opts.name ?? \"Captured skin\",\n ...(opts.sourceUrl ? { sourceUrl: opts.sourceUrl } : {}),\n ...(opts.theme ? { theme: opts.theme } : {}),\n ...(canvas ? { canvas } : {}),\n },\n slots: {\n ...(frameHtml ? { frame: frameHtml } : {}),\n ...(messageHtml ? { message: messageHtml } : {}),\n ...(composerHtml ? { composer: composerHtml } : {}),\n },\n css: \"\",\n tokens,\n detection,\n warnings,\n };\n}\n\n/** Index path from `root` down to `target` (list of child indices). */\nfunction pathTo(root: Element, target: Element): number[] | null {\n if (root === target) return [];\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i];\n if (!child) continue;\n const sub = pathTo(child, target);\n if (sub) return [i, ...sub];\n }\n return null;\n}\n\nfunction nodeAtPath(root: Element, path: number[]): Element | null {\n let node: Element | null = root;\n for (const i of path) {\n if (!node) return null;\n node = node.children[i] ?? null;\n }\n return node;\n}\n","import {\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type FC,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { ContentNode } from \"@typecaast/schema\";\nimport type { Participant } from \"@typecaast/schema\";\nimport type {\n Capabilities,\n ComposerProps,\n FrameProps,\n MessageProps,\n SystemProps,\n TypingProps,\n} from \"@typecaast/core\";\nimport type { Skin, SkinComponents, SkinTokens } from \"@typecaast/skin-kit\";\nimport { sanitizeHtml } from \"./sanitize.js\";\nimport { SLOT_ATTR } from \"./distill.js\";\nimport type { SkinDraft } from \"./draft.js\";\n\n/**\n * `TemplateSkinAdapter` — make a captured `SkinDraft` satisfy the `Skin`\n * contract by filling its slots at render time (PLAN §10). Template skins are\n * **untrusted regardless of source**, so the adapter (a) re-sanitizes every\n * template string and (b) renders inside an **open shadow root** at the Frame,\n * so even a sanitizer miss can't restyle or script the host page. Slot text is\n * written via `textContent` (never `innerHTML`), so authored content can't\n * inject markup either.\n *\n * This is a faithful *playback* of the capture, not the final hand-tuned skin —\n * `typecaast scaffold-skin` turns the same draft into an editable React skin.\n */\n\nexport interface TemplateSkinOptions {\n /** Override the skin id (defaults to a slug of the draft name). */\n id?: string;\n capabilities?: Capabilities;\n}\n\nfunction slug(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"captured\"\n );\n}\n\n/** Flatten a message body to plain text (the draft adapter renders text only). */\nfunction contentToText(content: ContentNode[]): string {\n const out: string[] = [];\n for (const node of content) {\n if (\n node.type === \"text\" &&\n Array.isArray((node as { spans?: unknown }).spans)\n ) {\n for (const span of (\n node as { spans: { value?: string; label?: string }[] }\n ).spans) {\n out.push(span.value ?? span.label ?? \"\");\n }\n } else if (node.type === \"image\") {\n out.push((node as { alt?: string }).alt ?? \"🖼\");\n }\n }\n return out.join(\"\");\n}\n\nfunction initials(name: string): string {\n return name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((w) => w[0]?.toUpperCase() ?? \"\")\n .join(\"\");\n}\n\nfunction fmtTime(atMs: number): string {\n const total = Math.floor(atMs / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${String(s).padStart(2, \"0\")}`;\n}\n\n/** Build the `<style>` text for the shadow root from draft tokens + extra CSS. */\nfunction styleText(tokens: SkinTokens, css: string): string {\n const vars = Object.entries(tokens.colors ?? {})\n .map(([k, v]) => `--${k}: ${v};`)\n .join(\" \");\n return `:host{all:initial; display:block; width:100%; height:100%; ${vars}}\n *{box-sizing:border-box;}\n ${css}`;\n}\n\n/** Fill a sanitized template's slots into `host` via safe textContent writes. */\nfunction fillInto(\n host: HTMLElement,\n templateHtml: string,\n values: Record<string, string>,\n): void {\n host.innerHTML = templateHtml; // templateHtml is pre-sanitized at skin build\n for (const node of host.querySelectorAll(`[${SLOT_ATTR}]`)) {\n const slot = node.getAttribute(SLOT_ATTR);\n if (slot && slot in values) node.textContent = values[slot] ?? \"\";\n }\n}\n\n/** progress-driven fade+slide (no CSS transitions — frame-parity, PLAN §8). */\nfunction revealStyle(progress: number): CSSProperties {\n const p = Math.max(0, Math.min(1, progress));\n return {\n opacity: p,\n transform: `translateY(${(1 - p) * 6}px)`,\n willChange: \"opacity, transform\",\n };\n}\n\nconst DEFAULT_CAPS: Capabilities = {\n events: {},\n content: {},\n reactions: false,\n threads: false,\n readReceipts: false,\n};\n\nexport function templateSkinFromDraft(\n draft: SkinDraft,\n opts: TemplateSkinOptions = {},\n): Skin {\n // Re-sanitize every template once, up front (untrusted regardless of source).\n const safe = {\n frame: draft.slots.frame ? sanitizeHtml(draft.slots.frame) : undefined,\n message: draft.slots.message\n ? sanitizeHtml(draft.slots.message)\n : undefined,\n composer: draft.slots.composer\n ? sanitizeHtml(draft.slots.composer)\n : undefined,\n };\n const lightTokens: SkinTokens = { colors: draft.tokens.colors ?? {} };\n const darkTokens: SkinTokens = draft.darkTokens\n ? { colors: draft.darkTokens.colors ?? {} }\n : lightTokens;\n const cssByTheme = {\n light: styleText(lightTokens, draft.css ?? \"\"),\n dark: styleText(darkTokens, draft.css ?? \"\"),\n };\n const supportsThemes: (\"light\" | \"dark\")[] = draft.darkTokens\n ? [\"light\", \"dark\"]\n : [draft.meta.theme ?? \"light\"];\n\n const Frame: FC<FrameProps & { children?: ReactNode }> = ({\n theme,\n children,\n }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n const [mount, setMount] = useState<HTMLElement | null>(null);\n useLayoutEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadow = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n shadow.innerHTML = \"\";\n const style = host.ownerDocument.createElement(\"style\");\n style.textContent = theme === \"dark\" ? cssByTheme.dark : cssByTheme.light;\n shadow.appendChild(style);\n const wrapper = host.ownerDocument.createElement(\"div\");\n wrapper.style.width = \"100%\";\n wrapper.style.height = \"100%\";\n wrapper.innerHTML = safe.frame ?? `<div ${SLOT_ATTR}=\"messages\"></div>`;\n shadow.appendChild(wrapper);\n const slot =\n wrapper.querySelector<HTMLElement>(`[${SLOT_ATTR}=\"messages\"]`) ??\n wrapper;\n slot.textContent = \"\";\n setMount(slot);\n }, [theme]);\n return (\n <div ref={hostRef} style={{ width: \"100%\", height: \"100%\" }}>\n {mount ? createPortal(children, mount) : null}\n </div>\n );\n };\n\n const Message: FC<MessageProps> = ({ message, author }) => {\n const ref = useRef<HTMLDivElement>(null);\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !safe.message) return;\n fillInto(el, safe.message, {\n author: author.name,\n avatar: initials(author.name),\n body: contentToText(message.content),\n time: fmtTime(message.atMs),\n });\n }, [message, author]);\n return <div ref={ref} style={revealStyle(message.revealProgress)} />;\n };\n\n const SystemMessage: FC<SystemProps> = ({ message }) => (\n <div\n style={{ ...revealStyle(message.revealProgress), textAlign: \"center\" }}\n >\n {contentToText(message.content)}\n </div>\n );\n\n const TypingIndicator: FC<TypingProps> = ({ author }) => (\n <div style={{ opacity: 0.7, fontStyle: \"italic\" }}>\n {author.name} is typing…\n </div>\n );\n\n const Composer: FC<ComposerProps> = ({ composer }) => {\n const ref = useRef<HTMLDivElement>(null);\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (safe.composer) {\n fillInto(el, safe.composer, { composer: composer.text });\n } else {\n el.textContent = composer.text;\n }\n }, [composer]);\n return <div ref={ref} />;\n };\n\n const Avatar: FC<{ participant: Participant; size?: number }> = ({\n participant,\n size = 36,\n }) => (\n <div\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n display: \"grid\",\n placeItems: \"center\",\n background: \"var(--color-1, #ccc)\",\n fontSize: size * 0.4,\n }}\n >\n {initials(participant.name)}\n </div>\n );\n\n const components: SkinComponents = {\n Frame,\n Message,\n SystemMessage,\n TypingIndicator,\n Reaction: () => null,\n Composer,\n Avatar,\n };\n\n return {\n id: opts.id ?? slug(draft.meta.name),\n meta: {\n name: draft.meta.name,\n defaultCanvas: draft.meta.canvas ?? { width: 420, height: 720 },\n supportsThemes,\n capabilities: opts.capabilities ?? DEFAULT_CAPS,\n },\n components,\n tokens: { light: lightTokens, dark: darkTokens },\n };\n}\n","import type { SkinDraft } from \"./draft.js\";\n\n/**\n * Light/dark double-capture (PLAN §10, M5.7). Capture the *same* UI twice — once\n * per theme — then merge: keep the light capture's slot templates (structure is\n * identical) and attach the dark capture's tokens as `darkTokens`, so the\n * resulting skin supports both themes and switches CSS vars at render time.\n *\n * Structure is taken from `light`; only the dark *colors* differ between a\n * well-built light/dark UI, which is exactly what we want to vary.\n */\nexport function mergeThemeDrafts(light: SkinDraft, dark: SkinDraft): SkinDraft {\n return {\n ...light,\n meta: { ...light.meta, theme: undefined },\n tokens: light.tokens,\n darkTokens: dark.tokens,\n warnings: [\n ...light.warnings,\n ...(dark.detection.message.found\n ? []\n : [\"Dark capture found no message row; reusing light structure.\"]),\n ],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/sanitize.ts","../src/draft.ts","../src/tokens.ts","../src/distill.ts","../src/css-capture.ts","../src/template-skin.tsx","../src/merge.ts"],"names":["createDOMPurify","z","getWindow","slotSkinFromDraft"],"mappings":";;;;;;;;;;;AAiBA,IAAM,YAAA,GAAe;AAAA,EACnB,KAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA;AAOA,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,iBAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA;AAQO,SAAS,SAAS,GAAA,EAAqB;AAC5C,EAAA,IAAI,GAAA,GAAM,GAAA;AAEV,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,mBAAA,EAAqB,cAAc,CAAA;AACrD,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,oBAAA,EAAsB,cAAc,CAAA;AACtD,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,gBAAA,EAAkB,cAAc,CAAA;AAClD,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,kBAAA,EAAoB,oBAAoB,CAAA;AAE1D,EAAA,GAAA,GAAM,IAAI,OAAA,CAAQ,mCAAA,EAAqC,CAAC,KAAA,EAAO,IAAI,GAAA,KAAQ;AACzE,IAAA,MAAM,IAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AACzC,IAAA,MAAM,UACJ,CAAA,CAAE,UAAA,CAAW,aAAa,CAAA,IAC1B,EAAE,UAAA,CAAW,WAAW,CAAA,IACvB,CAAA,CAAE,WAAW,OAAO,CAAA,IAAK,CAAC,CAAA,CAAE,WAAW,aAAa,CAAA;AACvD,IAAA,OAAO,UAAU,MAAA,GAAS,KAAA;AAAA,EAC5B,CAAC,CAAA;AAED,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,eAAA,EAAiB,UAAU,CAAA;AAC7C,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,aAAA,EAAe,UAAU,CAAA;AAC3C,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,UAAU,GAAA,EAA8B;AAC/C,EAAA,IAAI,KAAK,OAAO,GAAA;AAChB,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,MAAA;AAC1C,EAAA,MAAM,IAAI,KAAA;AAAA,IACR;AAAA,GACF;AACF;AAEA,IAAI,MAAA,GAAkB,IAAA;AAItB,SAAS,YAAY,GAAA,EAAqD;AACxE,EAAA,MAAM,MAAA,GAASA,iCAAgB,GAA8B,CAAA;AAE7D,EAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,IAAA,MAAA,CAAO,OAAA,CAAQ,yBAAA,EAA2B,CAAC,IAAA,KAAS;AAClD,MAAA,MAAM,EAAA,GAAK,IAAA;AAEX,MAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,YAAA,GAAe,OAAO,CAAA;AACvC,MAAA,IAAI,OAAO,EAAA,CAAG,YAAA,CAAa,OAAA,EAAS,QAAA,CAAS,KAAK,CAAC,CAAA;AAEnD,MAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,GAAe,KAAK,CAAA;AACnC,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,MAAM,CAAA,GAAI,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY;AACjC,QAAA,IAAI,CAAA,CAAE,WAAW,OAAO,CAAA,IAAK,CAAC,CAAA,CAAE,UAAA,CAAW,aAAa,CAAA,EAAG;AACzD,UAAA,EAAA,CAAG,gBAAgB,KAAK,CAAA;AAAA,QAC1B;AAAA,MACF;AAEA,MAAA,IAAI,EAAA,CAAG,YAAY,GAAA,EAAK;AACtB,QAAA,EAAA,CAAG,gBAAgB,MAAM,CAAA;AACzB,QAAA,EAAA,CAAG,YAAA,CAAa,QAAQ,MAAM,CAAA;AAAA,MAChC;AAEA,MAAA,IAAI,GAAG,YAAA,GAAe,QAAQ,CAAA,EAAG,EAAA,CAAG,gBAAgB,QAAQ,CAAA;AAAA,IAC9D,CAAC,CAAA;AACD,IAAA,MAAA,GAAS,MAAA;AAAA,EACX;AACA,EAAA,OAAO,MAAA;AACT;AAYO,SAAS,YAAA,CAAa,IAAA,EAAc,IAAA,GAAwB,EAAC,EAAW;AAC7E,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA;AACjC,EAAA,MAAM,MAAA,GAAS,YAAY,GAAG,CAAA;AAC9B,EAAA,OAAO,MAAA,CAAO,SAAS,IAAA,EAAM;AAAA,IAC3B,YAAA;AAAA,IACA,YAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,QAAA,EAAU,CAAC,cAAA,EAAgB,iBAAiB,CAAA;AAAA,IAC5C,eAAA,EAAiB,KAAA;AAAA,IACjB,eAAA,EAAiB,IAAA;AAAA,IACjB,WAAA,EAAa;AAAA,MACX,QAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,WAAA,EAAa,CAAC,QAAA,EAAU,YAAA,EAAc,YAAY;AAAA,GACnD,CAAA;AACH;AClNO,IAAM,WAAA,GAAc;AAAA,EACzB,QAAA,EAAU,cAAA;AAAA,EACV,MAAA,EAAQ,YAAA;AAAA,EACR,MAAA,EAAQ,YAAA;AAAA,EACR,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,UAAA;AAAA,EACN,QAAA,EAAU;AACZ;AAKO,IAAM,gBAAA,GAAmBC,MAAE,MAAA,CAAO;AAAA;AAAA,EAEvC,KAAA,EAAOA,MAAE,OAAA,EAAQ;AAAA;AAAA,EAEjB,QAAA,EAAUA,KAAA,CAAE,KAAA,CAAMA,KAAA,CAAE,QAAQ,CAAA;AAAA;AAAA,EAE5B,UAAA,EAAYA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,CAAC;AACrC,CAAC,CAAA;AAGD,IAAM,cAAA,GAAiBA,MAAE,MAAA,CAAO;AAAA,EAC9B,MAAA,EAAQA,MAAE,MAAA,CAAOA,KAAA,CAAE,QAAO,EAAGA,KAAA,CAAE,QAAQ,CAAA;AAAA,EACvC,KAAA,EAAOA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,IAAUA,KAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,EAAS;AAAA,EACjD,KAAA,EAAOA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,IAAUA,KAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,EAAS;AAAA,EACjD,MAAA,EAAQA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,IAAUA,KAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA;AAC3C,CAAC,CAAA;AAEM,IAAM,eAAA,GAAkBA,MAAE,MAAA,CAAO;AAAA,EACtC,OAAA,EAASA,KAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAAA,EACpB,IAAA,EAAMA,MAAE,MAAA,CAAO;AAAA;AAAA,IAEb,IAAA,EAAMA,MAAE,MAAA,EAAO;AAAA;AAAA,IAEf,SAAA,EAAWA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,IAE/B,KAAA,EAAOA,MAAE,IAAA,CAAK,CAAC,SAAS,MAAM,CAAC,EAAE,QAAA,EAAS;AAAA;AAAA,IAE1C,QAAQA,KAAA,CACL,MAAA,CAAO,EAAE,KAAA,EAAOA,KAAA,CAAE,QAAO,CAAE,GAAA,EAAI,EAAG,MAAA,EAAQA,MAAE,MAAA,EAAO,CAAE,KAAI,EAAG,EAC5D,QAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOZ,UAAA,EAAYA,MACT,MAAA,CAAO;AAAA,MACN,eAAeA,KAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,QAAA,EAAS;AAAA,MACzC,gBAAgBA,KAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,QAAA,EAAS;AAAA,MAC1C,UAAA,EAAYA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,KACjC,EACA,QAAA;AAAS,GACb,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKD,KAAA,EAAOA,MAAE,MAAA,CAAO;AAAA,IACd,KAAA,EAAOA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC3B,OAAA,EAASA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC7B,QAAA,EAAUA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC9B,MAAA,EAAQA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,GAC7B,CAAA;AAAA;AAAA,EAED,GAAA,EAAKA,MAAE,MAAA,EAAO;AAAA;AAAA,EAEd,MAAA,EAAQ,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKR,UAAA,EAAY,eAAe,QAAA,EAAS;AAAA;AAAA,EAEpC,SAAA,EAAWA,MAAE,MAAA,CAAO;AAAA,IAClB,KAAA,EAAO,gBAAA;AAAA,IACP,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU,gBAAA;AAAA,IACV,MAAA,EAAQ;AAAA,GACT,CAAA;AAAA;AAAA,EAED,QAAA,EAAUA,KAAA,CAAE,KAAA,CAAMA,KAAA,CAAE,QAAQ,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM5B,YAAYA,KAAA,CAAE,KAAA,CAAMA,MAAE,MAAA,EAAQ,EAAE,QAAA;AAClC,CAAC;AAKM,SAAS,eAAe,KAAA,EAA0B;AAEvD,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,QAAA,CAAS,SAAS,MAAM,CAAA;AAAA,IAChD,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,QAAA,CAAS,SAAS,QAAQ,CAAA;AAAA,IAClD,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,QAAA,CAAS,SAAS,QAAQ,CAAA;AAAA,IAClD,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,QAAA,CAAS,SAAS,MAAM,CAAA;AAAA,IAChD,KAAA,CAAM,UAAU,QAAA,CAAS;AAAA,GAC3B;AACA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA,CAAE,SAAS,MAAA,CAAO,MAAA;AAChD;;;AC5GA,SAAS,WAAW,KAAA,EAAoC;AACtD,EAAA,MAAM,CAAA,uBAAQ,GAAA,EAAoB;AAClC,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,EAAG;AACnC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC5B,IAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AACnD,IAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAC,EAAE,IAAA,EAAK;AACrC,IAAA,IAAI,IAAA,IAAQ,GAAA,EAAK,CAAA,CAAE,GAAA,CAAI,MAAM,GAAG,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,CAAA;AACT;AAEA,IAAM,QAAA,GAAW,oDAAA;AAEV,SAAS,cAAc,IAAA,EAAuB;AACnD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAE/B,EAAA,MAAM,IAAA,GAAO,CAAC,GAAA,KAAgB;AAC5B,IAAA,MAAM,CAAA,GAAI,IAAI,IAAA,EAAK;AACnB,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,KAAM,aAAA,IAAiB,CAAA,KAAM,aAAa,CAAA,KAAM,cAAA;AACxD,MAAA;AACF,IAAA,SAAA,CAAU,IAAI,CAAA,EAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,EAC9C,CAAA;AAEA,EAAA,KAAA,MAAW,EAAA,IAAM,CAAC,IAAA,EAAM,GAAG,KAAK,gBAAA,CAAiB,GAAG,CAAC,CAAA,EAAG;AACtD,IAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA;AACrC,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,KAAA,GAAQ,WAAW,KAAK,CAAA;AAC9B,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,KAAA,EAAO;AAC/B,MAAA,IAAI,IAAA,KAAS,OAAA,IAAW,IAAA,CAAK,UAAA,CAAW,YAAY,CAAA,EAAG;AACrD,QAAA,MAAM,OAAA,GAAU,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA;AAClC,QAAA,IAAI,OAAA,EAAS,KAAA,MAAW,CAAA,IAAK,OAAA,OAAc,CAAC,CAAA;AAAA,MAC9C;AACA,MAAA,IAAI,IAAA,KAAS,aAAA,EAAe,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AACzC,MAAA,IAAI,IAAA,KAAS,eAAA,EAAiB,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAC3C,MAAA,IAAI,SAAS,SAAA,IAAa,IAAA,KAAS,KAAA,EAAO,MAAA,CAAO,IAAI,GAAG,CAAA;AAAA,IAC1D;AAAA,EACF;AAEA,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,CAAC,GAAG,SAAA,CAAU,OAAA,EAAS,CAAA,CACpB,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,GAAI,EAAE,CAAC,CAAC,CAAA,CAC1B,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CACX,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,EAAG,CAAA,KAAM;AACnB,IAAA,MAAA,CAAO,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,CAAE,CAAA,GAAI,CAAA;AAAA,EAC7B,CAAC,CAAA;AAEH,EAAA,MAAM,GAAA,GAAc,EAAE,MAAA,EAAO;AAC7B,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,GAAA,CAAI,QAAQ,EAAC;AACb,IAAA,CAAC,GAAG,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvC,MAAA,GAAA,CAAI,KAAA,CAAO,CAAA,KAAA,EAAQ,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA;AAAA,IAChC,CAAC,CAAA;AAAA,EACH;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,GAAA,CAAI,SAAS,EAAC;AACd,IAAA,CAAC,GAAG,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvC,MAAA,GAAA,CAAI,MAAA,CAAQ,CAAA,OAAA,EAAU,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AACA,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,GAAA,CAAI,QAAQ,EAAC;AACb,IAAA,CAAC,GAAG,MAAM,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACxC,MAAA,GAAA,CAAI,KAAA,CAAO,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA;AAAA,IACjC,CAAC,CAAA;AAAA,EACH;AACA,EAAA,OAAO,GAAA;AACT;;;AC3BO,IAAM,SAAA,GAAY,cAAA;AAYzB,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA;AAAA,EACA,kBAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA;AAAA,EAEA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,eAAA,GAAkB,sCAAA;AAExB,SAASC,WAAU,GAAA,EAA8B;AAC/C,EAAA,IAAI,KAAK,OAAO,GAAA;AAChB,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,MAAA;AAC1C,EAAA,MAAM,IAAI,MAAM,+DAA0D,CAAA;AAC5E;AAEA,SAAS,QAAA,CAAS,IAAa,GAAA,EAA0B;AACvD,EAAA,IAAI,EAAA,CAAG,YAAA,CAAa,aAAa,CAAA,KAAM,QAAQ,OAAO,IAAA;AACtD,EAAA,IAAI,EAAA,CAAG,YAAA,CAAa,QAAQ,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA,IAAK,EAAA;AACxC,EAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,MAAM,UAAU,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA,IAAK,IAAI,WAAA,EAAY;AAC5D,EAAA,IAAI,oBAAA,CAAqB,IAAA,CAAK,MAAM,CAAA,EAAG,OAAO,IAAA;AAC9C,EAAA,IAAI,yBAAA,CAA0B,IAAA,CAAK,MAAM,CAAA,EAAG,OAAO,IAAA;AACnD,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,gBAAA,GAAmB,EAAE,CAAA;AACpC,EAAA,IAAI,EAAA,EAAI;AACN,IAAA,IAAI,EAAA,CAAG,OAAA,KAAY,MAAA,EAAQ,OAAO,IAAA;AAClC,IAAA,IAAI,EAAA,CAAG,UAAA,KAAe,QAAA,EAAU,OAAO,IAAA;AAAA,EACzC;AACA,EAAA,OAAO,KAAA;AACT;AAMA,SAAS,QAAQ,CAAA,EAAsC;AACrD,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,CAAA,GAAI,uBAAA,CAAwB,IAAA,CAAK,CAAA,CAAE,MAAM,CAAA;AAC/C,EAAA,OAAO,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,IAAA;AAC5B;AAUA,SAAS,uBAAA,CACP,OACA,EAAA,EACM;AACN,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,EAAA,CAAG,gBAAA,CAAiB,aAAa,CAAC,CAAA;AACvD,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,EAAA,CAAG,gBAAA,CAAiB,cAAc,CAAC,CAAA;AACzD,EAAA,IAAI,IAAA,IAAQ,IAAA,IAAQ,KAAA,IAAS,IAAA,EAAM;AACnC,EAAA,IAAI,IAAA,GAAO,EAAA,IAAM,KAAA,GAAQ,EAAA,EAAI;AAC7B,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA;AAC1D,EAAA,IAAI,QAAQ,GAAA,EAAK;AACjB,EAAA,MAAM,MAAM,OAAA,CAAQ,EAAA,CAAG,gBAAA,CAAiB,YAAY,CAAC,CAAA,IAAK,CAAA;AAC1D,EAAA,MAAM,MAAM,OAAA,CAAQ,EAAA,CAAG,gBAAA,CAAiB,eAAe,CAAC,CAAA,IAAK,CAAA;AAG7D,EAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,IAAA,IAAI,KAAA,CAAM,CAAC,CAAA,EAAG,UAAA,CAAW,SAAS,CAAA,EAAG,KAAA,CAAM,MAAA,CAAO,CAAA,EAAG,CAAC,CAAA;AAAA,EACxD;AACA,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,QAAA,EAAW,GAAG,CAAA,QAAA,EAAW,GAAG,CAAA,EAAA,CAAI,CAAA;AAC7C;AAEA,SAAS,YAAA,CAAa,IAAA,EAAe,KAAA,EAAgB,GAAA,EAAuB;AAC1E,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,gBAAA,GAAmB,IAAI,CAAA;AACtC,EAAA,IAAI,CAAC,EAAA,EAAI;AACT,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,QAAQ,YAAA,EAAc;AAC/B,IAAA,MAAM,CAAA,GAAI,EAAA,CAAG,gBAAA,CAAiB,IAAI,CAAA;AAClC,IAAA,IAAI,KAAK,CAAA,KAAM,MAAA,IAAU,MAAM,QAAA,IAAY,CAAA,CAAE,MAAK,KAAM,EAAA;AACtD,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EAC9B;AACA,EAAA,uBAAA,CAAwB,OAAO,EAAE,CAAA;AACjC,EAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,CAAM,YAAA,CAAa,SAAS,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAChE;AAGA,SAAS,cAAA,CACP,IAAA,EACA,KAAA,EACA,GAAA,EACA,QACA,OAAA,EACM;AACN,EAAA,IAAI,MAAA,EAAQ,YAAA,CAAa,IAAA,EAAM,KAAA,EAAO,GAAG,CAAA;AAEzC,EAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,GAAG,KAAA,CAAM,UAAU,CAAA,EAAG;AACxC,IAAA,IAAI,IAAA,CAAK,KAAK,UAAA,CAAW,OAAO,GAAG,KAAA,CAAM,eAAA,CAAgB,KAAK,IAAI,CAAA;AAAA,EACpE;AACA,EAAA,MAAM,QAAA,GAAW,CAAC,GAAG,IAAA,CAAK,QAAQ,CAAA;AAClC,EAAA,MAAM,SAAA,GAAY,CAAC,GAAG,KAAA,CAAM,QAAQ,CAAA;AACpC,EAAA,MAAM,SAAoB,EAAC;AAC3B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,MAAM,CAAA,GAAI,SAAS,CAAC,CAAA;AACpB,IAAA,MAAM,CAAA,GAAI,UAAU,CAAC,CAAA;AACrB,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,EAAG;AACd,IAAA,IAAI,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA,EAAG;AACpB,MAAA,MAAA,CAAO,KAAK,CAAC,CAAA;AACb,MAAA,OAAA,CAAQ,KAAA,EAAA;AACR,MAAA;AAAA,IACF;AACA,IAAA,cAAA,CAAe,CAAA,EAAG,CAAA,EAAG,GAAA,EAAK,MAAA,EAAQ,OAAO,CAAA;AAAA,EAC3C;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO;AACnC;AAGA,SAAS,UAAU,EAAA,EAAqB;AACtC,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,OAAA,CAAQ,WAAA,EAAY;AACnC,EAAA,MAAM,OAAA,GAAA,CAAW,EAAA,CAAG,YAAA,CAAa,OAAO,KAAK,EAAA,EAC1C,KAAA,CAAM,KAAK,CAAA,CACX,OAAO,OAAO,CAAA,CACd,IAAA,EAAK,CACL,KAAK,GAAG,CAAA;AACX,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,EAAA,CAAG,QAAQ,CAAA,CAC5B,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,OAAA,CAAQ,WAAA,EAAa,CAAA,CAClC,KAAK,GAAG,CAAA;AACX,EAAA,OAAO,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,OAAO,IAAI,OAAO,CAAA,CAAA;AACrC;AAQA,SAAS,kBAAkB,IAAA,EAAkC;AAC3D,EAAA,IAAI,IAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,MAAM,KAAA,GAAQ,CAAC,EAAA,KAAgB;AAC7B,IAAA,MAAM,MAAA,uBAAa,GAAA,EAAuB;AAC1C,IAAA,KAAA,MAAW,KAAA,IAAS,GAAG,QAAA,EAAU;AAC/B,MAAA,MAAM,GAAA,GAAM,UAAU,KAAK,CAAA;AAC3B,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,GAAA,CAAI,GAAG,KAAK,EAAC;AAChC,MAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AACd,MAAA,MAAA,CAAO,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,MAAA,EAAO,EAAG;AAClC,MAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AAGrB,MAAA,MAAM,UAAU,IAAA,CAAK,MAAA;AAAA,QACnB,CAAC,GAAG,CAAA,KAAM,CAAA,GAAA,CAAK,EAAE,WAAA,IAAe,EAAA,EAAI,MAAK,CAAE,MAAA;AAAA,QAC3C;AAAA,OACF;AACA,MAAA,MAAM,QAAQ,IAAA,CAAK,MAAA,GAAS,KAAK,IAAA,CAAK,GAAA,CAAI,SAAS,GAAG,CAAA;AACtD,MAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA,IAAA,GAAO,EAAE,SAAA,EAAW,EAAA,EAAI,IAAA,EAAK;AAAA,MAC/B;AAAA,IACF;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,EAAA,CAAG,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA;AAAA,EAC9C,CAAA;AACA,EAAA,KAAA,CAAM,IAAI,CAAA;AACV,EAAA,OAAO,IAAA;AACT;AAEA,IAAM,SAAA,GACJ,8DAAA;AACF,IAAM,SAAA,GAAY,uDAAA;AAClB,IAAM,OAAA,GAAU,yCAAA;AAChB,IAAM,OAAA,GAAU,wDAAA;AAChB,IAAM,YAAA,GACJ,6GAAA;AAEF,SAAS,QAAQ,EAAA,EAAqB;AACpC,EAAA,OAAO,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA,IAAK,EAAA;AACrC;AAKA,SAAS,qBAAqB,EAAA,EAAmB;AAC/C,EAAA,IAAI,GAAG,YAAA,CAAa,iBAAiB,CAAA,EAAG,EAAA,CAAG,gBAAgB,iBAAiB,CAAA;AAC5E,EAAA,KAAA,MAAW,KAAA,IAAS,EAAA,CAAG,QAAA,EAAU,oBAAA,CAAqB,KAAK,CAAA;AAC7D;AAEA,SAAS,QAAA,CAAS,EAAA,EAAa,IAAA,EAAc,KAAA,EAAqB;AAChE,EAAA,EAAA,CAAG,YAAA,CAAa,WAAW,IAAI,CAAA;AAC/B,EAAA,EAAA,CAAG,WAAA,GAAc,KAAA;AACnB;AAGA,SAAS,WAAW,GAAA,EAGlB;AACA,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,MAAM,MAAM,CAAC,GAAG,GAAA,CAAI,gBAAA,CAAiB,GAAG,CAAC,CAAA;AAGzC,EAAA,IAAI,MAAA,GACF,GAAA,CAAI,aAAA,CAAc,KAAK,KACvB,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM,UAAU,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,IAC1C,IAAA;AACF,EAAA,IAAI,MAAA,EAAQ;AAEV,IAAA,IAAI,MAAA,CAAO,YAAY,KAAA,EAAO;AAC5B,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,aAAA,CAAc,aAAA,CAAc,KAAK,CAAA;AACjD,MAAA,MAAM,GAAA,GAAM,QAAQ,MAAM,CAAA;AAC1B,MAAA,IAAI,GAAA,EAAK,GAAA,CAAI,YAAA,CAAa,OAAA,EAAS,GAAG,CAAA;AACtC,MAAA,MAAM,EAAA,GAAK,MAAA,CAAO,YAAA,CAAa,OAAO,CAAA;AACtC,MAAA,IAAI,EAAA,EAAI,GAAA,CAAI,YAAA,CAAa,OAAA,EAAS,EAAE,CAAA;AACpC,MAAA,MAAA,CAAO,YAAY,GAAG,CAAA;AACtB,MAAA,MAAA,GAAS,GAAA;AAAA,IACX;AACA,IAAA,QAAA,CAAS,MAAA,EAAQ,UAAU,YAAY,CAAA;AACvC,IAAA,QAAA,CAAS,KAAK,QAAQ,CAAA;AAAA,EACxB;AAGA,EAAA,IAAI,SAAS,GAAA,CAAI,IAAA;AAAA,IACf,CAAC,CAAA,KACC,CAAA,KAAM,MAAA,IACN,SAAA,CAAU,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,IAAA,CACxB,CAAA,CAAE,WAAA,IAAe,IAAI,IAAA;AAAK,GAC/B;AACA,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAA,GAAS,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM;AACvB,MAAA,IAAI,MAAM,MAAA,IAAU,CAAA,CAAE,YAAA,CAAa,SAAS,GAAG,OAAO,KAAA;AACtD,MAAA,MAAM,CAAA,GAAA,CAAK,CAAA,CAAE,WAAA,IAAe,EAAA,EAAI,IAAA,EAAK;AACrC,MAAA,MAAM,EAAA,GAAA,CAAM,CAAA,CAAE,YAAA,CAAa,OAAO,KAAK,EAAA,EAAI,KAAA;AAAA,QACzC;AAAA,OACF;AACA,MAAA,MAAM,OACJ,CAAA,CAAE,OAAA,KAAY,GAAA,IACd,CAAA,CAAE,YAAY,QAAA,KACb,EAAA,GAAK,EAAA,CAAG,CAAC,MAAM,MAAA,IAAU,MAAA,CAAO,GAAG,CAAC,CAAC,KAAK,GAAA,GAAM,KAAA,CAAA;AACnD,MAAA,OAAO,IAAA,IAAQ,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,EAAE,MAAA,GAAS,EAAA;AAAA,IAC5C,CAAC,CAAA;AAAA,EACH;AACA,EAAA,IAAI,MAAA,IAAU,CAAC,MAAA,CAAO,YAAA,CAAa,SAAS,CAAA,EAAG;AAC7C,IAAA,QAAA,CAAS,MAAA,EAAQ,UAAU,YAAY,CAAA;AACvC,IAAA,QAAA,CAAS,KAAK,QAAQ,CAAA;AAAA,EACxB;AAGA,EAAA,MAAM,IAAA,GACJ,IAAI,aAAA,CAAc,MAAM,KACxB,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM,CAAC,EAAE,YAAA,CAAa,SAAS,KAAK,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAC,CAAA,IACtE,GAAA,CAAI,IAAA;AAAA,IACF,CAAC,CAAA,KACC,CAAC,CAAA,CAAE,YAAA,CAAa,SAAS,CAAA,IACzB,CAAA,CAAE,QAAA,CAAS,MAAA,KAAW,KACtB,YAAA,CAAa,IAAA,CAAA,CAAM,EAAE,WAAA,IAAe,EAAA,EAAI,MAAM;AAAA,GAClD;AACF,EAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA,EAAG;AACzC,IAAA,QAAA,CAAS,IAAA,EAAM,QAAQ,UAAU,CAAA;AACjC,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAIA,EAAA,MAAM,QAAQ,GAAA,CAAI,IAAA;AAAA,IAChB,CAAC,CAAA,KACC,CAAC,EAAE,YAAA,CAAa,SAAS,KACzB,CAAC,CAAA,CAAE,aAAA,CAAc,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAG,CAAA,IACjC,QAAQ,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC;AAAA,GAC3B;AACA,EAAA,IAAI,OAAO,KAAA,IAAS,IAAA;AACpB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,IAAI,OAAA,GAAU,EAAA;AACd,IAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACnB,MAAA,IAAI,CAAA,CAAE,YAAA,CAAa,SAAS,CAAA,EAAG;AAC/B,MAAA,IAAI,CAAA,CAAE,aAAA,CAAc,CAAA,CAAA,EAAI,SAAS,GAAG,CAAA,EAAG;AACvC,MAAA,MAAM,CAAA,GAAA,CAAK,CAAA,CAAE,WAAA,IAAe,EAAA,EAAI,IAAA,EAAK;AACrC,MAAA,IAAI,CAAA,CAAE,SAAS,OAAA,EAAS;AACtB,QAAA,OAAA,GAAU,CAAA,CAAE,MAAA;AACZ,QAAA,IAAA,GAAO,CAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA,EAAG;AACzC,IAAA,QAAA,CAAS,IAAA,EAAM,QAAQ,UAAU,CAAA;AACjC,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB,CAAA,MAAA,IAAW,CAAC,IAAA,EAAM;AAEhB,IAAA,QAAA,CAAS,GAAA,EAAK,QAAQ,UAAU,CAAA;AAChC,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,GAAA,CAAI,SAAA,EAAW,QAAA,EAAS;AACzC;AAEA,IAAM,WAAA,GACJ,wGAAA;AACF,IAAM,gBAAA,GAAmB,gDAAA;AAKzB,SAAS,aAAA,CAAc,MAAe,IAAA,EAAwB;AAC5D,EAAA,IAAI,GAAA,GAAe,IAAA;AACnB,EAAA,OAAO,GAAA,CAAI,aAAA,IAAiB,GAAA,CAAI,aAAA,KAAkB,IAAA,EAAM;AACtD,IAAA,MAAM,SAAS,GAAA,CAAI,aAAA;AACnB,IAAA,MAAM,SAAS,MAAA,CAAO,YAAA,CAAa,OAAO,CAAA,IAAK,IAAI,WAAA,EAAY;AAC/D,IAAA,IAAI,2BAAA,CAA4B,IAAA,CAAK,KAAK,CAAA,EAAG,OAAO,MAAA;AACpD,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,GAAA;AACT;AAaA,SAAS,YAAA,CAAa,MAAe,OAAA,EAAkC;AACrE,EAAA,MAAM,MAAM,CAAC,GAAG,KAAK,gBAAA,CAAiB,GAAG,CAAC,CAAA,CAAE,MAAA;AAAA,IAC1C,CAAC,CAAA,KAAM,CAAC,OAAA,CAAQ,QAAA,CAAS,CAAC,CAAA,IAAK,CAAC,CAAA,CAAE,QAAA,CAAS,OAAO;AAAA,GACpD;AAEA,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM;AAC7B,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,YAAA,CAAa,YAAY,CAAA;AACzC,IAAA,OAAO,KAAA,IAAS,gBAAA,CAAiB,IAAA,CAAK,KAAK,CAAA;AAAA,EAC7C,CAAC,CAAA;AACD,EAAA,IAAI,MAAA,EAAQ,OAAO,aAAA,CAAc,MAAA,EAAQ,IAAI,CAAA;AAE7C,EAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,YAAA,CAAa,MAAM,CAAA,KAAM,SAAS,CAAA;AACnE,EAAA,IAAI,MAAA,EAAQ,OAAO,aAAA,CAAc,MAAA,EAAQ,IAAI,CAAA;AAE7C,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,YAAA,CAAa,iBAAiB,CAAC,CAAA;AAC9D,EAAA,IAAI,IAAA,EAAM,OAAO,aAAA,CAAc,IAAA,EAAM,IAAI,CAAA;AAEzC,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM,YAAY,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA;AAC5D,EAAA,IAAI,SAAS,OAAO,OAAA;AAIpB,EAAA,IAAI,MAAA,GAAyB,OAAA;AAC7B,EAAA,OAAO,MAAA,IAAU,WAAW,IAAA,EAAM;AAChC,IAAA,IAAI,MAAsB,MAAA,CAAO,kBAAA;AACjC,IAAA,OAAO,GAAA,EAAK;AACV,MAAA,MAAM,SAAS,GAAA,CAAI,YAAA,CAAa,OAAO,CAAA,IAAK,IAAI,WAAA,EAAY;AAC5D,MAAA,MAAM,OAAA,GAAU,CAAC,sBAAA,CAAuB,IAAA,CAAK,KAAK,CAAA;AAClD,MAAA,MAAM,eAAe,GAAA,CAAI,aAAA;AAAA,QACvB;AAAA,OACF;AACA,MAAA,MAAM,GAAA,GAAA,CAAO,GAAA,CAAI,WAAA,IAAe,EAAA,EAAI,IAAA,EAAK;AACzC,MAAA,IAAI,YAAY,YAAA,IAAgB,GAAA,CAAI,WAAW,CAAA,IAAK,GAAA,CAAI,SAAS,GAAA,CAAA,EAAM;AACrE,QAAA,OAAO,GAAA;AAAA,MACT;AACA,MAAA,GAAA,GAAM,GAAA,CAAI,kBAAA;AAAA,IACZ;AACA,IAAA,MAAA,GAAS,MAAA,CAAO,aAAA;AAAA,EAClB;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,WAAA,GAA0B;AACjC,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,UAAU,EAAC,EAAG,YAAY,CAAA,EAAE;AACrD;AAEO,SAAS,OAAA,CAAQ,IAAA,EAAe,IAAA,GAAuB,EAAC,EAAc;AAC3E,EAAA,MAAM,GAAA,GAAMA,UAAAA,CAAU,IAAA,CAAK,MAAM,CAAA;AACjC,EAAA,MAAM,MAAM,GAAA,CAAI,QAAA;AAChB,EAAA,MAAM,WAAqB,EAAC;AAG5B,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AACjC,EAAA,MAAM,OAAA,GAAU,EAAE,KAAA,EAAO,CAAA,EAAE;AAC3B,EAAA,cAAA,CAAe,MAAM,KAAA,EAAO,GAAA,EAAK,IAAA,CAAK,oBAAA,IAAwB,OAAO,OAAO,CAAA;AAC5E,EAAA,IAAI,QAAQ,KAAA,GAAQ,CAAA;AAClB,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,CAAA,QAAA,EAAW,QAAQ,KAAK,CAAA,oCAAA;AAAA,KAC1B;AAGF,EAAA,MAAM,OAAO,YAAA,CAAa,KAAA,CAAM,WAAW,EAAE,MAAA,EAAQ,KAAK,CAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,aAAA,CAAc,KAAK,CAAA;AACpC,EAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,EAAA,MAAM,SAAA,GAAa,KAAK,iBAAA,IAAwC,IAAA;AAGhE,EAAA,MAAM,IAAA,GAAO,kBAAkB,SAAS,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY;AAAA,IAChB,OAAO,WAAA,EAAY;AAAA,IACnB,SAAS,WAAA,EAAY;AAAA,IACrB,UAAU,WAAA,EAAY;AAAA,IACtB,QAAQ,WAAA;AAAY,GACtB;AAEA,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,YAAA;AAEJ,EAAA,IAAI,IAAA,EAAM;AAER,IAAA,MAAM,SAAU,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CAAc,UAAU,IAAI,CAAA;AACvD,IAAA,MAAM,OAAA,GAAU,WAAW,MAAM,CAAA;AACjC,IAAA,WAAA,GAAc,OAAA,CAAQ,IAAA;AACtB,IAAA,SAAA,CAAU,OAAA,GAAU;AAAA,MAClB,KAAA,EAAO,IAAA;AAAA,MACP,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,YAAY,IAAA,CAAK,GAAA,CAAI,GAAG,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAC;AAAA,KACrD;AAGA,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,aAAA,CAAc,KAAK,CAAA;AACpC,IAAA,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AACvC,IAAA,IAAA,CAAK,WAAA,GAAc,cAAA;AACnB,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA;AACtC,IAAA,IAAI,SAAS,IAAA,CAAK,YAAA,CAAa,OAAA,EAAS,CAAA,EAAG,OAAO,CAAA,YAAA,CAAc,CAAA;AAChE,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,KAAK,CAAA;AAErD,IAAA,IAAI,cAAA,CAAe,aAAa,OAAO,CAAA;AACrC,MAAA,IAAA,CAAK,YAAA;AAAA,QACH,OAAA;AAAA,QACA,cAAA,CAAe,aAAa,OAAO;AAAA,OACrC;AAEF,IAAA,MAAM,UAAA,GAAa,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AAC3C,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AAC7C,IAAA,MAAM,aAAA,GAAgB,IAAA,GAAO,UAAA,CAAW,UAAA,EAAY,IAAI,CAAA,GAAI,IAAA;AAC5D,IAAA,IAAI,aAAA,IAAiB,cAAc,aAAA,EAAe;AAChD,MAAA,aAAA,CAAc,YAAY,IAAI,CAAA;AAC9B,MAAA,SAAA,GAAY,UAAA,CAAW,SAAA;AACvB,MAAA,SAAA,CAAU,KAAA,GAAQ,EAAE,KAAA,EAAO,IAAA,EAAM,UAAU,CAAC,UAAU,CAAA,EAAG,UAAA,EAAY,CAAA,EAAE;AAAA,IACzE,CAAA,MAAO;AAEL,MAAA,SAAA,GAAY,IAAA,CAAK,SAAA;AACjB,MAAA,SAAA,CAAU,KAAA,GAAQ;AAAA,QAChB,KAAA,EAAO,IAAA;AAAA,QACP,QAAA,EAAU,CAAC,UAAU,CAAA;AAAA,QACrB,UAAA,EAAY;AAAA,OACd;AACA,MAAA,QAAA,CAAS,IAAA;AAAA,QACP;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AACvD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,CAAA,GAAI,QAAA,CAAS,SAAA,CAAU,IAAI,CAAA;AACjC,MAAA,CAAA,CAAE,YAAA,CAAa,WAAW,UAAU,CAAA;AACpC,MAAA,oBAAA,CAAqB,CAAC,CAAA;AACtB,MAAA,CAAA,CAAE,WAAA,GAAc,cAAA;AAChB,MAAA,YAAA,GAAe,CAAA,CAAE,SAAA;AACjB,MAAA,SAAA,CAAU,QAAA,GAAW;AAAA,QACnB,KAAA,EAAO,IAAA;AAAA,QACP,QAAA,EAAU,CAAC,UAAU,CAAA;AAAA,QACrB,UAAA,EAAY;AAAA,OACd;AAAA,IACF,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,IAAA;AAAA,QACP;AAAA,OACF;AAAA,IACF;AAGA,IAAA,IAAI,SAAA;AACF,MAAA,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,6BAAA,EAA+B,EAAE,CAAA;AACjE,IAAA,IAAI,WAAA;AACF,MAAA,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,6BAAA,EAA+B,EAAE,CAAA;AAAA,EACvE,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,IAAA;AAAA,MACP;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,cAAc,SAAS,CAAA;AAGtC,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,IAAA,GACJ,KACA,qBAAA,IAAwB;AAC1B,EAAA,IAAI,QAAQ,IAAA,CAAK,KAAA,GAAQ,CAAA,IAAK,IAAA,CAAK,SAAS,CAAA,EAAG;AAC7C,IAAA,MAAA,GAAS,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,EAAG,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,EAAE;AAAA,EAC5E;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAA;AAAA,IACT,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,KAAK,IAAA,IAAQ,eAAA;AAAA,MACnB,GAAI,KAAK,SAAA,GAAY,EAAE,WAAW,IAAA,CAAK,SAAA,KAAc,EAAC;AAAA,MACtD,GAAI,KAAK,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,KAAU,EAAC;AAAA,MAC1C,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW,EAAC;AAAA,MAC3B,GAAI,KAAK,UAAA,GAAa,EAAE,YAAY,IAAA,CAAK,UAAA,KAAe;AAAC,KAC3D;AAAA,IACA,KAAA,EAAO;AAAA,MACL,GAAI,SAAA,GAAY,EAAE,KAAA,EAAO,SAAA,KAAc,EAAC;AAAA,MACxC,GAAI,WAAA,GAAc,EAAE,OAAA,EAAS,WAAA,KAAgB,EAAC;AAAA,MAC9C,GAAI,YAAA,GAAe,EAAE,QAAA,EAAU,YAAA,KAAiB;AAAC,KACnD;AAAA,IACA,GAAA,EAAK,KAAK,GAAA,IAAO,EAAA;AAAA,IACjB,MAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAI,KAAK,UAAA,EAAY,MAAA,GAAS,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI;AAAC,GACnE;AACF;AAGA,SAAS,MAAA,CAAO,MAAe,MAAA,EAAkC;AAC/D,EAAA,IAAI,IAAA,KAAS,MAAA,EAAQ,OAAO,EAAC;AAC7B,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC7B,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,EAAO,MAAM,CAAA;AAChC,IAAA,IAAI,GAAA,EAAK,OAAO,CAAC,CAAA,EAAG,GAAG,GAAG,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,UAAA,CAAW,MAAe,IAAA,EAAgC;AACjE,EAAA,IAAI,IAAA,GAAuB,IAAA;AAC3B,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,IAAK,IAAA;AAAA,EAC7B;AACA,EAAA,OAAO,IAAA;AACT;;;ACpkBA,SAAS,cAAA,CAAe,MAAe,QAAA,EAA2B;AAMhE,EAAA,IAAI,QAAA,KAAa,OAAA,IAAW,QAAA,KAAa,MAAA,IAAU,QAAA,KAAa,MAAA;AAC9D,IAAA,OAAO,KAAA;AACT,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,QAAQ,CAAA,IAAK,IAAA;AAAA,EACzC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAOA,SAAS,SAAA,CACP,KAAA,EACA,IAAA,EACA,GAAA,EACA,IAAA,EACM;AACN,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,GAAA,EAAK;AAC5B,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AAEpB,IAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAoB;AACpC,MAAA,MAAM,CAAA,GAAI,IAAA;AACV,MAAA,MAAM,MAAM,CAAA,CAAE,YAAA;AACd,MAAA,IAAI,GAAA,IAAO,GAAA,CAAI,KAAA,CAAM,GAAG,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,cAAA,CAAe,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,CAAC,CAAA,EAAG;AACrE,QAAA,MAAM,OAAO,CAAA,CAAE,OAAA;AACf,QAAA,GAAA,CAAI,KAAK,IAAI,CAAA;AACb,QAAA,IAAA,CAAK,KAAA,IAAS,KAAK,MAAA,GAAS,CAAA;AAAA,MAC9B;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,QAAA,GAAW,IAAA;AAKjB,IAAA,IAAI,SAAS,QAAA,EAAU;AACrB,MAAA,MAAM,QAAkB,EAAC;AACzB,MAAA,MAAM,SAAA,GAAY,EAAE,KAAA,EAAO,CAAA,EAAG,KAAK,IAAA,CAAK,GAAA,GAAM,KAAK,KAAA,EAAM;AACzD,MAAA,SAAA,CAAU,QAAA,CAAS,QAAA,EAAU,IAAA,EAAM,KAAA,EAAO,SAAS,CAAA;AACnD,MAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,QAAA,MAAM,OAAA,GAAU,WAAW,IAAI,CAAA;AAC/B,QAAA,MAAM,UAAU,CAAA,EAAG,OAAO,MAAM,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,EAAA,CAAA;AAC/C,QAAA,GAAA,CAAI,KAAK,OAAO,CAAA;AAChB,QAAA,IAAA,CAAK,KAAA,IAAS,QAAQ,MAAA,GAAS,CAAA;AAAA,MACjC;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IACE,IAAA,CAAK,IAAA,KAAS,CAAA,IACd,IAAA,CAAK,SAAS,CAAA,EACd;AACA,MAAA,MAAM,OAAO,IAAA,CAAK,OAAA;AAClB,MAAA,GAAA,CAAI,KAAK,IAAI,CAAA;AACb,MAAA,IAAA,CAAK,KAAA,IAAS,KAAK,MAAA,GAAS,CAAA;AAAA,IAC9B;AAAA,EACF;AACF;AAEA,SAAS,WAAW,IAAA,EAAuB;AAIzC,EAAA,MAAM,CAAA,GAAI,IAAA;AAMV,EAAA,QAAQ,EAAE,IAAA;AAAM,IACd,KAAK,CAAA;AACH,MAAA,OAAO,CAAA,OAAA,EAAU,CAAA,CAAE,KAAA,EAAO,SAAA,IAAa,KAAK,CAAA,CAAA;AAAA,IAC9C,KAAK,EAAA;AACH,MAAA,OAAO,CAAA,UAAA,EAAa,CAAA,CAAE,aAAA,IAAiB,KAAK,CAAA,CAAA;AAAA,IAC9C,KAAK,EAAA;AACH,MAAA,OAAO,CAAA,WAAA,EAAc,CAAA,CAAE,aAAA,IAAiB,EAAE,CAAA,CAAA;AAAA,IAC5C,KAAK,EAAA;AACH,MAAA,OAAO,CAAA,OAAA,EAAU,CAAA,CAAE,IAAA,IAAQ,EAAE,CAAA,CAAA;AAAA,IAC/B;AAEE,MAAA,OAAO,KAAK,OAAA,CAAQ,OAAA,CAAQ,YAAA,EAAc,EAAE,EAAE,IAAA,EAAK;AAAA;AAEzD;AAOO,SAAS,iBAAA,CACd,IAAA,EACA,GAAA,EACA,IAAA,GAA0B,EAAC,EACT;AAClB,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,IAAY,GAAA,GAAM,IAAA;AACnC,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,MAAM,IAAA,GAAO,EAAE,KAAA,EAAO,CAAA,EAAG,GAAA,EAAI;AAC7B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,SAAS,GAAA,CAAI,WAAA;AACnB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,IAAA,IAAI,IAAA,CAAK,SAAS,GAAA,EAAK;AACvB,IAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AACtB,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AACF,MAAA,KAAA,GAAQ,KAAA,CAAM,QAAA;AAAA,IAChB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,IAAQ,UAAU,CAAA;AACrC,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,SAAA,CAAU,KAAA,EAAO,IAAA,EAAM,GAAA,EAAK,IAAI,CAAA;AAAA,EAClC;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAAA,IAClB,OAAA;AAAA,IACA,SAAA,EAAW,KAAK,KAAA,IAAS;AAAA,GAC3B;AACF;AClKA,SAAS,KAAK,CAAA,EAAmB;AAC/B,EAAA,OACE,CAAA,CACG,WAAA,EAAY,CACZ,OAAA,CAAQ,aAAA,EAAe,GAAG,CAAA,CAC1B,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,IAAK,UAAA;AAElC;AAEA,IAAM,YAAA,GAA6B;AAAA,EACjC,QAAQ,EAAC;AAAA,EACT,SAAS,EAAC;AAAA,EACV,SAAA,EAAW,KAAA;AAAA,EACX,OAAA,EAAS,KAAA;AAAA,EACT,YAAA,EAAc;AAChB,CAAA;AAQO,SAAS,qBAAA,CACd,KAAA,EACA,IAAA,GAA4B,EAAC,EACvB;AACN,EAAA,MAAM,SAAA,GAA2B;AAAA,IAC/B,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,MAAM,IAAA,CAAK,IAAA;AAAA,MACjB,KAAA,EAAO,MAAM,IAAA,CAAK,KAAA;AAAA,MAClB,MAAA,EAAQ,MAAM,IAAA,CAAK,MAAA;AAAA,MACnB,UAAA,EACE,MAAM,IAAA,CACN;AAAA,KACJ;AAAA,IACA,KAAA,EAAO;AAAA,MACL,KAAA,EAAO,MAAM,KAAA,CAAM,KAAA,GAAQ,aAAa,KAAA,CAAM,KAAA,CAAM,KAAK,CAAA,GAAI,MAAA;AAAA,MAC7D,OAAA,EAAS,MAAM,KAAA,CAAM,OAAA,GACjB,aAAa,KAAA,CAAM,KAAA,CAAM,OAAO,CAAA,GAChC,MAAA;AAAA,MACJ,QAAA,EAAU,MAAM,KAAA,CAAM,QAAA,GAClB,aAAa,KAAA,CAAM,KAAA,CAAM,QAAQ,CAAA,GACjC,MAAA;AAAA,MACJ,MAAA,EAAQ,MAAM,KAAA,CAAM,MAAA,GAAS,aAAa,KAAA,CAAM,KAAA,CAAM,MAAM,CAAA,GAAI;AAAA,KAClE;AAAA,IACA,GAAA,EAAK,MAAM,GAAA,IAAO,EAAA;AAAA,IAClB,QAAQ,EAAE,MAAA,EAAQ,MAAM,MAAA,CAAO,MAAA,IAAU,EAAC,EAAE;AAAA,IAC5C,UAAA,EAAY,KAAA,CAAM,UAAA,GACd,EAAE,MAAA,EAAQ,MAAM,UAAA,CAAW,MAAA,IAAU,EAAC,EAAE,GACxC;AAAA,GACN;AAEA,EAAA,OAAOC,0BAAkB,SAAA,EAAW;AAAA,IAClC,IAAI,IAAA,CAAK,EAAA,IAAM,IAAA,CAAK,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IACnC,YAAA,EAAc,KAAK,YAAA,IAAgB;AAAA,GACpC,CAAA;AACH;;;AC1EO,SAAS,gBAAA,CAAiB,OAAkB,IAAA,EAA4B;AAC7E,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,MAAM,EAAE,GAAG,KAAA,CAAM,IAAA,EAAM,OAAO,MAAA,EAAU;AAAA,IACxC,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,YAAY,IAAA,CAAK,MAAA;AAAA,IACjB,QAAA,EAAU;AAAA,MACR,GAAG,KAAA,CAAM,QAAA;AAAA,MACT,GAAI,KAAK,SAAA,CAAU,OAAA,CAAQ,QACvB,EAAC,GACD,CAAC,6DAA6D;AAAA;AACpE,GACF;AACF","file":"index.cjs","sourcesContent":["import createDOMPurify from \"dompurify\";\n\n/**\n * Allowlist sanitizer for captured / imported HTML+CSS (PLAN §10). Captured\n * markup is **untrusted** — it can carry scripts, event handlers, hostile\n * `url(javascript:)` CSS, `data:text/html` payloads, and framed content. We do\n * not roll our own: the heavy lifting is a maintained, audited sanitizer\n * (DOMPurify), wrapped here with a strict allowlist and a CSS scrubber, and the\n * `TemplateSkinAdapter` *additionally* renders in a shadow root so a sanitizer\n * miss still can't reach the host page. Defense in depth, not a single gate.\n */\n\ninterface WindowLike {\n document: Document;\n}\n\n/** Tags we keep — pure presentational/structural HTML. No scripts, forms, media. */\nconst ALLOWED_TAGS = [\n \"div\",\n \"span\",\n \"p\",\n \"a\",\n \"b\",\n \"strong\",\n \"i\",\n \"em\",\n \"u\",\n \"s\",\n \"small\",\n \"sub\",\n \"sup\",\n \"br\",\n \"hr\",\n \"ul\",\n \"ol\",\n \"li\",\n \"img\",\n \"svg\",\n \"path\",\n \"g\",\n \"circle\",\n \"rect\",\n \"line\",\n \"polyline\",\n \"polygon\",\n \"ellipse\",\n \"defs\",\n \"use\",\n \"title\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"time\",\n \"header\",\n \"footer\",\n \"section\",\n \"article\",\n \"aside\",\n \"nav\",\n \"figure\",\n \"figcaption\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"td\",\n \"th\",\n];\n\n/**\n * Attributes we keep. `data-*` is dropped via `ALLOW_DATA_ATTR: false`, with the\n * single exception of our own `data-tc-slot` marker, which is re-allowed via\n * `ADD_ATTR` below so the slot contract survives a re-sanitize.\n */\nconst ALLOWED_ATTR = [\n \"class\",\n \"style\",\n \"role\",\n \"contenteditable\",\n \"alt\",\n \"src\",\n \"srcset\",\n \"width\",\n \"height\",\n \"dir\",\n \"title\",\n \"viewbox\",\n \"fill\",\n \"stroke\",\n \"stroke-width\",\n \"d\",\n \"points\",\n \"cx\",\n \"cy\",\n \"r\",\n \"x\",\n \"y\",\n \"x1\",\n \"x2\",\n \"y1\",\n \"y2\",\n \"rx\",\n \"ry\",\n \"transform\",\n \"xmlns\",\n \"href\",\n];\n\n/**\n * Strip CSS-level code execution and exfiltration vectors from a style string\n * (inline `style=\"\"` or a stylesheet body). Inline styles survive sanitize, so\n * this is where `expression()`, `url(javascript:)`, `@import`, `behavior:`, and\n * non-image `data:` URLs are removed.\n */\nexport function scrubCss(css: string): string {\n let out = css;\n // Hostile functions / properties.\n out = out.replace(/expression\\s*\\(/gi, \"/*blocked*/(\");\n out = out.replace(/-moz-binding\\s*:/gi, \"/*blocked*/:\");\n out = out.replace(/behavior\\s*:/gi, \"/*blocked*/:\");\n out = out.replace(/@import[^;]*;?/gi, \"/*blocked-import*/\");\n // url(...) targets: block scripting protocols and non-image data URLs.\n out = out.replace(/url\\(\\s*(['\"]?)([^)'\"]*)\\1\\s*\\)/gi, (whole, _q, uri) => {\n const u = String(uri).trim().toLowerCase();\n const blocked =\n u.startsWith(\"javascript:\") ||\n u.startsWith(\"vbscript:\") ||\n (u.startsWith(\"data:\") && !u.startsWith(\"data:image/\"));\n return blocked ? \"none\" : whole;\n });\n // Bare scripting protocols anywhere in the declaration.\n out = out.replace(/javascript:/gi, \"blocked:\");\n out = out.replace(/vbscript:/gi, \"blocked:\");\n return out;\n}\n\nfunction getWindow(win?: WindowLike): WindowLike {\n if (win) return win;\n if (typeof window !== \"undefined\") return window as unknown as WindowLike;\n throw new Error(\n \"sanitizeHtml requires a DOM window — pass { window } in non-browser environments.\",\n );\n}\n\nlet hooked: unknown = null;\n\ntype PurifyWindow = Parameters<typeof createDOMPurify>[0];\n\nfunction purifierFor(win: WindowLike): ReturnType<typeof createDOMPurify> {\n const purify = createDOMPurify(win as unknown as PurifyWindow);\n // Install hooks once per purifier instance.\n if (hooked !== purify) {\n purify.addHook(\"afterSanitizeAttributes\", (node) => {\n const el = node as Element;\n // Scrub inline styles for CSS hazards.\n const style = el.getAttribute?.(\"style\");\n if (style) el.setAttribute(\"style\", scrubCss(style));\n // Enforce image-only data: URLs on src.\n const src = el.getAttribute?.(\"src\");\n if (src) {\n const u = src.trim().toLowerCase();\n if (u.startsWith(\"data:\") && !u.startsWith(\"data:image/\")) {\n el.removeAttribute(\"src\");\n }\n }\n // Force links inert and safe — no navigation out of a simulation.\n if (el.tagName === \"A\") {\n el.removeAttribute(\"href\");\n el.setAttribute(\"role\", \"link\");\n }\n // target=_blank/opener hygiene (belt-and-braces; href already removed).\n if (el.getAttribute?.(\"target\")) el.removeAttribute(\"target\");\n });\n hooked = purify;\n }\n return purify;\n}\n\nexport interface SanitizeOptions {\n /** DOM window to use (required in Node; defaults to global `window`). */\n window?: WindowLike;\n}\n\n/**\n * Sanitize an untrusted HTML string to the capture allowlist. Returns inert,\n * presentational HTML safe to parse and slot-ify. Always pair with shadow-DOM\n * isolation at render time (`TemplateSkinAdapter`).\n */\nexport function sanitizeHtml(html: string, opts: SanitizeOptions = {}): string {\n const win = getWindow(opts.window);\n const purify = purifierFor(win);\n return purify.sanitize(html, {\n ALLOWED_TAGS,\n ALLOWED_ATTR,\n // Keep our slot marker even though data-* is otherwise dropped, and\n // keep `contenteditable` so the composer-detection heuristic can find\n // div-based composers (Slack/PostHog/etc. fake the textarea with a\n // contenteditable div). The distiller strips it later, after marking.\n ADD_ATTR: [\"data-tc-slot\", \"contenteditable\"],\n ALLOW_DATA_ATTR: false,\n ALLOW_ARIA_ATTR: true,\n FORBID_TAGS: [\n \"script\",\n \"style\",\n \"iframe\",\n \"object\",\n \"embed\",\n \"form\",\n \"input\",\n \"button\",\n \"textarea\",\n \"select\",\n \"link\",\n \"meta\",\n \"base\",\n \"video\",\n \"audio\",\n \"source\",\n ],\n FORBID_ATTR: [\"srcdoc\", \"formaction\", \"xlink:href\"],\n }) as string;\n}\n","import { z } from \"zod\";\n\n/**\n * A `SkinDraft` is what the distiller emits from a captured chat UI: sanitized,\n * slotted HTML templates (with inline styles), extracted design tokens, and a\n * detection report describing what was auto-identified vs. what still needs a\n * human pass (PLAN §10). A draft is *not* a finished skin — `scaffold-skin`\n * turns one into an editable template-skin package, and the capture quality bar\n * (§10) decides whether it ships as a skin or stays \"draft only\".\n *\n * Slot tokens are double-brace placeholders the `TemplateSkinAdapter` fills:\n * frame: `{{messages}}` — where the message list mounts\n * message: `{{author}}` `{{avatar}}` `{{body}}` `{{time}}`\n * composer: `{{composer}}`\n * typing: `{{author}}`\n */\n\nexport const SLOT_TOKENS = {\n messages: \"{{messages}}\",\n author: \"{{author}}\",\n avatar: \"{{avatar}}\",\n body: \"{{body}}\",\n time: \"{{time}}\",\n composer: \"{{composer}}\",\n} as const;\n\nexport type SlotName = \"frame\" | \"message\" | \"composer\" | \"typing\";\n\n/** Per-slot detection outcome — drives the quality-bar metric (§10). */\nexport const slotReportSchema = z.object({\n /** Whether this region was found at all. */\n found: z.boolean(),\n /** Which inner slots were auto-detected (e.g. `[\"author\",\"body\"]`). */\n detected: z.array(z.string()),\n /** Heuristic confidence 0..1 for the auto-detection. */\n confidence: z.number().min(0).max(1),\n});\nexport type SlotReport = z.infer<typeof slotReportSchema>;\n\nconst tokenSetSchema = z.object({\n colors: z.record(z.string(), z.string()),\n fonts: z.record(z.string(), z.string()).optional(),\n space: z.record(z.string(), z.string()).optional(),\n radius: z.record(z.string(), z.string()).optional(),\n});\n\nexport const skinDraftSchema = z.object({\n version: z.literal(1),\n meta: z.object({\n /** Human label, defaulted from the source title/host. */\n name: z.string(),\n /** Source page URL, when known (informational only). */\n sourceUrl: z.string().optional(),\n /** Theme the capture was taken under, when known. */\n theme: z.enum([\"light\", \"dark\"]).optional(),\n /** Suggested canvas from the captured element's box. */\n canvas: z\n .object({ width: z.number().int(), height: z.number().int() })\n .optional(),\n /**\n * Snapshot of the page context the draft was taken from. Used by the\n * slot-template renderer to expose a `--captured-viewport-width` CSS\n * variable so authored CSS can ratio-scale against the original\n * viewport instead of the (much smaller) playback canvas.\n */\n capturedAt: z\n .object({\n viewportWidth: z.number().int().optional(),\n viewportHeight: z.number().int().optional(),\n pixelRatio: z.number().optional(),\n })\n .optional(),\n }),\n /**\n * Slotted, sanitized HTML per region. Elements carry inline `style`\n * attributes; `css` holds anything inline styles can't express.\n */\n slots: z.object({\n frame: z.string().optional(),\n message: z.string().optional(),\n composer: z.string().optional(),\n typing: z.string().optional(),\n }),\n /** Best-effort extra CSS (pseudo-elements, keyframes) — may be empty. */\n css: z.string(),\n /** Extracted design tokens (best effort) — the primary/captured theme. */\n tokens: tokenSetSchema,\n /**\n * Dark-theme tokens from a paired capture (M5.7 double-capture flow). When\n * present, the skin supports both themes and switches CSS vars by theme.\n */\n darkTokens: tokenSetSchema.optional(),\n /** Detection report per region. */\n detection: z.object({\n frame: slotReportSchema,\n message: slotReportSchema,\n composer: slotReportSchema,\n typing: slotReportSchema,\n }),\n /** Human-readable warnings (hidden content dropped, slots missing, …). */\n warnings: z.array(z.string()),\n /**\n * Stylesheets the matched-CSS capture couldn't read (typically blocked by\n * CORS). Informational — the slot template still renders, just without\n * the rules those sheets defined.\n */\n cssSkipped: z.array(z.string()).optional(),\n});\n\nexport type SkinDraft = z.infer<typeof skinDraftSchema>;\n\n/** Overall slot-detection ratio used by the §10 quality bar (0..1). */\nexport function detectionScore(draft: SkinDraft): number {\n // The five core slots: message-row found, author, avatar, body, composer.\n const checks = [\n draft.detection.message.detected.includes(\"body\"),\n draft.detection.message.detected.includes(\"author\"),\n draft.detection.message.detected.includes(\"avatar\"),\n draft.detection.message.detected.includes(\"time\"),\n draft.detection.composer.found,\n ];\n return checks.filter(Boolean).length / checks.length;\n}\n","/**\n * Best-effort design-token extraction from the inline styles of a distilled\n * tree (PLAN §10). This is a starting palette for the skin author to rename and\n * curate — not an authoritative theme. We pull distinct colors (most-frequent\n * first), font families, border radii, and padding scales.\n */\n\ninterface Tokens {\n colors: Record<string, string>;\n fonts?: Record<string, string>;\n space?: Record<string, string>;\n radius?: Record<string, string>;\n}\n\nfunction parseStyle(style: string): Map<string, string> {\n const m = new Map<string, string>();\n for (const decl of style.split(\";\")) {\n const idx = decl.indexOf(\":\");\n if (idx === -1) continue;\n const prop = decl.slice(0, idx).trim().toLowerCase();\n const val = decl.slice(idx + 1).trim();\n if (prop && val) m.set(prop, val);\n }\n return m;\n}\n\nconst COLOR_RE = /(#[0-9a-f]{3,8}\\b|rgba?\\([^)]*\\)|hsla?\\([^)]*\\))/gi;\n\nexport function extractTokens(root: Element): Tokens {\n const colorFreq = new Map<string, number>();\n const fonts = new Set<string>();\n const radii = new Set<string>();\n const spaces = new Set<string>();\n\n const bump = (raw: string) => {\n const v = raw.trim();\n if (!v || v === \"transparent\" || v === \"inherit\" || v === \"currentcolor\")\n return;\n colorFreq.set(v, (colorFreq.get(v) ?? 0) + 1);\n };\n\n for (const el of [root, ...root.querySelectorAll(\"*\")]) {\n const style = el.getAttribute(\"style\");\n if (!style) continue;\n const decls = parseStyle(style);\n for (const [prop, val] of decls) {\n if (prop === \"color\" || prop.startsWith(\"background\")) {\n const matches = val.match(COLOR_RE);\n if (matches) for (const c of matches) bump(c);\n }\n if (prop === \"font-family\") fonts.add(val);\n if (prop === \"border-radius\") radii.add(val);\n if (prop === \"padding\" || prop === \"gap\") spaces.add(val);\n }\n }\n\n const colors: Record<string, string> = {};\n [...colorFreq.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 12)\n .forEach(([c], i) => {\n colors[`color-${i + 1}`] = c;\n });\n\n const out: Tokens = { colors };\n if (fonts.size) {\n out.fonts = {};\n [...fonts].slice(0, 4).forEach((f, i) => {\n out.fonts![`font-${i + 1}`] = f;\n });\n }\n if (radii.size) {\n out.radius = {};\n [...radii].slice(0, 6).forEach((r, i) => {\n out.radius![`radius-${i + 1}`] = r;\n });\n }\n if (spaces.size) {\n out.space = {};\n [...spaces].slice(0, 8).forEach((s, i) => {\n out.space![`space-${i + 1}`] = s;\n });\n }\n return out;\n}\n","import { sanitizeHtml } from \"./sanitize.js\";\nimport { extractTokens } from \"./tokens.js\";\nimport type { SkinDraft, SlotReport } from \"./draft.js\";\n\n/**\n * The distiller (PLAN §10): given a chat-UI subtree, produce a sanitized,\n * slotted `SkinDraft`. The pipeline is\n *\n * clone → inline computed styles (live capture) → drop hidden/`data-*` →\n * sanitize (allowlist) → find the repeating message row → slot-ify\n * (author/avatar/body/time) → carve the frame chrome → find the composer →\n * extract tokens → report.\n *\n * Capture gets you ~80% of the way; the emitted `detection` report and\n * `warnings` tell the author exactly what to confirm by hand (the §10 quality\n * bar treats anything below the bar as \"draft only\", never a finished skin).\n * The function is DOM-agnostic — the extension passes a live element, the\n * saved-page importer passes a jsdom element.\n */\n\ninterface WindowLike {\n document: Document;\n getComputedStyle?: (el: Element) => CSSStyleDeclaration;\n}\n\nexport interface DistillOptions {\n /** DOM window (defaults to global `window`). Required in Node. */\n window?: WindowLike;\n /** Display name for the draft. */\n name?: string;\n sourceUrl?: string;\n theme?: \"light\" | \"dark\";\n /**\n * Inline computed styles from the live page so fidelity survives losing the\n * cascade. Off for saved-page import (the source CSS comes inline already).\n */\n inlineComputedStyles?: boolean;\n /**\n * Page CSS captured by `captureMatchedCss` to embed in the slot-template\n * renderer's shadow root. Without this, class-driven layout (Tailwind, CSS\n * modules) collapses because the captured class names lose their meaning.\n */\n css?: string;\n /** Stylesheets the CSS capture had to skip (CORS, parse errors). */\n cssSkipped?: string[];\n /**\n * Page context the capture was taken in. Forwarded into `meta.capturedAt`\n * so the renderer can expose `--captured-viewport-width` to authored CSS.\n */\n capturedAt?: {\n viewportWidth?: number;\n viewportHeight?: number;\n pixelRatio?: number;\n };\n}\n\n/** The slot-marker attribute the `TemplateSkinAdapter` keys off. */\nexport const SLOT_ATTR = \"data-tc-slot\";\n\n/**\n * Computed properties worth inlining. **Visual fidelity** (color, font,\n * border, padding, gap) plus **load-bearing layout** (width/max-width,\n * flex-grow/shrink/basis, position, overflow). The layout group used to be\n * omitted on the theory that \"we only want look, not frozen geometry\", but\n * modern apps drive layout from utility classes (Tailwind, CSS modules) and\n * those classes lose all meaning once they leave their stylesheet — without\n * the inlined layout properties, captures collapse into single-character\n * vertical columns when reflowed into a small canvas.\n */\nconst INLINE_PROPS = [\n \"color\",\n \"background-color\",\n \"background\",\n \"font-family\",\n \"font-size\",\n \"font-weight\",\n \"font-style\",\n \"line-height\",\n \"letter-spacing\",\n \"text-align\",\n \"text-transform\",\n \"border\",\n \"border-radius\",\n \"padding\",\n \"margin\",\n \"gap\",\n \"display\",\n \"flex-direction\",\n \"flex-wrap\",\n \"align-items\",\n \"align-self\",\n \"justify-content\",\n \"justify-self\",\n \"box-shadow\",\n \"opacity\",\n // Layout-bearing properties (added 2026-Q2 to fix Tailwind-style captures):\n \"width\",\n \"max-width\",\n \"min-width\",\n \"height\",\n \"max-height\",\n \"min-height\",\n \"flex\",\n \"flex-grow\",\n \"flex-shrink\",\n \"flex-basis\",\n \"position\",\n \"top\",\n \"right\",\n \"bottom\",\n \"left\",\n \"z-index\",\n \"overflow\",\n \"overflow-x\",\n \"overflow-y\",\n \"white-space\",\n \"overflow-wrap\",\n \"word-break\",\n];\n\nconst HIDDEN_CLASS_RE = /\\b(sr-only|visually-hidden|hidden)\\b/;\n\nfunction getWindow(win?: WindowLike): WindowLike {\n if (win) return win;\n if (typeof window !== \"undefined\") return window as unknown as WindowLike;\n throw new Error(\"distill requires a DOM window — pass { window } in Node.\");\n}\n\nfunction isHidden(el: Element, win: WindowLike): boolean {\n if (el.getAttribute(\"aria-hidden\") === \"true\") return true;\n if (el.hasAttribute(\"hidden\")) return true;\n const cls = el.getAttribute(\"class\") ?? \"\";\n if (HIDDEN_CLASS_RE.test(cls)) return true;\n const inline = (el.getAttribute(\"style\") ?? \"\").toLowerCase();\n if (/display\\s*:\\s*none/.test(inline)) return true;\n if (/visibility\\s*:\\s*hidden/.test(inline)) return true;\n const cs = win.getComputedStyle?.(el);\n if (cs) {\n if (cs.display === \"none\") return true;\n if (cs.visibility === \"hidden\") return true;\n }\n return false;\n}\n\n/**\n * Parse a pixel value (`\"234.5px\"` → 234.5; `\"auto\"`/`\"\"` → null). Used by\n * `normaliseDesktopMargins` to detect centering margins.\n */\nfunction pxValue(v: string | undefined): number | null {\n if (!v) return null;\n const m = /^(-?\\d+(?:\\.\\d+)?)px$/.exec(v.trim());\n return m ? Number(m[1]) : null;\n}\n\n/**\n * Captured pages run on desktop viewports, so a `mx-auto` ends up as\n * `margin-left: 234.5px; margin-right: 234.5px` once computed. Baked in\n * verbatim, that margin survives into a 480-px canvas and squeezes content\n * into a vertical column. When we see two horizontal margins that are\n * both > 24px and within 10% of each other, rewrite them to `margin: 0 auto`\n * (preserving top/bottom) so layout re-centers in any canvas size.\n */\nfunction normaliseDesktopMargins(\n decls: string[],\n cs: CSSStyleDeclaration,\n): void {\n const left = pxValue(cs.getPropertyValue(\"margin-left\"));\n const right = pxValue(cs.getPropertyValue(\"margin-right\"));\n if (left == null || right == null) return;\n if (left < 24 || right < 24) return;\n const ratio = Math.max(left, right) / Math.min(left, right);\n if (ratio > 1.1) return;\n const top = pxValue(cs.getPropertyValue(\"margin-top\")) ?? 0;\n const bot = pxValue(cs.getPropertyValue(\"margin-bottom\")) ?? 0;\n // Remove any margin entries we already pushed, then replace with the\n // responsive form so the captured layout re-centers fluidly.\n for (let i = decls.length - 1; i >= 0; i--) {\n if (decls[i]?.startsWith(\"margin:\")) decls.splice(i, 1);\n }\n decls.push(`margin: ${top}px auto ${bot}px`);\n}\n\nfunction inlineStyles(orig: Element, clone: Element, win: WindowLike): void {\n const cs = win.getComputedStyle?.(orig);\n if (!cs) return;\n const decls: string[] = [];\n for (const prop of INLINE_PROPS) {\n const v = cs.getPropertyValue(prop);\n if (v && v !== \"none\" && v !== \"normal\" && v.trim() !== \"\")\n decls.push(`${prop}: ${v}`);\n }\n normaliseDesktopMargins(decls, cs);\n if (decls.length) clone.setAttribute(\"style\", decls.join(\"; \"));\n}\n\n/** Recursively inline styles + drop hidden nodes, walking orig/clone in step. */\nfunction pruneAndInline(\n orig: Element,\n clone: Element,\n win: WindowLike,\n inline: boolean,\n dropped: { count: number },\n): void {\n if (inline) inlineStyles(orig, clone, win);\n // Strip data-* (defense-in-depth; sanitize also does this later).\n for (const attr of [...clone.attributes]) {\n if (attr.name.startsWith(\"data-\")) clone.removeAttribute(attr.name);\n }\n const origKids = [...orig.children];\n const cloneKids = [...clone.children];\n const remove: Element[] = [];\n for (let i = 0; i < origKids.length; i++) {\n const o = origKids[i];\n const c = cloneKids[i];\n if (!o || !c) continue;\n if (isHidden(o, win)) {\n remove.push(c);\n dropped.count++;\n continue;\n }\n pruneAndInline(o, c, win, inline, dropped);\n }\n for (const c of remove) c.remove();\n}\n\n/** A structural signature for grouping repeated rows. */\nfunction signature(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const classes = (el.getAttribute(\"class\") ?? \"\")\n .split(/\\s+/)\n .filter(Boolean)\n .sort()\n .join(\".\");\n const kidTags = [...el.children]\n .map((c) => c.tagName.toLowerCase())\n .join(\",\");\n return `${tag}|${classes}|${kidTags}`;\n}\n\ninterface RepeatPick {\n container: Element;\n rows: Element[];\n}\n\n/** Find the container whose children are the most-repeated similar rows. */\nfunction findRepeatingRows(root: Element): RepeatPick | null {\n let best: RepeatPick | null = null;\n let bestScore = 0;\n const visit = (el: Element) => {\n const groups = new Map<string, Element[]>();\n for (const child of el.children) {\n const sig = signature(child);\n const arr = groups.get(sig) ?? [];\n arr.push(child);\n groups.set(sig, arr);\n }\n for (const rows of groups.values()) {\n if (rows.length < 2) continue;\n // Score: repetition count weighted by how much text the rows carry, so\n // a list of message bubbles beats e.g. a repeated row of icon buttons.\n const textLen = rows.reduce(\n (n, r) => n + (r.textContent ?? \"\").trim().length,\n 0,\n );\n const score = rows.length * 10 + Math.min(textLen, 400);\n if (score > bestScore) {\n bestScore = score;\n best = { container: el, rows };\n }\n }\n for (const child of el.children) visit(child);\n };\n visit(root);\n return best;\n}\n\nconst AUTHOR_RE =\n /\\b(name|author|sender|user|handle|username|display-?name)\\b/i;\nconst AVATAR_RE = /\\b(avatar|photo|userpic|profile-?pic|pic|gravatar)\\b/i;\nconst TIME_RE = /\\b(time|timestamp|date|ago|sent-?at)\\b/i;\nconst BODY_RE = /\\b(body|text|content|message|bubble|markdown|prose)\\b/i;\nconst TIME_TEXT_RE =\n /^\\s*(\\d{1,2}:\\d{2}(\\s?[ap]\\.?m\\.?)?|\\d+\\s*(m|min|h|hr|d|days?|hours?|minutes?)( ago)?|yesterday|today)\\s*$/i;\n\nfunction classOf(el: Element): string {\n return el.getAttribute(\"class\") ?? \"\";\n}\n\n/** Recursively drop `contenteditable` from a subtree (used after composer\n * detection — the attribute survives sanitize only to help detection and\n * shouldn't ship in the final slot templates). */\nfunction stripContenteditable(el: Element): void {\n if (el.hasAttribute(\"contenteditable\")) el.removeAttribute(\"contenteditable\");\n for (const child of el.children) stripContenteditable(child);\n}\n\nfunction markSlot(el: Element, slot: string, token: string): void {\n el.setAttribute(SLOT_ATTR, slot);\n el.textContent = token;\n}\n\n/** Identify and mark author/avatar/body/time inside a representative row. */\nfunction slotifyRow(row: Element): {\n html: string;\n detected: string[];\n} {\n const detected: string[] = [];\n const all = [...row.querySelectorAll(\"*\")];\n\n // Avatar: an <img> or an element whose class names it.\n let avatar =\n row.querySelector(\"img\") ??\n all.find((e) => AVATAR_RE.test(classOf(e))) ??\n null;\n if (avatar) {\n // Convert an <img> avatar into a styled container we can fill.\n if (avatar.tagName === \"IMG\") {\n const div = row.ownerDocument.createElement(\"div\");\n const cls = classOf(avatar);\n if (cls) div.setAttribute(\"class\", cls);\n const st = avatar.getAttribute(\"style\");\n if (st) div.setAttribute(\"style\", st);\n avatar.replaceWith(div);\n avatar = div;\n }\n markSlot(avatar, \"avatar\", \"{{avatar}}\");\n detected.push(\"avatar\");\n }\n\n // Author: a named element, else the first short bold-ish text run.\n let author = all.find(\n (e) =>\n e !== avatar &&\n AUTHOR_RE.test(classOf(e)) &&\n (e.textContent ?? \"\").trim(),\n );\n if (!author) {\n author = all.find((e) => {\n if (e === avatar || e.getAttribute(SLOT_ATTR)) return false;\n const t = (e.textContent ?? \"\").trim();\n const fw = (e.getAttribute(\"style\") ?? \"\").match(\n /font-weight:\\s*(\\d+|bold)/i,\n );\n const bold =\n e.tagName === \"B\" ||\n e.tagName === \"STRONG\" ||\n (fw ? fw[1] === \"bold\" || Number(fw[1]) >= 600 : false);\n return bold && t.length > 0 && t.length < 40;\n });\n }\n if (author && !author.getAttribute(SLOT_ATTR)) {\n markSlot(author, \"author\", \"{{author}}\");\n detected.push(\"author\");\n }\n\n // Time: a <time>, a named element, or an element whose text reads as a time.\n const time =\n row.querySelector(\"time\") ??\n all.find((e) => !e.getAttribute(SLOT_ATTR) && TIME_RE.test(classOf(e))) ??\n all.find(\n (e) =>\n !e.getAttribute(SLOT_ATTR) &&\n e.children.length === 0 &&\n TIME_TEXT_RE.test((e.textContent ?? \"\").trim()),\n );\n if (time && !time.getAttribute(SLOT_ATTR)) {\n markSlot(time, \"time\", \"{{time}}\");\n detected.push(\"time\");\n }\n\n // Body: the remaining element with the most text (or a named one). Never an\n // ancestor of an already-marked slot, or filling it would wipe author/time.\n const named = all.find(\n (e) =>\n !e.getAttribute(SLOT_ATTR) &&\n !e.querySelector(`[${SLOT_ATTR}]`) &&\n BODY_RE.test(classOf(e)),\n );\n let body = named ?? null;\n if (!body) {\n let bestLen = -1;\n for (const e of all) {\n if (e.getAttribute(SLOT_ATTR)) continue;\n if (e.querySelector(`[${SLOT_ATTR}]`)) continue; // don't pick an ancestor of a slot\n const t = (e.textContent ?? \"\").trim();\n if (t.length > bestLen) {\n bestLen = t.length;\n body = e;\n }\n }\n }\n if (body && !body.getAttribute(SLOT_ATTR)) {\n markSlot(body, \"body\", \"{{body}}\");\n detected.push(\"body\");\n } else if (!body) {\n // Fall back: slot the row itself.\n markSlot(row, \"body\", \"{{body}}\");\n detected.push(\"body\");\n }\n\n return { html: row.outerHTML, detected };\n}\n\nconst COMPOSER_RE =\n /\\b(composer|compose|reply|message-?box|message-?input|input-?box|textbox|editor|prompt|chat-?input)\\b/i;\nconst COMPOSER_ARIA_RE = /\\b(compose|reply|message|prompt|input|chat)\\b/i;\n\n/** Climb to the nearest container that *looks like* the composer outer block\n * (flex/grid parent, per its inlined `display:`), not the inner contenteditable.\n * Falls back to the node itself if no such ancestor exists below `root`. */\nfunction blockAncestor(node: Element, root: Element): Element {\n let cur: Element = node;\n while (cur.parentElement && cur.parentElement !== root) {\n const parent = cur.parentElement;\n const style = (parent.getAttribute(\"style\") ?? \"\").toLowerCase();\n if (/display\\s*:\\s*(flex|grid)/.test(style)) return parent;\n cur = parent;\n }\n return cur;\n}\n\n/**\n * Find the composer container in the sanitised frame tree. Priority order:\n * 1. `aria-label` matching `/compose|reply|message|prompt|input|chat/i`\n * 2. `[role=\"textbox\"]`\n * 3. ancestor of `[contenteditable]` (preserved through sanitise via the\n * sanitiser's ADD_ATTR list)\n * 4. class name matching the broadened composer regex\n * 5. structural — the next block sibling after the message list, or\n * walking up & forward\n * Returns null if none found; caller emits a draft warning.\n */\nfunction findComposer(root: Element, exclude: Element): Element | null {\n const all = [...root.querySelectorAll(\"*\")].filter(\n (e) => !exclude.contains(e) && !e.contains(exclude),\n );\n\n const byAria = all.find((e) => {\n const label = e.getAttribute(\"aria-label\");\n return label && COMPOSER_ARIA_RE.test(label);\n });\n if (byAria) return blockAncestor(byAria, root);\n\n const byRole = all.find((e) => e.getAttribute(\"role\") === \"textbox\");\n if (byRole) return blockAncestor(byRole, root);\n\n const byCe = all.find((e) => e.hasAttribute(\"contenteditable\"));\n if (byCe) return blockAncestor(byCe, root);\n\n const byClass = all.find((e) => COMPOSER_RE.test(classOf(e)));\n if (byClass) return byClass;\n\n // Structural fallback: the composer typically sits as a block after the\n // message list. Walk forward siblings, then walk up & forward again.\n let cursor: Element | null = exclude;\n while (cursor && cursor !== root) {\n let sib: Element | null = cursor.nextElementSibling;\n while (sib) {\n const style = (sib.getAttribute(\"style\") ?? \"\").toLowerCase();\n const isBlock = !/display\\s*:\\s*inline/.test(style);\n const hasButtonish = sib.querySelector(\n \"[role='button'], [contenteditable]\",\n );\n const txt = (sib.textContent ?? \"\").trim();\n if (isBlock && (hasButtonish || txt.length === 0 || txt.length < 200)) {\n return sib;\n }\n sib = sib.nextElementSibling;\n }\n cursor = cursor.parentElement;\n }\n\n return null;\n}\n\nfunction emptyReport(): SlotReport {\n return { found: false, detected: [], confidence: 0 };\n}\n\nexport function distill(root: Element, opts: DistillOptions = {}): SkinDraft {\n const win = getWindow(opts.window);\n const doc = win.document;\n const warnings: string[] = [];\n\n // 1. Clone, inline styles, drop hidden + data-*.\n const clone = root.cloneNode(true) as Element;\n const dropped = { count: 0 };\n pruneAndInline(root, clone, win, opts.inlineComputedStyles ?? false, dropped);\n if (dropped.count > 0)\n warnings.push(\n `Dropped ${dropped.count} hidden element(s) from the capture.`,\n );\n\n // 2. Sanitize (allowlist) and re-parse.\n const safe = sanitizeHtml(clone.outerHTML, { window: win });\n const host = doc.createElement(\"div\");\n host.innerHTML = safe;\n const frameRoot = (host.firstElementChild as Element | null) ?? host;\n\n // 3. Find the repeating message row.\n const pick = findRepeatingRows(frameRoot);\n const detection = {\n frame: emptyReport(),\n message: emptyReport(),\n composer: emptyReport(),\n typing: emptyReport(),\n };\n\n let messageHtml: string | undefined;\n let frameHtml: string | undefined;\n let composerHtml: string | undefined;\n\n if (pick) {\n // 4. Slot-ify a representative row.\n const sample = (pick.rows[0] as Element).cloneNode(true) as Element;\n const slotted = slotifyRow(sample);\n messageHtml = slotted.html;\n detection.message = {\n found: true,\n detected: slotted.detected,\n confidence: Math.min(1, slotted.detected.length / 4),\n };\n\n // 5. Carve the frame: replace the message list with a {{messages}} slot.\n const slot = doc.createElement(\"div\");\n slot.setAttribute(SLOT_ATTR, \"messages\");\n slot.textContent = \"{{messages}}\";\n const listCls = classOf(pick.container);\n if (listCls) slot.setAttribute(\"class\", `${listCls} tc-messages`);\n const containerClone = pick.container.cloneNode(false) as Element;\n // Preserve the list container's own styling, but it now holds only the slot.\n if (containerClone.getAttribute(\"style\"))\n slot.setAttribute(\n \"style\",\n containerClone.getAttribute(\"style\") as string,\n );\n // Build the frame by replacing the container subtree with the slot.\n const frameClone = frameRoot.cloneNode(true) as Element;\n const path = pathTo(frameRoot, pick.container);\n const targetInClone = path ? nodeAtPath(frameClone, path) : null;\n if (targetInClone && targetInClone.parentElement) {\n targetInClone.replaceWith(slot);\n frameHtml = frameClone.outerHTML;\n detection.frame = { found: true, detected: [\"messages\"], confidence: 1 };\n } else {\n // The list *is* the root; frame is just the slot.\n frameHtml = slot.outerHTML;\n detection.frame = {\n found: true,\n detected: [\"messages\"],\n confidence: 0.5,\n };\n warnings.push(\n \"Message list is the captured root; no surrounding chrome was found.\",\n );\n }\n\n // 6. Composer (outside the message list).\n const composer = findComposer(frameRoot, pick.container);\n if (composer) {\n const c = composer.cloneNode(true) as Element;\n c.setAttribute(SLOT_ATTR, \"composer\");\n stripContenteditable(c);\n c.textContent = \"{{composer}}\";\n composerHtml = c.outerHTML;\n detection.composer = {\n found: true,\n detected: [\"composer\"],\n confidence: 1,\n };\n } else {\n warnings.push(\n \"No composer detected — add one by hand if the skin needs it.\",\n );\n }\n // contenteditable was only kept through sanitize to help composer\n // detection; strip it from every output template so it doesn't ship.\n if (frameHtml)\n frameHtml = frameHtml.replace(/\\s+contenteditable=\"[^\"]*\"/g, \"\");\n if (messageHtml)\n messageHtml = messageHtml.replace(/\\s+contenteditable=\"[^\"]*\"/g, \"\");\n } else {\n warnings.push(\n \"No repeating message row found — capture a tighter subtree around the thread.\",\n );\n }\n\n // 7. Tokens.\n const tokens = extractTokens(frameRoot);\n\n // 8. Canvas suggestion from the captured box (best effort).\n let canvas: { width: number; height: number } | undefined;\n const rect = (\n root as Element & { getBoundingClientRect?: () => DOMRect }\n ).getBoundingClientRect?.();\n if (rect && rect.width > 0 && rect.height > 0) {\n canvas = { width: Math.round(rect.width), height: Math.round(rect.height) };\n }\n\n return {\n version: 1,\n meta: {\n name: opts.name ?? \"Captured skin\",\n ...(opts.sourceUrl ? { sourceUrl: opts.sourceUrl } : {}),\n ...(opts.theme ? { theme: opts.theme } : {}),\n ...(canvas ? { canvas } : {}),\n ...(opts.capturedAt ? { capturedAt: opts.capturedAt } : {}),\n },\n slots: {\n ...(frameHtml ? { frame: frameHtml } : {}),\n ...(messageHtml ? { message: messageHtml } : {}),\n ...(composerHtml ? { composer: composerHtml } : {}),\n },\n css: opts.css ?? \"\",\n tokens,\n detection,\n warnings,\n ...(opts.cssSkipped?.length ? { cssSkipped: opts.cssSkipped } : {}),\n };\n}\n\n/** Index path from `root` down to `target` (list of child indices). */\nfunction pathTo(root: Element, target: Element): number[] | null {\n if (root === target) return [];\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i];\n if (!child) continue;\n const sub = pathTo(child, target);\n if (sub) return [i, ...sub];\n }\n return null;\n}\n\nfunction nodeAtPath(root: Element, path: number[]): Element | null {\n let node: Element | null = root;\n for (const i of path) {\n if (!node) return null;\n node = node.children[i] ?? null;\n }\n return node;\n}\n","/**\n * Capture the CSS rules that *actually apply* to a captured subtree.\n *\n * Why this exists: modern apps (Tailwind, CSS modules, styled-components)\n * drive layout from utility classes. The captured subtree's `class`\n * attributes survive the trip into a skin shadow root, but the\n * **stylesheet defining what those classes mean** does not. Without that\n * stylesheet, `max-w-180` / `flex-grow` / `mx-auto` are no-ops, and the\n * captured page collapses to a vertical column.\n *\n * The fix: walk `document.styleSheets`, keep every rule whose selector\n * matches at least one element in the captured subtree (or in an\n * `@media`/`@supports`/`@container` wrapper that does), and emit that\n * subset as a CSS string for the skin's shadow root.\n *\n * Honest limitations:\n * - Cross-origin stylesheets throw on `cssRules` access; we record them\n * in the returned `skipped` list and continue.\n * - Exotic selectors (`:has(...)` polyfills, custom pseudo) can throw\n * in `querySelector` — we swallow those and treat the rule as\n * non-matching.\n * - We cap output size (default 256 KB). For pages with massive\n * stylesheets the cap kicks in; the caller emits a warning.\n * - We don't try to scope rules to the captured subtree — they are\n * injected into a shadow root, so leakage to the host page is\n * already prevented by the boundary.\n */\n\ninterface StyleSheetLike {\n href?: string | null;\n cssRules?: CSSRuleList;\n ownerNode?: Node | null;\n}\n\ninterface DocumentLike {\n styleSheets: { [Symbol.iterator]: () => Iterator<StyleSheetLike> } & {\n length: number;\n [k: number]: StyleSheetLike;\n };\n}\n\nexport interface CaptureCssOptions {\n /** Bytes-budget for the emitted CSS. Default 256 KB. */\n maxBytes?: number;\n}\n\nexport interface CaptureCssResult {\n /** Concatenated CSS rules that match the captured subtree. */\n css: string;\n /** Stylesheets we couldn't read (typically CORS-blocked). */\n skipped: string[];\n /** True when we hit the byte cap and stopped collecting. */\n truncated: boolean;\n}\n\n/**\n * Test whether a CSS selector matches anything in the captured subtree.\n * Wraps `querySelector` so exotic selectors (`:has()` polyfills, vendor\n * pseudos) that throw don't abort the whole walk.\n */\nfunction subtreeMatches(root: Element, selector: string): boolean {\n // Some Tailwind/utility selectors include `\\:` escapes and arbitrary\n // value brackets (e.g. `.max-w-\\[480px\\]`) that querySelector handles\n // fine — but `:host`, `:root`, `&` etc. don't and would throw.\n // Cheap pre-filter: skip selectors that obviously target the document\n // root or page-wide chrome.\n if (selector === \":root\" || selector === \"html\" || selector === \"body\")\n return false;\n try {\n return root.querySelector(selector) != null;\n } catch {\n return false;\n }\n}\n\n/**\n * Walk a rule list, collecting matching rules (and their containing\n * group rules) into `out`. Recursive — handles nested `@media`,\n * `@supports`, `@layer`, `@container`.\n */\nfunction walkRules(\n rules: CSSRuleList,\n root: Element,\n out: string[],\n size: { bytes: number; cap: number },\n): void {\n for (let i = 0; i < rules.length; i++) {\n if (size.bytes >= size.cap) return;\n const rule = rules[i]!;\n // Style rule (most common).\n if (rule.type === 1 /* STYLE_RULE */) {\n const r = rule as CSSStyleRule;\n const sel = r.selectorText;\n if (sel && sel.split(\",\").some((s) => subtreeMatches(root, s.trim()))) {\n const text = r.cssText;\n out.push(text);\n size.bytes += text.length + 1;\n }\n continue;\n }\n // Group rules (media, supports, layer, container) — recurse, and if\n // any inner rule matched, wrap the inner output in the group prelude.\n const grouping = rule as unknown as {\n cssRules?: CSSRuleList;\n conditionText?: string;\n name?: string;\n };\n if (grouping.cssRules) {\n const inner: string[] = [];\n const innerSize = { bytes: 0, cap: size.cap - size.bytes };\n walkRules(grouping.cssRules, root, inner, innerSize);\n if (inner.length > 0) {\n const prelude = preludeFor(rule);\n const wrapped = `${prelude} { ${inner.join(\" \")} }`;\n out.push(wrapped);\n size.bytes += wrapped.length + 1;\n }\n continue;\n }\n // Other rules (font-face, keyframes) — keep them, they're commonly\n // referenced by matching rules and don't bloat much.\n if (\n rule.type === 5 /* FONT_FACE_RULE */ ||\n rule.type === 7 /* KEYFRAMES_RULE */\n ) {\n const text = rule.cssText;\n out.push(text);\n size.bytes += text.length + 1;\n }\n }\n}\n\nfunction preludeFor(rule: CSSRule): string {\n // We don't want to use `cssText` because that includes the body — and\n // we're rebuilding the body from filtered inner rules. Build the prelude\n // by hand for the common @-rules.\n const r = rule as unknown as {\n type: number;\n media?: { mediaText?: string };\n conditionText?: string;\n name?: string;\n };\n switch (r.type) {\n case 4 /* MEDIA_RULE */:\n return `@media ${r.media?.mediaText ?? \"all\"}`;\n case 12 /* SUPPORTS_RULE */:\n return `@supports ${r.conditionText ?? \"all\"}`;\n case 13 /* CONTAINER_RULE — not in lib.dom but emitted as such */:\n return `@container ${r.conditionText ?? \"\"}`;\n case 15 /* LAYER_BLOCK_RULE */:\n return `@layer ${r.name ?? \"\"}`;\n default:\n // Best-effort fallback: take everything before the first `{`.\n return rule.cssText.replace(/\\{[\\s\\S]*$/, \"\").trim();\n }\n}\n\n/**\n * Capture matched CSS for `root` from `doc`'s styleSheets. Safe to call in\n * any browser context (the extension picker runs this from the content\n * script before sending the draft to the background worker).\n */\nexport function captureMatchedCss(\n root: Element,\n doc: DocumentLike,\n opts: CaptureCssOptions = {},\n): CaptureCssResult {\n const cap = opts.maxBytes ?? 256 * 1024;\n const out: string[] = [];\n const size = { bytes: 0, cap };\n const skipped: string[] = [];\n const sheets = doc.styleSheets;\n for (let i = 0; i < sheets.length; i++) {\n if (size.bytes >= cap) break;\n const sheet = sheets[i]!;\n let rules: CSSRuleList | undefined;\n try {\n rules = sheet.cssRules;\n } catch {\n skipped.push(sheet.href ?? \"(inline)\");\n continue;\n }\n if (!rules) continue;\n walkRules(rules, root, out, size);\n }\n return {\n css: out.join(\"\\n\"),\n skipped,\n truncated: size.bytes >= cap,\n };\n}\n","import type { Capabilities } from \"@typecaast/core\";\nimport {\n slotSkinFromDraft,\n type Skin,\n type SlotSkinDraft,\n} from \"@typecaast/skin-kit\";\nimport { sanitizeHtml } from \"./sanitize.js\";\nimport type { SkinDraft } from \"./draft.js\";\n\n/**\n * `TemplateSkinAdapter` — make a captured `SkinDraft` satisfy the `Skin`\n * contract by filling its slots at render time (PLAN §10). Template skins are\n * **untrusted regardless of source**, so the adapter (a) re-sanitizes every\n * template string and (b) delegates rendering to `slotSkinFromDraft` in\n * `@typecaast/skin-kit`, which mounts the sanitized HTML in an open shadow\n * root. Slot text is written via `textContent` (never `innerHTML`), so\n * authored content can't inject markup either.\n *\n * This is a faithful *playback* of the capture, not the final hand-tuned skin —\n * `typecaast scaffold-skin` turns the same draft into an editable React skin.\n */\n\nexport interface TemplateSkinOptions {\n /** Override the skin id (defaults to a slug of the draft name). */\n id?: string;\n capabilities?: Capabilities;\n}\n\nfunction slug(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"captured\"\n );\n}\n\nconst DEFAULT_CAPS: Capabilities = {\n events: {},\n content: {},\n reactions: false,\n threads: false,\n readReceipts: false,\n};\n\n/**\n * Build a runtime `Skin` from a captured `SkinDraft`, re-sanitising every\n * slot template up front. The actual rendering (shadow root, slot fill,\n * responsive frame wrapper) is delegated to\n * `slotSkinFromDraft` in `@typecaast/skin-kit`.\n */\nexport function templateSkinFromDraft(\n draft: SkinDraft,\n opts: TemplateSkinOptions = {},\n): Skin {\n const safeDraft: SlotSkinDraft = {\n meta: {\n name: draft.meta.name,\n theme: draft.meta.theme,\n canvas: draft.meta.canvas,\n capturedAt: (\n draft.meta as { capturedAt?: SlotSkinDraft[\"meta\"][\"capturedAt\"] }\n ).capturedAt,\n },\n slots: {\n frame: draft.slots.frame ? sanitizeHtml(draft.slots.frame) : undefined,\n message: draft.slots.message\n ? sanitizeHtml(draft.slots.message)\n : undefined,\n composer: draft.slots.composer\n ? sanitizeHtml(draft.slots.composer)\n : undefined,\n typing: draft.slots.typing ? sanitizeHtml(draft.slots.typing) : undefined,\n },\n css: draft.css ?? \"\",\n tokens: { colors: draft.tokens.colors ?? {} },\n darkTokens: draft.darkTokens\n ? { colors: draft.darkTokens.colors ?? {} }\n : undefined,\n };\n\n return slotSkinFromDraft(safeDraft, {\n id: opts.id ?? slug(draft.meta.name),\n capabilities: opts.capabilities ?? DEFAULT_CAPS,\n });\n}\n","import type { SkinDraft } from \"./draft.js\";\n\n/**\n * Light/dark double-capture (PLAN §10, M5.7). Capture the *same* UI twice — once\n * per theme — then merge: keep the light capture's slot templates (structure is\n * identical) and attach the dark capture's tokens as `darkTokens`, so the\n * resulting skin supports both themes and switches CSS vars at render time.\n *\n * Structure is taken from `light`; only the dark *colors* differ between a\n * well-built light/dark UI, which is exactly what we want to vary.\n */\nexport function mergeThemeDrafts(light: SkinDraft, dark: SkinDraft): SkinDraft {\n return {\n ...light,\n meta: { ...light.meta, theme: undefined },\n tokens: light.tokens,\n darkTokens: dark.tokens,\n warnings: [\n ...light.warnings,\n ...(dark.detection.message.found\n ? []\n : [\"Dark capture found no message row; reusing light structure.\"]),\n ],\n };\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SkinDraft } from './draft.cjs';
|
|
2
2
|
export { SLOT_TOKENS, SlotName, SlotReport, detectionScore, skinDraftSchema } from './draft.cjs';
|
|
3
|
-
export { D as DistillOptions, d as distill } from './distill-
|
|
3
|
+
export { D as DistillOptions, d as distill } from './distill-CVvHwBKY.cjs';
|
|
4
4
|
import { Capabilities } from '@typecaast/core';
|
|
5
5
|
import { Skin } from '@typecaast/skin-kit';
|
|
6
6
|
import 'zod';
|
|
@@ -35,14 +35,73 @@ interface SanitizeOptions {
|
|
|
35
35
|
*/
|
|
36
36
|
declare function sanitizeHtml(html: string, opts?: SanitizeOptions): string;
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Capture the CSS rules that *actually apply* to a captured subtree.
|
|
40
|
+
*
|
|
41
|
+
* Why this exists: modern apps (Tailwind, CSS modules, styled-components)
|
|
42
|
+
* drive layout from utility classes. The captured subtree's `class`
|
|
43
|
+
* attributes survive the trip into a skin shadow root, but the
|
|
44
|
+
* **stylesheet defining what those classes mean** does not. Without that
|
|
45
|
+
* stylesheet, `max-w-180` / `flex-grow` / `mx-auto` are no-ops, and the
|
|
46
|
+
* captured page collapses to a vertical column.
|
|
47
|
+
*
|
|
48
|
+
* The fix: walk `document.styleSheets`, keep every rule whose selector
|
|
49
|
+
* matches at least one element in the captured subtree (or in an
|
|
50
|
+
* `@media`/`@supports`/`@container` wrapper that does), and emit that
|
|
51
|
+
* subset as a CSS string for the skin's shadow root.
|
|
52
|
+
*
|
|
53
|
+
* Honest limitations:
|
|
54
|
+
* - Cross-origin stylesheets throw on `cssRules` access; we record them
|
|
55
|
+
* in the returned `skipped` list and continue.
|
|
56
|
+
* - Exotic selectors (`:has(...)` polyfills, custom pseudo) can throw
|
|
57
|
+
* in `querySelector` — we swallow those and treat the rule as
|
|
58
|
+
* non-matching.
|
|
59
|
+
* - We cap output size (default 256 KB). For pages with massive
|
|
60
|
+
* stylesheets the cap kicks in; the caller emits a warning.
|
|
61
|
+
* - We don't try to scope rules to the captured subtree — they are
|
|
62
|
+
* injected into a shadow root, so leakage to the host page is
|
|
63
|
+
* already prevented by the boundary.
|
|
64
|
+
*/
|
|
65
|
+
interface StyleSheetLike {
|
|
66
|
+
href?: string | null;
|
|
67
|
+
cssRules?: CSSRuleList;
|
|
68
|
+
ownerNode?: Node | null;
|
|
69
|
+
}
|
|
70
|
+
interface DocumentLike {
|
|
71
|
+
styleSheets: {
|
|
72
|
+
[Symbol.iterator]: () => Iterator<StyleSheetLike>;
|
|
73
|
+
} & {
|
|
74
|
+
length: number;
|
|
75
|
+
[k: number]: StyleSheetLike;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
interface CaptureCssOptions {
|
|
79
|
+
/** Bytes-budget for the emitted CSS. Default 256 KB. */
|
|
80
|
+
maxBytes?: number;
|
|
81
|
+
}
|
|
82
|
+
interface CaptureCssResult {
|
|
83
|
+
/** Concatenated CSS rules that match the captured subtree. */
|
|
84
|
+
css: string;
|
|
85
|
+
/** Stylesheets we couldn't read (typically CORS-blocked). */
|
|
86
|
+
skipped: string[];
|
|
87
|
+
/** True when we hit the byte cap and stopped collecting. */
|
|
88
|
+
truncated: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Capture matched CSS for `root` from `doc`'s styleSheets. Safe to call in
|
|
92
|
+
* any browser context (the extension picker runs this from the content
|
|
93
|
+
* script before sending the draft to the background worker).
|
|
94
|
+
*/
|
|
95
|
+
declare function captureMatchedCss(root: Element, doc: DocumentLike, opts?: CaptureCssOptions): CaptureCssResult;
|
|
96
|
+
|
|
38
97
|
/**
|
|
39
98
|
* `TemplateSkinAdapter` — make a captured `SkinDraft` satisfy the `Skin`
|
|
40
99
|
* contract by filling its slots at render time (PLAN §10). Template skins are
|
|
41
100
|
* **untrusted regardless of source**, so the adapter (a) re-sanitizes every
|
|
42
|
-
* template string and (b)
|
|
43
|
-
*
|
|
44
|
-
* written via `textContent` (never `innerHTML`), so
|
|
45
|
-
* inject markup either.
|
|
101
|
+
* template string and (b) delegates rendering to `slotSkinFromDraft` in
|
|
102
|
+
* `@typecaast/skin-kit`, which mounts the sanitized HTML in an open shadow
|
|
103
|
+
* root. Slot text is written via `textContent` (never `innerHTML`), so
|
|
104
|
+
* authored content can't inject markup either.
|
|
46
105
|
*
|
|
47
106
|
* This is a faithful *playback* of the capture, not the final hand-tuned skin —
|
|
48
107
|
* `typecaast scaffold-skin` turns the same draft into an editable React skin.
|
|
@@ -52,6 +111,12 @@ interface TemplateSkinOptions {
|
|
|
52
111
|
id?: string;
|
|
53
112
|
capabilities?: Capabilities;
|
|
54
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Build a runtime `Skin` from a captured `SkinDraft`, re-sanitising every
|
|
116
|
+
* slot template up front. The actual rendering (shadow root, slot fill,
|
|
117
|
+
* responsive frame wrapper) is delegated to
|
|
118
|
+
* `slotSkinFromDraft` in `@typecaast/skin-kit`.
|
|
119
|
+
*/
|
|
55
120
|
declare function templateSkinFromDraft(draft: SkinDraft, opts?: TemplateSkinOptions): Skin;
|
|
56
121
|
|
|
57
122
|
/**
|
|
@@ -65,4 +130,4 @@ declare function templateSkinFromDraft(draft: SkinDraft, opts?: TemplateSkinOpti
|
|
|
65
130
|
*/
|
|
66
131
|
declare function mergeThemeDrafts(light: SkinDraft, dark: SkinDraft): SkinDraft;
|
|
67
132
|
|
|
68
|
-
export { type SanitizeOptions, SkinDraft, type TemplateSkinOptions, mergeThemeDrafts, sanitizeHtml, scrubCss, templateSkinFromDraft };
|
|
133
|
+
export { type CaptureCssOptions, type CaptureCssResult, type SanitizeOptions, SkinDraft, type TemplateSkinOptions, captureMatchedCss, mergeThemeDrafts, sanitizeHtml, scrubCss, templateSkinFromDraft };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SkinDraft } from './draft.js';
|
|
2
2
|
export { SLOT_TOKENS, SlotName, SlotReport, detectionScore, skinDraftSchema } from './draft.js';
|
|
3
|
-
export { D as DistillOptions, d as distill } from './distill-
|
|
3
|
+
export { D as DistillOptions, d as distill } from './distill-Cs7bOU8G.js';
|
|
4
4
|
import { Capabilities } from '@typecaast/core';
|
|
5
5
|
import { Skin } from '@typecaast/skin-kit';
|
|
6
6
|
import 'zod';
|
|
@@ -35,14 +35,73 @@ interface SanitizeOptions {
|
|
|
35
35
|
*/
|
|
36
36
|
declare function sanitizeHtml(html: string, opts?: SanitizeOptions): string;
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Capture the CSS rules that *actually apply* to a captured subtree.
|
|
40
|
+
*
|
|
41
|
+
* Why this exists: modern apps (Tailwind, CSS modules, styled-components)
|
|
42
|
+
* drive layout from utility classes. The captured subtree's `class`
|
|
43
|
+
* attributes survive the trip into a skin shadow root, but the
|
|
44
|
+
* **stylesheet defining what those classes mean** does not. Without that
|
|
45
|
+
* stylesheet, `max-w-180` / `flex-grow` / `mx-auto` are no-ops, and the
|
|
46
|
+
* captured page collapses to a vertical column.
|
|
47
|
+
*
|
|
48
|
+
* The fix: walk `document.styleSheets`, keep every rule whose selector
|
|
49
|
+
* matches at least one element in the captured subtree (or in an
|
|
50
|
+
* `@media`/`@supports`/`@container` wrapper that does), and emit that
|
|
51
|
+
* subset as a CSS string for the skin's shadow root.
|
|
52
|
+
*
|
|
53
|
+
* Honest limitations:
|
|
54
|
+
* - Cross-origin stylesheets throw on `cssRules` access; we record them
|
|
55
|
+
* in the returned `skipped` list and continue.
|
|
56
|
+
* - Exotic selectors (`:has(...)` polyfills, custom pseudo) can throw
|
|
57
|
+
* in `querySelector` — we swallow those and treat the rule as
|
|
58
|
+
* non-matching.
|
|
59
|
+
* - We cap output size (default 256 KB). For pages with massive
|
|
60
|
+
* stylesheets the cap kicks in; the caller emits a warning.
|
|
61
|
+
* - We don't try to scope rules to the captured subtree — they are
|
|
62
|
+
* injected into a shadow root, so leakage to the host page is
|
|
63
|
+
* already prevented by the boundary.
|
|
64
|
+
*/
|
|
65
|
+
interface StyleSheetLike {
|
|
66
|
+
href?: string | null;
|
|
67
|
+
cssRules?: CSSRuleList;
|
|
68
|
+
ownerNode?: Node | null;
|
|
69
|
+
}
|
|
70
|
+
interface DocumentLike {
|
|
71
|
+
styleSheets: {
|
|
72
|
+
[Symbol.iterator]: () => Iterator<StyleSheetLike>;
|
|
73
|
+
} & {
|
|
74
|
+
length: number;
|
|
75
|
+
[k: number]: StyleSheetLike;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
interface CaptureCssOptions {
|
|
79
|
+
/** Bytes-budget for the emitted CSS. Default 256 KB. */
|
|
80
|
+
maxBytes?: number;
|
|
81
|
+
}
|
|
82
|
+
interface CaptureCssResult {
|
|
83
|
+
/** Concatenated CSS rules that match the captured subtree. */
|
|
84
|
+
css: string;
|
|
85
|
+
/** Stylesheets we couldn't read (typically CORS-blocked). */
|
|
86
|
+
skipped: string[];
|
|
87
|
+
/** True when we hit the byte cap and stopped collecting. */
|
|
88
|
+
truncated: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Capture matched CSS for `root` from `doc`'s styleSheets. Safe to call in
|
|
92
|
+
* any browser context (the extension picker runs this from the content
|
|
93
|
+
* script before sending the draft to the background worker).
|
|
94
|
+
*/
|
|
95
|
+
declare function captureMatchedCss(root: Element, doc: DocumentLike, opts?: CaptureCssOptions): CaptureCssResult;
|
|
96
|
+
|
|
38
97
|
/**
|
|
39
98
|
* `TemplateSkinAdapter` — make a captured `SkinDraft` satisfy the `Skin`
|
|
40
99
|
* contract by filling its slots at render time (PLAN §10). Template skins are
|
|
41
100
|
* **untrusted regardless of source**, so the adapter (a) re-sanitizes every
|
|
42
|
-
* template string and (b)
|
|
43
|
-
*
|
|
44
|
-
* written via `textContent` (never `innerHTML`), so
|
|
45
|
-
* inject markup either.
|
|
101
|
+
* template string and (b) delegates rendering to `slotSkinFromDraft` in
|
|
102
|
+
* `@typecaast/skin-kit`, which mounts the sanitized HTML in an open shadow
|
|
103
|
+
* root. Slot text is written via `textContent` (never `innerHTML`), so
|
|
104
|
+
* authored content can't inject markup either.
|
|
46
105
|
*
|
|
47
106
|
* This is a faithful *playback* of the capture, not the final hand-tuned skin —
|
|
48
107
|
* `typecaast scaffold-skin` turns the same draft into an editable React skin.
|
|
@@ -52,6 +111,12 @@ interface TemplateSkinOptions {
|
|
|
52
111
|
id?: string;
|
|
53
112
|
capabilities?: Capabilities;
|
|
54
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Build a runtime `Skin` from a captured `SkinDraft`, re-sanitising every
|
|
116
|
+
* slot template up front. The actual rendering (shadow root, slot fill,
|
|
117
|
+
* responsive frame wrapper) is delegated to
|
|
118
|
+
* `slotSkinFromDraft` in `@typecaast/skin-kit`.
|
|
119
|
+
*/
|
|
55
120
|
declare function templateSkinFromDraft(draft: SkinDraft, opts?: TemplateSkinOptions): Skin;
|
|
56
121
|
|
|
57
122
|
/**
|
|
@@ -65,4 +130,4 @@ declare function templateSkinFromDraft(draft: SkinDraft, opts?: TemplateSkinOpti
|
|
|
65
130
|
*/
|
|
66
131
|
declare function mergeThemeDrafts(light: SkinDraft, dark: SkinDraft): SkinDraft;
|
|
67
132
|
|
|
68
|
-
export { type SanitizeOptions, SkinDraft, type TemplateSkinOptions, mergeThemeDrafts, sanitizeHtml, scrubCss, templateSkinFromDraft };
|
|
133
|
+
export { type CaptureCssOptions, type CaptureCssResult, type SanitizeOptions, SkinDraft, type TemplateSkinOptions, captureMatchedCss, mergeThemeDrafts, sanitizeHtml, scrubCss, templateSkinFromDraft };
|