@artooi/ag-ui-web-component 0.25.2 → 0.26.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/CHANGELOG.md +42 -1
- package/README.md +69 -0
- package/dist/ag-ui-web-component.bundle.js +73 -29
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +19 -0
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/agui_client.d.ts +12 -1
- package/dist/core/agui_client.d.ts.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +712 -165
- package/dist/index.js.map +4 -4
- package/dist/tools/client_tool_registry.d.ts +24 -1
- package/dist/tools/client_tool_registry.d.ts.map +1 -1
- package/dist/ui/chart_block.d.ts +39 -0
- package/dist/ui/chart_block.d.ts.map +1 -0
- package/dist/ui/chart_spec_from.d.ts +12 -0
- package/dist/ui/chart_spec_from.d.ts.map +1 -0
- package/dist/ui/chart_tool.d.ts +15 -0
- package/dist/ui/chart_tool.d.ts.map +1 -0
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +11 -0
- package/src/core/ag_ui_chat.ts +145 -3
- package/src/core/agui_client.ts +51 -3
- package/src/index.ts +8 -0
- package/src/tools/client_tool_registry.ts +24 -1
- package/src/ui/chart_block.ts +349 -0
- package/src/ui/chart_spec_from.ts +106 -0
- package/src/ui/chart_tool.ts +64 -0
- package/src/ui/styles.ts +44 -0
- package/src/version.ts +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/constants.ts", "../src/skills/fill_template.ts", "../src/skills/parse_skills.ts", "../src/tools/client_tool_registry.ts", "../src/tools/is_destructive.ts", "../src/tools/is_navigates.ts", "../src/dom/native_setter.ts", "../src/dom/animations.ts", "../src/tools/page_action_tools.ts", "../src/tools/page_map.ts", "../src/tools/page_state.ts", "../src/tools/parse_tool_catalog.ts", "../src/tools/route_map.ts", "../src/ui/ui_strings.ts", "../src/ui/approval_card.ts", "../src/ui/attach_copy_buttons.ts", "../src/ui/attachment_chips.ts", "../src/ui/attachment_tray.ts", "../src/ui/relative_time.ts", "../src/ui/checkpoint_menu.ts", "../src/ui/confirmation_card.ts", "../src/ui/prettify_tool_name.ts", "../src/ui/question_card.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/utils.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/tags.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/attrs.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/regexp.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/purify.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/defaults.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/rules.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/helpers.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Tokenizer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Lexer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Renderer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/TextRenderer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Parser.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Hooks.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Instance.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/marked.ts", "../src/ui/render_markdown.ts", "../src/ui/resize_handle.ts", "../src/ui/reveal_words.ts", "../src/ui/run_notice.ts", "../src/ui/skills_menu.ts", "../src/ui/styles.ts", "../src/ui/thoughts_block.ts", "../src/ui/thread_drawer.ts", "../src/ui/tool_call_card.ts", "../src/ui/voice_input.ts", "../src/core/agui_client.ts", "../src/core/attachment.ts", "../src/core/conversation_store.ts", "../src/core/create_http_agent.ts", "../src/core/utils.ts", "../src/core/remote_conversation_store.ts", "../src/core/run_index.ts", "../src/core/transcribe_audio.ts", "../src/core/upload_attachment.ts", "../src/core/ag_ui_chat.ts", "../src/core/define_ag_ui_chat.ts", "../src/dom/dom_driver.ts", "../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// The package's single home for enums and constant-like values, and per\n// CLAUDE.md the only file allowed to export multiple symbols.\n\n/** The Custom Element tag name registered by {@link defineAgUiChat}. */\nexport const ELEMENT_TAG = \"ag-ui-chat\";\n\n/** User submitted a message. `detail` is {@link SubmitDetail}. */\nexport const SUBMIT_EVENT = \"ag-ui-submit\";\n\n/**\n * Collapsed state changed, via the built-in toggle or `setCollapsed`.\n * `detail` is {@link ToggleDetail}.\n */\nexport const TOGGLE_EVENT = \"ag-ui-toggle\";\n\n/**\n * The count of answers that arrived while collapsed changed. `detail` is\n * {@link UnreadDetail}. The built-in launcher badge renders exactly this; a\n * host driving its own chrome sets `data-unread-badge=\"false\"` and listens.\n */\nexport const UNREAD_EVENT = \"ag-ui-unread\";\n\n/**\n * AG-UI shared state changed \u2014 a streamed `STATE_SNAPSHOT` / `STATE_DELTA`, or\n * a host assignment to `sharedState`. `detail` is {@link StateDetail}.\n *\n * The protocol's own state channel, distinct from `registerPageState`, which\n * exposes host state to the agent as ordinary tools.\n */\nexport const STATE_EVENT = \"ag-ui-state\";\n\n/**\n * The attachment tray changed \u2014 a file queued, an upload finishing or failing,\n * a chip removed, the tray cleared after a send. `detail` is\n * {@link AttachmentsDetail}, carrying the refs that finished uploading and how\n * many are still in flight. A host driving its own composer uses this to know\n * whether a send would leave files behind.\n */\nexport const ATTACHMENT_EVENT = \"ag-ui-attachments\";\n\n/**\n * An interaction has finished, whatever ended it. `detail` is\n * {@link RunFinishedDetail}, listing the tools that ran and which side ran them.\n *\n * For hosts that render data the agent can change. A server-side tool writes\n * without the page's knowledge \u2014 nothing else the element dispatches implies\n * \"something may have moved underneath you\", so a page showing that data has no\n * reason to refetch and quietly goes stale. Shared state\n * ({@link STATE_EVENT}) is the richer channel, but it needs the agent to emit\n * state; this needs nothing of the agent at all.\n *\n * Fires once per interaction rather than once per tool round, on completion,\n * error and cancellation alike, since a partial write is still a write.\n */\nexport const RUN_FINISHED_EVENT = \"ag-ui-run-finished\";\n\n/** Roles a chat message can take. */\nexport const MESSAGE_ROLE = {\n USER: \"user\",\n ASSISTANT: \"assistant\",\n} as const;\n\n/**\n * Schema-root key marking a tool destructive: the element gates its execution\n * behind the confirmation card unless `autoConfirm` is set. All four `x-*` keys\n * below mirror the `django-ag-ui` server side.\n */\nexport const X_DESTRUCTIVE_KEY = \"x-destructive\";\n\n/**\n * Schema-root key holding a confirmation prompt (e.g. `\"Activate this\n * project?\"`), shown instead of the generic `Run \"<tool>\"?`.\n */\nexport const X_CONFIRM_KEY = \"x-confirm\";\n\n/**\n * Schema-root key holding a short label for a tool (e.g. `\"Query orders\"` for\n * `query_model`), shown on the card instead of the raw tool name.\n */\nexport const X_SUMMARY_KEY = \"x-summary\";\n\n/**\n * Schema-root key marking a tool as navigating \u2014 its handler triggers a full\n * page reload. The element checkpoints the call before the reload and resumes\n * the run loop once the next page mounts.\n */\nexport const X_NAVIGATES_KEY = \"x-navigates\";\n\n/**\n * The built-in tool that re-reads the current page, registered only when a\n * page-map provider is set. Named here because the stale-page guard must exempt\n * it: refusing the one call that would refresh the agent's view deadlocks.\n */\nexport const READ_PAGE_TOOL = \"read_page\";\n\n/** Upper bound on frontend tool-call \u2192 re-run rounds within one send. */\nexport const MAX_TOOL_ROUNDS = 10;\n\n/**\n * Lifecycle status of a rendered tool-call card. A card opens as `PENDING`\n * while the call runs, then settles to `DONE`, `ERROR`, or `DECLINED`.\n *\n * `DEFERRED` is the one non-terminal state that is not \"running\": a server-side\n * tool a `ToolGuard` gated never executed, the run finished on an interrupt, and\n * the call is waiting on a person. Without it such a card sat at `PENDING` and\n * read \"running\u2026\" while the stream was over and the server idle \u2014 a status enum\n * missing a state does not omit that state, it renders it as whichever neighbour\n * is closest, and here the closest one claimed the opposite of the truth. A\n * *frontend* tool waiting on its own card (`ask_user`) stays `PENDING`, because\n * the browser really is running it.\n */\nexport const TOOL_CALL_STATUS = {\n PENDING: \"pending\",\n DEFERRED: \"deferred\",\n DONE: \"done\",\n ERROR: \"error\",\n DECLINED: \"declined\",\n} as const;\n\n/**\n * Lifecycle status of a pending-attachment chip in the composer tray. A chip\n * opens as `UPLOADING` (with a progress bar), then settles to `READY` (a durable\n * ref) or `ERROR` (with a retry control).\n */\nexport const ATTACHMENT_STATUS = {\n UPLOADING: \"uploading\",\n READY: \"ready\",\n ERROR: \"error\",\n} as const;\n\n/**\n * Default client-side upload size cap (10 MiB), matching django-ag-ui's\n * `ATTACHMENT_MAX_BYTES`. Overridable via `data-attachment-max-bytes`; the\n * server stays authoritative.\n */\nexport const DEFAULT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;\n\n/**\n * How much detail a tool-call card shows. Set via `data-tool-display`; the\n * default is `full`.\n *\n * - `inline` \u2014 one status row (icon + summary), no card chrome, result behind\n * its own toggle. Reads as a line of the answer rather than a boxed card.\n * - `minimal` \u2014 tool name + status pill only. No args, no result body.\n * - `compact` \u2014 name + status, args and result behind one \"Details\" toggle.\n * - `full` \u2014 args inline, result behind its own toggle.\n */\nexport const TOOL_DISPLAY = {\n INLINE: \"inline\",\n MINIMAL: \"minimal\",\n COMPACT: \"compact\",\n FULL: \"full\",\n} as const;\n\n/**\n * `activityType` of the `ACTIVITY_SNAPSHOT` event django-ag-ui emits when a\n * compaction capability trimmed the history. `content` carries\n * `{ removed, before, after }`.\n */\nexport const COMPACTION_ACTIVITY_TYPE = \"compaction\";\n\n/**\n * Pydantic-AI's built-in tool for loading a deferred capability, with `{ id }`\n * naming it. Agent skills are deferred capabilities keyed by skill name, so a\n * call to this tool is the only signal that the agent picked a skill.\n *\n * Distinct from the host-provided {@link Skill} catalog, which is a human\n * affordance launched from the slash palette.\n */\nexport const LOAD_CAPABILITY_TOOL = \"load_capability\";\n\n/**\n * The chrome's glyphs, as inline SVG markup.\n *\n * Static author-written markup assigned as a `<slot>`'s fallback content, so it\n * never passes through the sanitiser \u2014 nothing here is user or server data, and\n * nothing user-supplied may be interpolated into it. Each icon is a 24x24\n * viewBox carrying the shared `glyph` class, which `STYLES` sizes and paints\n * from `currentColor`; `glyph--solid` fills instead of stroking. A host wanting\n * its own mark projects a matching `slot=\"icon-\u2026\"` child instead of editing\n * these.\n */\nexport const ICON_SEND = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 19.5V5m-6.5 6.5L12 5l6.5 6.5\"/></svg>`;\n\n/** The Stop glyph the composer button wears while a run is in flight. */\nexport const ICON_STOP = `<svg class=\"glyph glyph--solid\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"2.5\"/></svg>`;\n\n/** The file-picker glyph (a paperclip). */\nexport const ICON_ATTACH = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M17 8.5V15a5 5 0 0 1-10 0V7a3 3 0 0 1 6 0v7.5a1 1 0 0 1-2 0V8.5\"/></svg>`;\n\n/** The voice-input glyph (a microphone on its stand). */\nexport const ICON_VOICE = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 4a3 3 0 0 1 3 3v5a3 3 0 0 1-6 0V7a3 3 0 0 1 3-3z\"/><path d=\"M5 11v1a7 7 0 0 0 14 0v-1\"/><path d=\"M12 19v3\"/></svg>`;\n\n/** The default launcher mark (a speech bubble), shown when the host slots none. */\nexport const ICON_LAUNCHER = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H9l-5 4z\"/></svg>`;\n\n/**\n * The generic attachment-chip mark, for a file family with nothing more\n * specific to say. The chip marks share the contract of the chrome glyphs\n * above; `iconFor` selects one by MIME family, never interpolating the MIME\n * string into the markup.\n */\nexport const ICON_FILE = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"/><path d=\"M14 3v5h5\"/></svg>`;\n\n/** An image attachment: a framed picture with a horizon and a sun. */\nexport const ICON_FILE_IMAGE = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"4.5\" width=\"17\" height=\"15\" rx=\"2.5\"/><circle cx=\"9\" cy=\"10\" r=\"1.5\"/><path d=\"M4.5 17.5 9 13.5l3.5 3 3-2.5 4.5 4\"/></svg>`;\n\n/** A PDF: the generic page, banded to read as a labelled document. */\nexport const ICON_FILE_PDF = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"/><path d=\"M14 3v5h5\"/><rect class=\"glyph--solid\" x=\"7.5\" y=\"13.5\" width=\"9\" height=\"4.5\" rx=\"1\"/></svg>`;\n\n/** A text document: the generic page, ruled. */\nexport const ICON_FILE_TEXT = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"/><path d=\"M14 3v5h5\"/><path d=\"M8.5 13.5h7M8.5 17h4.5\"/></svg>`;\n", "/** Result of {@link fillTemplate}: the filled text plus any unresolved keys. */\nexport interface TemplateResult {\n /** The prompt with resolved `{placeholder}`s substituted. */\n readonly text: string;\n /** Placeholder names with no value available (deduped, in first-seen order). */\n readonly missing: readonly string[];\n}\n\nconst PLACEHOLDER_RE = /\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g;\n\n/**\n * Substitute `{name}` placeholders in `template` from `values`.\n *\n * A placeholder whose value is missing, `null`, or an empty string is left\n * verbatim and reported in `missing`, so the caller can block the send rather\n * than dispatch a half-filled prompt.\n */\nexport function fillTemplate(template: string, values: Record<string, unknown>): TemplateResult {\n const missing: string[] = [];\n const text = template.replace(PLACEHOLDER_RE, (token, key: string) => {\n const value = values[key];\n if (value === undefined || value === null || value === \"\") {\n if (!missing.includes(key)) {\n missing.push(key);\n }\n return token;\n }\n return String(value);\n });\n return { text, missing };\n}\n", "import type { Skill } from \"./skill.js\";\n\n/**\n * Whether `value` has the required string fields of a {@link Skill}.\n *\n * `prompt` must stay optional: a server-resolved skill omits it, and requiring\n * it would silently drop exactly the skills kept off the client.\n */\nfunction isSkill(value: unknown): value is Skill {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const record = value as Record<string, unknown>;\n return (\n typeof record[\"name\"] === \"string\" &&\n typeof record[\"title\"] === \"string\" &&\n (record[\"prompt\"] === undefined || typeof record[\"prompt\"] === \"string\")\n );\n}\n\n/**\n * Parse an untrusted value (parsed JSON from `data-skills` or a skills\n * endpoint) into a list of {@link Skill}s, dropping anything malformed. Never\n * throws \u2014 a bad payload yields an empty list.\n */\nexport function parseSkills(value: unknown): Skill[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value.filter(isSkill);\n}\n", "import type { Tool } from \"@ag-ui/core\";\n\n/**\n * A tool the frontend declares and executes itself.\n *\n * `parameters` is a JSON Schema (and may carry the `x-destructive` extension).\n * `handler` receives the parsed arguments and returns a result that is\n * JSON-serialised into the AG-UI tool-result message sent back to the agent.\n */\nexport interface ClientTool {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n handler: (args: Record<string, unknown>) => unknown | Promise<unknown>;\n}\n\n/**\n * Holds the frontend tools a host has declared on an `<ag-ui-chat>` element.\n *\n * Produces AG-UI {@link Tool} definitions for `RunAgentInput.tools` and looks\n * up handlers when the agent calls a tool. Pure (no DOM); the element owns one\n * instance.\n */\nexport class ClientToolRegistry {\n readonly #tools = new Map<string, ClientTool>();\n\n /**\n * Register a tool, replacing any existing one with the same name.\n *\n * Idempotent on the name so a re-fired host ref or React StrictMode's\n * double-invoke replaces rather than throws.\n */\n register(tool: ClientTool): void {\n this.#tools.set(tool.name, tool);\n }\n\n has(name: string): boolean {\n return this.#tools.has(name);\n }\n\n /** Return a registered tool or throw. */\n get(name: string): ClientTool {\n const tool = this.#tools.get(name);\n if (tool === undefined) {\n throw new Error(`tool \"${name}\" is not registered`);\n }\n return tool;\n }\n\n /** AG-UI tool definitions for `RunAgentInput.tools`. */\n tools(): Tool[] {\n return [...this.#tools.values()].map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }));\n }\n}\n", "import { X_DESTRUCTIVE_KEY } from \"../constants.js\";\n\n/**\n * Whether a tool's JSON-Schema `parameters` marks it destructive.\n *\n * Reads the `x-destructive` extension stamped by the server (`django-ag-ui`'s\n * `build_input_schema`) or by a host declaring a tool directly.\n */\nexport function isDestructive(parameters: Record<string, unknown>): boolean {\n return parameters[X_DESTRUCTIVE_KEY] === true;\n}\n", "import { X_NAVIGATES_KEY } from \"../constants.js\";\n\n/**\n * Whether a tool's JSON-Schema `parameters` marks it as navigating.\n *\n * Reads the `x-navigates` extension. A navigating tool's handler reloads the\n * page (MPA navigation), so the element checkpoints the call and resumes the\n * run loop after the next page mounts, rather than awaiting a result inline.\n */\nexport function isNavigates(parameters: Record<string, unknown>): boolean {\n return parameters[X_NAVIGATES_KEY] === true;\n}\n", "// Set a control's `value` / `checked` through the native prototype setter, so\n// framework value-tracking sees the change. React (and Vue/Svelte) replace the\n// element's own setter with a tracked one, so `el.value = x` hits that override\n// and the following `input` event carries no change: the field looks filled\n// while the framework's state stays empty. Calling the original prototype\n// setter and then dispatching `input` avoids that.\n\ntype ValueSetter = (this: HTMLElement, value: string) => void;\ntype CheckedSetter = (this: HTMLElement, checked: boolean) => void;\n\n/** The original prototype setter for `prop` on `proto`. */\nfunction prototypeSetter(proto: object, prop: string): (this: HTMLElement, value: never) => void {\n // Captured once at module load; DOM environments always define these, which\n // is what makes the descriptor cast safe.\n const setter = (Object.getOwnPropertyDescriptor(proto, prop) as PropertyDescriptor).set;\n return setter as unknown as (this: HTMLElement, value: never) => void;\n}\n\nconst setInputValue = prototypeSetter(HTMLInputElement.prototype, \"value\") as ValueSetter;\nconst setTextareaValue = prototypeSetter(HTMLTextAreaElement.prototype, \"value\") as ValueSetter;\nconst setSelectValue = prototypeSetter(HTMLSelectElement.prototype, \"value\") as ValueSetter;\nconst setInputChecked = prototypeSetter(HTMLInputElement.prototype, \"checked\") as CheckedSetter;\n\n/** Set `el.value` via the element's native prototype setter. */\nexport function setNativeValue(\n el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement,\n value: string,\n): void {\n if (el instanceof HTMLTextAreaElement) {\n setTextareaValue.call(el, value);\n } else if (el instanceof HTMLSelectElement) {\n setSelectValue.call(el, value);\n } else {\n setInputValue.call(el, value);\n }\n}\n\n/** Set `el.checked` via the native prototype setter. */\nexport function setNativeChecked(el: HTMLInputElement, checked: boolean): void {\n setInputChecked.call(el, checked);\n}\n", "/**\n * Visible-action animation primitives.\n *\n * These run against the **host page** DOM (not the element's shadow root) so a\n * user watches the agent type, highlight, and click at human-readable speed.\n * Each is configurable; pass small/zero durations in tests (or use fake timers).\n */\n\nimport { setNativeChecked, setNativeValue } from \"./native_setter.js\";\n\n/** Ring colour when the host page has not themed `--ag-ui-accent`. */\nconst ACCENT = \"#4f46e5\";\n\n/**\n * Fallback for the box-shadow rings, which read as a soft halo rather than a\n * line and so carry their own alpha.\n */\nconst ACCENT_HALO = \"rgba(79, 70, 229, 0.4)\";\n\nconst ACCENT_PROPERTY = \"--ag-ui-accent\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\n/**\n * Whether the user has asked the OS/browser to minimise motion.\n *\n * Honoured by every primitive that moves something: hold delays are skipped,\n * `scrollIntoCenterView` jumps instead of gliding, and the flash drops its fade\n * but still holds the ring long enough to be seen \u2014 reduced motion asks for no\n * animation, not for no feedback. `typeInto` and `highlightThenClick` keep\n * their explicit-duration contract instead.\n */\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/** Like {@link delay}, but resolves immediately under reduced motion. */\nfunction motionDelay(ms: number): Promise<void> {\n if (ms <= 0 || prefersReducedMotion()) {\n return Promise.resolve();\n }\n return delay(ms);\n}\n\n/**\n * Resolve the accent colour from the target's own computed style.\n *\n * `--ag-ui-accent` inherits, so reading it off the element about to be touched\n * picks up whatever the host's cascade produced there, and a themed page is\n * flashed in its own colour rather than this package's indigo.\n */\nfunction accentColor(el: HTMLElement, fallback: string): string {\n const themed = window.getComputedStyle(el).getPropertyValue(ACCENT_PROPERTY).trim();\n return themed === \"\" ? fallback : themed;\n}\n\nfunction ringShadow(el: HTMLElement): string {\n return `0 0 0 3px ${accentColor(el, ACCENT_HALO)}`;\n}\n\n/** An element whose `value` can be typed into. */\nexport type TextLikeElement = HTMLInputElement | HTMLTextAreaElement;\n\nexport interface TypeOptions {\n /** Milliseconds between characters. Default 35. */\n charDelayMs?: number;\n}\n\n/**\n * Clear `el` and type `value` one character at a time, firing an `input` event\n * per character as a real user would, then a final `change`.\n */\nexport async function typeInto(\n el: TextLikeElement,\n value: string,\n options: TypeOptions = {},\n): Promise<void> {\n const charDelayMs = options.charDelayMs ?? 35;\n setNativeValue(el, \"\");\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n for (const char of value) {\n setNativeValue(el, el.value + char);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n if (charDelayMs > 0) {\n await delay(charDelayMs);\n }\n }\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\nexport interface HighlightClickOptions {\n /** Milliseconds to hold the highlight before clicking. Default 280. */\n highlightMs?: number;\n}\n\n/** Outline `el`, pause so the user sees it, then click and restore. */\nexport async function highlightThenClick(\n el: HTMLElement,\n options: HighlightClickOptions = {},\n): Promise<void> {\n const highlightMs = options.highlightMs ?? 280;\n const previousOutline = el.style.outline;\n const previousOffset = el.style.outlineOffset;\n el.style.outline = `2px solid ${accentColor(el, ACCENT)}`;\n el.style.outlineOffset = \"2px\";\n await delay(highlightMs);\n el.style.outline = previousOutline;\n el.style.outlineOffset = previousOffset;\n el.click();\n}\n\nexport interface ScrollOptions {\n /**\n * How long to wait for a moving scroll to settle before giving up.\n * Default 600.\n */\n settleMs?: number;\n}\n\nconst SCROLL_SETTLE_MS = 600;\n\n/** How long to give a smooth scroll to start moving before assuming it will not. */\nconst SCROLL_START_MS = 100;\n\n/**\n * Scroll `el` to the vertical centre of the viewport.\n *\n * Resolves once the scroll settles, so a caller can hold its animation until\n * the element stops moving \u2014 a ring drawn mid-glide lands where the user is not\n * looking yet. Awaiting is optional; the scroll is requested synchronously.\n */\nexport function scrollIntoCenterView(el: HTMLElement, options: ScrollOptions = {}): Promise<void> {\n const reduced = prefersReducedMotion();\n el.scrollIntoView({\n block: \"center\",\n inline: \"nearest\",\n behavior: reduced ? \"auto\" : \"smooth\",\n });\n if (reduced) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n let timer: ReturnType<typeof setTimeout>;\n const settle = (): void => {\n clearTimeout(timer);\n document.removeEventListener(\"scroll\", started, true);\n document.removeEventListener(\"scrollend\", settle, true);\n resolve();\n };\n const started = (): void => {\n document.removeEventListener(\"scroll\", started, true);\n clearTimeout(timer);\n timer = setTimeout(settle, options.settleMs ?? SCROLL_SETTLE_MS);\n };\n // Neither event bubbles, and both fire on whichever ancestor actually\n // scrolled, so listen on the document in the capture phase.\n //\n // Two timeouts, for two failure modes: an element already in view never\n // scrolls and so never fires scrollend (the short did-anything-move probe),\n // and once something is moving the longer budget covers browsers without\n // scrollend at all.\n timer = setTimeout(settle, SCROLL_START_MS);\n document.addEventListener(\"scroll\", started, true);\n document.addEventListener(\"scrollend\", settle, true);\n });\n}\n\n/** Total on-screen life of the flash ring, hold plus fade. */\nconst FLASH_MS = 1200;\n\n/** Share of {@link FLASH_MS} spent fading out rather than holding. */\nconst FLASH_FADE_RATIO = 1 / 3;\n\nexport interface FlashOptions {\n /** Total milliseconds the ring is on screen, hold plus fade. Default 1200. */\n flashMs?: number;\n /** Ring colour. Defaults to the target's `--ag-ui-accent`, else the package accent. */\n color?: string;\n /**\n * Move keyboard focus to the element as well. Defaults to false for\n * {@link flash} and true for {@link focusWithFlash}.\n */\n focus?: boolean;\n}\n\nasync function flashRing(\n el: HTMLElement,\n options: FlashOptions,\n focusByDefault: boolean,\n): Promise<void> {\n if (options.focus ?? focusByDefault) {\n // preventScroll: a caller's smooth scroll is typically still in flight, and\n // the instant scroll focus() would otherwise do fights it.\n el.focus({ preventScroll: true });\n }\n const flashMs = options.flashMs ?? FLASH_MS;\n if (flashMs <= 0) {\n return;\n }\n const previousOutline = el.style.outline;\n const previousOffset = el.style.outlineOffset;\n const previousTransition = el.style.transition;\n const color = options.color ?? accentColor(el, ACCENT);\n // outline, not box-shadow: a shadow paints outside the border box, so any\n // overflow:hidden ancestor sharing the target's box (a card, a table cell)\n // clips the whole ring away while the helper still reports success.\n el.style.outline = `3px solid ${color}`;\n el.style.outlineOffset = \"2px\";\n const fadeMs = prefersReducedMotion() ? 0 : Math.round(flashMs * FLASH_FADE_RATIO);\n await delay(flashMs - fadeMs);\n if (fadeMs > 0) {\n // Transition and new colour in the same task is fine: the browser starts\n // transitions from the after-change style.\n el.style.transition = `outline-color ${fadeMs}ms ease-out`;\n el.style.outline = \"3px solid transparent\";\n await delay(fadeMs);\n }\n el.style.outline = previousOutline;\n el.style.outlineOffset = previousOffset;\n el.style.transition = previousTransition;\n}\n\n/**\n * Flash a ring around `el` without touching focus.\n *\n * Prefer this over {@link focusWithFlash} when the point is to show the user\n * something: moving focus steals it from the composer, can fire blur validation\n * on whatever they were mid-edit in, and can close an open menu.\n */\nexport function flash(el: HTMLElement, options: FlashOptions = {}): Promise<void> {\n return flashRing(el, options, false);\n}\n\n/**\n * Focus `el` and flash a ring around it. Focus moves unless `options.focus`\n * says otherwise; use {@link flash} to leave focus where the user put it.\n */\nexport function focusWithFlash(el: HTMLElement, options: FlashOptions = {}): Promise<void> {\n return flashRing(el, options, true);\n}\n\nexport interface PressOptions {\n /** Milliseconds to hold the pressed state before clicking. Default 140. */\n pressMs?: number;\n}\n\n/**\n * Show a brief pressed affordance on a control \u2014 a slight scale-down plus\n * accent ring \u2014 then click it and restore. Reads as a press rather than the\n * plain outline {@link highlightThenClick} draws.\n */\nexport async function pressThenClick(el: HTMLElement, options: PressOptions = {}): Promise<void> {\n const pressMs = options.pressMs ?? 140;\n const previousTransform = el.style.transform;\n const previousTransition = el.style.transition;\n const previousShadow = el.style.boxShadow;\n el.style.transition = \"transform 80ms ease\";\n el.style.transform = \"scale(0.96)\";\n el.style.boxShadow = ringShadow(el);\n await motionDelay(pressMs);\n el.style.transform = previousTransform;\n el.style.transition = previousTransition;\n el.style.boxShadow = previousShadow;\n el.click();\n}\n\nexport interface SelectOptions {\n /** Milliseconds to hold the highlight before committing. Default 220. */\n highlightMs?: number;\n}\n\n/** Find an option in `el` whose value or visible text equals `value`. */\nfunction findOption(el: HTMLSelectElement, value: string): HTMLOptionElement | null {\n for (const option of Array.from(el.options)) {\n if (option.value === value || option.text === value) {\n return option;\n }\n }\n return null;\n}\n\n/**\n * Outline a `<select>`, pause so the user sees the pick, then set it to the\n * option matching `value` (by value or visible text) and fire `input` +\n * `change`. Throws when no option matches.\n */\nexport async function selectOption(\n el: HTMLSelectElement,\n value: string,\n options: SelectOptions = {},\n): Promise<void> {\n const option = findOption(el, value);\n if (option === null) {\n throw new Error(`no <option> matching \"${value}\"`);\n }\n const highlightMs = options.highlightMs ?? 220;\n const previousOutline = el.style.outline;\n const previousOffset = el.style.outlineOffset;\n el.style.outline = `2px solid ${accentColor(el, ACCENT)}`;\n el.style.outlineOffset = \"2px\";\n await motionDelay(highlightMs);\n setNativeValue(el, option.value);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n el.style.outline = previousOutline;\n el.style.outlineOffset = previousOffset;\n}\n\nexport interface ToggleOptions {\n /** Milliseconds to hold the flash. Default 200. */\n flashMs?: number;\n}\n\n/**\n * Flash a ring around a checkbox/radio, set its `checked` state, and fire\n * `input` + `change` so frameworks observe the flip.\n */\nexport async function toggleControl(\n el: HTMLInputElement,\n checked: boolean,\n options: ToggleOptions = {},\n): Promise<void> {\n const flashMs = options.flashMs ?? 200;\n const previousShadow = el.style.boxShadow;\n el.style.boxShadow = ringShadow(el);\n await motionDelay(flashMs);\n setNativeChecked(el, checked);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n el.style.boxShadow = previousShadow;\n}\n", "import { X_SUMMARY_KEY } from \"../constants.js\";\nimport { scrollIntoCenterView } from \"../dom/animations.js\";\nimport type { ClientTool } from \"./client_tool_registry.js\";\n\n/**\n * Resolve a page-action target string to a host-page element, or `null` when it\n * matches nothing. The default treats the string as a CSS selector; a host with\n * a page map overrides it to map its own element ids.\n */\nexport type ResolvePageTarget = (target: string) => HTMLElement | null;\n\n/** The built-in page-action tool tokens, opted in via `data-page-actions`. */\nexport const PAGE_ACTIONS = {\n SCROLL: \"scroll\",\n DRAG: \"drag\",\n} as const;\n\n/**\n * The opt-in page-action tools selected by `enabled` (a set of\n * {@link PAGE_ACTIONS} tokens), bound to a {@link ResolvePageTarget}.\n *\n * - `scroll_to` \u2014 scroll a target (`top` / `bottom` / a resolver target) into\n * view. Benign; no confirmation.\n * - `drag_and_drop` \u2014 drag one element onto another, firing the standard HTML5\n * drag sequence so the host page's own drop handler reacts. Deliberately not\n * stamped destructive: a drag rearranges transient state, and the durable\n * change happens at the page's explicit commit. A host whose page persists on\n * drop must gate it with the element's `confirmPredicate`.\n *\n * Both report a model-readable error when a target resolves to nothing.\n */\nexport function createPageActionTools(\n enabled: ReadonlySet<string>,\n resolveTarget: ResolvePageTarget,\n): ClientTool[] {\n const tools: ClientTool[] = [];\n if (enabled.has(PAGE_ACTIONS.SCROLL)) {\n tools.push(scrollTool(resolveTarget));\n }\n if (enabled.has(PAGE_ACTIONS.DRAG)) {\n tools.push(dragTool(resolveTarget));\n }\n return tools;\n}\n\nfunction scrollTool(resolveTarget: ResolvePageTarget): ClientTool {\n return {\n name: \"scroll_to\",\n description:\n \"Scroll a target into view. `target` is `top`, `bottom`, or a CSS \" +\n \"selector / page-map element id. Read-only: it changes nothing on the page.\",\n parameters: {\n type: \"object\",\n properties: { target: { type: \"string\" } },\n required: [\"target\"],\n [X_SUMMARY_KEY]: \"Scroll into view\",\n },\n handler: (args) => {\n const target = String(args[\"target\"] ?? \"\");\n if (target === \"top\" || target === \"bottom\") {\n const top = target === \"top\" ? 0 : document.body.scrollHeight;\n window.scrollTo({ top, behavior: \"smooth\" });\n return { scrolled: true, target };\n }\n const element = resolveTarget(target);\n if (element === null) {\n throw new Error(`no element matching \"${target}\"`);\n }\n scrollIntoCenterView(element);\n return { scrolled: true, target };\n },\n };\n}\n\nfunction dragTool(resolveTarget: ResolvePageTarget): ClientTool {\n return {\n name: \"drag_and_drop\",\n description:\n \"Drag the `from` element onto the `to` element (CSS selectors or page-map \" +\n \"element ids), firing the page's native drag-and-drop. Use for reordering \" +\n \"sortable lists. The page decides what the drop commits.\",\n parameters: {\n type: \"object\",\n properties: { from: { type: \"string\" }, to: { type: \"string\" } },\n required: [\"from\", \"to\"],\n [X_SUMMARY_KEY]: \"Drag and drop\",\n },\n handler: (args) => {\n const fromTarget = String(args[\"from\"] ?? \"\");\n const toTarget = String(args[\"to\"] ?? \"\");\n const from = resolveTarget(fromTarget);\n if (from === null) {\n throw new Error(`no element matching \"${fromTarget}\"`);\n }\n const to = resolveTarget(toTarget);\n if (to === null) {\n throw new Error(`no element matching \"${toTarget}\"`);\n }\n dispatchDragSequence(from, to);\n return { dragged: true, from: fromTarget, to: toTarget };\n },\n };\n}\n\n/**\n * Fire the standard HTML5 drag sequence in the order a page's own handlers\n * expect \u2014 `dragstart` on the source, `dragenter` / `dragover` / `drop` on the\n * target, `dragend` on the source \u2014 all sharing one {@link DataTransfer}, which\n * is attached to each event explicitly so a drop handler reads it in every\n * environment.\n */\nfunction dispatchDragSequence(from: HTMLElement, to: HTMLElement): void {\n const dataTransfer = new DataTransfer();\n fire(from, \"dragstart\", dataTransfer);\n fire(to, \"dragenter\", dataTransfer);\n fire(to, \"dragover\", dataTransfer);\n fire(to, \"drop\", dataTransfer);\n fire(from, \"dragend\", dataTransfer);\n}\n\nfunction fire(target: HTMLElement, type: string, dataTransfer: DataTransfer): void {\n const event = new Event(type, { bubbles: true, cancelable: true }) as Event & {\n dataTransfer: DataTransfer;\n };\n event.dataTransfer = dataTransfer;\n target.dispatchEvent(event);\n}\n", "import type { Context } from \"@ag-ui/core\";\n\n/**\n * A compact snapshot of the current page's actionable surface (field\n * names/types/labels, button labels+handles \u2014 not values). Host-defined shape;\n * kept small because it rides in every `RunAgentInput.context`.\n */\nexport type PageMap = Record<string, unknown>;\n\n/**\n * Build the per-run context entry for the page map.\n *\n * Returns a single `page_map` context item when auto-injection is on and a\n * provider is set, else nothing. Recomputed each run so it reflects the page\n * the agent is currently looking at.\n */\nexport function createPageMapContext(\n getPageMap: (() => PageMap) | null,\n autoInject: boolean,\n): Context[] {\n if (!autoInject || getPageMap === null) {\n return [];\n }\n return [{ description: \"page_map\", value: JSON.stringify(getPageMap()) }];\n}\n", "import { X_DESTRUCTIVE_KEY, X_SUMMARY_KEY } from \"../constants.js\";\nimport type { ClientTool } from \"./client_tool_registry.js\";\n\n/**\n * A binding from a named piece of host page state to agent tools.\n *\n * Ergonomic sugar over `registerTool` for SPA state (Redux/Zustand/signals):\n * generates a read tool and, when `write` is given, a destructive set tool.\n *\n * Not AG-UI shared state. `STATE_SNAPSHOT` / `STATE_DELTA` are protocol events\n * carrying state between agent and client; these are ordinary client tools the\n * agent calls like any other.\n */\nexport interface PageState {\n /** Base name; tools become `read_<name>` and `set_<name>`. */\n readonly name: string;\n /** Returns the current state value. */\n readonly read: () => unknown;\n /** Mutates the state from the agent-supplied args. Omit for read-only. */\n readonly write?: (args: Record<string, unknown>) => unknown;\n /** JSON-Schema for the set tool's args. Defaults to an open object. */\n readonly schema?: Record<string, unknown>;\n}\n\n/**\n * Build the tools for a {@link PageState}: always a `read_<name>` (read-only)\n * tool, plus a `set_<name>` (`x-destructive`) tool when `write` is supplied.\n */\nexport function createPageStateTools(binding: PageState): ClientTool[] {\n const tools: ClientTool[] = [\n {\n name: `read_${binding.name}`,\n description: `Read the \"${binding.name}\" state.`,\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n [X_SUMMARY_KEY]: `Read ${binding.name}`,\n },\n handler: () => binding.read(),\n },\n ];\n const write = binding.write;\n if (write !== undefined) {\n tools.push({\n name: `set_${binding.name}`,\n description: `Update the \"${binding.name}\" state.`,\n parameters: {\n ...(binding.schema ?? { type: \"object\" }),\n [X_DESTRUCTIVE_KEY]: true,\n [X_SUMMARY_KEY]: `Update ${binding.name}`,\n },\n handler: (args) => write(args),\n });\n }\n return tools;\n}\n\n/**\n * @deprecated Renamed to {@link PageState} \u2014 the old name read as AG-UI\n * shared-state sync. Will be removed in a future major.\n */\nexport type StateHook = PageState;\n\n/**\n * @deprecated Renamed to {@link createPageStateTools}. Will be removed in a\n * future major.\n */\nexport const createStateHookTools = createPageStateTools;\n", "/**\n * One entry in the server-tool catalog served by django-ag-ui's `tools/`\n * endpoint and fetched via the `data-tools-url` attribute.\n */\nexport interface ToolCatalogEntry {\n /** The tool's wire name (matches the name in `TOOL_CALL_START`). */\n readonly name: string;\n /** A friendly card label for the tool. */\n readonly summary: string;\n /** Optional longer blurb (e.g. for a future tooltip). */\n readonly description?: string;\n}\n\n/**\n * Parse a fetched tool catalog into a `name \u2192 summary` map, skipping any entry\n * that isn't a `{ name: string, summary: string }` object. Tolerant by design:\n * a malformed payload yields an empty map rather than throwing.\n */\nexport function parseToolCatalog(data: unknown): Record<string, string> {\n const out: Record<string, string> = {};\n if (!Array.isArray(data)) {\n return out;\n }\n for (const entry of data) {\n if (entry === null || typeof entry !== \"object\") {\n continue;\n }\n const record = entry as Record<string, unknown>;\n const name = record[\"name\"];\n const summary = record[\"summary\"];\n if (typeof name === \"string\" && typeof summary === \"string\") {\n out[name] = summary;\n }\n }\n return out;\n}\n", "import { X_NAVIGATES_KEY, X_SUMMARY_KEY } from \"../constants.js\";\nimport type { ClientTool } from \"./client_tool_registry.js\";\n\n/** A single navigable route the host declares for the agent. */\nexport interface Route {\n /** Stable id the agent uses with `navigate_to_route`. */\n readonly id: string;\n /**\n * The URL path to navigate to. May contain `:name` placeholders for dynamic\n * segments (e.g. `/admin/shop/book/:pk/change/`), which the agent fills via\n * `navigate_to_route`'s `params` argument.\n */\n readonly path: string;\n /** Human label shown to the agent. */\n readonly title?: string;\n /** Optional grouping (e.g. an app or section). */\n readonly group?: string;\n /** Optional longer description of when to use the route. */\n readonly description?: string;\n}\n\n/** The host-declared catalog of navigable routes. */\nexport type RouteMap = readonly Route[];\n\n/** A route enriched with its derived dynamic-segment parameter names. */\nexport interface RouteWithParams extends Route {\n /** Names of the `:name` placeholders in {@link Route.path} (may be empty). */\n readonly pathParams: readonly string[];\n}\n\nconst PATH_PARAM_RE = /:([A-Za-z_][A-Za-z0-9_]*)/g;\n\n/** The `:name` path-parameter names declared in a path template, in order. */\nfunction pathParamNames(path: string): string[] {\n // Slice the \":\" off the whole match rather than read the capture group: under\n // `noUncheckedIndexedAccess`, indexing the group forces an `undefined` guard\n // on a case the regex cannot produce, which no test can cover.\n return [...path.matchAll(PATH_PARAM_RE)].map((match) => match[0].slice(1));\n}\n\n/**\n * Substitute `:name` placeholders in `path` from `params`.\n *\n * Returns the concrete path plus the params no placeholder consumed, for the\n * caller to append as a query string. Throws (naming `routeId`) when a declared\n * path param is missing or empty \u2014 a half-filled path must never be navigated\n * to.\n */\nfunction fillPath(\n routeId: string,\n path: string,\n params: Record<string, unknown>,\n): { path: string; leftover: Record<string, unknown> } {\n const leftover: Record<string, unknown> = { ...params };\n const filled = path.replace(PATH_PARAM_RE, (_match, name: string) => {\n const value = params[name];\n if (value === undefined || value === null || String(value) === \"\") {\n throw new Error(`route \"${routeId}\" requires path param \"${name}\"`);\n }\n delete leftover[name];\n return encodeURIComponent(String(value));\n });\n return { path: filled, leftover };\n}\n\n/** Append `params` to `path` as a query string (no-op when empty). */\nfunction withQuery(path: string, params: Record<string, unknown>): string {\n const usp = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n usp.set(key, String(value));\n }\n const query = usp.toString();\n return query === \"\" ? path : `${path}?${query}`;\n}\n\n/**\n * The built-in `route.*` tools, bound to live getters so a host can set\n * `routeMap` / `navigate` before or after mount.\n *\n * `list_routes` is read-only and advertises each route's `pathParams` so the\n * model knows what to supply. `navigate_to_route` fills those params, appends\n * the rest as a query string, and is stamped `x-navigates` so an MPA reload\n * checkpoints and resumes; with a host `navigate(path)` callback (an SPA) it\n * routes client-side and the run loop continues instead.\n */\nexport function createRouteTools(\n getRouteMap: () => RouteMap,\n getNavigate: () => ((path: string) => void) | null,\n): ClientTool[] {\n return [\n {\n name: \"list_routes\",\n description:\n \"List the routes the app can navigate to. Each route's `pathParams` \" +\n \"names the dynamic segments to pass as `params` to `navigate_to_route`.\",\n parameters: { type: \"object\", properties: {}, required: [], [X_SUMMARY_KEY]: \"List pages\" },\n handler: (): RouteWithParams[] =>\n getRouteMap().map((route) => ({ ...route, pathParams: pathParamNames(route.path) })),\n },\n {\n name: \"navigate_to_route\",\n description:\n \"Navigate to one of the app's routes by its id, filling any dynamic \" +\n \"`:name` path segments (and extra query params) from `params`.\",\n parameters: {\n type: \"object\",\n properties: {\n route_id: { type: \"string\" },\n params: { type: \"object\" },\n },\n required: [\"route_id\"],\n [X_NAVIGATES_KEY]: true,\n [X_SUMMARY_KEY]: \"Navigate\",\n },\n handler: (args) => {\n const routeId = args[\"route_id\"];\n const route = getRouteMap().find((r) => r.id === routeId);\n if (route === undefined) {\n throw new Error(`unknown route \"${String(routeId)}\"`);\n }\n const provided = (args[\"params\"] as Record<string, unknown> | undefined) ?? {};\n const { path: filledPath, leftover } = fillPath(route.id, route.path, provided);\n const path = withQuery(filledPath, leftover);\n const navigate = getNavigate();\n if (navigate !== null) {\n navigate(path);\n } else {\n window.location.assign(path);\n }\n return { navigated: true, path };\n },\n },\n ];\n}\n", "/**\n * The flat table of every user-facing string the chat shell renders \u2014 labels,\n * placeholders, `aria-label`s, and `title` tooltips. A localizable seam, not a\n * framework: a host overrides any subset (via the element's `strings` property\n * or its `data-strings` JSON attribute) and the rest fall back to the English\n * defaults.\n *\n * Some values are templates carrying `{token}` placeholders the call site fills\n * in; the token names are noted on each key, and a translation must keep them\n * verbatim.\n */\nexport interface UiStrings {\n // \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Default header title (the `title-text` attribute overrides per element). */\n title: string;\n /** History button + drawer dialog label. */\n chatHistory: string;\n /** New-chat button (header + drawer). */\n newChat: string;\n /** Collapse button. */\n collapse: string;\n /** Expand affordance (the launcher, and the sidebar rail). */\n expand: string;\n /**\n * The launcher's label while unread answers wait behind it. Token: `{count}`.\n * Replaces {@link expand} rather than appending to it, so a translation can\n * order the two parts as its language needs.\n */\n expandUnread: string;\n /** Built-in header theme toggle (light \u21C4 dark). */\n toggleTheme: string;\n\n // \u2500\u2500 Messages region \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the scrolling message log. */\n conversation: string;\n /** `aria-label` of the \"thinking\" pending indicator, and the thoughts region's\n * header while the model is still reasoning. */\n thinking: string;\n /** The thoughts region's header once reasoning has streamed (collapsed label). */\n thoughts: string;\n /** The muted note after a cancelled run. */\n stopped: string;\n /** Error shown when the stream drops without a terminal AG-UI event. */\n connectionLost: string;\n /** Fallback when a tool call produced no result. */\n noResult: string;\n /** Tool-result content when the user declines a confirmed action. */\n declinedAction: string;\n /** A navigating tool's card text while the page reloads. */\n navigating: string;\n /** Missing-placeholder skill hint. Tokens: `{title}`, `{fields}`. */\n skillNeeds: string;\n /** Notice shown when the agent condensed earlier turns. Token: `{count}`. */\n historyCompacted: string;\n /** Notice shown when the agent loads an agent skill. Token: `{name}`. */\n usingSkill: string;\n /** Notice shown on mount when the previous run never produced a response. */\n runInterrupted: string;\n /** Tool-result content (and card text) when the page moved mid-run. */\n pageMoved: string;\n /** Notice when Send ran while a file was still uploading. Token: `{n}`. */\n attachmentsStillUploading: string;\n\n // \u2500\u2500 Composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the message textarea. */\n message: string;\n /** Placeholder of the message textarea. */\n inputPlaceholder: string;\n /** Send button (idle composer). */\n send: string;\n /** Stop button (composer while a run is in flight). */\n stop: string;\n /** Attach-files button. */\n attachFiles: string;\n /** Mic button while idle (start recording). */\n recordVoice: string;\n /** Mic button while recording (stop + transcribe). */\n stopRecording: string;\n /** Mic button while the clip is being transcribed. */\n transcribing: string;\n /** Mic button fallback message when transcription fails. */\n transcriptionFailed: string;\n\n // \u2500\u2500 Tool-call card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Status pill while the call runs. */\n toolRunning: string;\n /** Status pill on a gated call the run deferred, waiting on a person. */\n toolDeferred: string;\n /** Status pill on success. */\n toolDone: string;\n /** Status pill on error. */\n toolError: string;\n /** Status pill on a declined call. */\n toolDeclined: string;\n /** Accessible label on the panel resize handle. */\n resizePanel: string;\n /** Note on a tool card whose call a human approved. */\n decisionApproved: string;\n /** Note on a tool card whose call a human declined. */\n decisionDeclined: string;\n /** Heading over a tool card's arguments region. */\n argumentsLabel: string;\n /** Heading over a tool card's result region when the call succeeded. */\n resultLabel: string;\n /** Heading over a tool card's result region when the call failed. */\n errorLabel: string;\n /** Heading over a tool card's result region when the call was declined. */\n declinedLabel: string;\n /** Label on the toggle that expands a tool card's body. */\n details: string;\n\n // \u2500\u2500 Confirmation card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the inline confirmation card. */\n confirmAction: string;\n /** Generic confirmation prompt when a tool has no `x-confirm`. Token: `{tool}`. */\n confirmRun: string;\n /** Confirm button. */\n confirm: string;\n /** Cancel button (confirmation + delete confirm). */\n cancel: string;\n\n // \u2500\u2500 Approval card (server-side tool gate) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the inline server-side-tool approval card. */\n approveAction: string;\n /** Fallback approval prompt when the interrupt carries no message. */\n approvalPrompt: string;\n /** Approve button (runs the gated server-side tool). */\n approve: string;\n /** Deny button (declines the gated server-side tool). */\n deny: string;\n\n // \u2500\u2500 Question card (the `ask_user` frontend tool) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the inline question card. */\n askUserAction: string;\n /** Radio label for the free-text \"other\" choice (when custom answers are allowed). */\n otherOption: string;\n /** Placeholder for the free-text answer field. */\n answerPlaceholder: string;\n /** Submit button for the question card. */\n submit: string;\n\n // \u2500\u2500 Chat-history drawer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Drawer heading. */\n chats: string;\n /** Empty-state line when there are no threads. */\n noConversations: string;\n /** Rename row button (`title`). */\n rename: string;\n /** Rename row button `aria-label`. */\n renameConversation: string;\n /** Delete row button (`title`) + the inline-confirm action. */\n delete: string;\n /** Delete row button `aria-label`. */\n deleteConversation: string;\n /** Inline delete-confirm prompt. */\n deletePrompt: string;\n\n // \u2500\u2500 Attachments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Oversize rejection. Token: `{size}`. */\n tooLarge: string;\n /** Disallowed-type rejection. */\n fileTypeNotAllowed: string;\n /** Generic upload failure (when the error carries no message). */\n uploadFailed: string;\n /** Retry-upload button (`title`). */\n retry: string;\n /** Retry-upload button `aria-label`. */\n retryUpload: string;\n /** Remove-attachment button (`title`). */\n remove: string;\n /** Remove-attachment button `aria-label`. */\n removeAttachment: string;\n\n // \u2500\u2500 Relative time (drawer rows) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Under a minute ago. */\n justNow: string;\n /** Minutes ago. Token: `{n}`. */\n minutesAgo: string;\n /** Hours ago. Token: `{n}`. */\n hoursAgo: string;\n /** Title of the checkpoint panel. */\n /** Label on a code block's copy button. */\n copyCode: string;\n /** Shown on the copy button after the code reached the clipboard. */\n copied: string;\n /** Shown when the clipboard was unavailable or refused the write. */\n copyFailed: string;\n checkpoints: string;\n /** Empty state when no run can be continued. */\n noCheckpoints: string;\n /** Action: continue a run from its last checkpoint. */\n resumeRun: string;\n /** Action: branch a run without touching the original. */\n forkRun: string;\n /** Badge on a run that branched from another. */\n forkedRun: string;\n /** Days ago. Token: `{n}`. */\n daysAgo: string;\n /** Weeks ago. Token: `{n}`. */\n weeksAgo: string;\n}\n\n/** The built-in English strings \u2014 the fallback every override merges over. */\nexport const DEFAULT_UI_STRINGS: UiStrings = {\n title: \"Assistant\",\n chatHistory: \"Chat history\",\n newChat: \"New chat\",\n collapse: \"Collapse\",\n expand: \"Expand\",\n expandUnread: \"Expand \u2014 {count} unread\",\n toggleTheme: \"Toggle theme\",\n copyCode: \"Copy\",\n copied: \"Copied\",\n copyFailed: \"Copy failed\",\n checkpoints: \"Continue a run\",\n noCheckpoints: \"Nothing to continue yet.\",\n resumeRun: \"Resume\",\n forkRun: \"Fork\",\n forkedRun: \"branched\",\n\n conversation: \"Conversation\",\n thinking: \"Assistant is thinking\u2026\",\n thoughts: \"Thoughts\",\n stopped: \"\u23F9 Stopped\",\n connectionLost: \"Connection lost\",\n noResult: \"No result returned.\",\n declinedAction: \"User declined the action.\",\n navigating: \"Navigating\u2026\",\n historyCompacted: \"Earlier turns condensed to fit the context window ({count} removed)\",\n usingSkill: \"Using skill {name}\",\n runInterrupted: \"The previous response didn\u2019t finish \u2014 the page changed before it arrived.\",\n pageMoved:\n \"The page changed since you last looked at it. Call read_page to see the current page, then retry.\",\n attachmentsStillUploading:\n \"{n} file still uploading \u2014 it was not sent with this message and is still attached.\",\n skillNeeds: \"\u201C{title}\u201D needs {fields} \u2014 fill it in below, then send.\",\n\n message: \"Message\",\n inputPlaceholder: \"Ask anything\u2026\",\n send: \"Send\",\n stop: \"Stop\",\n attachFiles: \"Attach files\",\n recordVoice: \"Record voice\",\n stopRecording: \"Stop recording\",\n transcribing: \"Transcribing\u2026\",\n transcriptionFailed: \"Transcription failed\",\n\n toolRunning: \"running\u2026\",\n toolDeferred: \"waiting for you\",\n toolDone: \"\u2713 done\",\n toolError: \"\u26A0 error\",\n toolDeclined: \"\u2298 declined\",\n resizePanel: \"Resize the chat panel\",\n decisionApproved: \"approved by you\",\n decisionDeclined: \"declined by you\",\n argumentsLabel: \"Arguments\",\n resultLabel: \"Result\",\n errorLabel: \"Error\",\n declinedLabel: \"Declined\",\n details: \"Details\",\n\n confirmAction: \"Confirm action\",\n confirmRun: \"Run \u201C{tool}\u201D?\",\n confirm: \"Confirm\",\n cancel: \"Cancel\",\n\n approveAction: \"Approve action\",\n approvalPrompt: \"Approve this action?\",\n approve: \"Approve\",\n deny: \"Deny\",\n\n askUserAction: \"Question\",\n otherOption: \"Other\u2026\",\n answerPlaceholder: \"Type your answer\u2026\",\n submit: \"Submit\",\n\n chats: \"Chats\",\n noConversations: \"No conversations yet.\",\n rename: \"Rename\",\n renameConversation: \"Rename conversation\",\n delete: \"Delete\",\n deleteConversation: \"Delete conversation\",\n deletePrompt: \"Delete?\",\n\n tooLarge: \"Too large (max {size})\",\n fileTypeNotAllowed: \"File type not allowed\",\n uploadFailed: \"upload failed\",\n retry: \"Retry\",\n retryUpload: \"Retry upload\",\n remove: \"Remove\",\n removeAttachment: \"Remove attachment\",\n\n justNow: \"just now\",\n minutesAgo: \"{n}m ago\",\n hoursAgo: \"{n}h ago\",\n daysAgo: \"{n}d ago\",\n weeksAgo: \"{n}w ago\",\n};\n\n/**\n * Merge a partial set of overrides over {@link DEFAULT_UI_STRINGS}, yielding a\n * complete {@link UiStrings}. Keys whose override is `undefined` keep the\n * default (so a `data-strings` JSON with only a few keys \u2014 or a property carrying\n * explicit `undefined` \u2014 leaves the rest English).\n */\nexport function mergeUiStrings(overrides: Partial<UiStrings>): UiStrings {\n const merged: UiStrings = { ...DEFAULT_UI_STRINGS };\n for (const key of Object.keys(overrides) as (keyof UiStrings)[]) {\n const value = overrides[key];\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n return merged;\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** What the inline approval card displays for one server-side-tool interrupt. */\nexport interface ApprovalRequest {\n /**\n * Human-readable prompt from the AG-UI interrupt (e.g.\n * `Approve delete_thing({\u2026})?`). Falls back to the generic\n * {@link UiStrings.approvalPrompt} when the interrupt carries no message.\n */\n message?: string;\n /** Tool name, surfaced as a `data-tool-name` attribute for styling/tests. */\n toolName?: string;\n}\n\n/** Build a labelled action button. */\nfunction actionButton(modifier: string, label: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `approval-btn approval-btn--${modifier}`;\n button.setAttribute(\"part\", `approval-button approval-${modifier}`);\n button.textContent = label;\n return button;\n}\n\n/** Options for {@link requestApproval}. */\nexport interface ApprovalOptions {\n /**\n * Aborting this signal resolves the card as denied, with buttons disabled and\n * `data-resolved=\"denied\"` \u2014 how a Stop control dismisses a pending approval.\n */\n signal?: AbortSignal;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n strings?: UiStrings;\n}\n\n/**\n * A fully custom renderer for a server-side-tool approval, set via\n * `AgUiChat.approvalRenderer`. Receives the {@link ApprovalRequest} and an\n * `AbortSignal` that fires when the run is stopped, and resolves `true` to\n * approve or `false` to deny. Replaces the built-in {@link requestApproval}\n * card entirely, the host owning the DOM; to restyle the built-in card instead,\n * use the `strings` and `::part()` seams.\n */\nexport type ApprovalRenderer = (\n request: ApprovalRequest,\n options: { signal: AbortSignal },\n) => Promise<boolean>;\n\n/**\n * Append an inline approval card to `host` and resolve `true` to run a gated\n * server-side tool or `false` to deny it.\n *\n * Distinct from the client-tool confirmation card\n * ({@link requestConfirmation}): a gated server tool defers instead of\n * executing, so the run finishes on an AG-UI interrupt the client answers with\n * `resume[]`, and this is the browser half of that loop. Unlike the\n * confirmation card, this one stays in the transcript as a resolved record,\n * buttons disabled and `data-resolved` set.\n */\nexport function requestApproval(\n host: Node & ParentNode,\n request: ApprovalRequest,\n options: ApprovalOptions = {},\n): Promise<boolean> {\n const strings = options.strings ?? DEFAULT_UI_STRINGS;\n return new Promise<boolean>((resolve) => {\n const card = document.createElement(\"div\");\n card.className = \"approval\";\n card.setAttribute(\"part\", \"approval\");\n if (request.toolName !== undefined) {\n card.setAttribute(\"data-tool-name\", request.toolName);\n }\n card.setAttribute(\"role\", \"group\");\n card.setAttribute(\"aria-label\", strings.approveAction);\n\n const body = document.createElement(\"div\");\n body.className = \"approval-body\";\n body.setAttribute(\"part\", \"approval-body\");\n body.textContent = request.message ?? strings.approvalPrompt;\n\n const actions = document.createElement(\"div\");\n actions.className = \"approval-actions\";\n actions.setAttribute(\"part\", \"approval-actions\");\n\n const deny = actionButton(\"deny\", strings.deny);\n const approve = actionButton(\"approve\", strings.approve);\n\n let settled = false;\n const close = (approved: boolean): void => {\n if (settled) {\n return;\n }\n settled = true;\n deny.disabled = true;\n approve.disabled = true;\n card.setAttribute(\"data-resolved\", approved ? \"approved\" : \"denied\");\n resolve(approved);\n };\n\n deny.addEventListener(\"click\", () => close(false));\n approve.addEventListener(\"click\", () => close(true));\n options.signal?.addEventListener(\"abort\", () => close(false), { once: true });\n\n actions.append(deny, approve);\n card.append(body, actions);\n host.appendChild(card);\n if (options.signal?.aborted === true) {\n // The run was cancelled before the card could ask; record the denial.\n close(false);\n return;\n }\n approve.focus();\n });\n}\n", "import type { UiStrings } from \"./ui_strings.js\";\n\n/** How long the button shows its \"copied\" confirmation before reverting. */\nconst CONFIRM_MS = 1500;\n\n/**\n * Give every fenced code block in `root` a copy button.\n *\n * Call only on finished bubbles: the streaming bubble reassigns its `innerHTML`\n * on every delta, so a button attached mid-stream is discarded and rebuilt for\n * each one.\n *\n * Idempotent \u2014 a bubble already processed is skipped, so a re-render or a second\n * call cannot stack buttons.\n */\nexport function attachCopyButtons(root: ParentNode, strings: UiStrings): void {\n for (const pre of Array.from(root.querySelectorAll(\"pre\"))) {\n const code = pre.querySelector(\"code\");\n if (code === null || pre.querySelector(\".code-copy\") !== null) {\n continue;\n }\n pre.classList.add(\"has-copy\");\n pre.append(button(code, strings));\n }\n}\n\nfunction button(code: Element, strings: UiStrings): HTMLButtonElement {\n // Never null: `textContent` is nullable only on documents and doctypes,\n // and this is always the `code` element `querySelector` just returned.\n const text = code.textContent as string;\n const copy = document.createElement(\"button\");\n copy.type = \"button\";\n copy.className = \"code-copy\";\n copy.setAttribute(\"part\", \"code-copy\");\n copy.textContent = strings.copyCode;\n copy.title = strings.copyCode;\n copy.setAttribute(\"aria-label\", strings.copyCode);\n copy.addEventListener(\"click\", () => {\n void writeText(text).then((ok) => {\n // Report the real outcome: a button that always claims success leaves the\n // reader pasting stale clipboard content.\n confirm(copy, ok ? strings.copied : strings.copyFailed, strings);\n });\n });\n return copy;\n}\n\n/**\n * Copy `text`, reporting whether it landed. The Clipboard API needs a secure\n * context and a user gesture and is absent in some embeddings, so failure is an\n * ordinary outcome rather than an error to throw at the host page.\n */\nasync function writeText(text: string): Promise<boolean> {\n const clipboard = navigator.clipboard;\n if (clipboard === undefined) {\n return false;\n }\n try {\n await clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction confirm(copy: HTMLButtonElement, message: string, strings: UiStrings): void {\n copy.textContent = message;\n copy.dataset[\"state\"] = message === strings.copied ? \"copied\" : \"failed\";\n setTimeout(() => {\n copy.textContent = strings.copyCode;\n delete copy.dataset[\"state\"];\n }, CONFIRM_MS);\n}\n", "import { ICON_FILE, ICON_FILE_IMAGE, ICON_FILE_PDF, ICON_FILE_TEXT } from \"../constants.js\";\nimport type { AttachmentRef } from \"../core/attachment.js\";\n\n/**\n * Render the read-only attachment chips on a sent user message bubble and on\n * restored history \u2014 one chip per ref with a type icon, filename, and human\n * size. Static: no progress and no remove, both of which live in the composer\n * tray.\n */\nexport function renderAttachmentChips(refs: readonly AttachmentRef[]): HTMLDivElement {\n const list = document.createElement(\"div\");\n list.className = \"attachment-chips\";\n list.setAttribute(\"part\", \"attachment-chips\");\n for (const ref of refs) {\n list.appendChild(renderChip(ref));\n }\n return list;\n}\n\nfunction renderChip(ref: AttachmentRef): HTMLDivElement {\n const chip = document.createElement(\"div\");\n chip.className = \"attachment-chip attachment-chip--ready\";\n chip.setAttribute(\"part\", \"attachment-chip\");\n\n const icon = document.createElement(\"span\");\n icon.className = \"attachment-chip-icon\";\n icon.setAttribute(\"part\", \"attachment-chip-icon\");\n icon.innerHTML = iconFor(ref.mime);\n icon.setAttribute(\"aria-hidden\", \"true\");\n\n const name = document.createElement(\"span\");\n name.className = \"attachment-chip-name\";\n name.setAttribute(\"part\", \"attachment-chip-name\");\n name.textContent = ref.name;\n name.title = ref.name;\n\n const size = document.createElement(\"span\");\n size.className = \"attachment-chip-size\";\n size.setAttribute(\"part\", \"attachment-chip-size\");\n size.textContent = formatBytes(ref.size);\n\n chip.append(icon, name, size);\n return chip;\n}\n\n/**\n * A coarse type mark for a chip \u2014 image, PDF, text document, or generic file \u2014\n * as inline SVG markup rather than a character, so it matches the composer's\n * SVG buttons in weight and takes the glyph size and `currentColor`, which\n * emoji do not.\n *\n * The MIME string only selects among author-written constants and is never\n * interpolated into one, so the result is safe to assign as markup.\n */\nexport function iconFor(mime: string): string {\n if (mime.startsWith(\"image/\")) {\n return ICON_FILE_IMAGE;\n }\n if (mime === \"application/pdf\") {\n return ICON_FILE_PDF;\n }\n if (mime.startsWith(\"text/\")) {\n return ICON_FILE_TEXT;\n }\n return ICON_FILE;\n}\n\n/** A compact human-readable byte size (e.g. `1.2 MB`). */\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = [\"KB\", \"MB\", \"GB\"];\n let value = bytes / 1024;\n let unit = 0;\n while (value >= 1024 && unit < units.length - 1) {\n value /= 1024;\n unit += 1;\n }\n const rounded = value < 10 ? Math.round(value * 10) / 10 : Math.round(value);\n return `${rounded} ${units[unit]}`;\n}\n", "import { randomUUID } from \"@ag-ui/client\";\nimport { ATTACHMENT_STATUS } from \"../constants.js\";\nimport type { AttachmentRef } from \"../core/attachment.js\";\nimport type { UploadHandler } from \"../core/upload_attachment.js\";\nimport { formatBytes, iconFor } from \"./attachment_chips.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Status of a pending tray chip. */\ntype AttachmentStatus = (typeof ATTACHMENT_STATUS)[keyof typeof ATTACHMENT_STATUS];\n\n/** Config the host ({@link AgUiChat}) hands the tray. */\nexport interface AttachmentTrayConfig {\n /** Upload one file, reporting `0..1` progress; resolves to a durable ref. */\n readonly upload: UploadHandler;\n /** Client-side size cap in bytes (`0` = no cap). The server stays authoritative. */\n readonly maxBytes: number;\n /** Client-side accept list (`<input accept>` syntax; `\"\"` = any). */\n readonly accept: string;\n /** Fired when the set of attachments changes (add / settle / remove). */\n readonly onChange?: () => void;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n readonly strings?: UiStrings;\n}\n\n/** One pending file in the tray, from pick to ready/error. */\ninterface TrayItem {\n readonly localId: string;\n readonly file: File;\n status: AttachmentStatus;\n progress: number;\n ref: AttachmentRef | null;\n error: string;\n /** Aborts the in-flight upload when the chip is removed / the tray cleared. */\n controller: AbortController | null;\n}\n\n/**\n * The composer's pending-attachments tray: a chip per picked file with a\n * progress bar while it uploads, settling to a ready chip holding the durable\n * ref or an error chip with retry. A stateful view like {@link ThreadDrawer}:\n * the host appends {@link element}, calls {@link add} on pick or drop, reads\n * {@link readyRefs} on send, and clears it.\n *\n * Client-side size and type guards reject a bad file into an error chip without\n * uploading, for instant feedback, but the server stays the authority.\n */\nexport class AttachmentTray {\n /** The tray root; append above the input row. Hidden while empty. */\n readonly element: HTMLDivElement;\n\n readonly #config: AttachmentTrayConfig;\n readonly #strings: UiStrings;\n #items: TrayItem[] = [];\n\n constructor(config: AttachmentTrayConfig) {\n this.#config = config;\n this.#strings = config.strings ?? DEFAULT_UI_STRINGS;\n this.element = document.createElement(\"div\");\n this.element.className = \"attachment-tray\";\n this.element.setAttribute(\"part\", \"attachment-tray\");\n this.element.hidden = true;\n }\n\n /** Queue a file: reject oversize/disallowed into an error chip, else upload. */\n add(file: File): void {\n const item: TrayItem = {\n localId: randomUUID(),\n file,\n status: ATTACHMENT_STATUS.UPLOADING,\n progress: 0,\n ref: null,\n error: \"\",\n controller: null,\n };\n this.#items.push(item);\n const rejection = this.#reject(file);\n if (rejection !== null) {\n item.status = ATTACHMENT_STATUS.ERROR;\n item.error = rejection;\n this.#render();\n this.#config.onChange?.();\n return;\n }\n this.#render();\n this.#config.onChange?.();\n this.#upload(item);\n }\n\n /** The durable refs of every chip that finished uploading. */\n readyRefs(): readonly AttachmentRef[] {\n const refs: AttachmentRef[] = [];\n for (const item of this.#items) {\n if (item.ref !== null) {\n refs.push(item.ref);\n }\n }\n return refs;\n }\n\n /** Whether any chip is still uploading (a send would drop nothing if false). */\n hasPending(): boolean {\n return this.#items.some((item) => item.status === ATTACHMENT_STATUS.UPLOADING);\n }\n\n /** How many chips are still uploading \u2014 the count a send-time notice names. */\n pendingCount(): number {\n return this.#items.filter((item) => item.status === ATTACHMENT_STATUS.UPLOADING).length;\n }\n\n /** Whether the tray holds no chips. */\n isEmpty(): boolean {\n return this.#items.length === 0;\n }\n\n /** Drop the settled (ready / error) chips, leaving any still uploading. */\n clearReady(): void {\n this.#items = this.#items.filter((item) => item.status === ATTACHMENT_STATUS.UPLOADING);\n this.#render();\n }\n\n /** Drop every chip (a reset / new-chat), aborting any in-flight upload. */\n clear(): void {\n for (const item of this.#items) {\n item.controller?.abort();\n }\n this.#items = [];\n this.#render();\n }\n\n /**\n * Abort every in-flight upload without touching the rendered chips \u2014 the\n * teardown path when the host element is removed mid-upload, so a cancelled\n * transfer doesn't orphan a server-side file.\n */\n dispose(): void {\n for (const item of this.#items) {\n item.controller?.abort();\n }\n }\n\n /** The size/type rejection reason for a file, or `null` when accepted. */\n #reject(file: File): string | null {\n if (this.#config.maxBytes > 0 && file.size > this.#config.maxBytes) {\n return this.#strings.tooLarge.replace(\"{size}\", formatBytes(this.#config.maxBytes));\n }\n if (!accepts(this.#config.accept, file)) {\n return this.#strings.fileTypeNotAllowed;\n }\n return null;\n }\n\n #upload(item: TrayItem): void {\n // Re-apply the client guard on every attempt, not just the first `add` \u2014 an\n // ERROR chip always renders retry, so without this a size/type-rejected file\n // would upload in full on \u21BB.\n const rejection = this.#reject(item.file);\n if (rejection !== null) {\n item.status = ATTACHMENT_STATUS.ERROR;\n item.error = rejection;\n this.#render();\n this.#config.onChange?.();\n return;\n }\n item.status = ATTACHMENT_STATUS.UPLOADING;\n item.progress = 0;\n item.error = \"\";\n const controller = new AbortController();\n item.controller = controller;\n this.#render();\n this.#config\n .upload(\n item.file,\n (fraction) => {\n item.progress = fraction;\n this.#render();\n },\n controller.signal,\n )\n .then((ref) => {\n item.status = ATTACHMENT_STATUS.READY;\n item.ref = ref;\n })\n .catch((error: unknown) => {\n item.status = ATTACHMENT_STATUS.ERROR;\n item.error = error instanceof Error ? error.message : this.#strings.uploadFailed;\n })\n .finally(() => {\n item.controller = null;\n this.#render();\n this.#config.onChange?.();\n });\n }\n\n #remove(item: TrayItem): void {\n // Abort an in-flight upload so removing its chip doesn't orphan the file.\n item.controller?.abort();\n this.#items = this.#items.filter((other) => other !== item);\n this.#render();\n this.#config.onChange?.();\n }\n\n #render(): void {\n this.element.replaceChildren();\n this.element.hidden = this.#items.length === 0;\n for (const item of this.#items) {\n this.element.appendChild(this.#renderChip(item));\n }\n }\n\n #renderChip(item: TrayItem): HTMLDivElement {\n const chip = document.createElement(\"div\");\n chip.className = `attachment-chip attachment-chip--${item.status}`;\n chip.setAttribute(\"part\", \"attachment-chip\");\n\n const icon = document.createElement(\"span\");\n icon.className = \"attachment-chip-icon\";\n icon.setAttribute(\"part\", \"attachment-chip-icon\");\n // Author-written glyph markup, selected by MIME family \u2014 see iconFor.\n icon.innerHTML = iconFor(item.file.type);\n icon.setAttribute(\"aria-hidden\", \"true\");\n\n const name = document.createElement(\"span\");\n name.className = \"attachment-chip-name\";\n name.setAttribute(\"part\", \"attachment-chip-name\");\n name.textContent = item.file.name;\n name.title = item.file.name;\n\n const meta = document.createElement(\"span\");\n meta.className = \"attachment-chip-size\";\n meta.setAttribute(\"part\", \"attachment-chip-size\");\n meta.textContent =\n item.status === ATTACHMENT_STATUS.ERROR ? item.error : formatBytes(item.file.size);\n\n chip.append(icon, name, meta);\n\n if (item.status === ATTACHMENT_STATUS.UPLOADING) {\n const bar = document.createElement(\"div\");\n bar.className = \"attachment-chip-bar\";\n bar.setAttribute(\"part\", \"attachment-chip-bar\");\n const fill = document.createElement(\"div\");\n fill.className = \"attachment-chip-bar-fill\";\n fill.setAttribute(\"part\", \"attachment-chip-bar-fill\");\n fill.style.width = `${Math.round(item.progress * 100)}%`;\n bar.appendChild(fill);\n chip.appendChild(bar);\n }\n\n if (item.status === ATTACHMENT_STATUS.ERROR) {\n const retry = document.createElement(\"button\");\n retry.type = \"button\";\n retry.className = \"attachment-chip-retry\";\n retry.setAttribute(\"part\", \"attachment-chip-retry\");\n retry.title = this.#strings.retry;\n retry.setAttribute(\"aria-label\", this.#strings.retryUpload);\n retry.textContent = \"\u21BB\";\n retry.addEventListener(\"click\", () => this.#upload(item));\n chip.appendChild(retry);\n }\n\n const remove = document.createElement(\"button\");\n remove.type = \"button\";\n remove.className = \"attachment-chip-remove\";\n remove.setAttribute(\"part\", \"attachment-chip-remove\");\n remove.title = this.#strings.remove;\n remove.setAttribute(\"aria-label\", this.#strings.removeAttachment);\n remove.textContent = \"\u2715\";\n remove.addEventListener(\"click\", () => this.#remove(item));\n chip.appendChild(remove);\n\n return chip;\n }\n}\n\n/** Whether `file` matches an `<input accept>` list (`\"\"` accepts anything). */\nfunction accepts(accept: string, file: File): boolean {\n const tokens = accept\n .split(\",\")\n .map((token) => token.trim().toLowerCase())\n .filter((token) => token !== \"\");\n if (tokens.length === 0) {\n return true;\n }\n const mime = file.type.toLowerCase();\n const name = file.name.toLowerCase();\n return tokens.some((token) => {\n if (token.startsWith(\".\")) {\n return name.endsWith(token);\n }\n if (token.endsWith(\"/*\")) {\n return mime.startsWith(token.slice(0, -1));\n }\n return mime === token;\n });\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/**\n * A compact relative timestamp for a thread row \u2014 e.g. `\"just now\"`, `\"5m ago\"`,\n * `\"3h ago\"`, `\"2d ago\"`, `\"4w ago\"`.\n *\n * `now` is injectable so callers and tests can pin the reference point. A\n * future timestamp (clock skew) and a non-finite one (an unparseable or missing\n * `updated_at`, arriving as `NaN`) both read as `justNow`, rather than\n * rendering a nonsense age. Unit words come from {@link UiStrings} with `{n}`\n * filled in here; the bucketing stays integer-rounded and locale-neutral.\n */\nexport function relativeTime(\n timestamp: number,\n now: number = Date.now(),\n strings: UiStrings = DEFAULT_UI_STRINGS,\n): string {\n if (!Number.isFinite(timestamp)) {\n return strings.justNow;\n }\n const seconds = Math.round((now - timestamp) / 1000);\n if (seconds < 60) {\n return strings.justNow;\n }\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) {\n return strings.minutesAgo.replace(\"{n}\", String(minutes));\n }\n const hours = Math.round(minutes / 60);\n if (hours < 24) {\n return strings.hoursAgo.replace(\"{n}\", String(hours));\n }\n const days = Math.round(hours / 24);\n if (days < 7) {\n return strings.daysAgo.replace(\"{n}\", String(days));\n }\n return strings.weeksAgo.replace(\"{n}\", String(Math.round(days / 7)));\n}\n", "import type { RunRow } from \"../core/run_index.js\";\nimport { relativeTime } from \"./relative_time.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** How the host continues a picked run. */\nexport type CheckpointVerb = \"resume\" | \"fork\";\n\n/** The run's first message, or `null` where the row has no words to show. */\nfunction previewOf(run: RunRow): string | null {\n return run.preview !== undefined && run.preview !== null && run.preview !== \"\"\n ? run.preview\n : null;\n}\n\n/**\n * A preview reduced to what the row puts on screen, for comparing two rows.\n *\n * Whitespace is collapsed because the rendered row collapses it anyway, so two\n * previews that differ only there are one label to the eye. Case is kept: two\n * spellings a person can tell apart are two labels, and an id beside them would\n * answer a question nobody asked.\n */\nfunction asShown(preview: string): string {\n return preview.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * The checkpoint panel: continuable runs, each offering **resume** or **fork**.\n *\n * Deliberately separate from the thread drawer: a thread is a conversation you\n * switch to, a checkpoint is a run you continue from, and one thread holds\n * many. One list would make \"resume\" read as \"open\", when resuming starts a new\n * run seeded from a snapshot.\n *\n * The host feeds only rows the server marked `continuable`, a run without a\n * snapshot having nothing to resume from. Pure DOM, like {@link SkillsMenu}:\n * append {@link element}, toggle it, feed {@link setRuns}, act on\n * {@link onPick}.\n */\nexport class CheckpointMenu {\n /** The panel root. Append to the chat shell; hidden until opened. */\n readonly element: HTMLDivElement;\n\n readonly #onPick: (runId: string, verb: CheckpointVerb) => void;\n readonly #list: HTMLDivElement;\n readonly #heading: HTMLSpanElement;\n /** What had focus before the panel opened, restored on close. */\n #lastFocused: HTMLElement | null = null;\n #strings: UiStrings;\n #runs: readonly RunRow[] = [];\n\n constructor(\n onPick: (runId: string, verb: CheckpointVerb) => void,\n strings: UiStrings = DEFAULT_UI_STRINGS,\n ) {\n this.#onPick = onPick;\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"checkpoints\";\n this.element.setAttribute(\"part\", \"checkpoints\");\n this.element.setAttribute(\"role\", \"dialog\");\n this.element.setAttribute(\"aria-label\", strings.checkpoints);\n // Focusable as a fallback: with no continuable runs the panel holds no\n // controls at all, and a dialog that cannot take focus strands the\n // keyboard user outside it with no way back except Tab-ing blind.\n this.element.tabIndex = -1;\n this.element.hidden = true;\n\n const header = document.createElement(\"div\");\n header.className = \"checkpoints-header\";\n header.setAttribute(\"part\", \"checkpoints-header\");\n this.#heading = document.createElement(\"span\");\n this.#heading.className = \"checkpoints-title\";\n this.#heading.setAttribute(\"part\", \"checkpoints-title\");\n this.#heading.textContent = strings.checkpoints;\n header.append(this.#heading);\n\n this.#list = document.createElement(\"div\");\n this.#list.className = \"checkpoints-list\";\n this.#list.setAttribute(\"part\", \"checkpoints-list\");\n\n this.element.append(header, this.#list);\n this.element.addEventListener(\"keydown\", (event) => this.#onKeydown(event));\n }\n\n /** Replace the rows. The host passes only `continuable` runs. */\n setRuns(runs: readonly RunRow[]): void {\n this.#runs = runs;\n this.#render();\n }\n\n /** Re-localize a panel built before the host's strings resolved. */\n setStrings(strings: UiStrings): void {\n this.#strings = strings;\n this.element.setAttribute(\"aria-label\", strings.checkpoints);\n this.#heading.textContent = strings.checkpoints;\n this.#render();\n }\n\n open(): void {\n if (this.open_) {\n return;\n }\n // Remember what had focus so it is restored on close, then move focus into\n // the panel so a keyboard user lands inside the dialog rather than being\n // left behind it. The thread drawer already does this; a dialog that takes\n // no focus is one a keyboard user cannot reach and a screen reader does not\n // announce, however correct its role and label.\n this.#lastFocused = this.#activeElement() as HTMLElement | null;\n this.element.hidden = false;\n (this.#focusables()[0] ?? this.element).focus();\n }\n\n close(): void {\n if (!this.open_) {\n return;\n }\n this.element.hidden = true;\n this.#lastFocused?.focus();\n this.#lastFocused = null;\n }\n\n /** The focused element within this panel's root (shadow-aware). */\n #activeElement(): Element | null {\n return (this.element.getRootNode() as Document | ShadowRoot).activeElement;\n }\n\n /** The panel's tabbable controls, in document order. */\n #focusables(): HTMLElement[] {\n return Array.from(this.element.querySelectorAll<HTMLElement>(\"button, [tabindex]\")).filter(\n (el) => !el.hidden,\n );\n }\n\n /** Escape closes; Tab is trapped so focus cannot wander behind the dialog. */\n #onKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n event.stopPropagation();\n this.close();\n return;\n }\n if (event.key !== \"Tab\") {\n return;\n }\n const focusables = this.#focusables();\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = this.#activeElement();\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first?.focus();\n }\n }\n\n get open_(): boolean {\n return !this.element.hidden;\n }\n\n #render(): void {\n this.#list.replaceChildren();\n if (this.#runs.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"checkpoints-empty\";\n empty.setAttribute(\"part\", \"checkpoints-empty\");\n empty.textContent = this.#strings.noCheckpoints;\n this.#list.append(empty);\n return;\n }\n const repeated = this.#repeatedPreviews();\n for (const run of this.#runs) {\n this.#list.append(this.#row(run, repeated));\n }\n }\n\n /**\n * The previews more than one row shows.\n *\n * A preview identifies a run only while it is that run's alone. A real index\n * answered with five runs opening on the same sentence, and those rows read\n * alike exactly as bare timestamps used to \u2014 so where the words repeat the\n * short id comes back, and where they do not the row is left as it is.\n */\n #repeatedPreviews(): ReadonlySet<string> {\n const seen = new Set<string>();\n const repeated = new Set<string>();\n for (const run of this.#runs) {\n const preview = previewOf(run);\n if (preview === null) {\n continue;\n }\n const shown = asShown(preview);\n if (seen.has(shown)) {\n repeated.add(shown);\n }\n seen.add(shown);\n }\n return repeated;\n }\n\n #row(run: RunRow, repeated: ReadonlySet<string>): HTMLDivElement {\n const row = document.createElement(\"div\");\n row.className = \"checkpoint-row\";\n row.setAttribute(\"part\", \"checkpoint-row\");\n\n const preview = previewOf(run);\n const time =\n run.started_at === null\n ? null\n : relativeTime(Date.parse(run.started_at), Date.now(), this.#strings);\n\n const label = document.createElement(\"span\");\n label.className = \"checkpoint-label\";\n label.setAttribute(\"part\", \"checkpoint-label\");\n // What the run was about, if the server says. Otherwise the time, and only\n // then the id \u2014 a person recognises the first, reads the second, and\n // recognises nothing at all in the third.\n label.textContent = preview ?? time ?? run.run_id;\n row.append(label);\n\n if (preview !== null && time !== null) {\n // Demoted to a chip: with words in the label the time is no longer what\n // identifies the run, but it still orders it.\n const when = document.createElement(\"span\");\n when.className = \"checkpoint-time\";\n when.setAttribute(\"part\", \"checkpoint-time\");\n when.textContent = time;\n row.append(when);\n }\n\n // The id, for a row whose label does not identify the run on its own: two\n // runs a few seconds apart both read \"just now\", and words another row also\n // opens with name neither of them. Picking between either pair is picking\n // blind. Shown rather than left in a tooltip, since a hover is not an\n // identity either \u2014 and eight characters beats a full id on the row. A\n // label that already is the id needs no second copy, and a run that arrived\n // without one has nothing better to offer than the words it shares.\n const ambiguous = preview === null ? time !== null : repeated.has(asShown(preview));\n if (ambiguous && run.run_id !== \"\") {\n const short = document.createElement(\"span\");\n short.className = \"checkpoint-id\";\n short.setAttribute(\"part\", \"checkpoint-id\");\n short.textContent = run.run_id.slice(0, 8);\n short.title = run.run_id;\n row.append(short);\n }\n\n if (run.parent_run_id !== null) {\n // Lineage, so a branch doesn't read as a duplicate of its parent.\n const branch = document.createElement(\"span\");\n branch.className = \"checkpoint-branch\";\n branch.setAttribute(\"part\", \"checkpoint-branch\");\n branch.textContent = this.#strings.forkedRun;\n branch.title = run.parent_run_id;\n row.append(branch);\n }\n\n row.append(\n this.#action(run.run_id, \"resume\", this.#strings.resumeRun),\n this.#action(run.run_id, \"fork\", this.#strings.forkRun),\n );\n return row;\n }\n\n #action(runId: string, verb: CheckpointVerb, label: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `checkpoint-action checkpoint-${verb}`;\n button.setAttribute(\"part\", `checkpoint-action checkpoint-${verb}`);\n button.textContent = label;\n button.addEventListener(\"click\", () => {\n this.close();\n this.#onPick(runId, verb);\n });\n return button;\n }\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** What the inline confirmation card displays. */\nexport interface ConfirmationRequest {\n toolName: string;\n args: Record<string, unknown>;\n /**\n * Human-readable prompt (from the tool's `x-confirm` metadata), e.g.\n * \"Activate this project?\". Falls back to the generic `confirmRun` template.\n */\n message?: string;\n}\n\n/** Build a labelled action button. */\nfunction actionButton(modifier: string, label: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `confirm-btn confirm-btn--${modifier}`;\n button.setAttribute(\"part\", `confirm-button confirm-${modifier}`);\n button.textContent = label;\n return button;\n}\n\n/** Options for {@link requestConfirmation}. */\nexport interface ConfirmationOptions {\n /**\n * Aborting this signal resolves the card as declined, with buttons disabled\n * and `data-resolved=\"declined\"` \u2014 how a Stop control dismisses a pending\n * confirmation.\n */\n signal?: AbortSignal;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n strings?: UiStrings;\n}\n\n/**\n * Append an inline confirmation card to `host` (the chat message list) and\n * resolve `true` on confirm, `false` on cancel.\n *\n * The card lives in the transcript rather than in a modal overlay, so it reads\n * after the assistant's explanation and never steals focus from the page.\n *\n * Answering it removes it: the record of the decision belongs to the tool card\n * this gates, which settles to `done` or `declined` and carries it. A spent\n * form left in place reads as still outstanding.\n */\nexport function requestConfirmation(\n host: Node & ParentNode,\n request: ConfirmationRequest,\n options: ConfirmationOptions = {},\n): Promise<boolean> {\n const strings = options.strings ?? DEFAULT_UI_STRINGS;\n return new Promise<boolean>((resolve) => {\n const card = document.createElement(\"div\");\n card.className = \"confirm\";\n card.setAttribute(\"part\", \"confirm\");\n card.setAttribute(\"data-tool-name\", request.toolName);\n card.setAttribute(\"role\", \"group\");\n card.setAttribute(\"aria-label\", strings.confirmAction);\n\n const body = document.createElement(\"div\");\n body.className = \"confirm-body\";\n body.setAttribute(\"part\", \"confirm-body\");\n body.textContent = request.message ?? strings.confirmRun.replace(\"{tool}\", request.toolName);\n\n const args = document.createElement(\"pre\");\n args.className = \"confirm-args\";\n args.setAttribute(\"part\", \"confirm-args\");\n args.textContent = JSON.stringify(request.args, null, 2);\n // A call with no arguments rendered the string \"{}\" in a box of its own.\n args.hidden = Object.keys(request.args).length === 0;\n\n const actions = document.createElement(\"div\");\n actions.className = \"confirm-actions\";\n actions.setAttribute(\"part\", \"confirm-actions\");\n\n const cancel = actionButton(\"cancel\", strings.cancel);\n const confirm = actionButton(\"confirm\", strings.confirm);\n\n let settled = false;\n const close = (accepted: boolean): void => {\n if (settled) {\n return;\n }\n settled = true;\n // The prompt leaves once it has been answered. What stays is the tool\n // card next to it, which settles to the outcome and scrolls with the rest\n // of the transcript -- a record of the action rather than a spent form\n // sitting there as a standing reminder of one.\n card.remove();\n resolve(accepted);\n };\n\n cancel.addEventListener(\"click\", () => close(false));\n confirm.addEventListener(\"click\", () => close(true));\n options.signal?.addEventListener(\"abort\", () => close(false), { once: true });\n\n actions.append(cancel, confirm);\n card.append(body, args, actions);\n host.appendChild(card);\n if (options.signal?.aborted === true) {\n // The run was cancelled before the card could ask; record the decline.\n close(false);\n return;\n }\n confirm.focus();\n });\n}\n", "/**\n * Prettify a raw tool name for display: separators become spaces and the\n * first letter is capitalised \u2014 `list_projects` \u2192 \"List projects\",\n * `invoices.retrieve` \u2192 \"Invoices retrieve\".\n *\n * Final fallback of the tool-card label chain (`x-summary` \u2192\n * `toolSummaries` \u2192 fetched catalog \u2192 this). Purely cosmetic: the original\n * name still rides on the card's dataset for debugging.\n */\nexport function prettifyToolName(name: string): string {\n const spaced = name.replace(/[._-]+/g, \" \").trim();\n if (spaced === \"\") {\n return name;\n }\n return spaced.charAt(0).toUpperCase() + spaced.slice(1);\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** What the inline question card asks (the `ask_user` frontend tool's args). */\nexport interface QuestionRequest {\n /** The question shown to the user. */\n question: string;\n /**\n * Preset choices rendered as radios. When empty/omitted the card is a plain\n * free-text prompt.\n */\n options?: readonly string[];\n /**\n * Whether the user may type a custom answer. With `options`, adds an \"other\"\n * radio revealing a text field; without options the card is free-text anyway.\n */\n allowCustom?: boolean;\n}\n\n/** Options for {@link requestQuestion}. */\nexport interface QuestionOptions {\n /**\n * Aborting this signal resolves the card with an empty answer and disabled\n * fields \u2014 how a Stop control dismisses an open question.\n */\n signal?: AbortSignal;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n strings?: UiStrings;\n}\n\n/**\n * A fully custom renderer for the `ask_user` question, set via\n * `AgUiChat.askUserRenderer`. Receives the parsed {@link QuestionRequest} and an\n * `AbortSignal` that fires when the run is stopped, and resolves with the user's\n * answer; an empty string means no answer. Replaces the built-in\n * {@link requestQuestion} card entirely \u2014 see {@link ApprovalRenderer} for the\n * same seam on approvals.\n */\nexport type QuestionRenderer = (\n request: QuestionRequest,\n options: { signal: AbortSignal },\n) => Promise<string>;\n\n/** A single custom-answer text field. */\nfunction answerInput(placeholder: string): HTMLInputElement {\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.className = \"question-input\";\n input.setAttribute(\"part\", \"question-input\");\n input.placeholder = placeholder;\n return input;\n}\n\n/**\n * Append an inline question card to `host` and resolve with the user's answer \u2014\n * the browser half of the built-in `ask_user` frontend tool.\n *\n * Collects a typed answer rather than the yes/no the confirmation and approval\n * cards return: a radio pick from `options`, or free text when `allowCustom` is\n * set or no `options` are given. Stays in the transcript as a resolved record,\n * controls disabled and `data-resolved` set; a Stop while it is open resolves\n * it with an empty string.\n */\nexport function requestQuestion(\n host: Node & ParentNode,\n request: QuestionRequest,\n options: QuestionOptions = {},\n): Promise<string> {\n const strings = options.strings ?? DEFAULT_UI_STRINGS;\n const choices = request.options ?? [];\n const hasChoices = choices.length > 0;\n // Free text is offered when there are no preset choices, or when custom\n // answers are explicitly allowed alongside them (via an \"other\" radio).\n const allowsText = !hasChoices || request.allowCustom === true;\n\n return new Promise<string>((resolve) => {\n const card = document.createElement(\"div\");\n card.className = \"question\";\n card.setAttribute(\"part\", \"question\");\n card.setAttribute(\"role\", \"group\");\n card.setAttribute(\"aria-label\", strings.askUserAction);\n\n const body = document.createElement(\"div\");\n body.className = \"question-body\";\n body.setAttribute(\"part\", \"question-body\");\n body.textContent = request.question;\n\n const form = document.createElement(\"div\");\n form.className = \"question-options\";\n form.setAttribute(\"part\", \"question-options\");\n\n // `name` scopes the radio group to this card so multiple open cards don't\n // interfere; a per-card token keeps it unique without module state.\n const group = `q-${choices.length}-${request.question.length}`;\n const radios: HTMLInputElement[] = [];\n for (const choice of choices) {\n const label = document.createElement(\"label\");\n label.className = \"question-choice\";\n label.setAttribute(\"part\", \"question-choice\");\n const radio = document.createElement(\"input\");\n radio.type = \"radio\";\n radio.name = group;\n radio.value = choice;\n radio.setAttribute(\"part\", \"question-radio\");\n const text = document.createElement(\"span\");\n text.setAttribute(\"part\", \"question-choice-text\");\n text.textContent = choice;\n label.append(radio, text);\n form.appendChild(label);\n radios.push(radio);\n }\n\n // The \"other\" radio (only alongside choices) toggles the free-text field.\n let otherRadio: HTMLInputElement | null = null;\n let input: HTMLInputElement | null = null;\n if (allowsText) {\n input = answerInput(strings.answerPlaceholder);\n if (hasChoices) {\n const label = document.createElement(\"label\");\n label.className = \"question-choice\";\n label.setAttribute(\"part\", \"question-choice\");\n otherRadio = document.createElement(\"input\");\n otherRadio.type = \"radio\";\n otherRadio.name = group;\n otherRadio.value = \"\";\n otherRadio.setAttribute(\"part\", \"question-radio\");\n const text = document.createElement(\"span\");\n text.setAttribute(\"part\", \"question-choice-text\");\n text.textContent = strings.otherOption;\n label.append(otherRadio, text);\n form.appendChild(label);\n input.disabled = true;\n }\n form.appendChild(input);\n }\n\n const actions = document.createElement(\"div\");\n actions.className = \"question-actions\";\n actions.setAttribute(\"part\", \"question-actions\");\n const submit = document.createElement(\"button\");\n submit.type = \"button\";\n submit.className = \"question-btn\";\n submit.setAttribute(\"part\", \"question-button\");\n submit.textContent = strings.submit;\n actions.appendChild(submit);\n\n let settled = false;\n const answerFor = (): string | null => {\n const picked = radios.find((r) => r.checked);\n if (picked !== undefined) {\n return picked.value;\n }\n if (input !== null && (otherRadio === null || otherRadio.checked)) {\n const typed = input.value.trim();\n return typed === \"\" ? null : typed;\n }\n return null;\n };\n const refresh = (): void => {\n if (input !== null && otherRadio !== null) {\n input.disabled = !otherRadio.checked;\n }\n submit.disabled = answerFor() === null;\n };\n const close = (answer: string): void => {\n if (settled) {\n return;\n }\n settled = true;\n submit.disabled = true;\n for (const radio of radios) {\n radio.disabled = true;\n }\n if (otherRadio !== null) {\n otherRadio.disabled = true;\n }\n if (input !== null) {\n input.disabled = true;\n }\n card.setAttribute(\"data-resolved\", answer === \"\" ? \"cancelled\" : \"answered\");\n resolve(answer);\n };\n\n for (const radio of [...radios, ...(otherRadio !== null ? [otherRadio] : [])]) {\n radio.addEventListener(\"change\", refresh);\n }\n input?.addEventListener(\"input\", refresh);\n input?.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n const answer = answerFor();\n if (answer !== null) {\n close(answer);\n }\n }\n });\n submit.addEventListener(\"click\", () => {\n const answer = answerFor();\n if (answer !== null) {\n close(answer);\n }\n });\n options.signal?.addEventListener(\"abort\", () => close(\"\"), { once: true });\n\n card.append(body, form, actions);\n host.appendChild(card);\n if (options.signal?.aborted === true) {\n close(\"\");\n return;\n }\n refresh();\n (hasChoices ? radios[0] : input)?.focus();\n });\n}\n", "const {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!freeze) {\n freeze = function <T>(x: T): T {\n return x;\n };\n}\n\nif (!seal) {\n seal = function <T>(x: T): T {\n return x;\n };\n}\n\nif (!apply) {\n apply = function <T>(\n func: (thisArg: any, ...args: any[]) => T,\n thisArg: any,\n ...args: any[]\n ): T {\n return func.apply(thisArg, args);\n };\n}\n\nif (!construct) {\n construct = function <T>(Func: new (...args: any[]) => T, ...args: any[]): T {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\nconst arraySplice = unapply(Array.prototype.splice);\nconst arrayIsArray = Array.isArray;\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst numberToString = unapply(Number.prototype.toString);\nconst booleanToString = unapply(Boolean.prototype.toString);\nconst bigintToString =\n typeof BigInt === 'undefined' ? null : unapply(BigInt.prototype.toString);\nconst symbolToString =\n typeof Symbol === 'undefined' ? null : unapply(Symbol.prototype.toString);\n\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst objectToString = unapply(Object.prototype.toString);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply<T>(\n func: (thisArg: any, ...args: any[]) => T\n): (thisArg: any, ...args: any[]) => T {\n return (thisArg: any, ...args: any[]): T => {\n if (thisArg instanceof RegExp) {\n thisArg.lastIndex = 0;\n }\n\n return apply(func, thisArg, args);\n };\n}\n\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct<T>(\n Func: new (...args: any[]) => T\n): (...args: any[]) => T {\n return (...args: any[]): T => construct(Func, args);\n}\n\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(\n set: Record<string, boolean>,\n array: readonly unknown[],\n transformCaseFunc: ReturnType<typeof unapply<string>> = stringToLowerCase\n): Record<string, boolean> {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n if (!arrayIsArray(array)) {\n return set;\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n (array as unknown[])[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element as string] = true;\n }\n\n return set;\n}\n\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray<T>(array: T[]): Array<T | null> {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n\n return array;\n}\n\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone<T extends Record<string, any>>(object: T): T {\n const newObject = create(null);\n\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n\n if (isPropertyExist) {\n if (arrayIsArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (\n value &&\n typeof value === 'object' &&\n value.constructor === Object\n ) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n\n return newObject;\n}\n\n/**\n * Convert non-node values into strings without depending on direct property access.\n *\n * @param value - The value to stringify.\n * @returns A string representation of the provided value.\n */\nfunction stringifyValue(value: unknown): string {\n switch (typeof value) {\n case 'string': {\n return value;\n }\n\n case 'number': {\n return numberToString(value);\n }\n\n case 'boolean': {\n return booleanToString(value);\n }\n\n case 'bigint': {\n return bigintToString ? bigintToString(value) : '0';\n }\n\n case 'symbol': {\n return symbolToString ? symbolToString(value) : 'Symbol()';\n }\n\n case 'undefined': {\n return objectToString(value);\n }\n\n case 'function':\n case 'object': {\n if (value === null) {\n return objectToString(value);\n }\n\n const valueAsRecord = value as Record<string, any>;\n const valueToString = lookupGetter(valueAsRecord, 'toString');\n\n if (typeof valueToString === 'function') {\n const stringified = valueToString(valueAsRecord);\n\n return typeof stringified === 'string'\n ? stringified\n : objectToString(stringified);\n }\n\n return objectToString(value);\n }\n\n default: {\n return objectToString(value);\n }\n }\n}\n\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter<T extends Record<string, any>>(\n object: T,\n prop: string\n): ReturnType<typeof unapply<any>> | (() => null) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(): null {\n return null;\n }\n\n return fallbackValue;\n}\n\nfunction isRegex(value: unknown): value is RegExp {\n try {\n regExpTest(value as RegExp, '');\n return true;\n } catch {\n return false;\n }\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayIsArray,\n arrayLastIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n arraySplice,\n // Object\n entries,\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n isFrozen,\n setPrototypeOf,\n seal,\n clone,\n create,\n objectHasOwnProperty,\n objectToString,\n // RegExp\n regExpTest,\n isRegex,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringTrim,\n // Other conversion\n stringifyValue,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n addToSet,\n // Reflect\n unapply,\n unconstruct,\n};\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'search',\n 'section',\n 'select',\n 'shadow',\n 'slot',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n] as const);\n\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'enterkeyhint',\n 'exportparts',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'inputmode',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'part',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n] as const);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n] as const);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n] as const);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n 'mprescripts',\n] as const);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n] as const);\n\nexport const text = freeze(['#text'] as const);\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'command',\n 'commandfor',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'exportparts',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inert',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'part',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'popover',\n 'popovertarget',\n 'popovertargetaction',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'slot',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'wrap',\n 'xmlns',\n] as const);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'amplitude',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dominant-baseline',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'exponent',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'intercept',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'mask-type',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'slope',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'tablevalues',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-orientation',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n] as const);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnalign',\n 'columnlines',\n 'columnspacing',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lquote',\n 'lspace',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n] as const);\n", "import { seal } from './utils.js';\n\nexport const MUSTACHE_EXPR = seal(/{{[\\w\\W]*|^[\\w\\W]*}}/g);\nexport const ERB_EXPR = seal(/<%[\\w\\W]*|^[\\w\\W]*%>/g);\nexport const TMPLIT_EXPR = seal(/\\${[\\w\\W]*/g);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nexport const DOCTYPE_NAME = seal(/^html$/i);\nexport const CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\n// Markup-significant character probes used by _sanitizeElements.\n// Shared module-level instances are safe despite the sticky /g flags:\n// unapply() resets lastIndex for RegExp receivers before every call.\nexport const ELEMENT_MARKUP_PROBE = seal(/<[/\\w!]/g);\nexport const COMMENT_MARKUP_PROBE = seal(/<[/\\w]/g);\nexport const FALLBACK_TAG_CLOSE = seal(/<\\/no(script|embed|frames)/i);\nexport const SELF_CLOSING_TAG = seal(/\\/>/i);\n", "import type { Config, UseProfilesConfig } from './config';\nimport type { DOMPurify, HooksMap, HookFunction, WindowLike } from './types';\nimport * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n entries,\n freeze,\n seal,\n arrayForEach,\n arrayIsArray,\n arrayLastIndexOf,\n arrayPop,\n arrayPush,\n arraySplice,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringIndexOf,\n stringTrim,\n regExpTest,\n isRegex,\n typeErrorCreate,\n lookupGetter,\n create,\n objectHasOwnProperty,\n stringifyValue,\n} from './utils.js';\n\nexport type { Config } from './config';\n\nexport type {\n DOMPurify,\n RemovedElement,\n RemovedAttribute,\n HookName,\n NodeHook,\n ElementHook,\n DocumentFragmentHook,\n UponSanitizeElementHook,\n UponSanitizeAttributeHook,\n UponSanitizeElementHookEvent,\n UponSanitizeAttributeHookEvent,\n WindowLike,\n} from './types';\n\ndeclare const VERSION: string;\n\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5, // Deprecated\n entityNode: 6, // Deprecated\n processingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12, // Deprecated\n};\n\nconst getGlobal = function (): WindowLike {\n return typeof window === 'undefined' ? null : window;\n};\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function (\n trustedTypes: TrustedTypePolicyFactory,\n purifyHostElement: HTMLScriptElement\n) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nconst _createHooksMap = function (): HooksMap {\n return {\n afterSanitizeAttributes: [],\n afterSanitizeElements: [],\n afterSanitizeShadowDOM: [],\n beforeSanitizeAttributes: [],\n beforeSanitizeElements: [],\n beforeSanitizeShadowDOM: [],\n uponSanitizeAttribute: [],\n uponSanitizeElement: [],\n uponSanitizeShadowNode: [],\n };\n};\n\n/**\n * Resolve a set-valued configuration option: a fresh set built from\n * cfg[key] when it is an own array property (seeded with a clone of\n * options.base when given, case-normalized via options.transform),\n * the fallback set otherwise.\n *\n * @param cfg the cloned, prototype-free configuration object\n * @param key the configuration property to read\n * @param fallback the set to use when the option is absent or not an array\n * @param options transform and optional base set to merge into\n * @returns the resolved set\n */\nconst _resolveSetOption = function (\n cfg: Config,\n key: keyof Config,\n fallback: Record<string, boolean>,\n options: {\n transform: Parameters<typeof addToSet>[2];\n base?: Record<string, boolean>;\n }\n): Record<string, boolean> {\n return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key])\n ? addToSet(\n options.base ? clone(options.base) : {},\n cfg[key] as readonly unknown[],\n options.transform\n )\n : fallback;\n};\n\nfunction createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {\n const DOMPurify: DOMPurify = (root: WindowLike) => createDOMPurify(root);\n\n DOMPurify.version = VERSION;\n\n DOMPurify.removed = [];\n\n if (\n !window ||\n !window.document ||\n window.document.nodeType !== NODE_TYPE.document ||\n !window.Element\n ) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n let { document } = window;\n\n const originalDocument = document;\n const currentScript: HTMLScriptElement =\n originalDocument.currentScript as HTMLScriptElement;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || (window as any).MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes,\n } = window;\n\n const ElementPrototype = Element.prototype;\n\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n const getShadowRoot = lookupGetter(ElementPrototype, 'shadowRoot');\n const getAttributes = lookupGetter(ElementPrototype, 'attributes');\n const getNodeType =\n Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeType') : null;\n const getNodeName =\n Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeName') : null;\n const getOwnerDocument =\n Node && Node.prototype\n ? lookupGetter(Node.prototype, 'ownerDocument')\n : null;\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n let trustedTypesPolicy;\n let emptyHTML = '';\n\n // The instance's own internal Trusted Types policy. Unlike a caller-supplied\n // `TRUSTED_TYPES_POLICY`, this is created at most once \u2014 Trusted Types throws\n // on duplicate policy names \u2014 and is the only policy allowed to persist\n // across configurations and survive `clearConfig()`.\n let defaultTrustedTypesPolicy;\n let defaultTrustedTypesPolicyResolved = false;\n\n // Tracks whether we are already inside a call to the configured Trusted Types\n // policy (`createHTML` or `createScriptURL`). If a supplied policy callback\n // itself calls `DOMPurify.sanitize` (the cause of #1422), `sanitize` would\n // re-enter the policy and recurse until the stack overflows. We detect that\n // re-entry and throw a clear, actionable error instead. The guard is shared\n // across both callbacks, because either one re-entering `sanitize` triggers\n // the same unbounded recursion.\n let IN_TRUSTED_TYPES_POLICY = 0;\n const _assertNotInTrustedTypesPolicy = function (): void {\n if (IN_TRUSTED_TYPES_POLICY > 0) {\n throw typeErrorCreate(\n 'A configured TRUSTED_TYPES_POLICY callback (createHTML or ' +\n 'createScriptURL) must not call DOMPurify.sanitize, as that causes ' +\n 'infinite recursion. Do not pass a policy whose callbacks wrap ' +\n 'DOMPurify as TRUSTED_TYPES_POLICY; see the \"DOMPurify and Trusted ' +\n 'Types\" section of the README.'\n );\n }\n };\n\n const _createTrustedHTML = function (html: string): string {\n _assertNotInTrustedTypesPolicy();\n\n IN_TRUSTED_TYPES_POLICY++;\n try {\n return trustedTypesPolicy.createHTML(html);\n } finally {\n IN_TRUSTED_TYPES_POLICY--;\n }\n };\n\n const _createTrustedScriptURL = function (scriptUrl: string): string {\n _assertNotInTrustedTypesPolicy();\n\n IN_TRUSTED_TYPES_POLICY++;\n try {\n return trustedTypesPolicy.createScriptURL(scriptUrl);\n } finally {\n IN_TRUSTED_TYPES_POLICY--;\n }\n };\n\n // Lazily resolve (and cache) the instance's internal default policy.\n // Resolution is attempted at most once: a successful `createPolicy` cannot be\n // repeated (Trusted Types throws on duplicate names), and a failed or\n // unsupported attempt must not be retried on every parse.\n const _getDefaultTrustedTypesPolicy = function () {\n if (!defaultTrustedTypesPolicyResolved) {\n defaultTrustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n currentScript\n );\n defaultTrustedTypesPolicyResolved = true;\n }\n\n return defaultTrustedTypesPolicy;\n };\n\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName,\n } = document;\n const { importNode } = originalDocument;\n\n let hooks = _createHooksMap();\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n typeof entries === 'function' &&\n typeof getParentNode === 'function' &&\n implementation &&\n implementation.createHTMLDocument !== undefined;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /*\n * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(\n create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false,\n },\n })\n );\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */\n const EXTRA_ELEMENT_HANDLING = Object.seal(\n create(null, {\n tagCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n })\n );\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Pristine allowlist bindings captured at setConfig() time. On the\n * persistent-config path sanitize() restores the sets from these before\n * the per-walk hook clone-guard, so a hook's in-call widening cannot\n * carry across calls. Null until setConfig() is called; reset by\n * clearConfig(). */\n let SET_CONFIG_ALLOWED_TAGS = null;\n let SET_CONFIG_ALLOWED_ATTR = null;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (\u00A77.3.3)\n * - DOM Tree Accessors (\u00A73.1.5)\n * - Form Element Parent-Child Relations (\u00A74.10.3)\n * - Iframe srcdoc / Nested WindowProxies (\u00A74.8.5)\n * - HTMLCollection (\u00A74.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES: UseProfilesConfig | false = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'noscript',\n 'plaintext',\n 'script',\n // <selectedcontent> mirrors the selected <option>'s subtree, cloned by\n // the UA (customizable <select>) \u2014 including any on* handlers \u2014 and the\n // engine re-mirrors synchronously whenever a removal changes which\n // option/selectedcontent is current, even inside DOMPurify's inert\n // DOMParser document. Hoisting its children on removal re-inserts a fresh\n // mirror target ahead of the walk, which the engine refills, looping\n // forever (DoS) and amplifying output. Dropping its content on removal\n // (rather than hoisting) breaks that cascade; the content is a duplicate\n // of the option, which is sanitized on its own. See campaign-3 F1/F6.\n 'selectedcontent',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'role',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet(\n {},\n [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE],\n stringToString\n );\n\n const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze([\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n ]);\n let MATHML_TEXT_INTEGRATION_POINTS = addToSet(\n {},\n DEFAULT_MATHML_TEXT_INTEGRATION_POINTS\n );\n\n const DEFAULT_HTML_INTEGRATION_POINTS = freeze(['annotation-xml']);\n let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [\n 'title',\n 'style',\n 'font',\n 'a',\n 'script',\n ]);\n\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE: null | DOMParserSupportedType = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc: null | Parameters<typeof addToSet>[2] = null;\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG: Config | null = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function (\n testValue: unknown\n ): testValue is Function | RegExp {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n\n /**\n * _parseConfig\n *\n * @param cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg: Config = {}): void {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1\n ? DEFAULT_PARSER_MEDIA_TYPE\n : cfg.PARSER_MEDIA_TYPE;\n\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc =\n PARSER_MEDIA_TYPE === 'application/xhtml+xml'\n ? stringToString\n : stringToLowerCase;\n\n /* Set configuration parameters */\n ALLOWED_TAGS = _resolveSetOption(\n cfg,\n 'ALLOWED_TAGS',\n DEFAULT_ALLOWED_TAGS,\n { transform: transformCaseFunc }\n );\n ALLOWED_ATTR = _resolveSetOption(\n cfg,\n 'ALLOWED_ATTR',\n DEFAULT_ALLOWED_ATTR,\n { transform: transformCaseFunc }\n );\n ALLOWED_NAMESPACES = _resolveSetOption(\n cfg,\n 'ALLOWED_NAMESPACES',\n DEFAULT_ALLOWED_NAMESPACES,\n { transform: stringToString }\n );\n URI_SAFE_ATTRIBUTES = _resolveSetOption(\n cfg,\n 'ADD_URI_SAFE_ATTR',\n DEFAULT_URI_SAFE_ATTRIBUTES,\n { transform: transformCaseFunc, base: DEFAULT_URI_SAFE_ATTRIBUTES }\n );\n DATA_URI_TAGS = _resolveSetOption(\n cfg,\n 'ADD_DATA_URI_TAGS',\n DEFAULT_DATA_URI_TAGS,\n { transform: transformCaseFunc, base: DEFAULT_DATA_URI_TAGS }\n );\n FORBID_CONTENTS = _resolveSetOption(\n cfg,\n 'FORBID_CONTENTS',\n DEFAULT_FORBID_CONTENTS,\n { transform: transformCaseFunc }\n );\n FORBID_TAGS = _resolveSetOption(cfg, 'FORBID_TAGS', clone({}), {\n transform: transformCaseFunc,\n });\n FORBID_ATTR = _resolveSetOption(cfg, 'FORBID_ATTR', clone({}), {\n transform: transformCaseFunc,\n });\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES')\n ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === 'object'\n ? clone(cfg.USE_PROFILES)\n : cfg.USE_PROFILES\n : false;\n\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = isRegex(cfg.ALLOWED_URI_REGEXP)\n ? cfg.ALLOWED_URI_REGEXP\n : EXPRESSIONS.IS_ALLOWED_URI; // Default regexp\n\n NAMESPACE =\n typeof cfg.NAMESPACE === 'string' ? cfg.NAMESPACE : HTML_NAMESPACE; // Default HTML namespace\n\n MATHML_TEXT_INTEGRATION_POINTS =\n objectHasOwnProperty(cfg, 'MATHML_TEXT_INTEGRATION_POINTS') &&\n cfg.MATHML_TEXT_INTEGRATION_POINTS &&\n typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === 'object'\n ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS)\n : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS); // Default built-in map\n\n HTML_INTEGRATION_POINTS =\n objectHasOwnProperty(cfg, 'HTML_INTEGRATION_POINTS') &&\n cfg.HTML_INTEGRATION_POINTS &&\n typeof cfg.HTML_INTEGRATION_POINTS === 'object'\n ? clone(cfg.HTML_INTEGRATION_POINTS)\n : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS); // Default built-in map\n\n const customElementHandling =\n objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') &&\n cfg.CUSTOM_ELEMENT_HANDLING &&\n typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object'\n ? clone(cfg.CUSTOM_ELEMENT_HANDLING)\n : create(null);\n\n CUSTOM_ELEMENT_HANDLING = create(null);\n\n if (\n objectHasOwnProperty(customElementHandling, 'tagNameCheck') &&\n isRegexOrFunction(customElementHandling.tagNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck; // Default undefined\n }\n\n if (\n objectHasOwnProperty(customElementHandling, 'attributeNameCheck') &&\n isRegexOrFunction(customElementHandling.attributeNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck =\n customElementHandling.attributeNameCheck; // Default undefined\n }\n\n if (\n objectHasOwnProperty(\n customElementHandling,\n 'allowCustomizedBuiltInElements'\n ) &&\n typeof customElementHandling.allowCustomizedBuiltInElements === 'boolean'\n ) {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements =\n customElementHandling.allowCustomizedBuiltInElements; // Default undefined\n }\n\n seal(CUSTOM_ELEMENT_HANDLING);\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, TAGS.text);\n ALLOWED_ATTR = create(null);\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Always reset function-based ADD_TAGS / ADD_ATTR checks to prevent\n * leaking across calls when switching from function to array config */\n EXTRA_ELEMENT_HANDLING.tagCheck = null;\n EXTRA_ELEMENT_HANDLING.attributeCheck = null;\n\n /* Merge configuration parameters */\n if (objectHasOwnProperty(cfg, 'ADD_TAGS')) {\n if (typeof cfg.ADD_TAGS === 'function') {\n EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;\n } else if (arrayIsArray(cfg.ADD_TAGS)) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n }\n\n if (objectHasOwnProperty(cfg, 'ADD_ATTR')) {\n if (typeof cfg.ADD_ATTR === 'function') {\n EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;\n } else if (arrayIsArray(cfg.ADD_ATTR)) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n }\n\n if (\n objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') &&\n arrayIsArray(cfg.ADD_URI_SAFE_ATTR)\n ) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n\n if (\n objectHasOwnProperty(cfg, 'FORBID_CONTENTS') &&\n arrayIsArray(cfg.FORBID_CONTENTS)\n ) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n\n if (\n objectHasOwnProperty(cfg, 'ADD_FORBID_CONTENTS') &&\n arrayIsArray(cfg.ADD_FORBID_CONTENTS)\n ) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n // Re-derive the active Trusted Types policy from this configuration on\n // every parse. The active policy must never be sticky closure state that\n // outlives the config that set it: a caller-supplied policy left in place\n // after `clearConfig()` \u2014 or after a later call that supplied none, or\n // `TRUSTED_TYPES_POLICY: null` \u2014 could sign a subsequent \"default\"\n // `RETURN_TRUSTED_TYPE` result with a foreign, possibly unsafe policy.\n // See GHSA-vxr8-fq34-vvx9.\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.'\n );\n }\n\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.'\n );\n }\n\n // A caller-supplied policy applies to this configuration only.\n const previousTrustedTypesPolicy = trustedTypesPolicy;\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n\n // Sign local variables required by `sanitize`. If the supplied policy's\n // `createHTML` is circular (i.e. it calls `DOMPurify.sanitize`), this\n // throws via the re-entrancy guard. Restore the previous policy first so\n // the instance is not left in a poisoned state. See #1422.\n try {\n emptyHTML = _createTrustedHTML('');\n } catch (error) {\n trustedTypesPolicy = previousTrustedTypesPolicy;\n throw error;\n }\n } else if (cfg.TRUSTED_TYPES_POLICY === null) {\n // Explicit opt-out for this call: perform no Trusted Types signing and\n // create nothing (so a strict `trusted-types` CSP that disallows a\n // `dompurify` policy can still call `sanitize` from inside its own\n // policy \u2014 see #1422). Resetting to `undefined` rather than a sticky\n // `null` also drops any previously retained caller policy, so it cannot\n // resurface on a later call, while still allowing the next config-less\n // call to restore the internal default policy. See GHSA-vxr8-fq34-vvx9.\n trustedTypesPolicy = undefined;\n emptyHTML = '';\n } else {\n // No policy supplied: keep the currently active policy if one is set \u2014 a\n // previously supplied policy is intentionally sticky across config-less\n // calls \u2014 otherwise fall back to the instance's own internal policy,\n // created at most once. (A policy supplied for a *single* call still\n // lingers by design; what must not linger is a policy whose configuration\n // has been torn down via `clearConfig()`, which restores the default.)\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _getDefaultTrustedTypesPolicy();\n }\n\n // Sign internal variables only when a policy is active. A falsy policy\n // (Trusted Types unsupported, creation failed, or an explicit opt-out)\n // leaves `emptyHTML` as a plain string, so we never call `.createHTML` on\n // a non-policy and throw. See #1422.\n if (trustedTypesPolicy && typeof emptyHTML === 'string') {\n emptyHTML = _createTrustedHTML('');\n }\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.svgDisallowed,\n ]);\n const ALL_MATHML_TAGS = addToSet({}, [\n ...TAGS.mathMl,\n ...TAGS.mathMlDisallowed,\n ]);\n\n /**\n * Namespace rules for an element in the SVG namespace.\n *\n * @param tagName the element's lowercase tag name\n * @param parent the (possibly simulated) parent node\n * @param parentTagName the parent's lowercase tag name\n * @returns true if a spec-compliant parser could produce this element\n */\n const _checkSvgNamespace = function (\n tagName: string,\n parent: { namespaceURI?: string },\n parentTagName: string\n ): boolean {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via <svg>\n // if the parent is either <annotation-xml> or a MathML\n // text integration point.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return (\n tagName === 'svg' &&\n (parentTagName === 'annotation-xml' ||\n MATHML_TEXT_INTEGRATION_POINTS[parentTagName])\n );\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n };\n\n /**\n * Namespace rules for an element in the MathML namespace.\n *\n * @param tagName the element's lowercase tag name\n * @param parent the (possibly simulated) parent node\n * @param parentTagName the parent's lowercase tag name\n * @returns true if a spec-compliant parser could produce this element\n */\n const _checkMathMlNamespace = function (\n tagName: string,\n parent: { namespaceURI?: string },\n parentTagName: string\n ): boolean {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n };\n\n /**\n * Namespace rules for an element in the HTML namespace.\n *\n * @param tagName the element's lowercase tag name\n * @param parent the (possibly simulated) parent node\n * @param parentTagName the parent's lowercase tag name\n * @returns true if a spec-compliant parser could produce this element\n */\n const _checkHtmlNamespace = function (\n tagName: string,\n parent: { namespaceURI?: string },\n parentTagName: string\n ): boolean {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (\n parent.namespaceURI === SVG_NAMESPACE &&\n !HTML_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n if (\n parent.namespaceURI === MATHML_NAMESPACE &&\n !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return (\n !ALL_MATHML_TAGS[tagName] &&\n (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName])\n );\n };\n\n /**\n * @param element a DOM element whose namespace is being checked\n * @returns Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function (element: Element): boolean {\n let parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template',\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n return _checkSvgNamespace(tagName, parent, parentTagName);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n return _checkMathMlNamespace(tagName, parent, parentTagName);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n return _checkHtmlNamespace(tagName, parent, parentTagName);\n }\n\n // For XHTML and XML documents that support custom namespaces\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n ALLOWED_NAMESPACES[element.namespaceURI]\n ) {\n return true;\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param node a DOM node\n */\n const _forceRemove = function (node: Node): void {\n arrayPush(DOMPurify.removed, { element: node });\n\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n /* The normal detach failed \u2014 this is reached for a parentless node\n (getParentNode() is null, so .removeChild throws). Element.prototype\n .remove() is itself a spec no-op on a parentless node, so a recorded\n \"removal\" would otherwise hand the caller back an intact,\n payload-bearing node (e.g. a detached IN_PLACE root the mXSS canary or\n the style-with-element-child rule decided to kill). Fail closed by\n throwing \u2014 exactly as a clobbered root does at the IN_PLACE entry \u2014\n rather than trying to \"neutralize\" the node via its own methods.\n Neutralizing would mean calling getAttributeNames()/removeAttribute()\n on the node, both of which a <form> root can clobber via a named child\n (and _isClobbered does not even probe getAttributeNames), so the\n neutralize step could itself be silently defeated, leaving the payload\n intact. A throw touches only the cached, clobber-safe remove() and\n getParentNode(). Generalizes GHSA-r47g-fvhr-h676 (clobbered-form root)\n to every root-kill reason. REPORT-3.\n\n This lives inside the catch, so it never fires for a normally-removed\n in-tree node: those have a parent, removeChild() succeeds, and the\n catch is not entered. Only a kept (parentless) root reaches here. */\n remove(node);\n\n if (!getParentNode(node)) {\n throw typeErrorCreate(\n 'a node selected for removal could not be detached from its tree ' +\n 'and cannot be safely returned; refusing to sanitize in place'\n );\n }\n }\n };\n\n /**\n * _neutralizeRoot\n *\n * Fail-closed teardown of an in-place root after the sanitize walk aborts\n * (campaign-3 F2). An internal throw mid-walk \u2014 e.g. a page-registered\n * custom element's reaction detaches a node so `_forceRemove`'s deliberate\n * parentless guard throws, or any other re-entrant engine mutation \u2014 would\n * otherwise leave the caller's *live* tree half-sanitized, with everything\n * after the abort point still carrying its handlers. There is no safe way\n * to resume the walk (the tree mutated under us), so we strip the root bare:\n * remove every child and every attribute, then let the caller's catch see\n * the original error. Clobber-safe (cached `remove`/`childNodes`/`attributes`\n * getters; the root was already clobber-pre-flighted at the IN_PLACE entry).\n *\n * @param root the in-place root to empty\n */\n const _neutralizeRoot = function (root: Node): void {\n /* Strip every disallowed attribute (on* handlers included) off the whole\n subtree BEFORE detaching anything. Detaching first would hand back\n handler-bearing originals (e.g. an already-loading `<img onerror>`)\n whose queued resource event still fires in page scope after we throw.\n Clobber-safe reads; a doomed clobbered node's own attributes are\n irrelevant while its non-clobbered descendants are reached and scrubbed. */\n _neutralizeSubtree(root);\n\n const childNodes = getChildNodes(root);\n if (childNodes) {\n const snapshot: Node[] = [];\n arrayForEach(childNodes, (child) => {\n arrayPush(snapshot, child);\n });\n arrayForEach(snapshot, (child) => {\n try {\n remove(child);\n } catch (_) {\n /* Best-effort teardown; a still-attached child is handled below */\n }\n });\n }\n\n const attributes = getAttributes(root);\n if (attributes) {\n for (let i = attributes.length - 1; i >= 0; --i) {\n const attribute = attributes[i];\n const name = attribute && attribute.name;\n if (typeof name === 'string') {\n try {\n (root as Element).removeAttribute(name);\n } catch (_) {\n /* Clobbered removeAttribute \u2014 ignore (fail-closed best effort) */\n }\n }\n }\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param name an Attribute name\n * @param element a DOM node\n */\n const _removeAttribute = function (name: string, element: Element): void {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: element.getAttributeNode(name),\n from: element,\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: element,\n });\n }\n\n element.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\" attributes\n if (name === 'is') {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(element);\n } catch (_) {}\n } else {\n try {\n element.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _stripDisallowedAttributes\n *\n * Removes every attribute the active configuration does not allow from a\n * single element, using the same allowlist as the main attribute pass (so\n * `on*` handlers go, but no `/^on/` blocklist is introduced). Used only to\n * neutralise nodes that are being discarded from an in-place tree.\n *\n * @param element the element to strip\n */\n const _stripDisallowedAttributes = function (element: Element): void {\n const attributes = getAttributes(element);\n if (!attributes) {\n return;\n }\n\n for (let i = attributes.length - 1; i >= 0; --i) {\n const attribute = attributes[i];\n const name = attribute && attribute.name;\n if (typeof name !== 'string' || ALLOWED_ATTR[transformCaseFunc(name)]) {\n continue;\n }\n\n try {\n element.removeAttribute(name);\n } catch (_) {\n /* Clobbered removeAttribute on a doomed node \u2014 ignore */\n }\n }\n };\n\n /**\n * _neutralizeSubtree\n *\n * Completes the audit-5 F1 fix across every removal path. The KEEP_CONTENT\n * move-hoist neutralises only disallowed-tag removals; clobber, mXSS-canary,\n * namespace, comment, processing-instruction and KEEP_CONTENT:false removals\n * all drop their subtree wholesale via `_forceRemove`. On the IN_PLACE path\n * those dropped nodes are detached from the caller's LIVE tree but a\n * handler-bearing original among them (an `<img onerror>`/`<video>` that was\n * loading) keeps its queued resource event, which fires in page scope after\n * sanitize returns. This walks a removed subtree and strips every attribute\n * the active configuration does not allow \u2014 so `on*` handlers are cancelled\n * through the SAME allowlist that governs kept nodes, not a separate `/^on/`\n * blocklist. Run synchronously before sanitize returns, i.e. before any\n * queued event can fire. Hook-free by design: these nodes leave the output,\n * so firing attribute hooks for them would be surprising. Clobber-safe reads;\n * a doomed clobbered node may shadow `removeAttribute` (its own attributes are\n * irrelevant \u2014 it is discarded \u2014 while its non-clobbered descendants, e.g.\n * the `<img>`, are reached and scrubbed).\n *\n * @param root the root of a removed subtree to neutralise\n */\n const _neutralizeSubtree = function (root: Node): void {\n const stack: Node[] = [root];\n\n while (stack.length > 0) {\n const node = stack.pop();\n const nodeType = getNodeType ? getNodeType(node) : (node as any).nodeType;\n\n if (nodeType === NODE_TYPE.element) {\n _stripDisallowedAttributes(node as Element);\n }\n\n const childNodes = getChildNodes(node);\n if (childNodes) {\n for (let i = childNodes.length - 1; i >= 0; --i) {\n stack.push(childNodes[i]);\n }\n }\n }\n };\n\n /**\n * _neutralizePatchLinkage\n *\n * IN_PLACE entry pre-pass (declarative-partial-updates / streaming\n * hardening, https://github.com/WICG/declarative-partial-updates).\n *\n * The main walk strips patch linkage (`for`/`patchsrc`) and removes range\n * markers (PIs / markup comments) node-by-node, in document order, AS it\n * reaches each node. On a live in-place root that leaves a window: from the\n * moment the root is connected until the walk arrives at a given node, that\n * node's linkage is live. A patch applied on connection/stream can fire as\n * a microtask during the walk and inject or teleport an unsanitized DOM\n * range into a region the iterator has already passed and will not revisit,\n * so the post-return \"tree is sanitized\" contract is violated. Sweep the\n * whole tree once up front and sever every linkage before the walk begins,\n * closing that window.\n *\n * This CANNOT undo a patch that already fired before sanitize ran \u2014 that is\n * the irreducible \"do not IN_PLACE a live-connected attacker tree\" caveat \u2014\n * but it closes everything from sanitize-start onward. Gated on SAFE_FOR_XML\n * to group with the rest of the declarative-partial-updates handling and\n * stay overridable, consistent with the codebase.\n *\n * Clobber-safe traversal (cached childNodes getter); per-node try/catch so a\n * clobbered root cannot defeat the sweep of its non-clobbered descendants.\n *\n * NOTE (pending real-Chrome confirmation, see test/declarative-patch-probe\n * .html Q1): this mirrors the existing policy of keeping `for` on\n * <label>/<output>. If the shipping feature can drive a patch through a\n * surviving `for`-on-label/output + `id` pair, this pre-pass and the\n * attribute check at _isBasicCustomElement's caller must additionally drop\n * that pair on the IN_PLACE path. Left as-is until the taxonomy is verified.\n *\n * @param root the in-place root to sweep\n */\n const _neutralizePatchLinkage = function (root: Node): void {\n if (!SAFE_FOR_XML) {\n return;\n }\n\n const stack: Node[] = [root];\n while (stack.length > 0) {\n const node = stack.pop();\n const nodeType = getNodeType ? getNodeType(node) : (node as any).nodeType;\n\n /* Remove range markers (the target side of a patch linkage): every\n processing instruction, and any markup-bearing comment. */\n if (\n nodeType === NODE_TYPE.processingInstruction ||\n (nodeType === NODE_TYPE.comment &&\n regExpTest(EXPRESSIONS.COMMENT_MARKUP_PROBE, (node as any).data))\n ) {\n try {\n remove(node);\n } catch (_) {\n /* Best-effort */\n }\n\n continue;\n }\n\n /* Strip patch-source attributes (the source side) off elements. */\n if (nodeType === NODE_TYPE.element) {\n const element = node as Element;\n const lcTag = transformCaseFunc(\n getNodeName ? getNodeName(node) : (node as any).nodeName\n );\n try {\n if (element.hasAttribute && element.hasAttribute('patchsrc')) {\n element.removeAttribute('patchsrc');\n }\n\n if (\n element.hasAttribute &&\n element.hasAttribute('for') &&\n lcTag !== 'label' &&\n lcTag !== 'output'\n ) {\n element.removeAttribute('for');\n }\n } catch (_) {\n /* Clobbered removeAttribute/hasAttribute on a doomed node \u2014 ignore */\n }\n }\n\n const childNodes = getChildNodes(node);\n if (childNodes) {\n for (let i = childNodes.length - 1; i >= 0; --i) {\n stack.push(childNodes[i]);\n }\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param dirty - a string of dirty markup\n * @return a DOM, filled with the dirty markup\n */\n const _initDocument = function (dirty: string): Document {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n NAMESPACE === HTML_NAMESPACE\n ) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty =\n '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' +\n dirty +\n '</body></html>';\n }\n\n const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT\n ? emptyHTML\n : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n const body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(\n document.createTextNode(leadingWhitespace),\n body.childNodes[0] || null\n );\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(\n doc,\n WHOLE_DOCUMENT ? 'html' : 'body'\n )[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param root The root element or node to start traversing on.\n * @return The created NodeIterator\n */\n const _createNodeIterator = function (root: Node): NodeIterator {\n /* Read ownerDocument through the cached Node.prototype getter, never the\n direct property. HTMLFormElement has [LegacyOverrideBuiltIns], so a\n clobbering child (<input name=\"ownerDocument\"> or a form-associated\n external input) shadows the prototype getter and makes a direct read\n return that <input>. createNodeIterator.call(<input>, ...) then throws\n \"Illegal invocation\", and on the IN_PLACE path that throw lands before\n the walk's fail-closed barrier - leaving the caller's live tree, with\n any already-armed handler in it, un-neutralized. The cached getter\n returns the real Document regardless of the clobber. */\n const doc = getOwnerDocument ? getOwnerDocument(root) : root.ownerDocument;\n return createNodeIterator.call(\n doc || root,\n root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT |\n NodeFilter.SHOW_COMMENT |\n NodeFilter.SHOW_TEXT |\n NodeFilter.SHOW_PROCESSING_INSTRUCTION |\n NodeFilter.SHOW_CDATA_SECTION,\n null\n );\n };\n\n /**\n * Replace template expression syntax (mustache, ERB, template\n * literal) with a space; shared by all SAFE_FOR_TEMPLATES scrub\n * sites. Order matters: mustache, then ERB, then template literal.\n *\n * @param value the string to scrub\n * @returns the scrubbed string\n */\n const _stripTemplateExpressions = function (value: string): string {\n value = stringReplace(value, MUSTACHE_EXPR, ' ');\n value = stringReplace(value, ERB_EXPR, ' ');\n value = stringReplace(value, TMPLIT_EXPR, ' ');\n return value;\n };\n\n /**\n * Strip template-engine expressions ({{...}}, ${...}, <%...%>) from the\n * character data of an element subtree. Used as the final safety net for\n * SAFE_FOR_TEMPLATES on every DOM-returning code path so that expressions\n * which only form after text-node normalization (e.g. fragments split across\n * stripped elements) cannot survive into a template-evaluating framework.\n *\n * Walks text/comment/CDATA/processing-instruction nodes and mutates `.data`\n * in place rather than round-tripping through innerHTML. This preserves\n * descendant node references (important for IN_PLACE callers), avoids a\n * serialize/reparse cycle, and reads literal character data \u2014 which means\n * `<%...%>` in text content matches the ERB regex against its real bytes\n * instead of the HTML-entity-escaped form innerHTML would produce.\n *\n * Attribute values are not visited here; SAFE_FOR_TEMPLATES handling for\n * attributes is performed during the per-node `_sanitizeAttributes` pass.\n *\n * @param node The root element whose character data should be scrubbed.\n */\n const _scrubTemplateExpressions = function (node: Element): void {\n node.normalize();\n /* Clobber-safe ownerDocument read, same reasoning as _createNodeIterator:\n under SAFE_FOR_TEMPLATES this runs on the live IN_PLACE root, which may\n carry a form-named-getter override of ownerDocument. */\n const doc = getOwnerDocument ? getOwnerDocument(node) : node.ownerDocument;\n const walker = createNodeIterator.call(\n doc || node,\n node,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_TEXT |\n NodeFilter.SHOW_COMMENT |\n NodeFilter.SHOW_CDATA_SECTION |\n NodeFilter.SHOW_PROCESSING_INSTRUCTION,\n null\n );\n\n let currentNode = walker.nextNode() as CharacterData | null;\n while (currentNode) {\n currentNode.data = _stripTemplateExpressions(currentNode.data);\n currentNode = walker.nextNode() as CharacterData | null;\n }\n\n // NodeIterator does not descend into <template>.content per the DOM spec,\n // so we must explicitly recurse into each template's content fragment,\n // mirroring the approach used by _sanitizeShadowDOM.\n const templates = node.querySelectorAll?.('template');\n if (templates) {\n arrayForEach(templates, (tmpl: HTMLTemplateElement) => {\n if (_isDocumentFragment(tmpl.content)) {\n _scrubTemplateExpressions(tmpl.content as unknown as Element);\n }\n });\n }\n };\n\n /**\n * _isClobbered\n *\n * Detect DOM-clobbering on HTMLFormElement nodes. Form is the only HTML\n * interface with [LegacyOverrideBuiltIns]; a descendant element with a\n * `name` attribute matching a prototype property shadows that property\n * on direct reads. We use this check at the IN_PLACE entry-point and\n * during attribute sanitization to refuse clobbered forms.\n *\n * @param element element to check for clobbering attacks\n * @return true if clobbered, false if safe\n */\n const _isClobbered = function (element: Element): boolean {\n // Realm-independent tag-name probe. If we can't determine the tag\n // name at all, we can't reason about clobbering \u2014 return false\n // (the caller's other defences still apply).\n const realTagName = getNodeName ? getNodeName(element) : null;\n if (typeof realTagName !== 'string') {\n return false;\n }\n\n if (transformCaseFunc(realTagName) !== 'form') {\n return false;\n }\n\n return (\n typeof element.nodeName !== 'string' ||\n typeof element.textContent !== 'string' ||\n typeof element.removeChild !== 'function' ||\n // Realm-safe NamedNodeMap detection: equality against the cached\n // prototype getter. Clobbered .attributes (e.g. <input name=\"attributes\">)\n // makes the direct read diverge from the cached read; a clean form\n // (same-realm OR foreign-realm) has both reads pointing at the same\n // canonical NamedNodeMap.\n element.attributes !== getAttributes(element) ||\n typeof element.removeAttribute !== 'function' ||\n typeof element.setAttribute !== 'function' ||\n typeof element.namespaceURI !== 'string' ||\n typeof element.insertBefore !== 'function' ||\n typeof element.hasChildNodes !== 'function' ||\n // NodeType clobbering probe. Cached Node.prototype.nodeType getter\n // returns the integer 1 for any Element regardless of realm; direct\n // read on a clobbered form (e.g. <input name=\"nodeType\">) returns\n // the named child element. Cheap addition \u2014 nodeType is read from\n // an internal slot, no serialization cost \u2014 and removes a residual\n // clobbering surface used by several mXSS / PI / comment branches\n // in _sanitizeElements that compare currentNode.nodeType directly.\n element.nodeType !== getNodeType(element) ||\n // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named\n // \"childNodes\" shadows the prototype getter. Direct reads of\n // form.childNodes from a clobbered form return the named child\n // instead of the real NodeList, so any walk that reads it directly\n // skips the form's real children. Compare the direct read to the\n // cached Node.prototype getter \u2014 when the form's named-property\n // getter intercepts the read, the two values differ and we flag\n // the form. This catches every clobbering child type (input,\n // select, etc.) regardless of whether the named child happens to\n // carry a numeric .length, which a typeof-based probe would miss\n // (e.g. HTMLSelectElement.length is a defined unsigned-long).\n element.childNodes !== getChildNodes(element)\n );\n };\n\n /**\n * Checks whether the given value is a DocumentFragment from any realm.\n *\n * The realm-independent replacement reads `nodeType` through the cached\n * Node.prototype getter and compares to the DOCUMENT_FRAGMENT_NODE\n * constant (11). nodeType is a numeric value resolved from the node's\n * internal slot, identical across realms for the same kind of node.\n *\n * @param value object to check\n * @return true if value is a DocumentFragment-shaped node from any realm\n */\n const _isDocumentFragment = function (value: unknown): boolean {\n if (!getNodeType || typeof value !== 'object' || value === null) {\n return false;\n }\n\n try {\n return getNodeType(value as Node) === NODE_TYPE.documentFragment;\n } catch (_) {\n return false;\n }\n };\n\n /**\n * Checks whether the given object is a DOM node, including nodes that\n * originate from a different window/realm (e.g. an iframe's\n * contentDocument). The previous `value instanceof Node` check was\n * realm-bound: nodes from a different window failed it, causing\n * sanitize() to silently stringify them and reset IN_PLACE to false,\n * returning the original node unsanitized. See GHSA-4w3q-35jp-p934.\n *\n * @param value object to check whether it's a DOM node\n * @return true if value is a DOM node from any realm\n */\n const _isNode = function (value: unknown): value is Node {\n if (!getNodeType || typeof value !== 'object' || value === null) {\n return false;\n }\n\n try {\n return typeof getNodeType(value) === 'number';\n } catch (_) {\n return false;\n }\n };\n\n function _executeHooks<T extends HookFunction>(\n hooks: HookFunction[],\n currentNode: Parameters<T>[0],\n data: Parameters<T>[1]\n ): void {\n if (hooks.length === 0) {\n return;\n }\n\n arrayForEach(hooks, (hook: T) => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n }\n\n /**\n * Structural-threat checks that condemn a node regardless of the\n * allowlists: mXSS via namespace confusion, risky CSS construction,\n * processing instructions, markup-bearing comments. Pure predicate;\n * the caller removes. Check order is load-bearing.\n *\n * @param currentNode the node to inspect\n * @param tagName the node's transformCaseFunc'd tag name\n * @return true if the node must be removed\n */\n const _isUnsafeNode = function (currentNode: any, tagName: string): boolean {\n /* Detect mXSS attempts abusing namespace confusion */\n if (\n SAFE_FOR_XML &&\n currentNode.hasChildNodes() &&\n !_isNode(currentNode.firstElementChild) &&\n regExpTest(EXPRESSIONS.ELEMENT_MARKUP_PROBE, currentNode.textContent) &&\n regExpTest(EXPRESSIONS.ELEMENT_MARKUP_PROBE, currentNode.innerHTML)\n ) {\n return true;\n }\n\n /* Remove risky CSS construction leading to mXSS */\n if (\n SAFE_FOR_XML &&\n currentNode.namespaceURI === HTML_NAMESPACE &&\n tagName === 'style' &&\n _isNode(currentNode.firstElementChild)\n ) {\n return true;\n }\n\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.processingInstruction) {\n return true;\n }\n\n /* Remove any kind of possibly harmful comments */\n if (\n SAFE_FOR_XML &&\n currentNode.nodeType === NODE_TYPE.comment &&\n regExpTest(EXPRESSIONS.COMMENT_MARKUP_PROBE, currentNode.data)\n ) {\n return true;\n }\n\n return false;\n };\n\n /**\n * Handle a node whose tag is forbidden or not allowlisted: keep\n * allowed custom elements (false return exits _sanitizeElements\n * early - the namespace and fallback-tag removal checks are\n * intentionally skipped for kept custom elements), else hoist\n * content per KEEP_CONTENT and remove.\n *\n * A kept custom element is the ONLY case in which this function\n * returns false, so the caller uses that return value to run the\n * afterSanitizeElements hook on the kept element and keep the\n * element-hook lifecycle consistent with normal allowlisted\n * elements (GHSA-c2j3-45gr-mqc4).\n *\n * @param currentNode the disallowed node\n * @param tagName the node's transformCaseFunc'd tag name\n * @return true if the node was removed, false if kept\n */\n const _sanitizeDisallowedNode = function (\n currentNode: any,\n tagName: string,\n root: Node\n ): boolean {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)\n ) {\n return false;\n }\n\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)\n ) {\n return false;\n }\n }\n\n /* Keep content except for bad-listed elements.\n Use the cached prototype getters exclusively \u2014 the previous code\n had `|| currentNode.parentNode` / `|| currentNode.childNodes`\n fallbacks, but the cached getters always return the canonical\n value (or null for a real parent-less node), so the fallback\n path was dead in safe cases and a clobbering surface in unsafe\n ones. Falsy cached results stay falsy; the `if (childNodes &&\n parentNode)` check already gates correctly. */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode);\n const childNodes = getChildNodes(currentNode);\n\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n\n /* Hoist by moving each child up one level rather than deep-cloning\n it. Moving transfers every descendant exactly once, so a chain of\n nested disallowed elements costs O(n) instead of the O(n^2) that\n re-cloning the shrinking subtree at each level produced; it also\n empties the removed original, so `DOMPurify.removed` no longer\n pins whole subtrees. Moving preserves the in-place guarantee too:\n an original carrying already-queued resource events (`<img\n onerror>`, `<video>`/`<audio>` error, lazy/`onload`, \u2026) is\n relocated and sanitised rather than left detached but still armed.\n\n The sole case that must clone is removing the walk root itself.\n The result is serialised from the root's subtree, so a restrictive\n ALLOWED_TAGS that strips the root (`body` on the string path) must\n leave the content inside it, which only cloning does. In IN_PLACE\n the root is pre-validated as an allowed tag and so is never removed\n here, so that path always takes the move branch.\n\n `childNodes` is live; a tail-to-head walk keeps `childNodes[i]`\n valid whether we move (drops the trailing entry) or clone (leaves\n the list intact). */\n for (let i = childCount - 1; i >= 0; --i) {\n const hoisted =\n currentNode === root\n ? cloneNode(childNodes[i], true)\n : childNodes[i];\n parentNode.insertBefore(hoisted, getNextSibling(currentNode));\n }\n }\n }\n\n _forceRemove(currentNode);\n return true;\n };\n\n /**\n * Fork a hook-mutable allowlist off its shared binding the first time a\n * (possibly lazily-installed) uponSanitize* hook is about to see it, so the\n * hook cannot widen the per-instance default or the setConfig binding by\n * reference and leak past the call. Returns the set unchanged once it is\n * already call-local, so repeated calls across elements are idempotent.\n *\n * @param hookList the uponSanitize* hook array for this event\n * @param set the current ALLOWED_TAGS / ALLOWED_ATTR binding\n * @param defaultSet the per-instance DEFAULT_ALLOWED_* constant\n * @param setConfigSet the captured setConfig() binding, or null\n * @return a call-local clone if a hook is present and set is still shared,\n * else set unchanged\n */\n const _forkSharedAllowlist = function <T extends Record<string, any>>(\n hookList: unknown[],\n set: T,\n defaultSet: T,\n setConfigSet: T | null\n ): T {\n if (hookList.length === 0) {\n return set;\n }\n\n return set === defaultSet || set === setConfigSet ? clone(set) : set;\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n * @param currentNode to check for permission to exist\n * @return true if node was killed, false if left alive\n */\n // eslint-disable-next-line complexity\n const _sanitizeElements = function (currentNode: any, root: Node): boolean {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n\n /* A hook may have detached the node - treat it as removed (see the\n detached-node comment after the uponSanitizeElement hook below). On\n the IN_PLACE path, neutralize the detached subtree first so a queued\n resource handler on it cannot fire in page scope after we return. */\n if (currentNode !== root && getParentNode(currentNode) === null) {\n if (IN_PLACE) {\n _neutralizeSubtree(currentNode);\n }\n\n return true;\n }\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(\n getNodeName ? getNodeName(currentNode) : currentNode.nodeName\n );\n\n /* Close the pre-walk clone-guard's timing gap: an uponSanitizeElement\n hook may have been installed after that guard sampled the hook arrays\n (e.g. lazily from beforeSanitizeElements), leaving ALLOWED_TAGS still\n aliasing a shared binding that a widening hook would mutate by\n reference. Fork it before exposing it to the hook. */\n ALLOWED_TAGS = _forkSharedAllowlist(\n hooks.uponSanitizeElement,\n ALLOWED_TAGS,\n DEFAULT_ALLOWED_TAGS,\n SET_CONFIG_ALLOWED_TAGS\n );\n\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeElement, currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS,\n });\n\n /* A hook may have detached the node from the tree \u2014 a long-standing\n user pattern (issue #469; draw.io-style foreignObject filtering).\n Per the cached, unclobberable parentNode getter the node is\n genuinely out of the tree, so it can reach neither the serialized\n output nor an IN_PLACE live tree; treat it as removed and stop\n processing it. Without this guard, the unsafe-node / namespace\n checks below would call _forceRemove on a parentless node and hit\n the REPORT-3 fail-closed throw \u2014 which exists for nodes DOMPurify\n wants gone but *cannot* detach (clobbered / parentless roots), the\n opposite of a node that is already safely gone. The walk root is\n exempt: a detached IN_PLACE root is legitimate input and must still\n be fully sanitized, and a kill-decision on it must keep hitting the\n REPORT-3 throw. Nodes detached by hooks stay the hook's\n responsibility for placement: they are not recorded in\n DOMPurify.removed, so the post-walk IN_PLACE pass (which iterates\n DOMPurify.removed) does not reach them. But a hook-detached subtree\n can still hold a queued resource-event handler - e.g. an <img onload>\n that began loading when the caller built the live tree - which fires\n in page scope after sanitize returns even though the handler never\n reached the returned tree. That is the audit-5 F1 hazard, and the\n documented node.remove() hook pattern walks straight into it. So on\n the IN_PLACE path we neutralize the detached subtree inline here,\n stripping its non-allow-listed attributes before returning, exactly\n as the post-walk pass does for _forceRemove'd subtrees. */\n if (currentNode !== root && getParentNode(currentNode) === null) {\n if (IN_PLACE) {\n _neutralizeSubtree(currentNode);\n }\n\n return true;\n }\n\n /* Remove mXSS vectors, processing instructions and risky comments */\n if (_isUnsafeNode(currentNode, tagName)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove element if anything forbids its presence */\n if (\n FORBID_TAGS[tagName] ||\n (!(\n EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function &&\n EXTRA_ELEMENT_HANDLING.tagCheck(tagName)\n ) &&\n !ALLOWED_TAGS[tagName])\n ) {\n const removed = _sanitizeDisallowedNode(currentNode, tagName, root);\n\n /* A false return means the node is a custom element kept via\n CUSTOM_ELEMENT_HANDLING - the only keep path through\n _sanitizeDisallowedNode. Run afterSanitizeElements on it so the\n element-hook lifecycle matches normal allowlisted elements: a\n security policy applied in this hook (e.g. stripping an attribute\n from every surviving element) must not silently skip kept custom\n elements (GHSA-c2j3-45gr-mqc4). This mirrors the normal-element\n tail below - the hook runs, then the walker's subsequent\n _sanitizeAttributes pass sanitizes the element's attributes. The\n deliberately skipped namespace and fallback-tag removal checks stay\n skipped; they are removal decisions, not the hook contract. */\n if (removed === false) {\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n }\n\n return removed;\n }\n\n /* Check whether element has a valid namespace.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): use the cached Node.prototype\n nodeType getter rather than `instanceof Element`, which is realm-\n bound and short-circuits to false for any node minted in a different\n realm \u2014 letting a foreign-realm element with a forbidden namespace\n slip past the namespace check entirely. */\n const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;\n if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if (\n (tagName === 'noscript' ||\n tagName === 'noembed' ||\n tagName === 'noframes') &&\n regExpTest(EXPRESSIONS.FALLBACK_TAG_CLOSE, currentNode.innerHTML)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n const content = _stripTemplateExpressions(currentNode.textContent);\n\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param lcTag Lowercase tag name of containing element.\n * @param lcName Lowercase attribute name.\n * @param value Attribute value.\n * @return Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function (\n lcTag: string,\n lcName: string,\n value: string\n ): boolean {\n /* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */\n if (FORBID_ATTR[lcName]) {\n return false;\n }\n\n /* Reject declarative-partial-updates patch-linkage attributes\n (https://github.com/WICG/declarative-partial-updates).\n\n Empirical note (Chrome 150, verified \u2014 see\n test/declarative-patch-probe-v3.html): expansion is NOT applied after\n sanitization. For the string path it fires during sanitize()'s own\n parse, so the walk sees and sanitizes the fully materialized expanded\n tree \u2014 teleports into MathML/SVG integration points included; a\n weaponized `<template for>`->`<img onerror>` comes back with the handler\n stripped. For the IN_PLACE path it fires on connection, before the walk.\n Either way DOMPurify is NOT blind to the patch.\n\n This removal is therefore defense-in-depth rather than the sole barrier:\n it prevents live linkage from surviving into the OUTPUT and re-expanding\n in the caller's context, and keeps behaviour deterministic if a future\n engine defers expansion. `for` is legitimate only on <label>/<output>;\n anywhere else (notably <template for>) it links the element to a patch\n target and teleports or removes an arbitrary DOM range by id/marker name.\n `patchsrc` fetches remote markup and is treated as a script-loading\n mechanism (CSP). Gated on SAFE_FOR_XML so the removal groups with the\n other structural-threat checks and stays overridable, consistent with\n the rest of the codebase. PI range markers are already removed by\n _isUnsafeNode. */\n if (SAFE_FOR_XML && lcName === 'patchsrc') {\n return false;\n }\n\n if (\n SAFE_FOR_XML &&\n lcName === 'for' &&\n lcTag !== 'label' &&\n lcTag !== 'output'\n ) {\n return false;\n }\n\n /* Make sure attribute cannot clobber */\n if (\n SANITIZE_DOM &&\n (lcName === 'id' || lcName === 'name') &&\n (value in document || value in formElement)\n ) {\n return false;\n }\n\n const nameIsPermitted =\n ALLOWED_ATTR[lcName] ||\n (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function &&\n EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag));\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR, lcName)) {\n // This attribute is safe\n } else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) {\n // This attribute is safe\n /* Otherwise, check the name is permitted */\n } else if (!nameIsPermitted) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n (_isBasicCustomElement(lcTag) &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag))) &&\n ((CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName)) ||\n (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)))) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n (lcName === 'is' &&\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))))\n ) {\n // If user has supplied a regexp or function in CUSTOM_ELEMENT_HANDLING.tagNameCheck, we need to also allow derived custom elements using the same tagName test.\n // Additionally, we need to allow attributes passing the CUSTOM_ELEMENT_HANDLING.attributeNameCheck user has configured, as custom elements can define these at their own discretion.\n } else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) {\n // This attribute is safe\n /* Check no script, data or unknown possibly unsafe URI\n unless we know URI values are safe for that attribute */\n } else if (\n regExpTest(IS_ALLOWED_URI, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Keep image data URIs alive if src/xlink:href is allowed */\n /* Further prevent gadget XSS for dynamically built script tags */\n } else if (\n (lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') &&\n lcTag !== 'script' &&\n stringIndexOf(value, 'data:') === 0 &&\n DATA_URI_TAGS[lcTag]\n ) {\n // This attribute is safe\n /* Allow unknown protocols: This provides support for links that\n are handled by protocol handlers which may be unknown ahead of\n time, e.g. fb:, spotify: */\n } else if (\n ALLOW_UNKNOWN_PROTOCOLS &&\n !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Check for binary attributes */\n } else if (value) {\n return false;\n } else {\n // Binary attributes are safe at this point\n /* Anything else, presume unsafe, do not add it back */\n }\n\n return true;\n };\n\n /* Names the HTML spec reserves from valid-custom-element-name; these must\n * never be treated as basic custom elements even when a permissive\n * CUSTOM_ELEMENT_HANDLING.tagNameCheck is configured. */\n const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, [\n 'annotation-xml',\n 'color-profile',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'missing-glyph',\n ]);\n\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param tagName name of the tag of the node to sanitize\n * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function (tagName: string): boolean {\n return (\n !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] &&\n regExpTest(CUSTOM_ELEMENT, tagName)\n );\n };\n\n /**\n * Wrap an attribute value in the matching Trusted Types object when\n * the active policy requires it. Namespaced attributes pass through\n * unchanged (no TT support yet, see\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1305293).\n *\n * @param lcTag lowercase tag name of the containing element\n * @param lcName lowercase attribute name\n * @param namespaceURI the attribute's namespace, if any\n * @param value the attribute value to wrap\n * @return the value, wrapped when Trusted Types demand it\n */\n const _applyTrustedTypesToAttribute = function (\n lcTag: string,\n lcName: string,\n namespaceURI: string | null,\n value: string\n ): string {\n if (\n trustedTypesPolicy &&\n typeof trustedTypes === 'object' &&\n typeof trustedTypes.getAttributeType === 'function' &&\n !namespaceURI\n ) {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML': {\n return _createTrustedHTML(value);\n }\n\n case 'TrustedScriptURL': {\n return _createTrustedScriptURL(value);\n }\n\n default: {\n break;\n }\n }\n }\n\n return value;\n };\n\n /**\n * Write a modified attribute value back onto the element. On\n * success, re-probe for clobbering introduced by the new value and\n * remove the element when found; otherwise pop the removal entry\n * recorded by the earlier _removeAttribute (long-standing pairing\n * with the SANITIZE_NAMED_PROPS path - do not \"fix\" casually). On\n * failure, remove the attribute instead.\n *\n * @param currentNode the element carrying the attribute\n * @param name the attribute name as present on the element\n * @param namespaceURI the attribute's namespace, if any\n * @param value the new attribute value\n */\n const _setAttributeValue = function (\n currentNode: Element,\n name: string,\n namespaceURI: string | null,\n value: string\n ): void {\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {\n _removeAttribute(name, currentNode);\n }\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param currentNode to sanitize\n */\n const _sanitizeAttributes = function (currentNode: Element): void {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n\n const { attributes } = currentNode;\n\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes || _isClobbered(currentNode)) {\n return;\n }\n\n /* Same lazy-install guard as uponSanitizeElement (see there): fork the\n attribute allowlist off its shared binding before a hook can see it. */\n ALLOWED_ATTR = _forkSharedAllowlist(\n hooks.uponSanitizeAttribute,\n ALLOWED_ATTR,\n DEFAULT_ALLOWED_ATTR,\n SET_CONFIG_ALLOWED_ATTR\n );\n\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n forceKeepAttr: undefined,\n };\n let l = attributes.length;\n const lcTag = transformCaseFunc(currentNode.nodeName);\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const { name, namespaceURI, value: attrValue } = attr;\n const lcName = transformCaseFunc(name);\n\n const initValue = attrValue;\n let value = name === 'value' ? initValue : stringTrim(initValue);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n value = hookEvent.attrValue;\n\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (\n SANITIZE_NAMED_PROPS &&\n (lcName === 'id' || lcName === 'name') &&\n stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0\n ) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n // Else: already prefixed, leave the attribute alone \u2014 the prefix is\n // itself the clobbering protection, and re-applying it is incorrect.\n\n /* Work around a security issue with comments inside attributes */\n if (\n SAFE_FOR_XML &&\n regExpTest(\n /((--!?|])>)|<\\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,\n value\n )\n ) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Make sure we cannot easily use animated hrefs, even if animations are allowed */\n if (lcName === 'attributename' && stringMatch(value, 'href')) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Did the hooks force-keep the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (\n !ALLOW_SELF_CLOSE_IN_ATTR &&\n regExpTest(EXPRESSIONS.SELF_CLOSING_TAG, value)\n ) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n value = _stripTemplateExpressions(value);\n }\n\n /* Is `value` valid for this attribute? */\n if (!_isValidAttribute(lcTag, lcName, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Handle attributes that require Trusted Types */\n value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);\n\n /* Handle invalid data-* attribute set by try-catching it */\n if (value !== initValue) {\n _setAttributeValue(currentNode, name, namespaceURI, value);\n }\n }\n\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function (fragment: DocumentFragment): void {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n\n while ((shadowNode = shadowIterator.nextNode())) {\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n\n /* Sanitize tags and elements */\n _sanitizeElements(shadowNode, fragment);\n\n /* Check attributes next */\n _sanitizeAttributes(shadowNode);\n\n /* Deep shadow DOM detected.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): use nodeType against the\n DOCUMENT_FRAGMENT_NODE constant rather than instanceof, so we\n recurse into <template>.content from foreign realms too. */\n if (_isDocumentFragment(shadowNode.content)) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* An element iterated here may itself host an attached\n shadow root. The default NodeIterator does not enter shadow\n trees, so a shadow root nested inside template.content was\n previously reached by no walk at all (the pre-pass at\n _sanitizeAttachedShadowRoots descends via childNodes, which\n doesn't enter template.content; the template-content recursion\n above iterates the content but never inspected shadowRoot).\n Walk it explicitly. The nodeType guard avoids reading\n shadowRoot off text / comment / CDATA / PI nodes that the\n iterator also surfaces. */\n const shadowNodeType = getNodeType\n ? getNodeType(shadowNode)\n : shadowNode.nodeType;\n if (shadowNodeType === NODE_TYPE.element) {\n const innerSr = getShadowRoot(shadowNode);\n if (_isDocumentFragment(innerSr)) {\n _sanitizeAttachedShadowRoots(innerSr);\n _sanitizeShadowDOM(innerSr);\n }\n }\n }\n\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n };\n\n /**\n * _sanitizeAttachedShadowRoots\n *\n * Walks `root` and feeds every attached shadow root we encounter into\n * the existing _sanitizeShadowDOM pipeline. The default node iterator\n * does not descend into shadow trees, so nodes inside an attached\n * shadow root would otherwise be skipped entirely.\n *\n * Two real input paths put attached shadow roots in front of us:\n * 1. IN_PLACE on a DOM node that already has shadow roots attached.\n * 2. DOM-node input where importNode(dirty, true) deep-clones the\n * shadow root because it was created with `clonable: true`.\n *\n * This pass runs once, up front, so the main iteration loop (and the\n * existing _sanitizeShadowDOM template-content recursion) stay\n * untouched \u2014 string-input paths are not affected.\n *\n * @param root the subtree root to walk for attached shadow roots\n */\n const _sanitizeAttachedShadowRoots = function (root: Node): void {\n /* Iterative (explicit stack) rather than per-child recursion. DOM APIs\n impose no depth cap, so an attacker-shaped tree (JSON/CRDT/editor data\n built straight into the DOM \u2014 the IN_PLACE surface) deeper than the JS\n call-stack budget would otherwise overflow native recursion here and\n throw at the IN_PLACE entry pre-pass, before a single node is\n sanitized, leaving the caller's live tree untouched (fail-open). See\n campaign-3 F4. A heap stack keeps depth off the call stack.\n\n Each work item is either a node to descend into, or a deferred\n `_sanitizeShadowDOM` for an already-walked shadow root. The deferred\n form preserves the original post-order discipline: a shadow root's\n nested shadow roots are discovered before the outer shadow is\n sanitized (which may remove hosts). Pushes are in reverse of the\n desired processing order (LIFO): template content, then children, then\n the shadow-sanitize, then the shadow walk \u2014 so the order matches the\n previous recursion exactly. */\n const stack: Array<{ node: Node | null; shadow: DocumentFragment | null }> =\n [{ node: root, shadow: null }];\n\n while (stack.length > 0) {\n const item = stack.pop();\n\n /* Deferred shadow-DOM sanitisation: runs after its subtree was walked. */\n if (item.shadow) {\n _sanitizeShadowDOM(item.shadow);\n continue;\n }\n\n const node = item.node;\n const nodeType = getNodeType ? getNodeType(node) : (node as any).nodeType;\n const isElement = nodeType === NODE_TYPE.element;\n\n /* (pushed last \u2192 processed first) Children, snapshotted in reverse so\n the first child is processed first. Snapshotting matters because a\n hook may detach siblings mid-walk. */\n const childNodes = getChildNodes(node);\n if (childNodes) {\n for (let i = childNodes.length - 1; i >= 0; --i) {\n stack.push({ node: childNodes[i], shadow: null });\n }\n }\n\n /* (pushed before children \u2192 processed after them, matching the old\n \"template content last\" order) When the node is a <template>,\n descend into its content. */\n if (isElement) {\n const rootName = getNodeName ? getNodeName(node) : null;\n if (\n typeof rootName === 'string' &&\n transformCaseFunc(rootName) === 'template'\n ) {\n const content = (node as HTMLTemplateElement).content;\n if (_isDocumentFragment(content)) {\n stack.push({ node: content, shadow: null });\n }\n }\n }\n\n /* Shadow root (processed first): walk its subtree, then sanitise it.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): nodeType-based detection\n rather than `instanceof DocumentFragment`, which is realm-bound and\n silently skipped foreign-realm shadow roots (e.g.\n iframe.contentDocument attachShadow). */\n if (isElement) {\n const sr = getShadowRoot(node);\n if (_isDocumentFragment(sr)) {\n /* Push the deferred sanitise first so it pops after the shadow\n walk we push next, i.e. nested shadow roots are discovered\n before this one is sanitised. */\n stack.push({ node: null, shadow: sr }, { node: sr, shadow: null });\n }\n }\n }\n };\n\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg = {}) {\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n dirty = stringifyValue(dirty);\n\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n }\n\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n\n /* Assign config vars */\n if (SET_CONFIG) {\n /* Persistent setConfig() path: _parseConfig is skipped, so the sets are\n * not re-derived per call. Restore them from the pristine bindings\n * captured at setConfig() time so a previous call's hook clone (mutated\n * below) does not carry over. */\n ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;\n ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;\n } else {\n _parseConfig(cfg);\n }\n\n /* Clone the hook-mutable allowlists before the walk whenever an\n * uponSanitize* hook is registered. The hook event exposes ALLOWED_TAGS\n * and ALLOWED_ATTR by reference (as allowedTags / allowedAttributes), so\n * a hook that widens them would otherwise mutate the shared set\n * permanently: across later calls and across every element. Cloning per\n * walk keeps documented in-call widening working while scoping it to the\n * call. A single guard for both config paths - the per-call path rebinds\n * the sets in _parseConfig each call, the persistent path restores them\n * from the captured bindings just above - so the two cannot diverge. */\n if (\n hooks.uponSanitizeElement.length > 0 ||\n hooks.uponSanitizeAttribute.length > 0\n ) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n if (hooks.uponSanitizeAttribute.length > 0) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Resolve IN_PLACE for this call without mutating persistent config.\n Writing the IN_PLACE closure variable here leaks under setConfig(),\n where _parseConfig is skipped on later calls: a single string call would\n disable in-place mode for every subsequent node call, returning a\n sanitized copy while leaving the caller's node \u2014 which in-place callers\n keep using and whose return value they ignore \u2014 unsanitized. REPORT-2. */\n const inPlace = IN_PLACE && typeof dirty !== 'string' && _isNode(dirty);\n\n if (inPlace) {\n /* Declarative-partial-updates / streaming pre-pass: sever every patch\n linkage across the live tree BEFORE the walk, so no patch can fire\n mid-walk and inject into an already-processed region. Runs first, so\n it also covers the forbidden/clobbered roots that throw below. */\n _neutralizePatchLinkage(dirty as Node);\n\n /* Do some early pre-sanitization to avoid unsafe root nodes.\n Read nodeName through the cached prototype getter \u2014 a clobbering\n child named \"nodeName\" on the form root would otherwise shadow\n the property and let this check skip the root-allowlist\n validation entirely. */\n const nn = getNodeName\n ? getNodeName(dirty as Node)\n : (dirty as Node).nodeName;\n if (typeof nn === 'string') {\n const tagName = transformCaseFunc(nn);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Fail closed on a live root: neutralize handlers/children before\n throwing, exactly as the mid-walk abort path does. */\n _neutralizeRoot(dirty as Node);\n\n throw typeErrorCreate(\n 'root node is forbidden and cannot be sanitized in-place'\n );\n }\n }\n\n /* Pre-flight the root through _isClobbered. The iterator-driven\n removal path can not detach a parent-less root: _forceRemove\n falls through to Element.prototype.remove(), which per spec\n is a no-op on a node with no parent. A clobbered root would\n then survive the main loop with its attributes uninspected,\n because _sanitizeAttributes early-returns on _isClobbered. The\n result would be an attacker-controlled form, complete with any\n event-handler attributes the caller passed in, handed back to\n the application unsanitized. Refuse to sanitize such a root\n the same way we refuse a forbidden tag. GHSA-r47g-fvhr-h676. */\n if (_isClobbered(dirty as Element)) {\n /* Fail closed on a live clobbered root before throwing.\n _neutralizeRoot's reads are clobber-safe (cached getters); the\n form's non-clobbered descendants, e.g. an armed <img>, are scrubbed. */\n _neutralizeRoot(dirty as Node);\n\n throw typeErrorCreate(\n 'root node is clobbered and cannot be sanitized in-place'\n );\n }\n\n /* Sanitize attached shadow roots before the main iterator runs.\n The iterator does not descend into shadow trees. Same fail-closed\n barrier as the main walk (campaign-3 F2): a custom-element reaction\n inside a shadow root could abort this pre-pass before the walk runs,\n which would otherwise leave the entire live tree unsanitized. */\n try {\n _sanitizeAttachedShadowRoots(dirty as Node);\n } catch (error) {\n _neutralizeRoot(dirty as Node);\n\n throw error;\n }\n } else if (_isNode(dirty)) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (\n importedNode.nodeType === NODE_TYPE.element &&\n importedNode.nodeName === 'BODY'\n ) {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n\n /* Clonable shadow roots are deep-cloned by importNode(); sanitize\n them before the main iterator runs, since the iterator does not\n descend into shadow trees. The walk routes every read through a\n cached prototype getter so clobbering descendants on a form root\n cannot hide a shadow host from this pass. */\n _sanitizeAttachedShadowRoots(importedNode);\n } else {\n /* Exit directly if we have nothing to do */\n if (\n !RETURN_DOM &&\n !SAFE_FOR_TEMPLATES &&\n !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1\n ) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? _createTrustedHTML(dirty)\n : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n const walkRoot: Node = inPlace ? (dirty as Node) : body;\n\n /* Now start iterating over the created document.\n The walk runs inside an exception barrier (campaign-3 F2): a re-entrant\n engine/custom-element mutation can detach a node mid-walk so\n `_forceRemove`'s parentless guard throws, aborting the loop. Without the\n barrier the caller's in-place tree would be left half-sanitized with the\n unvisited tail still armed. _createNodeIterator itself is inside the\n barrier too: constructing the iterator dereferences the root's document,\n and any failure there (e.g. an exotic/clobbered root) must still fail\n closed rather than skip the neutralize. On any throw we fail closed -\n strip the in-place root bare - then rethrow so the existing throw\n contract is preserved. (String/DOM-copy paths never return the partial\n body, so the propagating throw is already fail-closed there.) */\n try {\n const nodeIterator = _createNodeIterator(walkRoot);\n while ((currentNode = nodeIterator.nextNode())) {\n /* Sanitize tags and elements */\n _sanitizeElements(currentNode, walkRoot);\n\n /* Check attributes next */\n _sanitizeAttributes(currentNode);\n\n /* Shadow DOM detected, sanitize it.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): nodeType-based detection\n instead of instanceof, so foreign-realm <template>.content is\n walked correctly. */\n if (_isDocumentFragment(currentNode.content)) {\n _sanitizeShadowDOM(currentNode.content);\n }\n }\n } catch (error) {\n if (inPlace) {\n _neutralizeRoot(dirty as Node);\n /* Nodes _forceRemove'd earlier in the aborted walk are already\n detached from the root, so _neutralizeRoot's subtree pass does not\n reach them. Defuse them too, mirroring the success-path loop below. */\n arrayForEach(DOMPurify.removed, (entry) => {\n if (entry.element) {\n _neutralizeSubtree(entry.element as Node);\n }\n });\n }\n\n throw error;\n }\n\n /* If we sanitized `dirty` in-place, return it. */\n if (inPlace) {\n /* Fail-closed completion of the audit-5 F1 fix: every node removed from\n the caller's live tree is detached but may still hold a queued\n resource-event handler that fires in page scope after we return. The\n move-hoist covers only disallowed-tag KEEP_CONTENT removals; strip the\n non-allow-listed attributes off every other removed subtree (clobber,\n mXSS, namespace, comments, KEEP_CONTENT:false, \u2026) so those handlers are\n cancelled before any event can fire. Runs synchronously, pre-return. */\n arrayForEach(DOMPurify.removed, (entry) => {\n if (entry.element) {\n _neutralizeSubtree(entry.element as Node);\n }\n });\n\n if (SAFE_FOR_TEMPLATES) {\n _scrubTemplateExpressions(dirty as Element);\n }\n\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (SAFE_FOR_TEMPLATES) {\n _scrubTemplateExpressions(body);\n }\n\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Serialize doctype if allowed */\n if (\n WHOLE_DOCUMENT &&\n ALLOWED_TAGS['!doctype'] &&\n body.ownerDocument &&\n body.ownerDocument.doctype &&\n body.ownerDocument.doctype.name &&\n regExpTest(EXPRESSIONS.DOCTYPE_NAME, body.ownerDocument.doctype.name)\n ) {\n serializedHTML =\n '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n serializedHTML = _stripTemplateExpressions(serializedHTML);\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? _createTrustedHTML(serializedHTML)\n : serializedHTML;\n };\n\n DOMPurify.setConfig = function (cfg = {}) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;\n SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;\n };\n\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n SET_CONFIG_ALLOWED_TAGS = null;\n SET_CONFIG_ALLOWED_ATTR = null;\n\n // Drop any caller-supplied Trusted Types policy so it cannot poison later\n // `RETURN_TRUSTED_TYPE` output. The internal default policy (cached, and\n // never recreated \u2014 Trusted Types throws on duplicate names) is restored by\n // the next `_parseConfig`. See GHSA-vxr8-fq34-vvx9.\n trustedTypesPolicy = defaultTrustedTypesPolicy;\n emptyHTML = '';\n };\n\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n DOMPurify.addHook = function (\n entryPoint: keyof HooksMap,\n hookFunction: HookFunction\n ) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n /* Reject unknown entry points. Without this, a non-hook key (e.g.\n * '__proto__') indexes off the prototype chain rather than a real\n * hook array, and arrayPush then writes to Object.prototype. Guard\n * with an own-property check against the known hook names. */\n if (!objectHasOwnProperty(hooks, entryPoint)) {\n return;\n }\n\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n DOMPurify.removeHook = function (\n entryPoint: keyof HooksMap,\n hookFunction: HookFunction\n ) {\n if (!objectHasOwnProperty(hooks, entryPoint)) {\n return undefined;\n }\n\n if (hookFunction !== undefined) {\n const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);\n\n return index === -1\n ? undefined\n : arraySplice(hooks[entryPoint], index, 1)[0];\n }\n\n return arrayPop(hooks[entryPoint]);\n };\n\n DOMPurify.removeHooks = function (entryPoint: keyof HooksMap) {\n if (!objectHasOwnProperty(hooks, entryPoint)) {\n return;\n }\n\n hooks[entryPoint] = [];\n };\n\n DOMPurify.removeAllHooks = function () {\n hooks = _createHooksMap();\n };\n\n return DOMPurify;\n}\n\nexport default createDOMPurify();\n", "import type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Gets the original marked default options.\n */\nexport function _getDefaults<ParserOutput = string, RendererOutput = string>(): MarkedOptions<ParserOutput, RendererOutput> {\n return {\n async: false,\n breaks: false,\n extensions: null,\n gfm: true,\n hooks: null,\n pedantic: false,\n renderer: null,\n silent: false,\n tokenizer: null,\n walkTokens: null,\n };\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport let _defaults: MarkedOptions<any, any> = _getDefaults();\n\nexport function changeDefaults<ParserOutput = string, RendererOutput = string>(newDefaults: MarkedOptions<ParserOutput, RendererOutput>) {\n _defaults = newDefaults;\n}\n", "const noopTest = { exec: () => null } as unknown as RegExp;\n\nfunction cachedIndentRegex(createRegex: (indent: number) => RegExp) {\n const cache: RegExp[] = [];\n return (indent: number) => {\n const cacheIndex = Math.max(0, Math.min(3, indent - 1));\n let regex = cache[cacheIndex];\n if (!regex) {\n regex = createRegex(cacheIndex);\n cache[cacheIndex] = regex;\n }\n return regex;\n };\n}\n\nfunction edit(regex: string | RegExp, opt = '') {\n let source = typeof regex === 'string' ? regex : regex.source;\n const obj = {\n replace: (name: string | RegExp, val: string | RegExp) => {\n let valSource = typeof val === 'string' ? val : val.source;\n valSource = valSource.replace(other.caret, '$1');\n source = source.replace(name, valSource);\n return obj;\n },\n getRegex: () => {\n return new RegExp(source, opt);\n },\n };\n return obj;\n}\n\n// use a default variable to ensure the regex is evaluated on client an not removed by minifiers\nconst supportsLookbehind = ((a = '') => {\ntry {\n return !!new RegExp('(?<=1)(?<!1)' + a);\n} catch {\n // See browser support here:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookbehind_assertion\n return false;\n}\n})();\n\nexport const other = {\n codeRemoveIndent: /^(?: {1,4}| {0,3}\\t)/gm,\n outputLinkReplace: /\\\\([\\[\\]])/g,\n indentCodeCompensation: /^(\\s+)(?:```)/,\n beginningSpace: /^\\s+/,\n endingHash: /#$/,\n startingSpaceChar: /^ /,\n endingSpaceChar: / $/,\n nonSpaceChar: /[^ ]/,\n newLineCharGlobal: /\\n/g,\n tabCharGlobal: /\\t/g,\n multipleSpaceGlobal: /\\s+/g,\n blankLine: /^[ \\t]*$/,\n doubleBlankLine: /\\n[ \\t]*\\n[ \\t]*$/,\n blockquoteStart: /^ {0,3}>/,\n blockquoteSetextReplace: /\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,\n blockquoteSetextReplace2: /^ {0,3}>[ \\t]?/gm,\n listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g,\n listIsTask: /^\\[[ xX]\\] +\\S/,\n listReplaceTask: /^\\[[ xX]\\] +/,\n listTaskCheckbox: /\\[[ xX]\\]/,\n anyLine: /\\n.*\\n/,\n hrefBrackets: /^<(.*)>$/,\n tableDelimiter: /[:|]/,\n tableAlignChars: /^\\||\\| *$/g,\n tableRowBlankLine: /\\n[ \\t]*$/,\n tableAlignRight: /^ *-+: *$/,\n tableAlignCenter: /^ *:-+: *$/,\n tableAlignLeft: /^ *:-+ *$/,\n startATag: /^<a /i,\n endATag: /^<\\/a>/i,\n startPreScriptTag: /^<(pre|code|kbd|script)(\\s|>)/i,\n endPreScriptTag: /^<\\/(pre|code|kbd|script)(\\s|>)/i,\n startAngleBracket: /^</,\n endAngleBracket: />$/,\n pedanticHrefTitle: /^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/,\n unicodeAlphaNumeric: /[\\p{L}\\p{N}]/u,\n escapeTest: /[&<>\"']/,\n escapeReplace: /[&<>\"']/g,\n escapeTestNoEncode: /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,\n escapeReplaceNoEncode: /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,\n caret: /(^|[^\\[])\\^/g,\n percentDecode: /%25/g,\n findPipe: /\\|/g,\n splitPipe: / \\|/,\n slashPipe: /\\\\\\|/g,\n carriageReturn: /\\r\\n|\\r/g,\n spaceLine: /^ +$/gm,\n notSpaceStart: /^\\S*/,\n endingNewline: /\\n$/,\n listItemRegex: (bull: string) => new RegExp(`^( {0,3}${bull})((?:[\\t ][^\\\\n]*)?(?:\\\\n|$))`),\n nextBulletRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \\t][^\\\\n]*)?(?:\\\\n|$))`)),\n hrRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),\n fencesBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:\\`\\`\\`|~~~)`)),\n headingBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}#`)),\n htmlBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}<(?:[a-z].*>|!--)`, 'i')),\n blockquoteBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}>`)),\n};\n\n/**\n * Block-Level Grammar\n */\n\nconst newline = /^(?:[ \\t]*(?:\\n|$))+/;\nconst blockCode = /^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/;\nconst fences = /^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/;\nconst hr = /^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/;\nconst heading = /^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/;\nconst bullet = / {0,3}(?:[*+-]|\\d{1,9}[.)])/;\nconst lheadingCore = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/;\nconst lheading = edit(lheadingCore)\n .replace(/bull/g, bullet) // lists can interrupt\n .replace(/blockCode/g, /(?: {4}| {0,3}\\t)/) // indented code blocks can interrupt\n .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt\n .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt\n .replace(/heading/g, / {0,3}#{1,6}(?:\\s|$)/) // ATX heading can interrupt\n .replace(/html/g, / {0,3}<[^\\n>]+>\\n/) // block html can interrupt\n .replace(/\\|table/g, '') // table not in commonmark\n .getRegex();\nconst lheadingGfm = edit(lheadingCore)\n .replace(/bull/g, bullet) // lists can interrupt\n .replace(/blockCode/g, /(?: {4}| {0,3}\\t)/) // indented code blocks can interrupt\n .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt\n .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt\n .replace(/heading/g, / {0,3}#{1,6}(?:\\s|$)/) // ATX heading can interrupt\n .replace(/html/g, / {0,3}<[^\\n>]+>\\n/) // block html can interrupt\n .replace(/table/g, / {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/) // table can interrupt\n .getRegex();\nconst _paragraph = /^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/;\nconst blockText = /^[^\\n]+/;\nconst _blockLabel = /(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/;\nconst def = edit(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/)\n .replace('label', _blockLabel)\n .replace('title', /(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/)\n .getRegex();\n\nconst list = edit(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/)\n .replace(/bull/g, bullet)\n .getRegex();\n\nconst _tag = 'address|article|aside|base|basefont|blockquote|body|caption'\n + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'\n + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'\n + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'\n + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title'\n + '|tr|track|ul';\nconst _comment = /<!--(?:-?>|[\\s\\S]*?(?:-->|$))/;\nconst html = edit(\n '^ {0,3}(?:' // optional indentation\n+ '<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n*|$)' // (1)\n+ '|comment[^\\\\n]*(\\\\n+|$)' // (2)\n+ '|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>[^\\\\n]*\\\\n*|$)' // (3)\n+ '|<![A-Z][\\\\s\\\\S]*?(?:>[^\\\\n]*\\\\n*|$)' // (4)\n+ '|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>[^\\\\n]*\\\\n*|$)' // (5)\n+ '|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (6)\n+ '|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) open tag\n+ '|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) closing tag\n+ ')', 'i')\n .replace('comment', _comment)\n .replace('tag', _tag)\n .replace('attribute', / +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/)\n .getRegex();\n\nconst createParagraph = (listInterrupt: RegExp) => edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n .replace('|table', '')\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n')\n .replace('list', listInterrupt)\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n .getRegex();\n\n// only non-empty lists starting from 1 can interrupt paragraphs\nconst paragraph = createParagraph(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/);\n// inside a blockquote a bare list marker (any number) starts a sibling list,\n// so it must not be lazily continued as paragraph text (unlike a top level\n// paragraph, where an empty list cannot interrupt)\nconst blockquoteParagraph = createParagraph(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/);\n\nconst blockquote = edit(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/)\n .replace('paragraph', blockquoteParagraph)\n .getRegex();\n\n/**\n * Normal Block Grammar\n */\n\nconst blockNormal = {\n blockquote,\n code: blockCode,\n def,\n fences,\n heading,\n hr,\n html,\n lheading,\n list,\n newline,\n paragraph,\n table: noopTest,\n text: blockText,\n};\n\ntype BlockKeys = keyof typeof blockNormal;\n\n/**\n * GFM Block Grammar\n */\n\nconst gfmTable = edit(\n '^ *([^\\\\n ].*)\\\\n' // Header\n+ ' {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)' // Align\n+ '(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)') // Cells\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('blockquote', ' {0,3}>')\n .replace('code', '(?: {4}| {0,3}\\t)[^\\\\n]')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)])[ \\\\t]') // any bullet ends the table rows\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // tables can be interrupted by type (6) html blocks\n .getRegex();\n\nconst blockGfm: Record<BlockKeys, RegExp> = {\n ...blockNormal,\n lheading: lheadingGfm,\n table: gfmTable,\n paragraph: edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n .replace('table', gfmTable) // interrupt paragraphs with table\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)])[ \\\\t]+[^ \\\\t\\\\n]') // only non-empty lists starting from 1 can interrupt\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n .getRegex(),\n};\n\n/**\n * Pedantic grammar (original John Gruber's loose markdown specification)\n */\n\nconst blockPedantic: Record<BlockKeys, RegExp> = {\n ...blockNormal,\n html: edit(\n '^ *(?:comment *(?:\\\\n|\\\\s*$)'\n + '|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)' // closed tag\n + '|<tag(?:\"[^\"]*\"|\\'[^\\']*\\'|\\\\s[^\\'\"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))')\n .replace('comment', _comment)\n .replace(/tag/g, '(?!(?:'\n + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'\n + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'\n + '\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b')\n .getRegex(),\n def: /^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,\n heading: /^(#{1,6})(.*)(?:\\n+|$)/,\n fences: noopTest, // fences not supported\n lheading: /^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,\n paragraph: edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' *#{1,6} *[^\\n]')\n .replace('lheading', lheading)\n .replace('|table', '')\n .replace('blockquote', ' {0,3}>')\n .replace('|fences', '')\n .replace('|list', '')\n .replace('|html', '')\n .replace('|tag', '')\n .getRegex(),\n};\n\n/**\n * Inline-Level Grammar\n */\n\nconst escape = /^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/;\nconst inlineCode = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst br = /^( {2,}|\\\\)\\n(?!\\s*$)/;\nconst inlineText = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/;\n\n// list of unicode punctuation marks, plus any missing characters from CommonMark spec\nconst _punctuation = /[\\p{P}\\p{S}]/u;\nconst _punctuationOrSpace = /[\\s\\p{P}\\p{S}]/u;\nconst _notPunctuationOrSpace = /[^\\s\\p{P}\\p{S}]/u;\nconst punctuation = edit(/^((?![*_])punctSpace)/, 'u')\n .replace(/punctSpace/g, _punctuationOrSpace).getRegex();\n\n/**\n * Opening punct/quotes excluded from pedantic LDelim nextChar so\n * `aa**\"A\"**bb` / `aa**(A)**bb` can start strong (Pi + Ps + ASCII straight quotes).\n */\nconst _openQuote = /[\\p{Pi}\\p{Ps}\"']/u;\n\n// GFM allows ~ inside strong and em for strikethrough\nconst _punctuationGfmStrongEm = /(?!~)[\\p{P}\\p{S}]/u;\nconst _punctuationOrSpaceGfmStrongEm = /(?!~)[\\s\\p{P}\\p{S}]/u;\nconst _notPunctuationOrSpaceGfmStrongEm = /(?:[^\\s\\p{P}\\p{S}]|~)/u;\n\n// sequences em should skip over [title](link), `code`, <html>\nconst blockSkip = edit(/link|precode-code|html/, 'g')\n .replace('link', /\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/)\n .replace('precode-', supportsLookbehind ? '(?<!`)()' : '(^^|[^`])')\n .replace('code', /(?<b>`+)[^`]+\\k<b>(?!`)/)\n .replace('html', /<(?! )[^<>]*?>/)\n .getRegex();\n\nconst emStrongLDelimCore = /^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/;\n\nconst emStrongLDelim = edit(emStrongLDelimCore, 'u')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongLDelimGfm = edit(emStrongLDelimCore, 'u')\n .replace(/punct/g, _punctuationGfmStrongEm)\n .getRegex();\n\n// Pedantic: do not treat opening punct/quotes as left-delim punct (e.g. **( / **\").\nconst emStrongLDelimPedanticCore = /^(?:\\*+(?:((?!\\*)(?!openQuote)punct)|([^\\s*]))?)|^_+(?:((?!_)(?!openQuote)punct)|([^\\s_]))?/;\n\nconst emStrongLDelimPedantic = edit(emStrongLDelimPedanticCore, 'u')\n .replace(/openQuote/g, _openQuote)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongRDelimAstCore =\n '^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)' // Skip orphan inside strong\n+ '|[^*]+(?=[^*])' // Consume to delim\n+ '|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)' // (1) #*** can only be a Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter\n+ '|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)' // (3) #***a, ***a can only be Left Delimiter\n+ '|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)' // (4) ***# can only be Left Delimiter\n+ '|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?=notPunctSpace)'; // (6) a***a can be either Left or Right Delimiter\n\nconst emStrongRDelimAst = edit(emStrongRDelimAstCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongRDelimAstGfm = edit(emStrongRDelimAstCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmStrongEm)\n .replace(/punctSpace/g, _punctuationOrSpaceGfmStrongEm)\n .replace(/punct/g, _punctuationGfmStrongEm)\n .getRegex();\n\n// Pedantic: rule 3 requires whitespace before left delim; rule 6 allows punct before close (e.g. `:**bar`).\nconst emStrongRDelimAstPedanticCore =\n '^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)' // Skip orphan inside strong\n+ '|[^*]+(?=[^*])' // Consume to delim\n+ '|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)' // (1) #*** can only be a Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter\n+ '|(?!\\\\*)[\\\\s](\\\\*+)(?=notPunctSpace)' // (3) ***a can only be Left Delimiter (whitespace required; not #***a)\n+ '|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)' // (4) ***# can only be Left Delimiter\n+ '|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter\n+ '|(?:(?!\\\\*)punct|notPunctSpace)(\\\\*+)(?!\\\\*)(?=notPunctSpace)'; // (6) a***a, #***a, and :** (e.g. **foo:**bar)\n\nconst emStrongRDelimAstPedantic = edit(emStrongRDelimAstPedanticCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Normal: no rule 6 for _ (a___a cannot close as emphasis).\nconst emStrongRDelimUnd = edit(\n '^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)' // Skip orphan inside strong\n+ '|[^_]+(?=[^_])' // Consume to delim\n+ '|(?!_)punct(_+)(?=[\\\\s]|$)' // (1) #___ can only be a Right Delimiter\n+ '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter\n+ '|(?!_)punctSpace(_+)(?=notPunctSpace)' // (3) #___a, ___a can only be Left Delimiter\n+ '|[\\\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter\n+ '|(?!_)punct(_+)(?!_)(?=punct)', 'gu') // (5) #___# can be either Left or Right Delimiter\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Pedantic: same rule 3/6 adjustments as emStrongRDelimAstPedantic (e.g. `_foo:_bar`).\nconst emStrongRDelimUndPedanticCore =\n '^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)' // Skip orphan inside strong\n+ '|[^_]+(?=[^_])' // Consume to delim\n+ '|(?!_)punct(_+)(?=[\\\\s]|$)' // (1) #___ can only be a Right Delimiter\n+ '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter\n+ '|(?!_)[\\\\s](_+)(?=notPunctSpace)' // (3) ___a can only be Left Delimiter (whitespace required; not #___a)\n+ '|[\\\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter\n+ '|(?!_)punct(_+)(?!_)(?=punct)' // (5) #___# can be either Left or Right Delimiter\n+ '|(?:(?!_)punct|notPunctSpace)(_+)(?!_)(?=notPunctSpace)'; // (6) a___a, #___a, and :__ (e.g. _foo:_bar)\n\nconst emStrongRDelimUndPedantic = edit(emStrongRDelimUndPedanticCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Tilde left delimiter for strikethrough (similar to emStrongLDelim for asterisk)\nconst delLDelim = edit(/^~~?(?:((?!~)punct)|[^\\s~])/, 'u')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Tilde delimiter patterns for strikethrough (similar to asterisk)\nconst delRDelimCore =\n '^[^~]+(?=[^~])' // Consume to delim\n+ '|(?!~)punct(~~?)(?=[\\\\s]|$)' // (1) #~~ can only be a Right Delimiter\n+ '|notPunctSpace(~~?)(?!~)(?=punctSpace|$)' // (2) a~~#, a~~ can only be a Right Delimiter\n+ '|(?!~)punctSpace(~~?)(?=notPunctSpace)' // (3) #~~a, ~~a can only be Left Delimiter\n+ '|[\\\\s](~~?)(?!~)(?=punct)' // (4) ~~# can only be Left Delimiter\n+ '|(?!~)punct(~~?)(?!~)(?=punct)' // (5) #~~# can be either Left or Right Delimiter\n+ '|notPunctSpace(~~?)(?=notPunctSpace)'; // (6) a~~a can be either Left or Right Delimiter\n\nconst delRDelim = edit(delRDelimCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst anyPunctuation = edit(/\\\\(punct)/, 'gu')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst autolink = edit(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/)\n .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)\n .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/)\n .getRegex();\n\nconst _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();\nconst tag = edit(\n '^comment'\n + '|^</[a-zA-Z][\\\\w:-]*\\\\s*>' // self-closing tag\n + '|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>' // open tag\n + '|^<\\\\?[\\\\s\\\\S]*?\\\\?>' // processing instruction, e.g. <?php ?>\n + '|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>' // declaration, e.g. <!DOCTYPE html>\n + '|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>') // CDATA section\n .replace('comment', _inlineComment)\n .replace('attribute', /\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/)\n .getRegex();\n\nconst _inlineLabel = /(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/;\n\nconst link = edit(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/)\n .replace('label', _inlineLabel)\n .replace('href', /<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/)\n .replace('title', /\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/)\n .getRegex();\n\nconst reflink = edit(/^!?\\[(label)\\]\\[(ref)\\]/)\n .replace('label', _inlineLabel)\n .replace('ref', _blockLabel)\n .getRegex();\n\nconst nolink = edit(/^!?\\[(ref)\\](?:\\[\\])?/)\n .replace('ref', _blockLabel)\n .getRegex();\n\nconst reflinkSearch = edit('reflink|nolink(?!\\\\()', 'g')\n .replace('reflink', reflink)\n .replace('nolink', nolink)\n .getRegex();\n\nconst _caseInsensitiveProtocol = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;\n\n/**\n * Normal Inline Grammar\n */\n\nconst inlineNormal = {\n _backpedal: noopTest, // only used for GFM url\n anyPunctuation,\n autolink,\n blockSkip,\n br,\n code: inlineCode,\n del: noopTest,\n delLDelim: noopTest,\n delRDelim: noopTest,\n emStrongLDelim,\n emStrongRDelimAst,\n emStrongRDelimUnd,\n escape,\n link,\n nolink,\n punctuation,\n reflink,\n reflinkSearch,\n tag,\n text: inlineText,\n url: noopTest,\n};\n\ntype InlineKeys = keyof typeof inlineNormal;\n\n/**\n * Pedantic Inline Grammar\n */\n\nconst inlinePedantic: Record<InlineKeys, RegExp> = {\n ...inlineNormal,\n emStrongLDelim: emStrongLDelimPedantic,\n emStrongRDelimAst: emStrongRDelimAstPedantic,\n emStrongRDelimUnd: emStrongRDelimUndPedantic,\n link: edit(/^!?\\[(label)\\]\\((.*?)\\)/)\n .replace('label', _inlineLabel)\n .getRegex(),\n reflink: edit(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/)\n .replace('label', _inlineLabel)\n .getRegex(),\n};\n\n/**\n * GFM Inline Grammar\n */\n\nconst inlineGfm: Record<InlineKeys, RegExp> = {\n ...inlineNormal,\n emStrongRDelimAst: emStrongRDelimAstGfm,\n emStrongLDelim: emStrongLDelimGfm,\n delLDelim,\n delRDelim,\n url: edit(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/)\n .replace('protocol', _caseInsensitiveProtocol)\n .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)\n .getRegex(),\n _backpedal: /(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,\n del: /^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,\n text: edit(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|protocol:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)))/)\n .replace('protocol', _caseInsensitiveProtocol)\n .getRegex(),\n};\n\n/**\n * GFM + Line Breaks Inline Grammar\n */\n\nconst inlineBreaks: Record<InlineKeys, RegExp> = {\n ...inlineGfm,\n br: edit(br).replace('{2,}', '*').getRegex(),\n text: edit(inlineGfm.text)\n .replace('\\\\b_', '\\\\b_| {2,}\\\\n')\n .replace(/\\{2,\\}/g, '*')\n .getRegex(),\n};\n\n/**\n * exports\n */\n\nexport const block = {\n normal: blockNormal,\n gfm: blockGfm,\n pedantic: blockPedantic,\n};\n\nexport const inline = {\n normal: inlineNormal,\n gfm: inlineGfm,\n breaks: inlineBreaks,\n pedantic: inlinePedantic,\n};\n\nexport interface Rules {\n other: typeof other\n block: Record<BlockKeys, RegExp>\n inline: Record<InlineKeys, RegExp>\n}\n", "import { other } from './rules.ts';\n\n/**\n * Helpers\n */\nconst escapeReplacements: { [index: string]: string } = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\nconst getEscapeReplacement = (ch: string) => escapeReplacements[ch];\n\nexport function escapeHtmlEntities(html: string, encode?: boolean) {\n if (encode) {\n if (other.escapeTest.test(html)) {\n return html.replace(other.escapeReplace, getEscapeReplacement);\n }\n } else {\n if (other.escapeTestNoEncode.test(html)) {\n return html.replace(other.escapeReplaceNoEncode, getEscapeReplacement);\n }\n }\n\n return html;\n}\n\nexport function cleanUrl(href: string) {\n try {\n href = encodeURI(href).replace(other.percentDecode, '%');\n } catch {\n return null;\n }\n return href;\n}\n\nexport function splitCells(tableRow: string, count?: number) {\n // ensure that every cell-delimiting pipe has a space\n // before it to distinguish it from an escaped pipe\n const row = tableRow.replace(other.findPipe, (match, offset, str) => {\n let escaped = false;\n let curr = offset;\n while (--curr >= 0 && str[curr] === '\\\\') escaped = !escaped;\n if (escaped) {\n // odd number of slashes means | is escaped\n // so we leave it alone\n return '|';\n } else {\n // add space before unescaped |\n return ' |';\n }\n }),\n cells = row.split(other.splitPipe);\n let i = 0;\n\n // First/last cell in a row cannot be empty if it has no leading/trailing pipe\n if (!cells[0].trim()) {\n cells.shift();\n }\n if (cells.length > 0 && !cells.at(-1)?.trim()) {\n cells.pop();\n }\n\n if (count) {\n if (cells.length > count) {\n cells.splice(count);\n } else {\n while (cells.length < count) cells.push('');\n }\n }\n\n for (; i < cells.length; i++) {\n // leading or trailing whitespace is ignored per the gfm spec\n cells[i] = cells[i].trim().replace(other.slashPipe, '|');\n }\n return cells;\n}\n\n/**\n * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').\n * /c*$/ is vulnerable to REDOS.\n *\n * @param str\n * @param c\n * @param invert Remove suffix of non-c chars instead. Default falsey.\n */\nexport function rtrim(str: string, c: string, invert?: boolean) {\n const l = str.length;\n if (l === 0) {\n return '';\n }\n\n // Length of suffix matching the invert condition.\n let suffLen = 0;\n\n // Step left until we fail to match the invert condition.\n while (suffLen < l) {\n const currChar = str.charAt(l - suffLen - 1);\n if (currChar === c && !invert) {\n suffLen++;\n } else if (currChar !== c && invert) {\n suffLen++;\n } else {\n break;\n }\n }\n\n return str.slice(0, l - suffLen);\n}\n\nexport function trimTrailingBlankLines(str: string) {\n const lines = str.split('\\n');\n let end = lines.length - 1;\n while (end >= 0 && other.blankLine.test(lines[end])) {\n end--;\n }\n if (lines.length - end <= 2) {\n // we want to keep single trailing blank lines\n return str;\n }\n\n return lines.slice(0, end + 1).join('\\n');\n}\n\nexport function findClosingBracket(str: string, b: string) {\n if (str.indexOf(b[1]) === -1) {\n return -1;\n }\n\n let level = 0;\n for (let i = 0; i < str.length; i++) {\n if (str[i] === '\\\\') {\n i++;\n } else if (str[i] === b[0]) {\n level++;\n } else if (str[i] === b[1]) {\n level--;\n if (level < 0) {\n return i;\n }\n }\n }\n if (level > 0) {\n return -2;\n }\n\n return -1;\n}\n\nexport function expandTabs(line: string, indent = 0) {\n let col = indent;\n let expanded = '';\n for (const char of line) {\n if (char === '\\t') {\n const added = 4 - (col % 4);\n expanded += ' '.repeat(added);\n col += added;\n } else {\n expanded += char;\n col++;\n }\n }\n\n return expanded;\n}\n", "import { _defaults } from './defaults.ts';\nimport {\n rtrim,\n splitCells,\n findClosingBracket,\n expandTabs,\n trimTrailingBlankLines,\n} from './helpers.ts';\nimport type { Rules } from './rules.ts';\nimport type { _Lexer } from './Lexer.ts';\nimport type { Links, Tokens, Token } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\nfunction outputLink(cap: string[], link: Pick<Tokens.Link, 'href' | 'title'>, raw: string, lexer: _Lexer, rules: Rules): Tokens.Link | Tokens.Image {\n const href = link.href;\n const title = link.title || null;\n const text = cap[1].replace(rules.other.outputLinkReplace, '$1');\n\n lexer.state.inLink = true;\n const token: Tokens.Link | Tokens.Image = {\n type: cap[0].charAt(0) === '!' ? 'image' : 'link',\n raw,\n href,\n title,\n text,\n tokens: lexer.inlineTokens(text),\n };\n lexer.state.inLink = false;\n return token;\n}\n\nfunction indentCodeCompensation(raw: string, text: string, rules: Rules) {\n const matchIndentToCode = raw.match(rules.other.indentCodeCompensation);\n\n if (matchIndentToCode === null) {\n return text;\n }\n\n const indentToCode = matchIndentToCode[1];\n\n return text\n .split('\\n')\n .map(node => {\n const matchIndentInNode = node.match(rules.other.beginningSpace);\n if (matchIndentInNode === null) {\n return node;\n }\n\n const [indentInNode] = matchIndentInNode;\n\n if (indentInNode.length >= indentToCode.length) {\n return node.slice(indentToCode.length);\n }\n\n return node;\n })\n .join('\\n');\n}\n\n/**\n * Tokenizer\n */\nexport class _Tokenizer<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n rules!: Rules; // set by the lexer\n lexer!: _Lexer<ParserOutput, RendererOutput>; // set by the lexer\n\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n }\n\n space(src: string): Tokens.Space | undefined {\n const cap = this.rules.block.newline.exec(src);\n if (cap && cap[0].length > 0) {\n return {\n type: 'space',\n raw: cap[0],\n };\n }\n }\n\n code(src: string): Tokens.Code | undefined {\n const cap = this.rules.block.code.exec(src);\n if (cap) {\n const raw = this.options.pedantic\n ? cap[0]\n : trimTrailingBlankLines(cap[0]);\n const text = raw.replace(this.rules.other.codeRemoveIndent, '');\n return {\n type: 'code',\n raw,\n codeBlockStyle: 'indented',\n text,\n };\n }\n }\n\n fences(src: string): Tokens.Code | undefined {\n const cap = this.rules.block.fences.exec(src);\n if (cap) {\n const raw = cap[0];\n const text = indentCodeCompensation(raw, cap[3] || '', this.rules);\n\n return {\n type: 'code',\n raw,\n lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],\n text,\n };\n }\n }\n\n heading(src: string): Tokens.Heading | undefined {\n const cap = this.rules.block.heading.exec(src);\n if (cap) {\n let text = cap[2].trim();\n\n // remove trailing #s\n if (this.rules.other.endingHash.test(text)) {\n const trimmed = rtrim(text, '#');\n if (this.options.pedantic) {\n text = trimmed.trim();\n } else if (!trimmed || this.rules.other.endingSpaceChar.test(trimmed)) {\n // CommonMark requires space before trailing #s\n text = trimmed.trim();\n }\n }\n\n return {\n type: 'heading',\n raw: rtrim(cap[0], '\\n'),\n depth: cap[1].length,\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n hr(src: string): Tokens.Hr | undefined {\n const cap = this.rules.block.hr.exec(src);\n if (cap) {\n return {\n type: 'hr',\n raw: rtrim(cap[0], '\\n'),\n };\n }\n }\n\n blockquote(src: string): Tokens.Blockquote | undefined {\n const cap = this.rules.block.blockquote.exec(src);\n if (cap) {\n let lines = rtrim(cap[0], '\\n').split('\\n');\n let raw = '';\n let text = '';\n const tokens: Token[] = [];\n\n while (lines.length > 0) {\n let inBlockquote = false;\n const currentLines = [];\n\n let i;\n for (i = 0; i < lines.length; i++) {\n // get lines up to a continuation\n if (this.rules.other.blockquoteStart.test(lines[i])) {\n currentLines.push(lines[i]);\n inBlockquote = true;\n } else if (!inBlockquote) {\n currentLines.push(lines[i]);\n } else {\n break;\n }\n }\n lines = lines.slice(i);\n\n const currentRaw = currentLines.join('\\n');\n const currentText = currentRaw\n // precede setext continuation with 4 spaces so it isn't a setext\n .replace(this.rules.other.blockquoteSetextReplace, '\\n $1')\n .replace(this.rules.other.blockquoteSetextReplace2, '');\n raw = raw ? `${raw}\\n${currentRaw}` : currentRaw;\n text = text ? `${text}\\n${currentText}` : currentText;\n\n // parse blockquote lines as top level tokens\n // merge paragraphs if this is a continuation\n const top = this.lexer.state.top;\n this.lexer.state.top = true;\n this.lexer.blockTokens(currentText, tokens, true);\n this.lexer.state.top = top;\n\n // if there is no continuation then we are done\n if (lines.length === 0) {\n break;\n }\n\n const lastToken = tokens.at(-1);\n\n if (lastToken?.type === 'code') {\n // blockquote continuation cannot be preceded by a code block\n break;\n } else if (lastToken?.type === 'blockquote') {\n // include continuation in nested blockquote\n const oldToken = lastToken as Tokens.Blockquote;\n // The continuation lines belong to the same nesting frame as the\n // nested blockquote, which already had one '>' marker stripped, so\n // strip one marker from them too. Otherwise a restated marker after a\n // lazy line is re-parsed as a spurious deeper blockquote.\n const continuation = lines.join('\\n');\n const newText = oldToken.raw + '\\n' + continuation.replace(this.rules.other.blockquoteSetextReplace2, '');\n const newToken = this.blockquote(newText)!;\n tokens[tokens.length - 1] = newToken;\n\n raw = `${raw}\\n${continuation}`;\n text = text.substring(0, text.length - oldToken.text.length) + newToken.text;\n break;\n } else if (lastToken?.type === 'list') {\n // include continuation in nested list\n const oldToken = lastToken as Tokens.List;\n const newText = oldToken.raw + '\\n' + lines.join('\\n');\n const newToken = this.list(newText)!;\n tokens[tokens.length - 1] = newToken;\n\n raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;\n text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;\n lines = newText.substring(tokens.at(-1)!.raw.length).split('\\n');\n continue;\n }\n }\n\n return {\n type: 'blockquote',\n raw,\n tokens,\n text,\n };\n }\n }\n\n list(src: string): Tokens.List | undefined {\n let cap = this.rules.block.list.exec(src);\n if (cap) {\n let bull = cap[1].trim();\n const isordered = bull.length > 1;\n\n const list: Tokens.List = {\n type: 'list',\n raw: '',\n ordered: isordered,\n start: isordered ? +bull.slice(0, -1) : '',\n loose: false,\n items: [],\n };\n\n bull = isordered ? `\\\\d{1,9}\\\\${bull.slice(-1)}` : `\\\\${bull}`;\n\n if (this.options.pedantic) {\n bull = isordered ? bull : '[*+-]';\n }\n\n // Get next list item\n const itemRegex = this.rules.other.listItemRegex(bull);\n let endsWithBlankLine = false;\n // Check if current bullet point can start a new List Item\n while (src) {\n let endEarly = false;\n let raw = '';\n let itemContents = '';\n if (!(cap = itemRegex.exec(src))) {\n break;\n }\n\n if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)\n break;\n }\n\n raw = cap[0];\n src = src.substring(raw.length);\n\n let line = expandTabs(cap[2].split('\\n', 1)[0], cap[1].length);\n let nextLine = src.split('\\n', 1)[0];\n let blankLine = !line.trim();\n\n let indent = 0;\n if (this.options.pedantic) {\n indent = 2;\n itemContents = line.trimStart();\n } else if (blankLine) {\n indent = cap[1].length + 1;\n } else {\n indent = line.search(this.rules.other.nonSpaceChar); // Find first non-space char\n indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent\n itemContents = line.slice(indent);\n indent += cap[1].length;\n }\n\n if (blankLine && this.rules.other.blankLine.test(nextLine)) { // Items begin with at most one blank line\n raw += nextLine + '\\n';\n src = src.substring(nextLine.length + 1);\n endEarly = true;\n }\n\n if (!endEarly) {\n const nextBulletRegex = this.rules.other.nextBulletRegex(indent);\n const hrRegex = this.rules.other.hrRegex(indent);\n const fencesBeginRegex = this.rules.other.fencesBeginRegex(indent);\n const headingBeginRegex = this.rules.other.headingBeginRegex(indent);\n const htmlBeginRegex = this.rules.other.htmlBeginRegex(indent);\n const blockquoteBeginRegex = this.rules.other.blockquoteBeginRegex(indent);\n\n // Check if following lines should be included in List Item\n while (src) {\n const rawLine = src.split('\\n', 1)[0];\n let nextLineWithoutTabs;\n nextLine = rawLine;\n\n // Re-align to follow commonmark nesting rules\n if (this.options.pedantic) {\n nextLine = nextLine.replace(this.rules.other.listReplaceNesting, ' ');\n nextLineWithoutTabs = nextLine;\n } else {\n nextLineWithoutTabs = nextLine.replace(this.rules.other.tabCharGlobal, ' ');\n }\n\n // End list item if found code fences\n if (fencesBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of new heading\n if (headingBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of html block\n if (htmlBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of blockquote\n if (blockquoteBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of new bullet\n if (nextBulletRegex.test(nextLine)) {\n break;\n }\n\n // Horizontal rule found\n if (hrRegex.test(nextLine)) {\n break;\n }\n\n if (nextLineWithoutTabs.search(this.rules.other.nonSpaceChar) >= indent || !nextLine.trim()) { // Dedent if possible\n itemContents += '\\n' + nextLineWithoutTabs.slice(indent);\n } else {\n // not enough indentation\n if (blankLine) {\n break;\n }\n\n // paragraph continuation unless last line was a different block level element\n if (line.replace(this.rules.other.tabCharGlobal, ' ').search(this.rules.other.nonSpaceChar) >= 4) { // indented code block\n break;\n }\n if (fencesBeginRegex.test(line)) {\n break;\n }\n if (headingBeginRegex.test(line)) {\n break;\n }\n if (hrRegex.test(line)) {\n break;\n }\n\n itemContents += '\\n' + nextLine;\n }\n\n blankLine = !nextLine.trim();\n\n raw += rawLine + '\\n';\n src = src.substring(rawLine.length + 1);\n line = nextLineWithoutTabs.slice(indent);\n }\n }\n\n if (!list.loose) {\n // If the previous item ended with a blank line, the list is loose\n if (endsWithBlankLine) {\n list.loose = true;\n } else if (this.rules.other.doubleBlankLine.test(raw)) {\n endsWithBlankLine = true;\n }\n }\n\n list.items.push({\n type: 'list_item',\n raw,\n task: !!this.options.gfm && this.rules.other.listIsTask.test(itemContents),\n loose: false,\n text: itemContents,\n tokens: [],\n });\n\n list.raw += raw;\n }\n\n // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic\n const lastItem = list.items.at(-1);\n if (lastItem) {\n lastItem.raw = lastItem.raw.trimEnd();\n lastItem.text = lastItem.text.trimEnd();\n } else {\n // not a list since there were no items\n return;\n }\n list.raw = list.raw.trimEnd();\n\n // Item child tokens handled here at end because we needed to have the final item to trim it first\n for (const item of list.items) {\n this.lexer.state.top = false;\n item.tokens = this.lexer.blockTokens(item.text, []);\n const itemToken = item.tokens[0];\n if (item.task && (itemToken?.type === 'text' || itemToken?.type === 'paragraph')) {\n // Remove checkbox markdown from item tokens\n item.text = item.text.replace(this.rules.other.listReplaceTask, '');\n itemToken.raw = itemToken.raw.replace(this.rules.other.listReplaceTask, '');\n itemToken.text = itemToken.text.replace(this.rules.other.listReplaceTask, '');\n for (let i = this.lexer.inlineQueue.length - 1; i >= 0; i--) {\n if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[i].src)) {\n this.lexer.inlineQueue[i].src = this.lexer.inlineQueue[i].src.replace(this.rules.other.listReplaceTask, '');\n break;\n }\n }\n\n const taskRaw = this.rules.other.listTaskCheckbox.exec(item.raw);\n if (taskRaw) {\n const checkboxToken: Tokens.Checkbox = {\n type: 'checkbox',\n raw: taskRaw[0] + ' ',\n checked: taskRaw[0] !== '[ ]',\n };\n item.checked = checkboxToken.checked;\n if (list.loose) {\n if (item.tokens[0] && ['paragraph', 'text'].includes(item.tokens[0].type) && 'tokens' in item.tokens[0] && item.tokens[0].tokens) {\n item.tokens[0].raw = checkboxToken.raw + item.tokens[0].raw;\n item.tokens[0].text = checkboxToken.raw + item.tokens[0].text;\n item.tokens[0].tokens.unshift(checkboxToken);\n } else {\n item.tokens.unshift({\n type: 'paragraph',\n raw: checkboxToken.raw,\n text: checkboxToken.raw,\n tokens: [checkboxToken],\n });\n }\n } else {\n item.tokens.unshift(checkboxToken);\n }\n }\n } else if (item.task) {\n item.task = false;\n }\n\n if (!list.loose) {\n // Check if list should be loose\n const spacers = item.tokens.filter(t => t.type === 'space');\n const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => this.rules.other.anyLine.test(t.raw));\n\n list.loose = hasMultipleLineBreaks;\n }\n }\n\n // Set all items to loose if list is loose\n if (list.loose) {\n for (const item of list.items) {\n item.loose = true;\n for (const token of item.tokens) {\n if (token.type === 'text') {\n token.type = 'paragraph';\n }\n }\n }\n }\n\n return list;\n }\n }\n\n html(src: string): Tokens.HTML | undefined {\n const cap = this.rules.block.html.exec(src);\n if (cap) {\n const raw = trimTrailingBlankLines(cap[0]);\n const token: Tokens.HTML = {\n type: 'html',\n block: true,\n raw,\n pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',\n text: raw,\n };\n return token;\n }\n }\n\n def(src: string): Tokens.Def | undefined {\n const cap = this.rules.block.def.exec(src);\n if (cap) {\n const tag = cap[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, ' ');\n const href = cap[2] ? cap[2].replace(this.rules.other.hrefBrackets, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';\n const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];\n return {\n type: 'def',\n tag,\n raw: rtrim(cap[0], '\\n'),\n href,\n title,\n };\n }\n }\n\n table(src: string): Tokens.Table | undefined {\n const cap = this.rules.block.table.exec(src);\n if (!cap) {\n return;\n }\n\n if (!this.rules.other.tableDelimiter.test(cap[2])) {\n // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading\n return;\n }\n\n const headers = splitCells(cap[1]);\n const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');\n const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\\n') : [];\n\n const item: Tokens.Table = {\n type: 'table',\n raw: rtrim(cap[0], '\\n'),\n header: [],\n align: [],\n rows: [],\n };\n\n if (headers.length !== aligns.length) {\n // header and align columns must be equal, rows can be different.\n return;\n }\n\n for (const align of aligns) {\n if (this.rules.other.tableAlignRight.test(align)) {\n item.align.push('right');\n } else if (this.rules.other.tableAlignCenter.test(align)) {\n item.align.push('center');\n } else if (this.rules.other.tableAlignLeft.test(align)) {\n item.align.push('left');\n } else {\n item.align.push(null);\n }\n }\n\n for (let i = 0; i < headers.length; i++) {\n item.header.push({\n text: headers[i],\n tokens: this.lexer.inline(headers[i]),\n header: true,\n align: item.align[i],\n });\n }\n\n for (const row of rows) {\n item.rows.push(splitCells(row, item.header.length).map((cell, i) => {\n return {\n text: cell,\n tokens: this.lexer.inline(cell),\n header: false,\n align: item.align[i],\n };\n }));\n }\n\n return item;\n }\n\n lheading(src: string): Tokens.Heading | undefined {\n const cap = this.rules.block.lheading.exec(src);\n if (cap) {\n const text = cap[1].trim();\n return {\n type: 'heading',\n raw: rtrim(cap[0], '\\n'),\n depth: cap[2].charAt(0) === '=' ? 1 : 2,\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n paragraph(src: string): Tokens.Paragraph | undefined {\n const cap = this.rules.block.paragraph.exec(src);\n if (cap) {\n const text = cap[1].charAt(cap[1].length - 1) === '\\n'\n ? cap[1].slice(0, -1)\n : cap[1];\n return {\n type: 'paragraph',\n raw: cap[0],\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n text(src: string): Tokens.Text | undefined {\n const cap = this.rules.block.text.exec(src);\n if (cap) {\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n tokens: this.lexer.inline(cap[0]),\n };\n }\n }\n\n escape(src: string): Tokens.Escape | undefined {\n const cap = this.rules.inline.escape.exec(src);\n if (cap) {\n return {\n type: 'escape',\n raw: cap[0],\n text: cap[1],\n };\n }\n }\n\n tag(src: string): Tokens.Tag | undefined {\n const cap = this.rules.inline.tag.exec(src);\n if (cap) {\n if (!this.lexer.state.inLink && this.rules.other.startATag.test(cap[0])) {\n this.lexer.state.inLink = true;\n } else if (this.lexer.state.inLink && this.rules.other.endATag.test(cap[0])) {\n this.lexer.state.inLink = false;\n }\n if (!this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(cap[0])) {\n this.lexer.state.inRawBlock = true;\n } else if (this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(cap[0])) {\n this.lexer.state.inRawBlock = false;\n }\n\n return {\n type: 'html',\n raw: cap[0],\n inLink: this.lexer.state.inLink,\n inRawBlock: this.lexer.state.inRawBlock,\n block: false,\n text: cap[0],\n };\n }\n }\n\n link(src: string): Tokens.Link | Tokens.Image | undefined {\n const cap = this.rules.inline.link.exec(src);\n if (cap) {\n const trimmedUrl = cap[2].trim();\n if (!this.options.pedantic && this.rules.other.startAngleBracket.test(trimmedUrl)) {\n // commonmark requires matching angle brackets\n if (!(this.rules.other.endAngleBracket.test(trimmedUrl))) {\n return;\n }\n\n // ending angle bracket cannot be escaped\n const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\\\');\n if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {\n return;\n }\n } else {\n // find closing parenthesis\n const lastParenIndex = findClosingBracket(cap[2], '()');\n if (lastParenIndex === -2) {\n // more open parens than closed\n return;\n }\n\n if (lastParenIndex > -1) {\n const start = cap[0].indexOf('!') === 0 ? 5 : 4;\n const linkLen = start + cap[1].length + lastParenIndex;\n cap[2] = cap[2].substring(0, lastParenIndex);\n cap[0] = cap[0].substring(0, linkLen).trim();\n cap[3] = '';\n }\n }\n let href = cap[2];\n let title = '';\n if (this.options.pedantic) {\n // split pedantic href and title\n const link = this.rules.other.pedanticHrefTitle.exec(href);\n\n if (link) {\n href = link[1];\n title = link[3];\n }\n } else {\n title = cap[3] ? cap[3].slice(1, -1) : '';\n }\n\n href = href.trim();\n if (this.rules.other.startAngleBracket.test(href)) {\n if (this.options.pedantic && !(this.rules.other.endAngleBracket.test(trimmedUrl))) {\n // pedantic allows starting angle bracket without ending angle bracket\n href = href.slice(1);\n } else {\n href = href.slice(1, -1);\n }\n }\n return outputLink(cap, {\n href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,\n title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title,\n }, cap[0], this.lexer, this.rules);\n }\n }\n\n reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined {\n let cap;\n if ((cap = this.rules.inline.reflink.exec(src))\n || (cap = this.rules.inline.nolink.exec(src))) {\n const linkString = (cap[2] || cap[1]).replace(this.rules.other.multipleSpaceGlobal, ' ');\n const link = links[linkString.toLowerCase()];\n if (!link) {\n const text = cap[0].charAt(0);\n return {\n type: 'text',\n raw: text,\n text,\n };\n }\n return outputLink(cap, link, cap[0], this.lexer, this.rules);\n }\n }\n\n emStrong(src: string, maskedSrc: string, prevChar = ''): Tokens.Em | Tokens.Strong | undefined {\n let match = this.rules.inline.emStrongLDelim.exec(src);\n if (!match) return;\n if (!match[1] && !match[2] && !match[3] && !match[4]) return;\n\n // _ can't be between two alphanumerics. \\p{L}\\p{N} includes non-english alphabet/numbers as well\n if (match[4] && prevChar.match(this.rules.other.unicodeAlphaNumeric)) return;\n\n const nextChar = match[1] || match[3] || '';\n\n if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)\n const lLength = [...match[0]].length - 1;\n let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;\n\n const delimChar = match[0][0];\n // A mid-run opener (for example the second star of an unmatched `**`) must\n // only pair with a delimiter that can only close, otherwise it steals the\n // opener of a later span (`**a*b*c` must be `**a<em>b</em>c`).\n const midRun = prevChar === delimChar;\n const endReg = delimChar === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;\n endReg.lastIndex = 0;\n\n // Clip maskedSrc to same section of string as src (move to lexer?)\n maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n\n while ((match = endReg.exec(maskedSrc)) !== null) {\n rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n\n if (!rDelim) continue; // skip single * in __abc*abc__\n\n rLength = [...rDelim].length;\n\n if (match[3] || match[4]) { // found another Left Delim\n delimTotal += rLength;\n continue;\n } else if (match[5] || match[6]) { // either Left or Right Delim\n if (lLength % 3 && !((lLength + rLength) % 3)) {\n midDelimTotal += rLength;\n continue; // CommonMark Emphasis Rules 9-10\n }\n if (midRun) {\n // A mid-run opener cannot close against an ambiguous delimiter that\n // can also open; that delimiter opens its own emphasis span instead.\n break;\n }\n }\n\n delimTotal -= rLength;\n\n if (delimTotal > 0) continue; // Haven't found enough closing delimiters\n\n // Remove extra characters. *a*** -> *a*\n rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);\n // char length can be >1 for unicode characters;\n const lastCharLength = [...match[0]][0].length;\n const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n\n // Create `em` if smallest delimiter has odd char count. *a***\n if (Math.min(lLength, rLength) % 2) {\n const text = raw.slice(1, -1);\n return {\n type: 'em',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n\n // Create 'strong' if smallest delimiter has even char count. **a***\n const text = raw.slice(2, -2);\n return {\n type: 'strong',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n }\n }\n\n codespan(src: string): Tokens.Codespan | undefined {\n const cap = this.rules.inline.code.exec(src);\n if (cap) {\n let text = cap[2].replace(this.rules.other.newLineCharGlobal, ' ');\n const hasNonSpaceChars = this.rules.other.nonSpaceChar.test(text);\n const hasSpaceCharsOnBothEnds = this.rules.other.startingSpaceChar.test(text) && this.rules.other.endingSpaceChar.test(text);\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n return {\n type: 'codespan',\n raw: cap[0],\n text,\n };\n }\n }\n\n br(src: string): Tokens.Br | undefined {\n const cap = this.rules.inline.br.exec(src);\n if (cap) {\n return {\n type: 'br',\n raw: cap[0],\n };\n }\n }\n\n del(src: string, maskedSrc: string, prevChar = ''): Tokens.Del | undefined {\n let match = this.rules.inline.delLDelim.exec(src);\n if (!match) return;\n\n const nextChar = match[1] || '';\n\n if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n // unicode Regex counts emoji as 1 char; spread into array for proper count\n const lLength = [...match[0]].length - 1;\n let rDelim, rLength, delimTotal = lLength;\n\n const endReg = this.rules.inline.delRDelim;\n endReg.lastIndex = 0;\n\n // Clip maskedSrc to same section of string as src\n maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n\n while ((match = endReg.exec(maskedSrc)) !== null) {\n rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n\n if (!rDelim) continue;\n\n rLength = [...rDelim].length;\n\n if (rLength !== lLength) continue;\n\n if (match[3] || match[4]) { // found another Left Delim\n delimTotal += rLength;\n continue;\n }\n\n delimTotal -= rLength;\n\n if (delimTotal > 0) continue; // Haven't found enough closing delimiters\n\n // Remove extra characters\n rLength = Math.min(rLength, rLength + delimTotal);\n // char length can be >1 for unicode characters\n const lastCharLength = [...match[0]][0].length;\n const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n\n // Create del token - only single ~ or double ~~ supported\n const text = raw.slice(lLength, -lLength);\n return {\n type: 'del',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n }\n }\n\n autolink(src: string): Tokens.Link | undefined {\n const cap = this.rules.inline.autolink.exec(src);\n if (cap) {\n let text, href;\n if (cap[2] === '@') {\n text = cap[1];\n href = 'mailto:' + text;\n } else {\n text = cap[1];\n href = text;\n }\n\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text,\n },\n ],\n };\n }\n }\n\n url(src: string): Tokens.Link | undefined {\n let cap;\n if (cap = this.rules.inline.url.exec(src)) {\n let text, href;\n if (cap[2] === '@') {\n text = cap[0];\n href = 'mailto:' + text;\n } else {\n // do extended autolink path validation\n let prevCapZero;\n do {\n prevCapZero = cap[0];\n cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';\n } while (prevCapZero !== cap[0]);\n text = cap[0];\n if (cap[1] === 'www.') {\n href = 'http://' + cap[0];\n } else {\n href = cap[0];\n }\n }\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text,\n },\n ],\n };\n }\n }\n\n inlineText(src: string): Tokens.Text | undefined {\n const cap = this.rules.inline.text.exec(src);\n if (cap) {\n const escaped = this.lexer.state.inRawBlock;\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n escaped,\n };\n }\n }\n}\n", "import { _Tokenizer } from './Tokenizer.ts';\nimport { _defaults } from './defaults.ts';\nimport { other, block, inline } from './rules.ts';\nimport type { Token, TokensList, Tokens } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Block Lexer\n */\nexport class _Lexer<ParserOutput = string, RendererOutput = string> {\n tokens: TokensList;\n options: MarkedOptions<ParserOutput, RendererOutput>;\n state: {\n inLink: boolean;\n inRawBlock: boolean;\n top: boolean;\n };\n\n public inlineQueue: { src: string, tokens: Token[] }[];\n\n private tokenizer: _Tokenizer<ParserOutput, RendererOutput>;\n\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n // TokenList cannot be created in one go\n this.tokens = [] as unknown as TokensList;\n this.tokens.links = Object.create(null);\n this.options = options || _defaults;\n this.options.tokenizer = this.options.tokenizer || new _Tokenizer<ParserOutput, RendererOutput>();\n this.tokenizer = this.options.tokenizer;\n this.tokenizer.options = this.options;\n this.tokenizer.lexer = this;\n this.inlineQueue = [];\n this.state = {\n inLink: false,\n inRawBlock: false,\n top: true,\n };\n\n const rules = {\n other,\n block: block.normal,\n inline: inline.normal,\n };\n\n if (this.options.pedantic) {\n rules.block = block.pedantic;\n rules.inline = inline.pedantic;\n } else if (this.options.gfm) {\n rules.block = block.gfm;\n if (this.options.breaks) {\n rules.inline = inline.breaks;\n } else {\n rules.inline = inline.gfm;\n }\n }\n this.tokenizer.rules = rules;\n }\n\n /**\n * Expose Rules\n */\n static get rules() {\n return {\n block,\n inline,\n };\n }\n\n /**\n * Static Lex Method\n */\n static lex<ParserOutput = string, RendererOutput = string>(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const lexer = new _Lexer<ParserOutput, RendererOutput>(options);\n return lexer.lex(src);\n }\n\n /**\n * Static Lex Inline Method\n */\n static lexInline<ParserOutput = string, RendererOutput = string>(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const lexer = new _Lexer<ParserOutput, RendererOutput>(options);\n return lexer.inlineTokens(src);\n }\n\n /**\n * Preprocessing\n */\n lex(src: string) {\n src = src.replace(other.carriageReturn, '\\n');\n\n this.blockTokens(src, this.tokens);\n\n for (let i = 0; i < this.inlineQueue.length; i++) {\n const next = this.inlineQueue[i];\n this.inlineTokens(next.src, next.tokens);\n }\n this.inlineQueue = [];\n\n return this.tokens;\n }\n\n /**\n * Lexing\n */\n blockTokens(src: string, tokens?: Token[], lastParagraphClipped?: boolean): Token[];\n blockTokens(src: string, tokens?: TokensList, lastParagraphClipped?: boolean): TokensList;\n blockTokens(src: string, tokens: Token[] = [], lastParagraphClipped = false) {\n this.tokenizer.lexer = this;\n if (this.options.pedantic) {\n src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');\n }\n\n let srcLength = Infinity;\n while (src) {\n if (src.length < srcLength) {\n srcLength = src.length;\n } else {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n\n let token: Tokens.Generic | undefined;\n\n if (this.options.extensions?.block?.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n\n // newline\n if (token = this.tokenizer.space(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (token.raw.length === 1 && lastToken !== undefined) {\n // if there's a single \\n as a spacer, it's terminating the last line,\n // so move it there so that we don't get unnecessary paragraph tags\n lastToken.raw += '\\n';\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // code\n if (token = this.tokenizer.code(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n // An indented code block cannot interrupt a paragraph.\n if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // fences\n if (token = this.tokenizer.fences(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // heading\n if (token = this.tokenizer.heading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // hr\n if (token = this.tokenizer.hr(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // blockquote\n if (token = this.tokenizer.blockquote(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // list\n if (token = this.tokenizer.list(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // html\n if (token = this.tokenizer.html(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // def\n if (token = this.tokenizer.def(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.raw;\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else if (!this.tokens.links[token.tag]) {\n this.tokens.links[token.tag] = {\n href: token.href,\n title: token.title,\n };\n tokens.push(token);\n }\n continue;\n }\n\n // table (gfm)\n if (token = this.tokenizer.table(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // lheading\n if (token = this.tokenizer.lheading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // top-level paragraph\n // prevent paragraph consuming extensions by clipping 'src' to extension start\n let cutSrc = src;\n if (this.options.extensions?.startBlock) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startBlock.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {\n const lastToken = tokens.at(-1);\n if (lastParagraphClipped && lastToken?.type === 'paragraph') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n lastParagraphClipped = cutSrc.length !== src.length;\n src = src.substring(token.raw.length);\n continue;\n }\n\n // text\n if (token = this.tokenizer.text(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n if (src) {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n }\n\n this.state.top = true;\n return tokens;\n }\n\n inline(src: string, tokens: Token[] = []) {\n this.inlineQueue.push({ src, tokens });\n return tokens;\n }\n\n /**\n * Lexing/Compiling\n */\n inlineTokens(src: string, tokens: Token[] = []): Token[] {\n this.tokenizer.lexer = this;\n // String with links masked to avoid interference with em and strong\n let maskedSrc = src;\n\n // Mask out reflinks\n if (this.tokens.links) {\n const links = Object.keys(this.tokens.links);\n if (links.length > 0) {\n maskedSrc = maskedSrc.replace(this.tokenizer.rules.inline.reflinkSearch, match0 =>\n links.includes(match0.slice(match0.lastIndexOf('[') + 1, -1))\n ? '[' + 'a'.repeat(match0.length - 2) + ']'\n : match0);\n }\n }\n\n // Mask out escaped characters\n maskedSrc = maskedSrc.replace(this.tokenizer.rules.inline.anyPunctuation, '++');\n\n // Mask out other blocks\n maskedSrc = maskedSrc.replace(this.tokenizer.rules.inline.blockSkip, (match0, _link, context) => {\n const offset = context ? context.length : 0;\n return match0.slice(0, offset) + '[' + 'a'.repeat(match0.length - offset - 2) + ']';\n });\n\n // Mask out blocks from extensions\n maskedSrc = this.options.hooks?.emStrongMask?.call({ lexer: this }, maskedSrc) ?? maskedSrc;\n\n let keepPrevChar = false;\n let prevChar = '';\n let srcLength = Infinity;\n while (src) {\n if (src.length < srcLength) {\n srcLength = src.length;\n } else {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n\n if (!keepPrevChar) {\n prevChar = '';\n }\n keepPrevChar = false;\n\n let token: Tokens.Generic | undefined;\n\n // extensions\n if (this.options.extensions?.inline?.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n\n // escape\n if (token = this.tokenizer.escape(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // tag\n if (token = this.tokenizer.tag(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // link\n if (token = this.tokenizer.link(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // reflink, nolink\n if (token = this.tokenizer.reflink(src, this.tokens.links)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (token.type === 'text' && lastToken?.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // em & strong\n if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // code\n if (token = this.tokenizer.codespan(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // br\n if (token = this.tokenizer.br(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // del (gfm)\n if (token = this.tokenizer.del(src, maskedSrc, prevChar)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // autolink\n if (token = this.tokenizer.autolink(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // url (gfm)\n if (!this.state.inLink && (token = this.tokenizer.url(src))) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // text\n // prevent inlineText consuming extensions by clipping 'src' to extension start\n let cutSrc = src;\n if (this.options.extensions?.startInline) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startInline.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (token = this.tokenizer.inlineText(cutSrc)) {\n src = src.substring(token.raw.length);\n if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started\n prevChar = token.raw.slice(-1);\n }\n keepPrevChar = true;\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n if (src) {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n }\n\n return tokens;\n }\n\n private infiniteLoopError(byte: number) {\n const errMsg = 'Infinite loop on byte: ' + byte;\n if (this.options.silent) {\n console.error(errMsg);\n } else {\n throw new Error(errMsg);\n }\n }\n}\n", "import { _defaults } from './defaults.ts';\nimport {\n cleanUrl,\n escapeHtmlEntities,\n} from './helpers.ts';\nimport { other } from './rules.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\nimport type { Tokens } from './Tokens.ts';\nimport type { _Parser } from './Parser.ts';\n\n/**\n * Renderer\n */\nexport class _Renderer<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n parser!: _Parser<ParserOutput, RendererOutput>; // set by the parser\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n }\n\n space(token: Tokens.Space): RendererOutput {\n return '' as RendererOutput;\n }\n\n code({ text, lang, escaped }: Tokens.Code): RendererOutput {\n const langString = (lang || '').match(other.notSpaceStart)?.[0];\n\n const code = text.replace(other.endingNewline, '') + '\\n';\n\n if (!langString) {\n return '<pre><code>'\n + (escaped ? code : escapeHtmlEntities(code, true))\n + '</code></pre>\\n' as RendererOutput;\n }\n\n return '<pre><code class=\"language-'\n + escapeHtmlEntities(langString)\n + '\">'\n + (escaped ? code : escapeHtmlEntities(code, true))\n + '</code></pre>\\n' as RendererOutput;\n }\n\n blockquote({ tokens }: Tokens.Blockquote): RendererOutput {\n const body = this.parser.parse(tokens);\n return `<blockquote>\\n${body}</blockquote>\\n` as RendererOutput;\n }\n\n html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n def(token: Tokens.Def): RendererOutput {\n return '' as RendererOutput;\n }\n\n heading({ tokens, depth }: Tokens.Heading): RendererOutput {\n return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\\n` as RendererOutput;\n }\n\n hr(token: Tokens.Hr): RendererOutput {\n return '<hr>\\n' as RendererOutput;\n }\n\n list(token: Tokens.List): RendererOutput {\n const ordered = token.ordered;\n const start = token.start;\n\n let body = '';\n for (let j = 0; j < token.items.length; j++) {\n const item = token.items[j];\n body += this.listitem(item);\n }\n\n const type = ordered ? 'ol' : 'ul';\n const startAttr = (ordered && start !== 1) ? (' start=\"' + start + '\"') : '';\n return '<' + type + startAttr + '>\\n' + body + '</' + type + '>\\n' as RendererOutput;\n }\n\n listitem(item: Tokens.ListItem): RendererOutput {\n return `<li>${this.parser.parse(item.tokens)}</li>\\n` as RendererOutput;\n }\n\n checkbox({ checked }: Tokens.Checkbox): RendererOutput {\n return '<input '\n + (checked ? 'checked=\"\" ' : '')\n + 'disabled=\"\" type=\"checkbox\"> ' as RendererOutput;\n }\n\n paragraph({ tokens }: Tokens.Paragraph): RendererOutput {\n return `<p>${this.parser.parseInline(tokens)}</p>\\n` as RendererOutput;\n }\n\n table(token: Tokens.Table): RendererOutput {\n let header = '';\n\n // header\n let cell = '';\n for (let j = 0; j < token.header.length; j++) {\n cell += this.tablecell(token.header[j]);\n }\n header += this.tablerow({ text: cell as ParserOutput });\n\n let body = '';\n for (let j = 0; j < token.rows.length; j++) {\n const row = token.rows[j];\n\n cell = '';\n for (let k = 0; k < row.length; k++) {\n cell += this.tablecell(row[k]);\n }\n\n body += this.tablerow({ text: cell as ParserOutput });\n }\n if (body) body = `<tbody>${body}</tbody>`;\n\n return '<table>\\n'\n + '<thead>\\n'\n + header\n + '</thead>\\n'\n + body\n + '</table>\\n' as RendererOutput;\n }\n\n tablerow({ text }: Tokens.TableRow<ParserOutput>): RendererOutput {\n return `<tr>\\n${text}</tr>\\n` as RendererOutput;\n }\n\n tablecell(token: Tokens.TableCell): RendererOutput {\n const content = this.parser.parseInline(token.tokens);\n const type = token.header ? 'th' : 'td';\n const tag = token.align\n ? `<${type} align=\"${token.align}\">`\n : `<${type}>`;\n return tag + content + `</${type}>\\n` as RendererOutput;\n }\n\n /**\n * span level renderer\n */\n strong({ tokens }: Tokens.Strong): RendererOutput {\n return `<strong>${this.parser.parseInline(tokens)}</strong>` as RendererOutput;\n }\n\n em({ tokens }: Tokens.Em): RendererOutput {\n return `<em>${this.parser.parseInline(tokens)}</em>` as RendererOutput;\n }\n\n codespan({ text }: Tokens.Codespan): RendererOutput {\n return `<code>${escapeHtmlEntities(text, true)}</code>` as RendererOutput;\n }\n\n br(token: Tokens.Br): RendererOutput {\n return '<br>' as RendererOutput;\n }\n\n del({ tokens }: Tokens.Del): RendererOutput {\n return `<del>${this.parser.parseInline(tokens)}</del>` as RendererOutput;\n }\n\n link({ href, title, tokens }: Tokens.Link): RendererOutput {\n const text = this.parser.parseInline(tokens) as string;\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return text as RendererOutput;\n }\n href = cleanHref;\n let out = '<a href=\"' + href + '\"';\n if (title) {\n out += ' title=\"' + (escapeHtmlEntities(title)) + '\"';\n }\n out += '>' + text + '</a>';\n return out as RendererOutput;\n }\n\n image({ href, title, text, tokens }: Tokens.Image): RendererOutput {\n if (tokens) {\n text = this.parser.parseInline(tokens, this.parser.textRenderer) as string;\n }\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return escapeHtmlEntities(text) as RendererOutput;\n }\n href = cleanHref;\n\n let out = `<img src=\"${href}\" alt=\"${escapeHtmlEntities(text)}\"`;\n if (title) {\n out += ` title=\"${escapeHtmlEntities(title)}\"`;\n }\n out += '>';\n return out as RendererOutput;\n }\n\n text(token: Tokens.Text | Tokens.Escape): RendererOutput {\n return 'tokens' in token && token.tokens\n ? this.parser.parseInline(token.tokens) as unknown as RendererOutput\n : ('escaped' in token && token.escaped ? token.text as RendererOutput : escapeHtmlEntities(token.text) as RendererOutput);\n }\n}\n", "import type { Tokens } from './Tokens.ts';\n\n/**\n * TextRenderer\n * returns only the textual part of the token\n */\nexport class _TextRenderer<RendererOutput = string> {\n // no need for block level renderers\n strong({ text }: Tokens.Strong): RendererOutput {\n return text as RendererOutput;\n }\n\n em({ text }: Tokens.Em): RendererOutput {\n return text as RendererOutput;\n }\n\n codespan({ text }: Tokens.Codespan): RendererOutput {\n return text as RendererOutput;\n }\n\n del({ text }: Tokens.Del): RendererOutput {\n return text as RendererOutput;\n }\n\n html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n link({ text }: Tokens.Link): RendererOutput {\n return '' + text as RendererOutput;\n }\n\n image({ text }: Tokens.Image): RendererOutput {\n return '' + text as RendererOutput;\n }\n\n br(): RendererOutput {\n return '' as RendererOutput;\n }\n\n checkbox({ raw }: Tokens.Checkbox): RendererOutput {\n return raw as RendererOutput;\n }\n}\n", "import { _Renderer } from './Renderer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { _defaults } from './defaults.ts';\nimport type { MarkedToken, Token, Tokens } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Parsing & Compiling\n */\nexport class _Parser<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n renderer: _Renderer<ParserOutput, RendererOutput>;\n textRenderer: _TextRenderer<RendererOutput>;\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n this.options.renderer = this.options.renderer || new _Renderer<ParserOutput, RendererOutput>();\n this.renderer = this.options.renderer;\n this.renderer.options = this.options;\n this.renderer.parser = this;\n this.textRenderer = new _TextRenderer<RendererOutput>();\n }\n\n /**\n * Static Parse Method\n */\n static parse<ParserOutput = string, RendererOutput = string>(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const parser = new _Parser<ParserOutput, RendererOutput>(options);\n return parser.parse(tokens);\n }\n\n /**\n * Static Parse Inline Method\n */\n static parseInline<ParserOutput = string, RendererOutput = string>(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const parser = new _Parser<ParserOutput, RendererOutput>(options);\n return parser.parseInline(tokens);\n }\n\n /**\n * Parse Loop\n */\n parse(tokens: Token[]): ParserOutput {\n this.renderer.parser = this;\n let out = '';\n\n for (let i = 0; i < tokens.length; i++) {\n const anyToken = tokens[i];\n\n // Run any renderer extensions\n if (this.options.extensions?.renderers?.[anyToken.type]) {\n const genericToken = anyToken as Tokens.Generic;\n const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);\n if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'checkbox', 'html', 'def', 'paragraph', 'text'].includes(genericToken.type)) {\n out += ret || '';\n continue;\n }\n }\n\n const token = anyToken as MarkedToken;\n\n switch (token.type) {\n case 'space': {\n out += this.renderer.space(token);\n break;\n }\n case 'hr': {\n out += this.renderer.hr(token);\n break;\n }\n case 'heading': {\n out += this.renderer.heading(token);\n break;\n }\n case 'code': {\n out += this.renderer.code(token);\n break;\n }\n case 'table': {\n out += this.renderer.table(token);\n break;\n }\n case 'blockquote': {\n out += this.renderer.blockquote(token);\n break;\n }\n case 'list': {\n out += this.renderer.list(token);\n break;\n }\n case 'checkbox': {\n out += this.renderer.checkbox(token);\n break;\n }\n case 'html': {\n out += this.renderer.html(token);\n break;\n }\n case 'def': {\n out += this.renderer.def(token);\n break;\n }\n case 'paragraph': {\n out += this.renderer.paragraph(token);\n break;\n }\n case 'text': {\n out += this.renderer.text(token);\n break;\n }\n\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '' as ParserOutput;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n }\n\n return out as ParserOutput;\n }\n\n /**\n * Parse Inline Tokens\n */\n parseInline(tokens: Token[], renderer: _Renderer<ParserOutput, RendererOutput> | _TextRenderer<RendererOutput> = this.renderer): ParserOutput {\n this.renderer.parser = this;\n let out = '';\n\n for (let i = 0; i < tokens.length; i++) {\n const anyToken = tokens[i];\n\n // Run any renderer extensions\n if (this.options.extensions?.renderers?.[anyToken.type]) {\n const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);\n if (ret !== false || !['escape', 'html', 'link', 'image', 'checkbox', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {\n out += ret || '';\n continue;\n }\n }\n\n const token = anyToken as MarkedToken;\n\n switch (token.type) {\n case 'escape': {\n out += renderer.text(token);\n break;\n }\n case 'html': {\n out += renderer.html(token);\n break;\n }\n case 'link': {\n out += renderer.link(token);\n break;\n }\n case 'image': {\n out += renderer.image(token);\n break;\n }\n case 'checkbox': {\n out += renderer.checkbox(token);\n break;\n }\n case 'strong': {\n out += renderer.strong(token);\n break;\n }\n case 'em': {\n out += renderer.em(token);\n break;\n }\n case 'codespan': {\n out += renderer.codespan(token);\n break;\n }\n case 'br': {\n out += renderer.br(token);\n break;\n }\n case 'del': {\n out += renderer.del(token);\n break;\n }\n case 'text': {\n out += renderer.text(token);\n break;\n }\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '' as ParserOutput;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n }\n return out as ParserOutput;\n }\n}\n", "import { _defaults } from './defaults.ts';\nimport { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, TokensList } from './Tokens.ts';\n\nexport class _Hooks<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n block?: boolean;\n\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n }\n\n static passThroughHooks = new Set([\n 'preprocess',\n 'postprocess',\n 'processAllTokens',\n 'emStrongMask',\n ]);\n\n static passThroughHooksRespectAsync = new Set([\n 'preprocess',\n 'postprocess',\n 'processAllTokens',\n ]);\n\n /**\n * Process markdown before marked\n */\n preprocess(markdown: string) {\n return markdown;\n }\n\n /**\n * Process HTML after marked is finished\n */\n postprocess(html: ParserOutput) {\n return html;\n }\n\n /**\n * Process all tokens before walk tokens\n */\n processAllTokens(tokens: Token[] | TokensList) {\n return tokens;\n }\n\n /**\n * Mask contents that should not be interpreted as em/strong delimiters\n */\n emStrongMask(src: string) {\n return src;\n }\n\n /**\n * Provide function to tokenize markdown\n */\n provideLexer(block = this.block) {\n return block ? _Lexer.lex : _Lexer.lexInline;\n }\n\n /**\n * Provide function to parse tokens\n */\n provideParser(block = this.block) {\n return block ? _Parser.parse<ParserOutput, RendererOutput> : _Parser.parseInline<ParserOutput, RendererOutput>;\n }\n}\n", "import { _getDefaults } from './defaults.ts';\nimport { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport { _Hooks } from './Hooks.ts';\nimport { _Renderer } from './Renderer.ts';\nimport { _Tokenizer } from './Tokenizer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { escapeHtmlEntities } from './helpers.ts';\nimport type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, Tokens, TokensList } from './Tokens.ts';\n\nexport type MaybePromise = void | Promise<void>;\n\ntype UnknownFunction = (...args: unknown[]) => unknown;\ntype GenericRendererFunction = (...args: unknown[]) => string | false;\n\nexport class Marked<ParserOutput = string, RendererOutput = string> {\n defaults = _getDefaults<ParserOutput, RendererOutput>();\n options = this.setOptions;\n\n /**\n * Compiles markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a separate `Marked`\n * instance and use `Marked#use` instead of passing them on each call.\n */\n parse = this.parseMarkdown(true);\n\n /**\n * Compiles inline markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a separate `Marked`\n * instance and use `Marked#use` instead of passing them on each call.\n */\n parseInline = this.parseMarkdown(false);\n\n Parser = _Parser<ParserOutput, RendererOutput>;\n Renderer = _Renderer<ParserOutput, RendererOutput>;\n TextRenderer = _TextRenderer<RendererOutput>;\n Lexer = _Lexer;\n Tokenizer = _Tokenizer<ParserOutput, RendererOutput>;\n Hooks = _Hooks<ParserOutput, RendererOutput>;\n\n constructor(...args: MarkedExtension<ParserOutput, RendererOutput>[]) {\n this.use(...args);\n }\n\n /**\n * Run callback for every token\n */\n walkTokens(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) {\n let values: MaybePromise[] = [];\n for (const token of tokens) {\n values = values.concat(callback.call(this, token));\n switch (token.type) {\n case 'table': {\n const tableToken = token as Tokens.Table;\n for (const cell of tableToken.header) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n for (const row of tableToken.rows) {\n for (const cell of row) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n }\n break;\n }\n case 'list': {\n const listToken = token as Tokens.List;\n values = values.concat(this.walkTokens(listToken.items, callback));\n break;\n }\n default: {\n const genericToken = token as Tokens.Generic;\n if (this.defaults.extensions?.childTokens?.[genericToken.type]) {\n this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {\n const tokens = genericToken[childTokens].flat(Infinity) as Token[] | TokensList;\n values = values.concat(this.walkTokens(tokens, callback));\n });\n } else if (genericToken.tokens) {\n values = values.concat(this.walkTokens(genericToken.tokens, callback));\n }\n }\n }\n }\n return values;\n }\n\n /**\n * Registers extensions with this Marked instance.\n *\n * The `renderer`, `tokenizer`, and `hooks` objects may each contain only the\n * methods that should be overridden. Their methods are merged with built-in\n * behavior and extensions registered by earlier calls.\n *\n * Use this method when supplying only some hook methods.\n */\n use(...args: MarkedExtension<ParserOutput, RendererOutput>[]) {\n const extensions: MarkedOptions<ParserOutput, RendererOutput>['extensions'] = this.defaults.extensions || { renderers: {}, childTokens: {} };\n\n args.forEach((pack) => {\n // copy options to new object\n const opts = { ...pack } as MarkedOptions<ParserOutput, RendererOutput>;\n\n // set async to true if it was set to true before\n opts.async = this.defaults.async || opts.async || false;\n\n // ==-- Parse \"addon\" extensions --== //\n if (pack.extensions) {\n pack.extensions.forEach((ext) => {\n if (!ext.name) {\n throw new Error('extension name required');\n }\n if ('renderer' in ext) { // Renderer extensions\n const prevRenderer = extensions.renderers[ext.name];\n if (prevRenderer) {\n // Replace extension with func to run new extension but fall back if false\n extensions.renderers[ext.name] = function(...args) {\n let ret = ext.renderer.apply(this, args);\n if (ret === false) {\n ret = prevRenderer.apply(this, args);\n }\n return ret;\n };\n } else {\n extensions.renderers[ext.name] = ext.renderer;\n }\n }\n if ('tokenizer' in ext) { // Tokenizer Extensions\n if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {\n throw new Error(\"extension level must be 'block' or 'inline'\");\n }\n const extLevel = extensions[ext.level];\n if (extLevel) {\n extLevel.unshift(ext.tokenizer);\n } else {\n extensions[ext.level] = [ext.tokenizer];\n }\n if (ext.start) { // Function to check for start of token\n if (ext.level === 'block') {\n if (extensions.startBlock) {\n extensions.startBlock.push(ext.start);\n } else {\n extensions.startBlock = [ext.start];\n }\n } else if (ext.level === 'inline') {\n if (extensions.startInline) {\n extensions.startInline.push(ext.start);\n } else {\n extensions.startInline = [ext.start];\n }\n }\n }\n }\n if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens\n extensions.childTokens[ext.name] = ext.childTokens;\n }\n });\n opts.extensions = extensions;\n }\n\n // ==-- Parse \"overwrite\" extensions --== //\n if (pack.renderer) {\n const renderer = this.defaults.renderer || new _Renderer<ParserOutput, RendererOutput>(this.defaults);\n for (const prop in pack.renderer) {\n if (!(prop in renderer)) {\n throw new Error(`renderer '${prop}' does not exist`);\n }\n if (['options', 'parser'].includes(prop)) {\n // ignore options property\n continue;\n }\n const rendererProp = prop as Exclude<keyof _Renderer<ParserOutput, RendererOutput>, 'options' | 'parser'>;\n const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction;\n const prevRenderer = renderer[rendererProp] as GenericRendererFunction;\n // Replace renderer with func to run extension, but fall back if false\n renderer[rendererProp] = (...args: unknown[]) => {\n let ret = rendererFunc.apply(renderer, args);\n if (ret === false) {\n ret = prevRenderer.apply(renderer, args);\n }\n return (ret || '') as RendererOutput;\n };\n }\n opts.renderer = renderer;\n }\n if (pack.tokenizer) {\n const tokenizer = this.defaults.tokenizer || new _Tokenizer<ParserOutput, RendererOutput>(this.defaults);\n for (const prop in pack.tokenizer) {\n if (!(prop in tokenizer)) {\n throw new Error(`tokenizer '${prop}' does not exist`);\n }\n if (['options', 'rules', 'lexer'].includes(prop)) {\n // ignore options, rules, and lexer properties\n continue;\n }\n const tokenizerProp = prop as Exclude<keyof _Tokenizer<ParserOutput, RendererOutput>, 'options' | 'rules' | 'lexer'>;\n const tokenizerFunc = pack.tokenizer[tokenizerProp] as UnknownFunction;\n const prevTokenizer = tokenizer[tokenizerProp] as UnknownFunction;\n // Replace tokenizer with func to run extension, but fall back if false\n // @ts-expect-error cannot type tokenizer function dynamically\n tokenizer[tokenizerProp] = (...args: unknown[]) => {\n let ret = tokenizerFunc.apply(tokenizer, args);\n if (ret === false) {\n ret = prevTokenizer.apply(tokenizer, args);\n }\n return ret;\n };\n }\n opts.tokenizer = tokenizer;\n }\n\n // ==-- Parse Hooks extensions --== //\n if (pack.hooks) {\n const hooks = this.defaults.hooks || new _Hooks<ParserOutput, RendererOutput>();\n for (const prop in pack.hooks) {\n if (!(prop in hooks)) {\n throw new Error(`hook '${prop}' does not exist`);\n }\n if (['options', 'block'].includes(prop)) {\n // ignore options and block properties\n continue;\n }\n const hooksProp = prop as Exclude<keyof _Hooks<ParserOutput, RendererOutput>, 'options' | 'block'>;\n const hooksFunc = pack.hooks[hooksProp] as UnknownFunction;\n const prevHook = hooks[hooksProp] as UnknownFunction;\n if (_Hooks.passThroughHooks.has(prop)) {\n // @ts-expect-error cannot type hook function dynamically\n hooks[hooksProp] = (arg: unknown) => {\n if (this.defaults.async && _Hooks.passThroughHooksRespectAsync.has(prop)) {\n return (async() => {\n const ret = await hooksFunc.call(hooks, arg);\n return prevHook.call(hooks, ret);\n })();\n }\n\n const ret = hooksFunc.call(hooks, arg);\n return prevHook.call(hooks, ret);\n };\n } else {\n // @ts-expect-error cannot type hook function dynamically\n hooks[hooksProp] = (...args: unknown[]) => {\n if (this.defaults.async) {\n return (async() => {\n let ret = await hooksFunc.apply(hooks, args);\n if (ret === false) {\n ret = await prevHook.apply(hooks, args);\n }\n return ret;\n })();\n }\n\n let ret = hooksFunc.apply(hooks, args);\n if (ret === false) {\n ret = prevHook.apply(hooks, args);\n }\n return ret;\n };\n }\n }\n opts.hooks = hooks;\n }\n\n // ==-- Parse WalkTokens extensions --== //\n if (pack.walkTokens) {\n const walkTokens = this.defaults.walkTokens;\n const packWalktokens = pack.walkTokens;\n opts.walkTokens = function(token) {\n let values: MaybePromise[] = [];\n values.push(packWalktokens.call(this, token));\n if (walkTokens) {\n values = values.concat(walkTokens.call(this, token));\n }\n return values;\n };\n }\n\n this.defaults = { ...this.defaults, ...opts };\n });\n\n return this;\n }\n\n setOptions(opt: MarkedOptions<ParserOutput, RendererOutput>) {\n this.defaults = { ...this.defaults, ...opt };\n return this;\n }\n\n lexer(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>) {\n return _Lexer.lex(src, options ?? this.defaults);\n }\n\n parser(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>) {\n return _Parser.parse<ParserOutput, RendererOutput>(tokens, options ?? this.defaults);\n }\n\n private parseMarkdown(blockType: boolean) {\n type overloadedParse = {\n (src: string, options: MarkedOptions<ParserOutput, RendererOutput> & { async: true }): Promise<ParserOutput>;\n (src: string, options: MarkedOptions<ParserOutput, RendererOutput> & { async: false }): ParserOutput;\n (src: string, options?: MarkedOptions<ParserOutput, RendererOutput> | null): ParserOutput | Promise<ParserOutput>;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const parse: overloadedParse = (src: string, options?: MarkedOptions<ParserOutput, RendererOutput> | null): any => {\n const origOpt = { ...options };\n const opt = { ...this.defaults, ...origOpt };\n\n const throwError = this.onError(!!opt.silent, !!opt.async);\n\n // throw error if an extension set async to true but parse was called with async: false\n if (this.defaults.async === true && origOpt.async === false) {\n return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));\n }\n\n // throw error in case of non string input\n if (typeof src === 'undefined' || src === null) {\n return throwError(new Error('marked(): input parameter is undefined or null'));\n }\n if (typeof src !== 'string') {\n return throwError(new Error('marked(): input parameter is of type '\n + Object.prototype.toString.call(src) + ', string expected'));\n }\n\n if (opt.hooks) {\n opt.hooks.options = opt;\n opt.hooks.block = blockType;\n }\n\n if (opt.async) {\n return (async() => {\n const processedSrc = opt.hooks ? await opt.hooks.preprocess(src) : src;\n const lexer = opt.hooks ? await opt.hooks.provideLexer(blockType) : (blockType ? _Lexer.lex : _Lexer.lexInline);\n const tokens = await lexer(processedSrc, opt);\n const processedTokens = opt.hooks ? await opt.hooks.processAllTokens(tokens) : tokens;\n if (opt.walkTokens) {\n await Promise.all(this.walkTokens(processedTokens, opt.walkTokens));\n }\n const parser = opt.hooks ? await opt.hooks.provideParser(blockType) : (blockType ? _Parser.parse : _Parser.parseInline);\n const html = await parser(processedTokens, opt);\n return opt.hooks ? await opt.hooks.postprocess(html) : html;\n })().catch(throwError);\n }\n\n try {\n if (opt.hooks) {\n src = opt.hooks.preprocess(src) as string;\n }\n const lexer = opt.hooks ? opt.hooks.provideLexer(blockType) : (blockType ? _Lexer.lex : _Lexer.lexInline);\n let tokens = lexer(src, opt);\n if (opt.hooks) {\n tokens = opt.hooks.processAllTokens(tokens);\n }\n if (opt.walkTokens) {\n this.walkTokens(tokens, opt.walkTokens);\n }\n const parser = opt.hooks ? opt.hooks.provideParser(blockType) : (blockType ? _Parser.parse : _Parser.parseInline);\n let html = parser(tokens, opt);\n if (opt.hooks) {\n html = opt.hooks.postprocess(html);\n }\n return html;\n } catch(e) {\n return throwError(e as Error);\n }\n };\n\n return parse;\n }\n\n private onError(silent: boolean, async: boolean) {\n return (e: Error): string | Promise<string> => {\n e.message += '\\nPlease report this to https://github.com/markedjs/marked.';\n\n if (silent) {\n const msg = '<p>An error occurred:</p><pre>'\n + escapeHtmlEntities(e.message + '', true)\n + '</pre>';\n if (async) {\n return Promise.resolve(msg);\n }\n return msg;\n }\n\n if (async) {\n return Promise.reject(e);\n }\n throw e;\n };\n }\n}\n", "import { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport { _Tokenizer } from './Tokenizer.ts';\nimport { _Renderer } from './Renderer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { _Hooks } from './Hooks.ts';\nimport { Marked } from './Instance.ts';\nimport {\n _getDefaults,\n changeDefaults,\n _defaults,\n} from './defaults.ts';\nimport type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, TokensList } from './Tokens.ts';\nimport type { MaybePromise } from './Instance.ts';\n\nconst markedInstance = new Marked();\n\n/**\n * Compiles markdown to HTML asynchronously.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options, having async: true\n * @return Promise of string of compiled HTML\n */\nexport function marked(src: string, options: MarkedOptions & { async: true }): Promise<string>;\n\n/**\n * Compiles markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n *\n * @param src String of markdown source to be compiled\n * @param options Optional hash of options\n * @return String of compiled HTML. Will be a Promise of string if async is set to true by any extensions.\n */\nexport function marked(src: string, options: MarkedOptions & { async: false }): string;\nexport function marked(src: string, options: MarkedOptions & { async: true }): Promise<string>;\nexport function marked(src: string, options?: MarkedOptions | null): string | Promise<string>;\nexport function marked(src: string, opt?: MarkedOptions | null): string | Promise<string> {\n return markedInstance.parse(src, opt);\n}\n\nexport declare namespace marked {\n /**\n * Compiles inline markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n */\n let parseInline: typeof markedInstance.parseInline;\n\n /**\n * Registers extensions with the default Marked instance.\n *\n * The `renderer`, `tokenizer`, and `hooks` objects may each contain only the\n * methods that should be overridden. Their methods are merged with built-in\n * behavior and extensions registered by earlier calls.\n *\n * Use this function when supplying only some hook methods.\n */\n let use: (...args: MarkedExtension[]) => typeof marked;\n}\n\n/**\n * Sets the default options.\n *\n * @param options Hash of options\n */\nmarked.options =\n marked.setOptions = function(options: MarkedOptions) {\n markedInstance.setOptions(options);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n };\n\n/**\n * Gets the original marked default options.\n */\nmarked.getDefaults = _getDefaults;\n\nmarked.defaults = _defaults;\n\n/**\n * Registers extensions with the default Marked instance.\n *\n * The `renderer`, `tokenizer`, and `hooks` objects may each contain only the\n * methods that should be overridden. Their methods are merged with built-in\n * behavior and extensions registered by earlier calls.\n *\n * Use this function when supplying only some hook methods.\n *\n * @param args Extensions to register\n * @return The `marked` function\n */\nfunction useExtension(...args: MarkedExtension[]) {\n markedInstance.use(...args);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n}\n\nmarked.use = useExtension;\n\n/**\n * Run callback for every token\n */\n\nmarked.walkTokens = function(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) {\n return markedInstance.walkTokens(tokens, callback);\n};\n\n/**\n * Compiles markdown to HTML without enclosing `p` tag.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options\n * @return String of compiled HTML\n */\nmarked.parseInline = markedInstance.parseInline;\n\n/**\n * Expose\n */\nmarked.Parser = _Parser;\nmarked.parser = _Parser.parse;\nmarked.Renderer = _Renderer;\nmarked.TextRenderer = _TextRenderer;\nmarked.Lexer = _Lexer;\nmarked.lexer = _Lexer.lex;\nmarked.Tokenizer = _Tokenizer;\nmarked.Hooks = _Hooks;\nmarked.parse = marked;\n\nexport const options = marked.options;\nexport const setOptions = marked.setOptions;\nexport const walkTokens = marked.walkTokens;\n/**\n * Compiles inline markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n */\nexport const parseInline = marked.parseInline;\nexport const parse = marked;\nexport const parser = _Parser.parse;\nexport const lexer = _Lexer.lex;\nexport { _defaults as defaults, _getDefaults as getDefaults } from './defaults.ts';\nexport { _Lexer as Lexer } from './Lexer.ts';\nexport { _Parser as Parser } from './Parser.ts';\nexport { _Tokenizer as Tokenizer } from './Tokenizer.ts';\nexport { _Renderer as Renderer } from './Renderer.ts';\nexport { _TextRenderer as TextRenderer } from './TextRenderer.ts';\nexport { _Hooks as Hooks } from './Hooks.ts';\nexport { Marked } from './Instance.ts';\nexport { useExtension as use };\nexport type * from './MarkedOptions.ts';\nexport type * from './Tokens.ts';\n", "// This module's sanitisation is verified only by the `chromium` project in\n// vitest.config.ts, and must stay there. DOMPurify 3.4.8+ silently sanitises\n// nothing under happy-dom (every element resolves to an empty tag name), so a\n// happy-dom-only suite goes green while this module strips nothing at all.\n// Moving those assertions back under happy-dom for speed removes the only check\n// that this module does anything. CLAUDE.md records the upstream root cause.\nimport DOMPurify from \"dompurify\";\nimport { Marked } from \"marked\";\n\n// A local parser instance, so configuration never leaks into the shared\n// `marked` singleton a host app's deduped copy would share. Built once at module\n// scope and never mutated; per-call construction would re-pay setup on every\n// streaming re-render.\nconst parser = new Marked({ gfm: true, breaks: true });\n\n// Conservative allowlist for assistant chat content. Rendering untrusted\n// model/tool output as HTML is an XSS surface and this sanitiser is the only\n// thing standing in front of it, so `iframe`, `style` and all scripting stay\n// out.\n//\n// `img` is excluded by default: a model-controlled image URL is fetched with no\n// user interaction, turning prompt-injected page data into a zero-click\n// exfiltration channel. Hosts that trust their content opt in via `allowImages`.\nconst ALLOWED_TAGS = [\n \"a\",\n \"p\",\n \"br\",\n \"strong\",\n \"em\",\n \"b\",\n \"i\",\n \"u\",\n \"s\",\n \"del\",\n \"code\",\n \"pre\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"hr\",\n \"span\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n];\n\nconst ALLOWED_ATTR = [\"href\", \"title\", \"class\"];\n\n// The image-permitting variants used when the host opts in.\nconst ALLOWED_TAGS_WITH_IMAGES = [...ALLOWED_TAGS, \"img\"];\nconst ALLOWED_ATTR_WITH_IMAGES = [...ALLOWED_ATTR, \"src\", \"alt\", \"width\", \"height\"];\n\n/** Options for {@link renderMarkdown}. */\nexport interface RenderMarkdownOptions {\n /**\n * Permit `<img>` tags (and their `src`/`alt`/`width`/`height` attributes) in\n * the sanitised output. Off by default; see the exfiltration note on the\n * allowlist above. Only enable for trusted content sources.\n */\n readonly allowImages?: boolean;\n}\n\n/**\n * Render markdown (and any embedded raw HTML) to a sanitised HTML string.\n *\n * Markdown syntax and literal HTML share one path: `marked` emits HTML, then\n * DOMPurify strips everything outside {@link ALLOWED_TAGS} /\n * {@link ALLOWED_ATTR} \u2014 scripts, event handlers, `javascript:` URLs. Links are\n * hardened with `target=\"_blank\"` and `rel=\"noopener noreferrer\"`.\n *\n * The result is trimmed so a single-paragraph message round-trips to clean\n * `textContent`, without the wrapping paragraph's trailing newline.\n */\nexport function renderMarkdown(text: string, options?: RenderMarkdownOptions): string {\n const allowImages = options?.allowImages === true;\n const rendered = parser.parse(text, { async: false });\n const clean = DOMPurify.sanitize(rendered, {\n ALLOWED_TAGS: allowImages ? ALLOWED_TAGS_WITH_IMAGES : ALLOWED_TAGS,\n ALLOWED_ATTR: allowImages ? ALLOWED_ATTR_WITH_IMAGES : ALLOWED_ATTR,\n });\n const template = document.createElement(\"template\");\n template.innerHTML = clean;\n for (const anchor of template.content.querySelectorAll(\"a[href]\")) {\n anchor.setAttribute(\"target\", \"_blank\");\n anchor.setAttribute(\"rel\", \"noopener noreferrer\");\n }\n return template.innerHTML.trim();\n}\n", "/** Which edges the layout holds still while the panel changes size. */\nexport interface ResizeAnchor {\n /** The horizontal edge that does not move. */\n readonly x: \"left\" | \"right\";\n /** The vertical edge that does not move. */\n readonly y: \"top\" | \"bottom\";\n}\n\n/**\n * What the current placement allows: both axes, width only, or nothing. Which\n * corner the grip sits on is separate, and is measured rather than assumed.\n */\nexport type ResizeAxis = \"none\" | \"width\" | \"both\";\n\n/** Persisted size, in CSS pixels. Either axis may be absent. */\nexport interface ResizeSize {\n readonly width?: number;\n readonly height?: number;\n}\n\n/** The panel's position on screen at the moment a drag starts. */\nexport interface PanelRect {\n readonly left: number;\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n}\n\n/** What the handle needs from its host to do its job. */\nexport interface ResizeOptions {\n /**\n * Which axes the current placement allows, read per interaction. A getter\n * because `placement` is a live attribute, and a value read at construction\n * would survive the host switching to a docked or full-bleed layout.\n */\n readonly axis: () => ResizeAxis;\n /**\n * Which edges the layout is holding still, measured at the moment of the drag\n * rather than derived from `placement`: a floating panel is pinned\n * bottom-right, while an embedded one goes wherever the host's CSS puts it,\n * so `placement` alone cannot answer the question.\n */\n readonly anchor: () => ResizeAnchor;\n /** The panel's current bounding box. */\n readonly rect: () => PanelRect;\n /** Apply a size (the host writes the custom properties). */\n readonly apply: (size: ResizeSize) => void;\n /** Called once per completed drag, for persistence. */\n readonly commit: (size: ResizeSize) => void;\n /** Accessible label. */\n readonly label: string;\n}\n\n/** Smallest usable panel; below this the composer and header collide. */\nconst MIN_WIDTH = 280;\nconst MIN_HEIGHT = 240;\n\n/**\n * A drag handle that resizes the chat panel.\n *\n * Two rules keep it correct, and both are easy to break invisibly:\n *\n * - The new size is measured from the edge that is *not* moving, never from a\n * delta, and that edge is measured rather than assumed. Getting it wrong is\n * very visible: the panel shrinks when dragged outward and travels by its\n * opposite corner.\n * - It writes the `--ag-ui-width` / `--ag-ui-height` custom properties, not\n * inline `width` / `height`. The placement rules set those same properties,\n * so an inline dimension would outrank and fight them \u2014 a sidebar would keep\n * its dragged width after switching to fullscreen. Writing the property\n * leaves placement the final say.\n *\n * Axes and anchor are both read per interaction, so a runtime `placement`\n * change takes effect at once.\n */\nexport function createResizeHandle(options: ResizeOptions): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className = \"resize-handle\";\n handle.setAttribute(\"part\", \"resize-handle\");\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-label\", options.label);\n handle.tabIndex = 0;\n\n /** The size implied by a pointer at (x, y), given which edges are pinned. */\n const sizeAt = (\n axis: ResizeAxis,\n anchor: ResizeAnchor,\n rect: PanelRect,\n x: number,\n y: number,\n ): ResizeSize => {\n const width = anchor.x === \"right\" ? rect.right - x : x - rect.left;\n const clamped: ResizeSize = { width: Math.max(MIN_WIDTH, width) };\n if (axis !== \"both\") {\n return clamped;\n }\n const height = anchor.y === \"bottom\" ? rect.bottom - y : y - rect.top;\n return { ...clamped, height: Math.max(MIN_HEIGHT, height) };\n };\n\n handle.addEventListener(\"pointerdown\", (event: PointerEvent) => {\n const axis = options.axis();\n if (axis === \"none\") {\n return;\n }\n // Captured once: the pinned edges cannot move during the drag, and reading\n // them live would chase the panel as it resizes.\n const anchor = options.anchor();\n const rect = options.rect();\n\n const onMove = (move: PointerEvent): void => {\n options.apply(sizeAt(axis, anchor, rect, move.clientX, move.clientY));\n };\n\n const onUp = (up: PointerEvent): void => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n handle.removeAttribute(\"data-dragging\");\n options.commit(sizeAt(axis, anchor, rect, up.clientX, up.clientY));\n };\n\n handle.setAttribute(\"data-dragging\", \"true\");\n // Listeners on `window`, not the handle: a fast drag outruns the pointer\n // and would otherwise strand the panel mid-resize with no pointerup.\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n event.preventDefault();\n });\n\n // Keyboard parity: a pointer-only resize is unreachable without a mouse, and\n // this control has no equivalent elsewhere in the UI.\n handle.addEventListener(\"keydown\", (event: KeyboardEvent) => {\n const axis = options.axis();\n if (axis === \"none\") {\n return;\n }\n const anchor = options.anchor();\n const rect = options.rect();\n const step = event.shiftKey ? 64 : 16;\n // An arrow moves the grip, so whether it grows or shrinks depends on which\n // side the grip is on \u2014 the asymmetry the pointer path also handles.\n const outward = anchor.x === \"right\" ? -1 : 1;\n const width = rect.right - rect.left;\n const height = rect.bottom - rect.top;\n let next: ResizeSize | null = null;\n if (event.key === \"ArrowLeft\") {\n next = { width: Math.max(MIN_WIDTH, width - step * outward) };\n } else if (event.key === \"ArrowRight\") {\n next = { width: Math.max(MIN_WIDTH, width + step * outward) };\n } else if (axis === \"both\" && (event.key === \"ArrowUp\" || event.key === \"ArrowDown\")) {\n const grow = event.key === (anchor.y === \"bottom\" ? \"ArrowUp\" : \"ArrowDown\");\n next = { height: Math.max(MIN_HEIGHT, height + (grow ? step : -step)) };\n }\n if (next === null) {\n return;\n }\n event.preventDefault();\n options.apply(next);\n options.commit(next);\n });\n\n return handle;\n}\n", "/** Collect the text nodes under ``root`` with their parents (depth-first). */\nfunction collectTextNodes(root: Node, out: { node: Text; parent: Node }[]): void {\n for (const child of Array.from(root.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) {\n out.push({ node: child as Text, parent: root });\n } else {\n collectTextNodes(child, out);\n }\n }\n}\n\n/**\n * Wrap each word under ``root`` in `<span class=\"word\" style=\"--ag-ui-word-index: N\">`\n * so CSS can reveal them one-by-one (staggered by the index). Whitespace is\n * preserved as plain text. Used for the `word` text-animation mode on a\n * completed assistant message; pure DOM, idempotent enough to re-run.\n */\nexport function wrapWords(root: HTMLElement): void {\n const texts: { node: Text; parent: Node }[] = [];\n collectTextNodes(root, texts);\n let index = 0;\n for (const { node, parent } of texts) {\n const fragment = document.createDocumentFragment();\n for (const part of node.data.split(/(\\s+)/)) {\n if (part === \"\") {\n continue;\n }\n if (/\\s/.test(part)) {\n fragment.appendChild(document.createTextNode(part));\n continue;\n }\n const span = document.createElement(\"span\");\n span.className = \"word\";\n span.style.setProperty(\"--ag-ui-word-index\", String(index));\n span.textContent = part;\n fragment.appendChild(span);\n index += 1;\n }\n parent.replaceChild(fragment, node);\n }\n}\n", "/**\n * A muted one-line notice about something the run did (history condensed, a\n * skill loaded), rendered inline between turns.\n *\n * Distinct from a tool card, which reports work the agent asked for and\n * settles, and from an error, which is a failure. A notice never settles, takes\n * no action, and carries no controls.\n */\nexport function renderRunNotice(icon: string, text: string, kind: string): HTMLDivElement {\n const notice = document.createElement(\"div\");\n notice.className = `run-notice run-notice--${kind}`;\n notice.setAttribute(\"part\", `run-notice run-notice-${kind}`);\n // status, not alert: informational, so it must not interrupt a screen reader\n // mid-sentence. Polite announcements land after the current utterance.\n notice.setAttribute(\"role\", \"status\");\n\n const glyph = document.createElement(\"span\");\n glyph.className = \"run-notice-icon\";\n glyph.setAttribute(\"part\", \"run-notice-icon\");\n glyph.textContent = icon;\n // Decorative: the adjacent text already says what happened, so announcing the\n // glyph's name would only add noise.\n glyph.setAttribute(\"aria-hidden\", \"true\");\n\n const label = document.createElement(\"span\");\n label.className = \"run-notice-text\";\n label.setAttribute(\"part\", \"run-notice-text\");\n label.textContent = text;\n\n notice.append(glyph, label);\n return notice;\n}\n", "import type { Skill } from \"../skills/skill.js\";\n\n/**\n * The two skill surfaces over a single catalog: a chips row (the `chip: true`\n * subset) and a slash-command palette (all skills, filtered). Both opt-in.\n * Pure DOM; the host appends {@link chips} and {@link palette}, feeds input via\n * {@link onInput} / {@link onKeydown}, and acts on {@link onPick}.\n */\nexport class SkillsMenu {\n /** Chips row \u2014 append above the input. Hidden unless chips are enabled and present. */\n readonly chips: HTMLDivElement;\n /** The `/`-command dropdown \u2014 append in the input area. Hidden until opened. */\n readonly palette: HTMLDivElement;\n\n readonly #onPick: (skill: Skill) => void;\n #skills: readonly Skill[] = [];\n #chipsEnabled = false;\n #slashEnabled = false;\n #filtered: Skill[] = [];\n #activeIndex = 0;\n\n constructor(onPick: (skill: Skill) => void) {\n this.#onPick = onPick;\n this.chips = document.createElement(\"div\");\n this.chips.className = \"skill-chips\";\n this.chips.setAttribute(\"part\", \"skill-chips\");\n this.chips.hidden = true;\n this.palette = document.createElement(\"div\");\n this.palette.className = \"skill-palette\";\n this.palette.setAttribute(\"part\", \"skill-palette\");\n this.palette.setAttribute(\"role\", \"listbox\");\n this.palette.hidden = true;\n }\n\n /** Replace the catalog (both surfaces re-derive from it). */\n setSkills(skills: readonly Skill[]): void {\n this.#skills = skills;\n this.#renderChips();\n }\n\n enableChips(enabled: boolean): void {\n this.#chipsEnabled = enabled;\n this.#renderChips();\n }\n\n enableSlash(enabled: boolean): void {\n this.#slashEnabled = enabled;\n }\n\n /** Whether the palette is currently open. */\n isOpen(): boolean {\n return !this.palette.hidden;\n }\n\n /**\n * React to an input value change: open + filter the palette when slash mode\n * is on and the value starts with `/`, otherwise close it.\n */\n onInput(value: string): void {\n if (this.#slashEnabled && value.startsWith(\"/\")) {\n this.#open(value.slice(1));\n } else {\n this.close();\n }\n }\n\n /**\n * Handle a keydown while the palette is open. Returns ``true`` when consumed\n * (the host should `preventDefault` and skip its own handling).\n */\n onKeydown(event: KeyboardEvent): boolean {\n if (!this.isOpen()) {\n return false;\n }\n if (event.key === \"ArrowDown\") {\n this.#move(1);\n return true;\n }\n if (event.key === \"ArrowUp\") {\n this.#move(-1);\n return true;\n }\n if (event.key === \"Escape\") {\n this.close();\n return true;\n }\n if (event.key === \"Enter\") {\n // `slice(i, i+1)` yields a 0-or-1 element array; forEach gives a\n // definite Skill (no indexed-access `| undefined`).\n this.#filtered.slice(this.#activeIndex, this.#activeIndex + 1).forEach((skill) => {\n this.#pick(skill);\n });\n return true;\n }\n return false;\n }\n\n /** Close the palette. */\n close(): void {\n this.palette.hidden = true;\n this.palette.replaceChildren();\n }\n\n #open(query: string): void {\n const needle = query.trim().toLowerCase();\n const matches = this.#skills.filter(\n (skill) =>\n skill.name.toLowerCase().includes(needle) || skill.title.toLowerCase().includes(needle),\n );\n if (matches.length === 0) {\n this.close();\n return;\n }\n this.#filtered = matches;\n this.#activeIndex = 0;\n this.#renderPalette();\n this.palette.hidden = false;\n }\n\n #move(delta: number): void {\n const count = this.#filtered.length;\n this.#activeIndex = (this.#activeIndex + delta + count) % count;\n this.#renderPalette();\n }\n\n #pick(skill: Skill): void {\n this.close();\n this.#onPick(skill);\n }\n\n #renderChips(): void {\n this.chips.replaceChildren();\n const chipSkills = this.#chipsEnabled\n ? this.#skills.filter((skill) => skill.chip === true)\n : [];\n this.chips.hidden = chipSkills.length === 0;\n for (const skill of chipSkills) {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = \"skill-chip\";\n button.setAttribute(\"part\", \"skill-chip\");\n button.textContent = skill.title;\n // The chip stays a label \u2014 it is a one-click affordance, not something to\n // memorise \u2014 but naming the command it stands for makes the two\n // discoverable as the same thing.\n button.title = `/${skill.name}`;\n button.addEventListener(\"click\", () => this.#pick(skill));\n this.chips.appendChild(button);\n }\n }\n\n #renderPalette(): void {\n this.palette.replaceChildren();\n this.#filtered.forEach((skill, index) => {\n const item = document.createElement(\"button\");\n item.type = \"button\";\n item.className = \"skill-item\";\n item.setAttribute(\"part\", \"skill-item\");\n item.setAttribute(\"role\", \"option\");\n item.setAttribute(\"aria-selected\", index === this.#activeIndex ? \"true\" : \"false\");\n\n const title = document.createElement(\"span\");\n title.className = \"skill-item-title\";\n title.setAttribute(\"part\", \"skill-item-title\");\n\n // The token leads, because it is the thing the user has to type. A row\n // showing only the label taught the label and not the command, so the\n // palette could not be used to learn its own vocabulary.\n const token = document.createElement(\"code\");\n token.className = \"skill-item-token\";\n token.setAttribute(\"part\", \"skill-item-token\");\n token.textContent = `/${skill.name}`;\n title.append(token, document.createTextNode(` ${skill.title}`));\n item.appendChild(title);\n\n if (skill.description !== undefined) {\n const desc = document.createElement(\"span\");\n desc.className = \"skill-item-desc\";\n desc.setAttribute(\"part\", \"skill-item-desc\");\n desc.textContent = skill.description;\n item.appendChild(desc);\n }\n\n item.addEventListener(\"click\", () => this.#pick(skill));\n this.palette.appendChild(item);\n });\n }\n}\n", "// Shadow-DOM-scoped styles for the chat shell. Kept as a string constant so\n// the Custom Element can inject it into its shadow root without a build-time\n// CSS pipeline. Scoped by the shadow boundary, so class names stay terse.\n\nexport const STYLES = `\n/* \u2500\u2500 Token defaults \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Every public --ag-ui-* token is read here into a private --_* alias, and\n only the alias is used by the rules below.\n\n The indirection is what makes ancestor theming work. Declaring the public\n name on :host would set it on the host element, and a value on an element\n always beats one inherited from an ancestor, so tokens put on a wrapper\n would have no effect. Reading the public name with the default as a var()\n fallback leaves it undeclared on the element, so an ancestor's value\n inherits normally while one aimed at the element still wins.\n\n Two invariants hold this together:\n 1. No rule outside this file's :host blocks may reference a public name\n directly. A public name read outside these blocks resolves to nothing and\n silently drops its declaration rather than erroring, so the miss shows up\n as a missing colour, not a failure.\n 2. Every --_* alias in use is declared here. Aliases inherit like any custom\n property, so an undeclared one would pick up a same-named property from\n the host page; declaring it on :host shields the shadow tree from that. */\n:host {\n /* Colors */\n --_bg: var(--ag-ui-bg, #ffffff);\n --_fg: var(--ag-ui-fg, #1a1a2e);\n --_accent: var(--ag-ui-accent, #4f46e5);\n --_user-bg: var(--ag-ui-user-bg, #4f46e5);\n --_user-fg: var(--ag-ui-user-fg, #ffffff);\n --_assistant-bg: var(--ag-ui-assistant-bg, #f1f1f6);\n --_hover: var(--ag-ui-hover, #e7e7ee);\n --_input-bg: var(--ag-ui-input-bg, var(--_bg));\n --_tool-bg: var(--ag-ui-tool-bg, var(--_assistant-bg));\n --_tool-fg: var(--ag-ui-tool-fg, var(--_accent));\n --_header-bg: var(--ag-ui-header-bg, var(--_accent));\n --_header-fg: var(--ag-ui-header-fg, #ffffff);\n --_border: var(--ag-ui-border, #e2e2ec);\n --_radius: var(--ag-ui-radius, 12px);\n\n /* Body text and raised chrome, read only by the code-block copy button.\n The defaults restate what it inherits, so a host that sets neither sees\n no repaint \u2014 see the note on .code-copy. */\n --_text: var(--ag-ui-text, var(--_fg));\n --_surface: var(--ag-ui-surface, transparent);\n\n /* Status accents for tool-call cards. */\n --_success: var(--ag-ui-success, #15803d);\n --_danger: var(--ag-ui-danger, #b91c1c);\n --_muted: var(--ag-ui-muted, #6b7280);\n\n /* Tool-call status icon glyphs (override to re-theme) + spinner speed.\n The pending state is the animated ring; the settled states use these. */\n --_tool-icon-done: var(--ag-ui-tool-icon-done, \"\u2713\");\n --_tool-icon-error: var(--ag-ui-tool-icon-error, \"\u2715\");\n --_tool-icon-declined: var(--ag-ui-tool-icon-declined, \"\u2298\");\n --_tool-spin-duration: var(--ag-ui-tool-spin-duration, 0.7s);\n\n /* Answer well (opt-in via data-answer-well) \u2014 boxes a whole assistant turn. */\n --_well-bg: var(--ag-ui-well-bg, transparent);\n --_well-border: var(--ag-ui-well-border, var(--_border));\n\n /* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(20, 20, 50, 0.18));\n --_font: var(--ag-ui-font, inherit);\n --_font-size: var(--ag-ui-font-size, 14px);\n --_code-font: var(--ag-ui-code-font, ui-monospace, \"SF Mono\", Menlo, monospace);\n\n /* Header / launcher icon box. */\n --_icon-size: var(--ag-ui-icon-size, 22px);\n --_icon-radius: var(--ag-ui-icon-radius, 4px);\n\n /* Composer \u2014 one bordered surface holding the field and its tool row. */\n --_composer-radius: var(--ag-ui-composer-radius, 14px);\n --_composer-max-height: var(--ag-ui-composer-max-height, 40vh);\n --_tool-btn-size: var(--ag-ui-tool-btn-size, 30px);\n --_send-size: var(--ag-ui-send-size, 30px);\n --_glyph-size: var(--ag-ui-glyph-size, 18px);\n --_glyph-stroke: var(--ag-ui-glyph-stroke, 1.75);\n\n /* Unread badge on the launcher. */\n --_badge-bg: var(--ag-ui-badge-bg, var(--_danger));\n --_badge-fg: var(--ag-ui-badge-fg, #ffffff);\n --_badge-size: var(--ag-ui-badge-size, 18px);\n --_badge-font-size: var(--ag-ui-badge-font-size, 11px);\n\n /* The floating launcher a collapsed widget shrinks to. */\n --_launcher-size: var(--ag-ui-launcher-size, 56px);\n --_launcher-bg: var(--ag-ui-launcher-bg, var(--_header-bg));\n --_launcher-fg: var(--ag-ui-launcher-fg, var(--_header-fg));\n --_launcher-radius: var(--ag-ui-launcher-radius, 50%);\n --_launcher-icon-size: var(--ag-ui-launcher-icon-size, 26px);\n --_launcher-inset: var(--ag-ui-launcher-inset, auto 0 0 auto);\n\n /* Motion. One duration and two curves drive every collapse, expand and\n slide-over, so the widget accelerates and settles as one thing. The\n default curve decelerates into place; the pop curve overshoots slightly,\n for something arriving. */\n --_motion: var(--ag-ui-motion, 0.28s);\n --_ease: var(--ag-ui-ease, cubic-bezier(0.32, 0.72, 0, 1));\n --_ease-pop: var(--ag-ui-ease-pop, cubic-bezier(0.34, 1.36, 0.64, 1));\n\n /* Spacing \u2014 the density preset overrides these. */\n --_space: var(--ag-ui-space, 10px);\n --_pad: var(--ag-ui-pad, 16px);\n --_msg-pad: var(--ag-ui-msg-pad, 8px 12px);\n --_msg-radius: var(--ag-ui-msg-radius, 14px);\n\n /* Layout \u2014 override from outside to dock the widget anywhere.\n Set --ag-ui-position: static (and place this element in your own\n grid/flex layout) to embed it in the page flow instead of floating. */\n --_position: var(--ag-ui-position, fixed);\n --_z-index: var(--ag-ui-z-index, 2147483000);\n --_width: var(--ag-ui-width, 380px);\n --_height: var(--ag-ui-height, 560px);\n --_inset: var(--ag-ui-inset, auto 24px 24px auto);\n --_max-width: var(--ag-ui-max-width, calc(100vw - 48px));\n --_max-height: var(--ag-ui-max-height, calc(100vh - 48px));\n /* Reading-column width for placement=\"page\" (full-bleed, centred content). */\n --_content-max-width: var(--ag-ui-content-max-width, 820px);\n /* Slim rail the sidebar placement collapses to. Only that placement reads\n it, but it is declared here so every alias has a default in one place. */\n --_rail-width: var(--ag-ui-rail-width, 52px);\n\n position: var(--_position);\n inset: var(--_inset);\n z-index: var(--_z-index);\n width: var(--_width);\n max-width: var(--_max-width);\n height: var(--_height);\n max-height: var(--_max-height);\n display: flex;\n font-family: var(--_font);\n font-size: var(--_font-size);\n color: var(--_fg);\n}\n\n/* \u2500\u2500 Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Themes only re-set the colour variables; layout/spacing are unaffected.\n theme=\"auto\" follows the OS via prefers-color-scheme. */\n:host([theme=\"dark\"]) {\n --_bg: var(--ag-ui-bg, #15151f);\n --_fg: var(--ag-ui-fg, #e8e8f2);\n --_assistant-bg: var(--ag-ui-assistant-bg, #25253a);\n --_hover: var(--ag-ui-hover, #303049);\n --_header-bg: var(--ag-ui-header-bg, #1f1f30);\n --_header-fg: var(--ag-ui-header-fg, #e8e8f2);\n --_border: var(--ag-ui-border, #33334a);\n --_muted: var(--ag-ui-muted, #9aa0b4);\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.5));\n}\n\n@media (prefers-color-scheme: dark) {\n :host([theme=\"auto\"]) {\n --_bg: var(--ag-ui-bg, #15151f);\n --_fg: var(--ag-ui-fg, #e8e8f2);\n --_assistant-bg: var(--ag-ui-assistant-bg, #25253a);\n --_hover: var(--ag-ui-hover, #303049);\n --_header-bg: var(--ag-ui-header-bg, #1f1f30);\n --_header-fg: var(--ag-ui-header-fg, #e8e8f2);\n --_border: var(--ag-ui-border, #33334a);\n --_muted: var(--ag-ui-muted, #9aa0b4);\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.5));\n }\n}\n\n/* A terminal-flavoured \"code\" theme: dark, monospace, green accent. */\n:host([theme=\"code\"]) {\n --_bg: var(--ag-ui-bg, #0d1117);\n --_fg: var(--ag-ui-fg, #c9d1d9);\n --_accent: var(--ag-ui-accent, #3fb950);\n --_user-bg: var(--ag-ui-user-bg, #238636);\n --_assistant-bg: var(--ag-ui-assistant-bg, #161b22);\n --_hover: var(--ag-ui-hover, #21262d);\n --_header-bg: var(--ag-ui-header-bg, #010409);\n --_header-fg: var(--ag-ui-header-fg, #c9d1d9);\n --_border: var(--ag-ui-border, #30363d);\n --_muted: var(--ag-ui-muted, #8b949e);\n --_font: var(--ag-ui-font, var(--_code-font));\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.6));\n}\n\n/* \u2500\u2500 Density \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([density=\"compact\"]) {\n --_font-size: var(--ag-ui-font-size, 13px);\n --_space: var(--ag-ui-space, 6px);\n --_pad: var(--ag-ui-pad, 10px);\n --_msg-pad: var(--ag-ui-msg-pad, 5px 9px);\n --_msg-radius: var(--ag-ui-msg-radius, 10px);\n}\n\n/* \u2500\u2500 Placement presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([placement=\"bottom-left\"]) {\n --_inset: var(--ag-ui-inset, auto auto 24px 24px);\n}\n\n:host([placement=\"side\"]) {\n --_inset: var(--ag-ui-inset, 0 0 0 auto);\n --_width: var(--ag-ui-width, 420px);\n --_height: var(--ag-ui-height, 100vh);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n}\n\n:host([placement=\"full\"]) {\n --_inset: var(--ag-ui-inset, 0);\n --_width: var(--ag-ui-width, 100vw);\n --_height: var(--ag-ui-height, 100vh);\n --_max-width: var(--ag-ui-max-width, 100vw);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n}\n\n/* Page: full-bleed background with a centred reading column capped at\n --ag-ui-content-max-width, where \"full\" is edge-to-edge and left-aligned.\n The column comes from symmetric auto padding on the scroll area and\n composer rather than a per-row wrapper, so user pills still right-align and\n the assistant well spans the column. */\n:host([placement=\"page\"]) {\n --_inset: var(--ag-ui-inset, 0);\n --_width: var(--ag-ui-width, 100vw);\n --_height: var(--ag-ui-height, 100vh);\n --_max-width: var(--ag-ui-max-width, 100vw);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n}\n\n:host([placement=\"page\"]) .messages {\n padding-inline: max(var(--_pad), calc((100% - var(--_content-max-width)) / 2));\n}\n\n:host([placement=\"page\"]) .input-row {\n padding-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));\n}\n\n/* The rows between the message list and the composer line up with the column\n too. Chips and tray are padding-based while palette and hint are\n margin-based, so each gets its own inline axis nudged by the same gutter. */\n:host([placement=\"page\"]) .skill-chips,\n:host([placement=\"page\"]) .attachment-tray {\n padding-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));\n}\n\n:host([placement=\"page\"]) .skill-palette,\n:host([placement=\"page\"]) .skill-hint {\n margin-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));\n}\n\n/* In the reading column the assistant well uses the full width; the user\n message stays a right-aligned pill (its default align-self + max-width). */\n:host([placement=\"page\"]) .message--assistant {\n max-width: 100%;\n}\n\n/* Sidebar: a full-height docked panel that slides open/closed and\n collapses to a slim icon rail (not the floating launcher). Docked right by\n default; data-side=\"left\" docks it left. Overlay by default \u2014 set\n --ag-ui-position: static (and place this element in your own layout) for a\n host-managed push instead. */\n:host([placement=\"sidebar\"]) {\n --_inset: var(--ag-ui-inset, 0 0 0 auto);\n --_width: var(--ag-ui-width, 420px);\n --_height: var(--ag-ui-height, 100vh);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n transition: width var(--_motion) var(--_ease);\n}\n\n:host([placement=\"sidebar\"][data-side=\"left\"]) {\n --_inset: var(--ag-ui-inset, 0 auto 0 0);\n}\n\n/* The docked panel is pinned to the edge it docks against rather than filling\n the host as a flex child. Collapsing shrinks the host to the rail width, and\n a flex child would be squashed to 52px on the way out instead of sliding out\n at full width. */\n:host([placement=\"sidebar\"]) .chat {\n position: absolute;\n inset: 0 0 0 auto;\n width: var(--_width);\n transform-origin: right center;\n}\n\n:host([placement=\"sidebar\"][data-side=\"left\"]) .chat {\n inset: 0 auto 0 0;\n transform-origin: left center;\n}\n\n/* Collapsed sidebar: shrink the host to the rail width and slide the panel out\n through the edge it docks against. Higher specificity than the generic\n collapse rules, so it wins regardless of source order. */\n:host([placement=\"sidebar\"][collapsed]) {\n width: var(--_rail-width);\n height: 100vh;\n max-height: 100vh;\n bottom: 0;\n pointer-events: auto;\n}\n\n:host([placement=\"sidebar\"][collapsed]) .chat {\n transform: translateX(100%);\n}\n\n:host([placement=\"sidebar\"][data-side=\"left\"][collapsed]) .chat {\n transform: translateX(-100%);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([placement=\"sidebar\"]),\n :host([placement=\"sidebar\"]) .chat {\n transition: none;\n }\n}\n\n/* \u2500\u2500 Launcher \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n What a collapsed widget shrinks to: a round floating button by default, the\n sidebar's slim edge rail under that placement. A sibling of the panel, so it\n survives the panel being hidden, and the only part of a collapsed widget\n that takes pointer events. */\n.launcher {\n display: flex;\n position: absolute;\n inset: var(--_launcher-inset);\n align-items: center;\n justify-content: center;\n width: var(--_launcher-size);\n height: var(--_launcher-size);\n padding: 0;\n border: none;\n border-radius: var(--_launcher-radius);\n background: var(--_launcher-bg);\n color: var(--_launcher-fg);\n box-shadow: var(--_shadow);\n font: inherit;\n cursor: pointer;\n pointer-events: auto;\n opacity: 0;\n transform: scale(0.4);\n visibility: hidden;\n transition:\n opacity var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease-pop),\n visibility var(--_motion) var(--_ease);\n}\n\n/* The launcher grows out of the corner the panel shrank into. It stays laid\n out at rest rather than display:none, which is what lets it animate both in\n and out: an unrendered element has no before-change style to transition\n from, and one flipping display to none cannot transition at all. visibility\n keeps it unpaintable, untabbable and unclickable in between, so the expanded\n panel's own controls underneath stay reachable. */\n:host([collapsed]) .launcher {\n opacity: 1;\n transform: none;\n visibility: visible;\n}\n\n:host([collapsed]) .launcher:hover {\n transform: scale(1.06);\n}\n\n:host([collapsed]) .launcher:active {\n transform: scale(0.94);\n}\n\n.launcher .icon-holder {\n width: var(--_launcher-icon-size);\n height: var(--_launcher-icon-size);\n}\n\n/* The unread badge rides the launcher's top-right corner. The ring in the\n widget's own background is what separates it from the launcher underneath,\n whatever colour the host themes either one. */\n.launcher-badge {\n position: absolute;\n top: -2px;\n right: -2px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-width: var(--_badge-size);\n height: var(--_badge-size);\n padding: 0 5px;\n border-radius: 999px;\n background: var(--_badge-bg);\n color: var(--_badge-fg);\n font-size: var(--_badge-font-size);\n font-weight: 600;\n line-height: 1;\n box-shadow: 0 0 0 2px var(--_bg);\n}\n\n.launcher-badge[hidden] {\n display: none;\n}\n\n/* The sidebar collapses to an edge rail instead: full height, square, flush\n against the dock. It slides in with the panel rather than popping. */\n:host([placement=\"sidebar\"][collapsed]) .launcher {\n inset: 0;\n width: auto;\n height: auto;\n align-items: flex-start;\n padding-top: 16px;\n border: 1px solid var(--_border);\n border-radius: 0;\n background: var(--_header-bg);\n color: var(--_header-fg);\n box-shadow: none;\n transform: none;\n}\n\n/* Every transition in this file is timed by --_motion, so collapsing it to a\n frame is the whole reduced-motion story: states still change (and display\n still flips at the end of its discrete transition), nothing travels. */\n@media (prefers-reduced-motion: reduce) {\n :host {\n --_motion: var(--ag-ui-motion, 0.001s);\n }\n}\n\n/* Embedded: drop the floating chrome and the high z-index stacking context so\n the widget lives in the host's own layout (fixes overlay/z-index clashes). */\n:host([placement=\"embedded\"]) {\n --_position: var(--ag-ui-position, static);\n --_width: var(--ag-ui-width, 100%);\n --_height: var(--ag-ui-height, 100%);\n --_max-width: var(--ag-ui-max-width, 100%);\n --_max-height: var(--ag-ui-max-height, 100%);\n --_shadow: var(--ag-ui-shadow, none);\n --_z-index: var(--ag-ui-z-index, auto);\n}\n\n.chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n box-shadow: var(--_shadow);\n overflow: hidden;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--_border);\n background: var(--_header-bg);\n color: var(--_header-fg);\n}\n\n.header-title {\n flex: 1;\n min-width: 0;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header / launcher icon holder: a slot, with a data-icon-url <img>\n fallback, sized via --ag-ui-icon-size. */\n.icon-holder {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: var(--_icon-size);\n height: var(--_icon-size);\n line-height: 1;\n}\n\n.icon-img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n border-radius: var(--_icon-radius);\n}\n\n.header-controls {\n display: flex;\n gap: 2px;\n flex: none;\n}\n\n.header-btn {\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n padding: 4px 7px;\n border-radius: 6px;\n cursor: pointer;\n opacity: 0.85;\n}\n\n.header-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.18);\n}\n\n/* \u2500\u2500 Collapse \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Collapsing shrinks the widget to the round floating launcher: the panel\n scales toward the launcher's corner and fades, the launcher pops in from the\n same point. Both halves are transform and opacity only, so the morph runs on\n the compositor and never reflows the host page.\n\n The host box keeps its expanded size, since animating it would animate\n layout and a dragged --ag-ui-width would fight the launcher's own size.\n Nothing paints there once the panel is gone, so the box only has to stop\n swallowing clicks: pointer events go to none and the launcher takes them.\n\n Two placements collapse differently: \"sidebar\" slides to its rail (below),\n while \"embedded\" and \"page\" keep the header bar, having no corner for a\n floating circle that would escape the host's layout. */\n:host([collapsed]) {\n pointer-events: none;\n}\n\n:host([collapsed]) .chat {\n opacity: 0;\n transform: scale(0.94);\n visibility: hidden;\n}\n\n/* visibility keeps the panel out of the tab order and the a11y tree at rest\n without display:none killing the transition. It interpolates so any progress\n below 1 still counts as visible: the panel stays on screen for the whole\n collapse, flips hidden exactly at the end, and on expand is visible from the\n first frame. */\n.chat {\n transform-origin: bottom right;\n transition:\n opacity var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease),\n visibility var(--_motion) var(--_ease);\n}\n\n:host([placement=\"bottom-left\"]) .chat {\n transform-origin: bottom left;\n}\n\n/* The two in-flow placements keep the original collapse: hide the body, let\n the host shrink to the header bar. */\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) {\n height: auto;\n max-height: none;\n pointer-events: auto;\n}\n\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .chat {\n opacity: 1;\n transform: none;\n visibility: visible;\n}\n\n/* These two keep the header bar, so the launcher must stay out of the way: an\n embedded host is position: static, which would let an absolutely-positioned\n circle escape the layout and land against whatever the page positions. */\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .launcher {\n visibility: hidden;\n opacity: 0;\n}\n\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .messages,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .input-row,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .skill-chips,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .skill-palette,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .skill-hint {\n display: none;\n}\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: var(--_pad);\n display: flex;\n flex-direction: column;\n gap: var(--_space);\n}\n\n/* Empty-state region (slot): centred while it's the only thing in the\n list, hidden as soon as a message, card, or pending indicator renders. */\n.empty {\n margin: auto;\n text-align: center;\n color: var(--_muted);\n}\n\n.empty[hidden] {\n display: none;\n}\n\n/* \u2500\u2500 Answer group / well \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n One .answer per assistant turn wraps the streamed text, its tool cards,\n and the pending indicator so a whole answer reads (and can be boxed) as one\n unit. A flex column on the message-list gap, stretched to the list width so\n its children keep their own left/right alignment. data-answer-well opts into\n the bordered \"well\"; without it the turn renders as a flat stack. */\n.answer {\n display: flex;\n flex-direction: column;\n gap: var(--_space);\n align-self: stretch;\n min-width: 0;\n}\n\n:host([data-answer-well]) .answer {\n padding: var(--_pad);\n background: var(--_well-bg);\n border: 1px solid var(--_well-border);\n border-radius: var(--_radius);\n}\n\n.message {\n max-width: 80%;\n padding: var(--_msg-pad);\n border-radius: var(--_msg-radius);\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* \u2500\u2500 Incoming-text animations (data-text-animation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* .message--restored (rehydrated history) is excluded: entrance animations are\n for freshly-arriving messages, not the whole transcript replaying on reload.\n Word mode is excluded implicitly \u2014 restored bubbles aren't wrapped. */\n:host([data-text-animation=\"fade\"]) .message--assistant:not(.message--restored) {\n animation: ag-ui-msg-fade 0.25s ease both;\n}\n\n@keyframes ag-ui-msg-fade {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n}\n\n.message--assistant .word {\n animation: ag-ui-word-in 0.3s ease both;\n animation-delay: calc(var(--ag-ui-word-index, 0) * 35ms);\n}\n\n@keyframes ag-ui-word-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([data-text-animation=\"fade\"]) .message--assistant,\n .message--assistant .word {\n animation: none;\n }\n}\n\n.message--user {\n align-self: flex-end;\n background: var(--_user-bg);\n color: var(--_user-fg);\n border-bottom-right-radius: 4px;\n}\n\n.message--assistant {\n align-self: flex-start;\n background: var(--_assistant-bg);\n border-bottom-left-radius: 4px;\n /* Assistant bubbles hold rendered markdown/HTML, so collapse the source\n whitespace the renderer leaves between block tags. */\n white-space: normal;\n}\n\n/* Rendered-markdown elements inside an assistant bubble. */\n.message--assistant > :first-child {\n margin-top: 0;\n}\n\n.message--assistant > :last-child {\n margin-bottom: 0;\n}\n\n.message--assistant p,\n.message--assistant ul,\n.message--assistant ol,\n.message--assistant blockquote,\n.message--assistant pre {\n margin: 0.5em 0;\n}\n\n.message--assistant ul,\n.message--assistant ol {\n padding-left: 1.3em;\n}\n\n.message--assistant a {\n color: var(--_accent);\n text-decoration: underline;\n}\n\n.message--assistant code {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n font-size: 0.92em;\n background: rgba(127, 127, 127, 0.16);\n padding: 1px 4px;\n border-radius: 4px;\n}\n\n.message--assistant pre {\n padding: 8px 10px;\n overflow: auto;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 6px;\n}\n\n.message--assistant pre code {\n background: none;\n padding: 0;\n}\n\n/* The copy button sits inside the block, so it scrolls with wide code rather\n than floating over the bubble. Positioning is on the pre; the button only\n appears once one has been attached. */\n.message--assistant pre.has-copy {\n position: relative;\n}\n\n/* The only reader of --ag-ui-surface and --ag-ui-text. Their defaults are\n transparent and the body foreground, which is what this button rendered as\n before either token existed; changing them repaints only this control. */\n.code-copy {\n position: absolute;\n top: 4px;\n right: 4px;\n padding: 2px 8px;\n font: inherit;\n font-size: 0.75em;\n line-height: 1.6;\n color: var(--_muted);\n background: var(--_surface);\n border: 1px solid var(--_border);\n border-radius: 4px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.12s ease;\n}\n\n/* Revealed on hover or keyboard focus. Focus matters as much as hover here:\n hidden-until-hover is invisible to a keyboard user otherwise. */\n.message--assistant pre.has-copy:hover .code-copy,\n.code-copy:focus-visible {\n opacity: 1;\n}\n\n.code-copy:hover {\n color: var(--_text);\n background: var(--_hover);\n}\n\n.code-copy[data-state=\"copied\"] {\n opacity: 1;\n color: var(--_text);\n}\n\n.code-copy[data-state=\"failed\"] {\n opacity: 1;\n color: var(--_danger, var(--_text));\n}\n\n.message--assistant blockquote {\n padding-left: 10px;\n border-left: 3px solid var(--_border);\n color: var(--_muted);\n}\n\n/* Markdown tables. table/thead/tbody/tr/th/td are all in the sanitizer's\n ALLOWED_TAGS, so an agent can emit one. A wide table must scroll inside its\n own box rather than stretch the message: the bubble is width-constrained, so\n without this the columns either crush or push the layout sideways. */\n.message--assistant table {\n display: block;\n width: fit-content;\n max-width: 100%;\n overflow-x: auto;\n border-collapse: collapse;\n font-size: 0.95em;\n}\n\n.message--assistant th,\n.message--assistant td {\n padding: 6px 10px;\n border: 1px solid var(--_border);\n text-align: left;\n vertical-align: top;\n}\n\n.message--assistant th {\n background: var(--_hover);\n font-weight: 600;\n}\n\n.pending {\n align-self: flex-start;\n display: inline-flex;\n gap: 4px;\n align-items: center;\n padding: 12px 14px;\n background: var(--_assistant-bg);\n border-radius: 14px;\n border-bottom-left-radius: 4px;\n}\n\n.pending-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--_muted);\n animation: ag-ui-pending 1.2s infinite ease-in-out both;\n}\n\n.pending-dot:nth-child(2) {\n animation-delay: 0.16s;\n}\n\n.pending-dot:nth-child(3) {\n animation-delay: 0.32s;\n}\n\n@keyframes ag-ui-pending {\n 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pending-dot {\n animation: none;\n opacity: 0.6;\n }\n}\n\n/* \u2500\u2500 Thoughts region \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n A muted, collapsible chain-of-thought at the top of the answer group: open\n while the model reasons, folded once the answer text starts. */\n.thoughts {\n align-self: stretch;\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 12px;\n color: var(--_muted);\n}\n\n.thoughts-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-size: 12px;\n font-weight: 600;\n color: var(--_muted);\n cursor: pointer;\n}\n\n.thoughts-toggle::before {\n content: \"\u25BE \";\n}\n\n.thoughts-toggle[aria-expanded=\"false\"]::before {\n content: \"\u25B8 \";\n}\n\n/* A gentle pulse on the label while reasoning is still streaming. */\n.thoughts[data-streaming] .thoughts-label {\n animation: ag-ui-thoughts-pulse 1.4s ease-in-out infinite;\n}\n\n@keyframes ag-ui-thoughts-pulse {\n 0%, 100% { opacity: 0.55; }\n 50% { opacity: 1; }\n}\n\n.thoughts-body {\n margin: 0;\n padding: 4px 0 4px 10px;\n border-left: 2px solid var(--_border);\n max-height: 220px;\n overflow: auto;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: inherit;\n}\n\n.thoughts-body[hidden] {\n display: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .thoughts[data-streaming] .thoughts-label {\n animation: none;\n }\n}\n\n.tool-call {\n align-self: flex-start;\n max-width: 80%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--_tool-bg);\n border: 1px solid var(--_border);\n color: var(--_tool-fg);\n}\n\n/* Wraps, because the name is the only flexible child and every badge the row\n gains is taken out of it. An approved call adds a third fixed badge, which in\n a sidebar-width panel left the name 37px and broke it mid-word. Badges drop to\n their own row instead. */\n.tool-call-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.tool-call-name {\n /* An auto basis, and a min-width floor rather than zero: the name may shrink,\n but not below something readable, so wrapping moves a badge instead of\n shredding a word. Breaking anywhere still applies to a name that cannot fit\n on a line of its own, which is what keeps a long unbroken tool name inside\n the card. */\n flex: 1 1 auto;\n min-width: 6ch;\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n\n/* Leading status icon. Empty in the DOM \u2014 the glyph/spinner is drawn\n here from the card's data-status, so it stays themeable. */\n.tool-call-icon {\n flex: none;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n font-size: 12px;\n line-height: 1;\n}\n\n/* Pending: a real spinning ring. Speed is tunable; reduced motion stops it. */\n.tool-call[data-status=\"pending\"] .tool-call-icon {\n border: 2px solid var(--_muted);\n border-top-color: transparent;\n border-radius: 50%;\n animation: ag-ui-tool-spin var(--_tool-spin-duration) linear infinite;\n}\n\n@keyframes ag-ui-tool-spin {\n to { transform: rotate(360deg); }\n}\n\n/* Deferred: no spinner, because nothing is spinning. A steady accent dot, since\n the state is waiting-on-you rather than an outcome. */\n.tool-call[data-status=\"deferred\"] .tool-call-icon {\n border-radius: 50%;\n background: var(--_accent);\n}\n\n/* Settled: a themeable glyph coloured by outcome. */\n.tool-call[data-status=\"done\"] .tool-call-icon::before {\n content: var(--_tool-icon-done);\n color: var(--_success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-icon::before {\n content: var(--_tool-icon-error);\n color: var(--_danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-icon::before {\n content: var(--_tool-icon-declined);\n color: var(--_muted);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .tool-call[data-status=\"pending\"] .tool-call-icon {\n animation: none;\n }\n}\n\n/* Inline display mode: the lightest card. Drop the box chrome so the status row\n reads as one line of the answer; the result toggle still expands below it. */\n:host([data-tool-display=\"inline\"]) .tool-call {\n max-width: 100%;\n background: transparent;\n border: none;\n padding: 2px 0;\n gap: 2px;\n}\n\n.tool-call-status {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: rgba(127, 127, 127, 0.16);\n color: var(--_muted);\n}\n\n.tool-call[data-status=\"deferred\"] .tool-call-status {\n color: var(--_accent);\n}\n\n.tool-call[data-status=\"done\"] .tool-call-status {\n color: var(--_success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-status {\n color: var(--_danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-status {\n color: var(--_muted);\n}\n\n.tool-call-body {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.tool-call-section {\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n/* The heading that tells the two payloads apart. Without it the arguments and\n the result were one run of text and a reader had to guess the boundary. */\n.tool-call-section-label {\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--_muted);\n}\n\n.skill-item-token {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n font-size: 0.92em;\n color: var(--_accent);\n margin-right: 6px;\n}\n\n/* The lasting record of a human decision on a gated call \u2014 without it an\n approved call looks exactly like one that was never gated. */\n.tool-call-decision {\n flex: none;\n font-size: 11px;\n font-style: italic;\n color: var(--_muted);\n}\n\n.tool-call-args,\n.tool-call-result {\n margin: 0;\n padding: 6px 8px;\n max-height: 160px;\n overflow: auto;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--_fg);\n}\n\n/* Display modes are pure visibility over one DOM shape, selected from the host\n attribute rather than a value stamped on the card at build time, so flipping\n data-tool-display re-styles cards already on screen. See ToolCallCard.\n\n Default (no attribute) is the full mode: arguments always visible, result\n behind the toggle. */\n.tool-call[data-expanded=\"false\"] .tool-call-section--result {\n display: none;\n}\n\n/* Compact: one toggle over both regions, so a settled card is a single line\n until asked. */\n:host([data-tool-display=\"compact\"]) .tool-call[data-expanded=\"false\"] .tool-call-section {\n display: none;\n}\n\n/* Inline: the result only; the call's arguments are noise at this density. */\n:host([data-tool-display=\"inline\"]) .tool-call .tool-call-section--args {\n display: none;\n}\n\n/* Minimal: the status row and nothing else, so there is no toggle to press. */\n:host([data-tool-display=\"minimal\"]) .tool-call .tool-call-toggle,\n:host([data-tool-display=\"minimal\"]) .tool-call .tool-call-body {\n display: none;\n}\n\n/* A pending card has no result yet, and in the modes where the arguments are\n hidden too there is nothing behind the toggle. Hide the control rather than\n offer one that expands onto nothing. A deferred card is the same, and its\n arguments are shown unconditionally by the rules below. */\n.tool-call[data-status=\"pending\"] .tool-call-toggle,\n.tool-call[data-status=\"deferred\"] .tool-call-toggle,\n:host([data-tool-display=\"inline\"]) .tool-call[data-status=\"pending\"] .tool-call-toggle {\n display: none;\n}\n\n/* The approval prompt for a gated call, rendered inside that call's own card.\n Empty on every card nobody is being asked about, so it collapses instead of\n adding a gap to each one. */\n.tool-call-approval:empty {\n display: none;\n}\n\n.tool-call-approval {\n margin-top: 8px;\n}\n\n/* A card that is asking a question shows what it is asking about, in every\n display mode. Three gated calls of one tool ask the same words, so the\n arguments are the only thing telling them apart, and a density setting must\n not be able to hide the answer to \"which one is this\". */\n:host([data-tool-display=\"minimal\"]) .tool-call[data-status=\"deferred\"] .tool-call-body {\n display: flex;\n}\n\n/* The arguments region only, never every section: the result region carries the\n hidden attribute until a result exists, and a display value here overrides it,\n framing an empty RESULT heading under the question. */\n:host([data-tool-display=\"compact\"]) .tool-call[data-status=\"deferred\"] .tool-call-section--args,\n:host([data-tool-display=\"inline\"]) .tool-call[data-status=\"deferred\"] .tool-call-section--args {\n display: flex;\n}\n\n.tool-call-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-weight: 600;\n color: var(--_accent);\n cursor: pointer;\n}\n\n.tool-call-toggle::before {\n content: \"\u25B8 \";\n}\n\n.tool-call-toggle[aria-expanded=\"true\"]::before {\n content: \"\u25BE \";\n}\n\n/* Resize handle: a corner grip on a floating panel, an edge grip on a docked\n one. Absent entirely where the placement is full-bleed, since there is\n nothing to drag. */\n.resize-handle {\n position: absolute;\n z-index: 2;\n background: transparent;\n touch-action: none;\n}\n\n.resize-handle:focus-visible {\n outline: 2px solid var(--_accent);\n outline-offset: -2px;\n}\n\n/* The grip sits on the corner opposite the panel's anchor, because a resize\n measures from whichever edge is not moving.\n\n Default is floating: pinned bottom-right, so the grip is top-left. */\n.resize-handle {\n top: 0;\n left: 0;\n width: 14px;\n height: 14px;\n cursor: nwse-resize;\n}\n\n/* Placement is only the opening guess, and these two rules are all it is good\n for. Embedded sits in normal flow, pinned top-left, so it grows bottom-right;\n bottom-left is pinned there, so its free corner is top-right. */\n:host([placement=\"embedded\"]) .resize-handle {\n top: auto;\n left: auto;\n right: 0;\n bottom: 0;\n cursor: nwse-resize;\n}\n\n:host([placement=\"bottom-left\"]) .resize-handle {\n left: auto;\n right: 0;\n cursor: nesw-resize;\n}\n\n/* Then the measurement corrects it. Which edges are held still belongs to the\n host's layout, not to placement -- a floating panel a host right-aligns is\n anchored bottom-left -- so the element measures them and stamps a single\n hyphenated \"<y>-<x>\" token here. Equal specificity to the rules above, so\n source order is what lets the measured value win.\n\n Two traps, both of which silently draw the grip on the corner that moves:\n\n Never write these as [data-resize-anchor~=\"left\"]. The stamped value is one\n hyphenated token and ~= matches whitespace-separated words, so it can never\n match.\n\n Each rule must set both sides of its axis, not only the side it moves, or it\n cannot undo a placement guess that flipped the other way. */\n:host([data-resize-anchor$=\"-left\"]) .resize-handle {\n left: auto;\n right: 0;\n}\n\n:host([data-resize-anchor$=\"-right\"]) .resize-handle {\n left: 0;\n right: auto;\n}\n\n:host([data-resize-anchor^=\"top-\"]) .resize-handle {\n top: auto;\n bottom: 0;\n}\n\n:host([data-resize-anchor^=\"bottom-\"]) .resize-handle {\n top: 0;\n bottom: auto;\n}\n\n/* One axis flipped means the drag runs along the other diagonal. */\n:host([data-resize-anchor=\"top-left\"]) .resize-handle,\n:host([data-resize-anchor=\"bottom-right\"]) .resize-handle {\n cursor: nwse-resize;\n}\n\n:host([data-resize-anchor=\"top-right\"]) .resize-handle,\n:host([data-resize-anchor=\"bottom-left\"]) .resize-handle {\n cursor: nesw-resize;\n}\n\n/* Docked: the placement owns the height, so only the inner edge is the user's --\n an edge, not a corner, so this outranks the measured anchor by coming after. */\n:host([placement=\"sidebar\"]) .resize-handle,\n:host([placement=\"side\"]) .resize-handle {\n top: 0;\n bottom: auto;\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n}\n\n/* Docked to the left, so the inner edge is the right-hand one. */\n:host([placement=\"sidebar\"][data-side=\"left\"]) .resize-handle {\n left: auto;\n right: 0;\n}\n\n/* Full-bleed: nothing to drag. */\n:host([placement=\"full\"]) .resize-handle,\n:host([placement=\"page\"]) .resize-handle {\n display: none;\n}\n\n.resize-handle[data-dragging] {\n background: var(--_accent);\n opacity: 0.35;\n}\n\n/* \u2500\u2500 Composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n One surface owns the border, the background and the focus ring; the field\n and its tool row sit inside it, rather than being siblings stretched to the\n textarea's height. */\n.input-row {\n display: flex;\n padding: 12px;\n border-top: 1px solid var(--_border);\n}\n\n.composer {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 6px 6px 6px 10px;\n background: var(--_input-bg);\n border: 1px solid var(--_border);\n border-radius: var(--_composer-radius);\n transition: border-color var(--_motion) var(--_ease);\n}\n\n.composer:focus-within {\n border-color: var(--_accent);\n}\n\n/* The field grows with its content (sized by #autoGrow) up to the ceiling,\n then scrolls. border-box keeps that measurement stable: with content-box the\n padding would be added to every scrollHeight read and the field would creep\n taller on each keystroke. */\n.input {\n box-sizing: border-box;\n resize: none;\n max-height: var(--_composer-max-height);\n overflow-y: auto;\n padding: 6px 4px 2px;\n background: transparent;\n border: none;\n font: inherit;\n color: inherit;\n outline: none;\n}\n\n.composer-tools {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n/* Icon buttons: quiet at rest, so the field is what the eye lands on. */\n.attach-btn,\n.voice-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--_tool-btn-size);\n height: var(--_tool-btn-size);\n padding: 0;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--_muted);\n font: inherit;\n line-height: 1;\n cursor: pointer;\n transition:\n background-color var(--_motion) var(--_ease),\n color var(--_motion) var(--_ease);\n}\n\n.attach-btn:hover,\n.voice-btn:hover {\n background: var(--_hover);\n color: var(--_fg);\n}\n\n.attach-btn:disabled,\n.voice-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n/* The same trap the attachment tray carries a note about, two rules along: an\n author display beats the UA stylesheet's rule for the hidden property, so a\n button the element has explicitly hidden keeps laying out and painting. The\n clip is hidden until a host supplies an upload handler or an attachments URL,\n and without this it is a visible control that cannot do anything.\n\n The mic needs no such rule, and the asymmetry is worth knowing before adding\n one: it is not hidden when unconfigured, it is never built. The voice wiring\n returns before constructing the button, leaving only an empty voice slot that\n is display: contents. A hidden-state rule for the mic would match nothing. */\n.attach-btn[hidden] {\n display: none;\n}\n\n/* Send closes the row on the right: a circle, the only filled control in the\n composer, so \"the thing that acts\" reads at a glance. */\n.send {\n margin-left: auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: var(--_send-size);\n height: var(--_send-size);\n padding: 0;\n border: none;\n border-radius: 50%;\n background: var(--_accent);\n color: #ffffff;\n font: inherit;\n line-height: 1;\n cursor: pointer;\n transition:\n background-color var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease-pop);\n}\n\n.send:hover {\n transform: scale(1.08);\n}\n\n.send:active {\n transform: scale(0.92);\n}\n\n.send:disabled {\n opacity: 0.5;\n cursor: default;\n transform: none;\n}\n\n/* The composer button doubles as the Stop control while a run is in flight \u2014\n same circle, different glyph, so nothing moves when a run starts. */\n.send[data-state=\"running\"] {\n background: var(--_muted);\n}\n\n.send[data-state=\"idle\"] .send-stop,\n.send[data-state=\"running\"] .send-send {\n display: none;\n}\n\n/* Glyphs \u2014 one class, painted from the button's own colour so every state\n (hover, recording, running) carries the icon with it. */\n.glyph {\n width: var(--_glyph-size);\n height: var(--_glyph-size);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--_glyph-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n.glyph--solid {\n fill: currentColor;\n stroke: none;\n}\n\n/* In an icon holder (header brand, launcher) the glyph takes the holder's size\n rather than the composer's. */\n.icon-holder .glyph {\n width: 100%;\n height: 100%;\n}\n\n/* \u2500\u2500 File attachments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* The picker button sits in the composer's tool row; hidden until\n data-attachments-url. */\n.attach-input {\n display: none;\n}\n\n/* The mic button's mount point; filled only once #wireVoice mounts the\n control. */\n.voice-slot {\n display: contents;\n}\n\n/* Recording: a red tint + a gentle pulse so it's clearly \"live\". */\n.voice-btn[data-state=\"recording\"] {\n background: var(--_danger);\n color: #ffffff;\n animation: ag-ui-voice-pulse 1.2s ease-in-out infinite;\n}\n\n.voice-btn[data-state=\"recording\"]:hover {\n background: var(--_danger);\n color: #ffffff;\n}\n\n@keyframes ag-ui-voice-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .voice-btn[data-state=\"recording\"] {\n animation: none;\n }\n}\n\n/* Pending-attachments tray, above the input row; collapses (hidden) when empty. */\n.attachment-slot {\n display: contents;\n}\n\n/* The padding is the only separation the tray gets: its slot is display:\n contents, so the tray is a direct child of the .chat column, and that column\n sets no gap. The bottom value keeps a chip off the composer's top edge.\n The inline value here is only the default: the page placement overrides\n padding-inline further down to compute its reading-column gutter, and wins\n on specificity whichever way this declaration is written. Read the two\n together before changing either. */\n.attachment-tray {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 12px;\n}\n\n/* The tray sets the hidden property while empty, and an author display beats\n the UA stylesheet's rule for it, so without this the empty tray keeps\n laying out and its padding is permanent dead space above the composer. */\n.attachment-tray[hidden] {\n display: none;\n}\n\n.attachment-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n.run-notice {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n align-self: flex-start;\n max-width: 100%;\n margin: 2px 0;\n padding: 3px 10px;\n border: 1px dashed var(--_border);\n border-radius: 999px;\n background: transparent;\n color: var(--_muted);\n font-size: 0.8em;\n line-height: 1.4;\n}\n\n.run-notice-icon {\n flex: none;\n opacity: 0.75;\n}\n\n.run-notice-text {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* A chip carries its own text colour because it carries its own background.\n The same chip renders in two places with opposite inherited colours: the\n composer tray gives it the panel's, a sent user bubble gives it the user\n foreground, which is white on the stock light theme and near-invisible\n against the chip. Pairing the colour with the background it belongs to makes\n both placements read alike. Overridden below for an errored chip, which\n keeps its red. */\n.attachment-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n /* Without this the 100% below caps the content box, so the chip still\n overflows its container by its own padding and border. Invisible while a\n character cap kept names short; routine once the container is what bounds\n the name. */\n box-sizing: border-box;\n max-width: 100%;\n padding: 4px 8px;\n border: 1px solid var(--_border);\n border-radius: 999px;\n background: var(--_assistant-bg);\n color: var(--_text);\n font-size: 0.85em;\n position: relative;\n}\n\n.attachment-chip--error {\n border-color: var(--_danger);\n color: var(--_danger);\n}\n\n/* The type mark. Painted from currentColor, so it carries the chip's state\n with it and turns red along with an errored one; muted by opacity rather\n than a colour, which is what keeps that true. Sized from the chip's own text\n rather than --ag-ui-glyph-size, the way an icon holder's glyph takes the\n holder's size: the composer's 18px buttons would make a chip button-height. */\n.attachment-chip-icon {\n display: inline-flex;\n flex: none;\n opacity: 0.75;\n}\n\n.attachment-chip-icon .glyph {\n width: 1.25em;\n height: 1.25em;\n}\n\n/* No character cap: the chip is already max-width 100%, so its container is\n what bounds the name, and a fixed cap only truncated names the chip had room\n for. min-width: 0 is what lets the flex item shrink past its content, so the\n ellipsis appears at the container edge instead of the chip overflowing. */\n.attachment-chip-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.attachment-chip-size {\n color: var(--_muted);\n white-space: nowrap;\n}\n\n.attachment-chip--error .attachment-chip-size {\n color: var(--_danger);\n}\n\n/* The progress bar fills as the file uploads. */\n.attachment-chip-bar {\n flex-basis: 100%;\n height: 3px;\n border-radius: 2px;\n background: var(--_border);\n overflow: hidden;\n}\n\n.attachment-chip-bar-fill {\n height: 100%;\n background: var(--_accent);\n transition: width 0.15s ease;\n}\n\n.attachment-chip-remove,\n.attachment-chip-retry {\n border: none;\n background: none;\n color: inherit;\n cursor: pointer;\n padding: 0;\n line-height: 1;\n opacity: 0.7;\n}\n\n.attachment-chip-remove:hover,\n.attachment-chip-retry:hover {\n opacity: 1;\n}\n\n/* A subtle outline while a file is dragged over the shell. */\n.chat--dragover {\n outline: 2px dashed var(--_accent);\n outline-offset: -4px;\n}\n\n/* Muted \"\u23F9 Stopped\" line after a cancelled run \u2014 a note, not an error bubble. */\n.stopped-note {\n align-self: flex-start;\n color: var(--_muted);\n font-size: 12px;\n padding: 2px 4px;\n}\n\n/* Inline confirmation card \u2014 lives in the transcript, no focus-stealing overlay. */\n.confirm {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--_bg);\n border: 1px solid var(--_accent);\n border-radius: 10px;\n}\n\n.confirm[data-resolved] {\n opacity: 0.7;\n border-color: var(--_border);\n}\n\n.confirm-body {\n font-weight: 600;\n}\n\n.confirm-args {\n margin: 0;\n padding: 8px 10px;\n max-height: 140px;\n overflow: auto;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n background: var(--_assistant-bg);\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.confirm-btn {\n border: 1px solid var(--_border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--_bg);\n color: var(--_fg);\n}\n\n.confirm-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.confirm-btn--confirm {\n border-color: var(--_accent);\n background: var(--_accent);\n color: #ffffff;\n}\n\n/* Approval card \u2014 the server-side-tool gate (approve/deny an interrupt). */\n.approval {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--_bg);\n border: 1px solid var(--_accent);\n border-radius: 10px;\n}\n\n.approval[data-resolved] {\n opacity: 0.7;\n border-color: var(--_border);\n}\n\n.approval-body {\n font-weight: 600;\n}\n\n.approval-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.approval-btn {\n border: 1px solid var(--_border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--_bg);\n color: var(--_fg);\n}\n\n.approval-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.approval-btn--approve {\n border-color: var(--_accent);\n background: var(--_accent);\n color: #ffffff;\n}\n\n/* Question card \u2014 the built-in ask_user prompt (radios and/or free text). */\n.question {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--_bg);\n border: 1px solid var(--_accent);\n border-radius: 10px;\n}\n\n.question[data-resolved] {\n opacity: 0.7;\n border-color: var(--_border);\n}\n\n.question-body {\n font-weight: 600;\n}\n\n.question-options {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.question-choice {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n\n.question-input {\n box-sizing: border-box;\n width: 100%;\n padding: 8px 10px;\n font: inherit;\n color: var(--_fg);\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 8px;\n}\n\n.question-input:disabled {\n opacity: 0.6;\n}\n\n.question-actions {\n display: flex;\n justify-content: flex-end;\n}\n\n.question-btn {\n border: 1px solid var(--_accent);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--_accent);\n color: #ffffff;\n}\n\n.question-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n/* Skills \u2014 chips row + the /-command palette, above the input. */\n.skill-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 10px 12px;\n}\n\n.skill-chip {\n border: 1px solid var(--_border);\n border-radius: 999px;\n padding: 4px 12px;\n font: inherit;\n font-size: 0.9em;\n cursor: pointer;\n background: var(--_assistant-bg);\n color: var(--_fg);\n}\n\n.skill-chip:hover {\n border-color: var(--_accent);\n}\n\n.skill-palette {\n margin: 8px 12px 0;\n display: flex;\n flex-direction: column;\n max-height: 220px;\n overflow: auto;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);\n}\n\n.skill-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n align-items: flex-start;\n padding: 8px 12px;\n border: none;\n background: none;\n font: inherit;\n text-align: left;\n cursor: pointer;\n color: var(--_fg);\n}\n\n.skill-item[aria-selected=\"true\"] {\n background: var(--_assistant-bg);\n}\n\n.skill-item-title {\n font-weight: 600;\n}\n\n.skill-item-desc {\n font-size: 0.85em;\n color: var(--_muted);\n}\n\n/* The hint sits directly above the composer's top border, so a zero bottom\n margin left the text touching the divider. */\n.skill-hint {\n margin: 8px 12px;\n font-size: 0.85em;\n line-height: 1.4;\n color: var(--_danger);\n}\n\n/* Chat-history drawer \u2014 a slide-over within the chat panel.\n The hidden attribute stays the single source of truth for open/closed (no\n JS-driven animation state): display is transitioned discretely, so on close\n the drawer stays displayed for the whole exit and is removed only at the end,\n which is what lets the backdrop fade and the panel slide out. */\n.drawer {\n position: absolute;\n inset: 0;\n z-index: 5;\n display: flex;\n transition: visibility var(--_motion) var(--_ease);\n}\n\n/* Closed. The overlay keeps its box (display, not none) so the backdrop and\n panel inside it stay rendered and can transition both ways; visibility is\n what takes the whole subtree out of the tab order, the a11y tree and hit\n testing at rest, and it holds off until the slide has finished. */\n.drawer[hidden] {\n display: flex;\n visibility: hidden;\n pointer-events: none;\n}\n\n.drawer[hidden] .drawer-backdrop {\n opacity: 0;\n}\n\n.drawer[hidden] .drawer-panel {\n transform: translateX(-100%);\n}\n\n.checkpoints {\n position: absolute;\n inset-block-start: 3rem;\n inset-inline: 0.75rem;\n z-index: 6;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n border: 1px solid var(--_border);\n border-radius: 0.5rem;\n background: var(--_assistant-bg);\n box-shadow: 0 6px 24px rgb(0 0 0 / 12%);\n max-height: 60%;\n overflow-y: auto;\n transform-origin: top center;\n transition:\n opacity var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease),\n visibility var(--_motion) var(--_ease);\n}\n\n/* Same idiom as the drawer: laid out at rest, hidden by visibility, so the\n popover can animate open and closed. */\n.checkpoints[hidden] {\n display: flex;\n visibility: hidden;\n pointer-events: none;\n opacity: 0;\n transform: scale(0.96) translateY(-6px);\n}\n\n.checkpoints-title {\n font-size: 0.75rem;\n font-weight: 600;\n opacity: 0.7;\n}\n\n.checkpoints-empty {\n padding: 0.5rem 0.25rem;\n font-size: 0.8125rem;\n opacity: 0.7;\n}\n\n/* A row is a label and two buttons, and nothing about the row itself is\n pressable. It used to light up on hover, which is the affordance of something\n clickable and made the buttons look like decoration on a clickable strip. The\n resting surface groups the row instead, so hover can mean what it says: only\n the buttons respond to it.\n\n It wraps for the same reason the tool-call head does. Every child but the label\n is fixed-width, so in a narrow panel the label is the only thing that can give\n -- and a flex-basis of zero lets it give everything. Adding the run id was\n enough to crush \"just now\" to zero pixels: present, correct, and invisible.\n Wrapping puts the buttons on their own line instead. */\n.checkpoint-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5rem;\n padding: 0.3125rem 0.4375rem;\n border-radius: 0.375rem;\n background: var(--_hover);\n}\n\n/* Grows into spare room, and refuses to shrink past the shortest thing it ever\n says. A time is short and bounded, so there is no case for eliding it. */\n.checkpoint-label {\n flex: 1 1 auto;\n min-width: 7ch;\n font-size: 0.8125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* When the label holds the run's first message, the time moves here: still worth\n showing, no longer what identifies the row. Muted and unshrinkable, so it does\n not compete with the words beside it. */\n.checkpoint-time {\n flex: 0 0 auto;\n font-size: 0.6875rem;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n/* Enough of the run id to tell two runs apart when both say \"just now\". Muted\n and monospaced: it is a reference, not a name. */\n.checkpoint-id {\n flex: 0 0 auto;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.6875rem;\n opacity: 0.55;\n}\n\n/* On the panel's own surface, not the row's: the row now paints the hover token\n itself, and a badge the same colour as what it sits on is not a badge. */\n.checkpoint-branch {\n font-size: 0.6875rem;\n padding: 0 0.375rem;\n border-radius: 999px;\n background: var(--_assistant-bg);\n opacity: 0.8;\n}\n\n/* The two things in the row that actually do something, so they are the two\n things that look like it: a filled surface at rest rather than a transparent\n outline, which on top of the old row highlight was nearly invisible. */\n.checkpoint-action {\n font: inherit;\n font-size: 0.75rem;\n line-height: 1.4;\n cursor: pointer;\n padding: 0.1875rem 0.5625rem;\n border: 1px solid var(--_border);\n border-radius: 0.375rem;\n background: var(--_bg);\n color: inherit;\n transition:\n background var(--_motion) var(--_ease),\n border-color var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease);\n}\n\n/* Resume is what a reader wants nine times in ten; fork is the deliberate choice\n beside it. Filled and outlined, the same pair the confirmation and approval\n cards already use for their primary and secondary action. */\n.checkpoint-resume {\n font-weight: 600;\n border-color: var(--_accent);\n background: var(--_accent);\n color: #ffffff;\n}\n\n.checkpoint-fork:hover {\n background: var(--_hover);\n border-color: var(--_accent);\n}\n\n/* The filled one cannot go lighter on hover without losing its contrast with the\n white label, so it dims instead. */\n.checkpoint-resume:hover {\n opacity: 0.88;\n}\n\n/* Pressed: a pixel down, so the click is felt as well as seen. */\n.checkpoint-action:active {\n transform: translateY(1px);\n}\n\n/* Keyboard focus was invisible here, in a panel that traps focus and is reached\n by Tab -- so the one navigation path guaranteed to land on these buttons was\n the one with nothing to show for it. */\n.checkpoint-action:focus-visible {\n outline: 2px solid var(--_accent);\n outline-offset: 2px;\n}\n\n.drawer-backdrop {\n position: absolute;\n inset: 0;\n background: rgba(20, 20, 50, 0.32);\n opacity: 1;\n transition: opacity var(--_motion) var(--_ease);\n}\n\n.drawer-panel {\n position: relative;\n display: flex;\n flex-direction: column;\n width: min(300px, 85%);\n height: 100%;\n background: var(--_bg);\n border-right: 1px solid var(--_border);\n box-shadow: var(--_shadow);\n overflow: hidden;\n transform: none;\n transition: transform var(--_motion) var(--_ease);\n}\n\n.drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--_space);\n padding: var(--_pad);\n border-bottom: 1px solid var(--_border);\n}\n\n.drawer-title {\n font-weight: 600;\n}\n\n.drawer-new {\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_bg);\n color: var(--_accent);\n padding: 4px 10px;\n font: inherit;\n font-size: 0.85em;\n cursor: pointer;\n}\n\n.drawer-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n\n.drawer-empty {\n padding: var(--_pad);\n font-size: 0.9em;\n color: var(--_muted);\n}\n\n.drawer-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--_border);\n}\n\n.drawer-row--active {\n background: var(--_assistant-bg);\n}\n\n.drawer-row-select {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 12px;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.drawer-row-title {\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-time {\n font-size: 0.72em;\n color: var(--_muted);\n}\n\n.drawer-row-preview {\n font-size: 0.8em;\n color: var(--_muted);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 6px;\n}\n\n.drawer-row-rename,\n.drawer-row-delete {\n border: none;\n background: none;\n color: var(--_muted);\n font-size: 0.9em;\n padding: 4px;\n cursor: pointer;\n}\n\n.drawer-rename-input {\n flex: 1;\n min-width: 0;\n margin: 6px 10px;\n padding: 4px 8px;\n border: 1px solid var(--_accent);\n border-radius: 6px;\n background: var(--_input-bg);\n color: var(--_fg);\n font: inherit;\n}\n\n.drawer-confirm {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n font-size: 0.85em;\n}\n\n.drawer-confirm-label {\n color: var(--_danger);\n}\n\n.drawer-confirm-yes {\n border: none;\n border-radius: 6px;\n background: var(--_danger);\n color: #ffffff;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n.drawer-confirm-no {\n border: 1px solid var(--_border);\n border-radius: 6px;\n background: none;\n color: inherit;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n/* Embedded placement: an inline, flush side panel rather than a dimmed,\n floating slide-over. */\n:host([placement=\"embedded\"]) .drawer-backdrop {\n background: none;\n}\n\n:host([placement=\"embedded\"]) .drawer-panel {\n width: 100%;\n border-right: none;\n box-shadow: none;\n}\n`;\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/**\n * A muted, collapsible \"thinking\" region for a reasoning model's streamed\n * chain-of-thought.\n *\n * Sits at the top of the current answer group. It opens expanded while the\n * model reasons, {@link stream} replacing its body with the running buffer, and\n * {@link collapse} folds it away once the answer's first text token arrives.\n * The header toggle reopens it.\n *\n * Pure DOM. The host inserts {@link element}; all visible chrome text comes\n * from {@link UiStrings}.\n */\nexport class ThoughtsBlock {\n /** The block's root element; insert this at the top of the answer group. */\n readonly element: HTMLDivElement;\n\n readonly #label: HTMLSpanElement;\n readonly #body: HTMLPreElement;\n readonly #toggle: HTMLButtonElement;\n readonly #strings: UiStrings;\n #collapsed = false;\n\n constructor(strings: UiStrings = DEFAULT_UI_STRINGS) {\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"thoughts\";\n this.element.setAttribute(\"part\", \"thoughts\");\n // Lets CSS animate the header while the model is still reasoning; dropped\n // on collapse.\n this.element.setAttribute(\"data-streaming\", \"\");\n\n this.#toggle = document.createElement(\"button\");\n this.#toggle.type = \"button\";\n this.#toggle.className = \"thoughts-toggle\";\n this.#toggle.setAttribute(\"part\", \"thoughts-toggle\");\n this.#toggle.setAttribute(\"aria-expanded\", \"true\");\n\n this.#label = document.createElement(\"span\");\n this.#label.className = \"thoughts-label\";\n this.#label.setAttribute(\"part\", \"thoughts-label\");\n this.#label.textContent = strings.thinking;\n this.#toggle.append(this.#label);\n\n this.#body = document.createElement(\"pre\");\n this.#body.className = \"thoughts-body\";\n this.#body.setAttribute(\"part\", \"thoughts-body\");\n\n this.#toggle.addEventListener(\"click\", () => {\n this.#setCollapsed(!this.#collapsed);\n });\n\n this.element.append(this.#toggle, this.#body);\n }\n\n /** Replace the reasoning body with the running buffer (the full text so far). */\n stream(buffer: string): void {\n this.#body.textContent = buffer;\n }\n\n /**\n * Fold the region away when the answer's first text token arrives, flipping\n * the header label to its settled form. Idempotent, since the per-token text\n * handler calls it repeatedly.\n */\n collapse(): void {\n if (this.#collapsed) {\n return;\n }\n this.element.removeAttribute(\"data-streaming\");\n this.#label.textContent = this.#strings.thoughts;\n this.#setCollapsed(true);\n }\n\n #setCollapsed(collapsed: boolean): void {\n this.#collapsed = collapsed;\n this.#body.hidden = collapsed;\n this.#toggle.setAttribute(\"aria-expanded\", String(!collapsed));\n }\n}\n", "import type { ThreadMeta } from \"../core/conversation_store.js\";\nimport { relativeTime } from \"./relative_time.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Actions the host ({@link AgUiChat}) wires to the drawer's rows. */\nexport interface ThreadDrawerCallbacks {\n /** A row was picked \u2014 load that thread and make it active. */\n readonly onSelect: (threadId: string) => void;\n /** The \"New chat\" action \u2014 start a fresh thread. */\n readonly onNew: () => void;\n /** A row was renamed to `title`. */\n readonly onRename: (threadId: string, title: string) => void;\n /** A row was deleted (after the inline confirm). */\n readonly onDelete: (threadId: string) => void;\n}\n\n/**\n * The chat-history drawer: a slide-over listing the user's threads (title,\n * relative time, preview), with select / new / rename / delete actions and an\n * empty state. Pure DOM, like {@link SkillsMenu}: the host appends\n * {@link element}, toggles it, feeds rows via {@link setThreads}, and acts on\n * the callbacks.\n *\n * A view only \u2014 it never mutates the store. After a callback the host updates\n * the store and calls {@link setThreads} to refresh. All visible text comes\n * from {@link UiStrings}; {@link setStrings} re-localizes a drawer built before\n * its strings resolved.\n */\nexport class ThreadDrawer {\n /** The drawer root (backdrop + panel). Append to the chat shell; hidden until opened. */\n readonly element: HTMLDivElement;\n\n readonly #callbacks: ThreadDrawerCallbacks;\n readonly #panel: HTMLDivElement;\n readonly #heading: HTMLSpanElement;\n readonly #newButton: HTMLButtonElement;\n readonly #list: HTMLDivElement;\n #strings: UiStrings;\n #threads: readonly ThreadMeta[] = [];\n #activeId = \"\";\n /** The element focused before the drawer opened, restored on close. */\n #lastFocused: HTMLElement | null = null;\n\n constructor(callbacks: ThreadDrawerCallbacks, strings: UiStrings = DEFAULT_UI_STRINGS) {\n this.#callbacks = callbacks;\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"drawer\";\n this.element.setAttribute(\"part\", \"drawer\");\n this.element.hidden = true;\n\n const backdrop = document.createElement(\"div\");\n backdrop.className = \"drawer-backdrop\";\n backdrop.setAttribute(\"part\", \"drawer-backdrop\");\n backdrop.addEventListener(\"click\", () => this.close());\n\n this.#panel = document.createElement(\"div\");\n this.#panel.className = \"drawer-panel\";\n this.#panel.setAttribute(\"part\", \"drawer-panel\");\n this.#panel.setAttribute(\"role\", \"dialog\");\n this.#panel.setAttribute(\"aria-modal\", \"true\");\n this.#panel.setAttribute(\"aria-label\", strings.chatHistory);\n // Escape closes the drawer; Tab is trapped within the panel while it's open.\n this.#panel.addEventListener(\"keydown\", (event) => this.#onPanelKeydown(event));\n\n const header = document.createElement(\"div\");\n header.className = \"drawer-header\";\n header.setAttribute(\"part\", \"drawer-header\");\n this.#heading = document.createElement(\"span\");\n this.#heading.className = \"drawer-title\";\n this.#heading.setAttribute(\"part\", \"drawer-title\");\n this.#heading.textContent = strings.chats;\n this.#newButton = document.createElement(\"button\");\n this.#newButton.type = \"button\";\n this.#newButton.className = \"drawer-new\";\n this.#newButton.setAttribute(\"part\", \"drawer-new\");\n this.#newButton.textContent = strings.newChat;\n this.#newButton.addEventListener(\"click\", () => {\n this.close();\n this.#callbacks.onNew();\n });\n header.append(this.#heading, this.#newButton);\n\n this.#list = document.createElement(\"div\");\n this.#list.className = \"drawer-list\";\n this.#list.setAttribute(\"part\", \"drawer-list\");\n\n this.#panel.append(header, this.#list);\n this.element.append(backdrop, this.#panel);\n }\n\n /** Re-localize the drawer's chrome and rows (the host calls this on connect). */\n setStrings(strings: UiStrings): void {\n this.#strings = strings;\n this.#panel.setAttribute(\"aria-label\", strings.chatHistory);\n this.#heading.textContent = strings.chats;\n this.#newButton.textContent = strings.newChat;\n this.#renderList();\n }\n\n isOpen(): boolean {\n return !this.element.hidden;\n }\n\n open(): void {\n if (this.isOpen()) {\n return;\n }\n // Remember what had focus so it's restored on close, then move focus into\n // the panel (its first control) so keyboard users land inside the dialog.\n this.#lastFocused = this.#activeElement() as HTMLElement | null;\n this.element.hidden = false;\n this.#newButton.focus();\n }\n\n close(): void {\n if (!this.isOpen()) {\n return;\n }\n this.element.hidden = true;\n this.#lastFocused?.focus();\n this.#lastFocused = null;\n }\n\n toggle(): void {\n if (this.isOpen()) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /** The currently-focused element within the drawer's root (shadow-aware). */\n #activeElement(): Element | null {\n return (this.element.getRootNode() as Document | ShadowRoot).activeElement;\n }\n\n /** Escape-to-close and a Tab focus trap while the dialog is open. */\n #onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n event.preventDefault();\n this.close();\n return;\n }\n if (event.key !== \"Tab\") {\n return;\n }\n const focusables = Array.from(\n this.#panel.querySelectorAll<HTMLElement>(\"button, input, [tabindex]\"),\n ).filter((el) => !el.hidden);\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = this.#activeElement();\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first?.focus();\n }\n }\n\n /** Render the rows (or the empty state), highlighting the active thread. */\n setThreads(threads: readonly ThreadMeta[], activeId: string): void {\n this.#threads = threads;\n this.#activeId = activeId;\n this.#renderList();\n }\n\n #renderList(): void {\n this.#list.replaceChildren();\n if (this.#threads.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"drawer-empty\";\n empty.setAttribute(\"part\", \"drawer-empty\");\n empty.textContent = this.#strings.noConversations;\n this.#list.appendChild(empty);\n return;\n }\n for (const meta of this.#threads) {\n this.#list.appendChild(this.#renderRow(meta));\n }\n }\n\n #renderRow(meta: ThreadMeta): HTMLDivElement {\n const row = document.createElement(\"div\");\n row.className = \"drawer-row\";\n row.setAttribute(\"part\", \"drawer-row\");\n if (meta.threadId === this.#activeId) {\n row.classList.add(\"drawer-row--active\");\n }\n\n const select = document.createElement(\"button\");\n select.type = \"button\";\n select.className = \"drawer-row-select\";\n select.setAttribute(\"part\", \"drawer-row-select\");\n const title = document.createElement(\"span\");\n title.className = \"drawer-row-title\";\n title.setAttribute(\"part\", \"drawer-row-title\");\n title.textContent = meta.title;\n const time = document.createElement(\"span\");\n time.className = \"drawer-row-time\";\n time.setAttribute(\"part\", \"drawer-row-time\");\n time.textContent = relativeTime(meta.updatedAt, undefined, this.#strings);\n const preview = document.createElement(\"span\");\n preview.className = \"drawer-row-preview\";\n preview.setAttribute(\"part\", \"drawer-row-preview\");\n preview.textContent = meta.preview;\n select.append(title, time, preview);\n select.addEventListener(\"click\", () => {\n this.close();\n this.#callbacks.onSelect(meta.threadId);\n });\n\n const rename = document.createElement(\"button\");\n rename.type = \"button\";\n rename.className = \"drawer-row-rename\";\n rename.setAttribute(\"part\", \"drawer-row-rename\");\n rename.title = this.#strings.rename;\n rename.setAttribute(\"aria-label\", this.#strings.renameConversation);\n rename.textContent = \"\u270E\";\n rename.addEventListener(\"click\", () => this.#startRename(row, meta));\n\n const remove = document.createElement(\"button\");\n remove.type = \"button\";\n remove.className = \"drawer-row-delete\";\n remove.setAttribute(\"part\", \"drawer-row-delete\");\n remove.title = this.#strings.delete;\n remove.setAttribute(\"aria-label\", this.#strings.deleteConversation);\n remove.textContent = \"\uD83D\uDDD1\";\n remove.addEventListener(\"click\", () => this.#confirmDelete(row, meta));\n\n const actions = document.createElement(\"div\");\n actions.className = \"drawer-row-actions\";\n actions.setAttribute(\"part\", \"drawer-row-actions\");\n actions.append(rename, remove);\n\n row.append(select, actions);\n return row;\n }\n\n /** Swap a row for an inline rename input; Enter/blur commits, Escape cancels. */\n #startRename(row: HTMLDivElement, meta: ThreadMeta): void {\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.className = \"drawer-rename-input\";\n input.setAttribute(\"part\", \"drawer-rename-input\");\n input.value = meta.title;\n // One-shot: Enter, Escape, and blur can all fire for a single edit (Enter\n // commits and re-renders, which blurs the detached input); the flag makes\n // the later events no-ops so a rename isn't submitted twice.\n let done = false;\n const commit = (): void => {\n if (done) {\n return;\n }\n done = true;\n const value = input.value.trim();\n if (value === \"\" || value === meta.title) {\n this.#renderList();\n } else {\n this.#callbacks.onRename(meta.threadId, value);\n }\n };\n const cancel = (): void => {\n if (done) {\n return;\n }\n done = true;\n this.#renderList();\n };\n input.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n commit();\n } else if (event.key === \"Escape\") {\n // Stop the panel's Escape handler from also closing the drawer.\n event.preventDefault();\n event.stopPropagation();\n cancel();\n }\n });\n input.addEventListener(\"blur\", () => commit());\n row.replaceChildren(input);\n input.focus();\n input.select();\n }\n\n /** Swap a row for an inline \"Delete? [Delete] [Cancel]\" confirm. */\n #confirmDelete(row: HTMLDivElement, meta: ThreadMeta): void {\n const confirm = document.createElement(\"div\");\n confirm.className = \"drawer-confirm\";\n confirm.setAttribute(\"part\", \"drawer-confirm\");\n const label = document.createElement(\"span\");\n label.className = \"drawer-confirm-label\";\n label.setAttribute(\"part\", \"drawer-confirm-label\");\n label.textContent = this.#strings.deletePrompt;\n const yes = document.createElement(\"button\");\n yes.type = \"button\";\n yes.className = \"drawer-confirm-yes\";\n yes.setAttribute(\"part\", \"drawer-confirm-yes\");\n yes.textContent = this.#strings.delete;\n yes.addEventListener(\"click\", () => this.#callbacks.onDelete(meta.threadId));\n const no = document.createElement(\"button\");\n no.type = \"button\";\n no.className = \"drawer-confirm-no\";\n no.setAttribute(\"part\", \"drawer-confirm-no\");\n no.textContent = this.#strings.cancel;\n no.addEventListener(\"click\", () => this.#renderList());\n confirm.append(label, yes, no);\n row.replaceChildren(confirm);\n }\n}\n", "import { TOOL_CALL_STATUS, type TOOL_DISPLAY } from \"../constants.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Any state a tool-call card can be in. */\nexport type ToolCallStatus = (typeof TOOL_CALL_STATUS)[keyof typeof TOOL_CALL_STATUS];\n\n/** How much detail a card renders. */\nexport type ToolDisplayMode = (typeof TOOL_DISPLAY)[keyof typeof TOOL_DISPLAY];\n\n/** The two states a card can sit in before an outcome exists. */\nexport type UnsettledStatus = typeof TOOL_CALL_STATUS.PENDING | typeof TOOL_CALL_STATUS.DEFERRED;\n\n/** The terminal states a card settles into (everything unsettled excluded). */\nexport type SettledStatus = Exclude<ToolCallStatus, UnsettledStatus>;\n\n/** Short pill text shown for each status, drawn from the string table. */\nfunction statusLabels(strings: UiStrings): Record<ToolCallStatus, string> {\n return {\n [TOOL_CALL_STATUS.PENDING]: strings.toolRunning,\n [TOOL_CALL_STATUS.DEFERRED]: strings.toolDeferred,\n [TOOL_CALL_STATUS.DONE]: strings.toolDone,\n [TOOL_CALL_STATUS.ERROR]: strings.toolError,\n [TOOL_CALL_STATUS.DECLINED]: strings.toolDeclined,\n };\n}\n\n/** Section-heading text for each settled outcome's result region. */\nfunction resultLabels(strings: UiStrings): Record<SettledStatus, string> {\n return {\n [TOOL_CALL_STATUS.DONE]: strings.resultLabel,\n [TOOL_CALL_STATUS.ERROR]: strings.errorLabel,\n [TOOL_CALL_STATUS.DECLINED]: strings.declinedLabel,\n };\n}\n\n/** Pretty-print a JSON payload; fall back to the raw text if it isn't JSON. */\nfunction formatPayload(text: string): string {\n try {\n return JSON.stringify(JSON.parse(text), null, 2);\n } catch {\n return text;\n }\n}\n\n/**\n * A live tool-call card for the chat transcript.\n *\n * Construction renders a status icon, the tool name, a status pill, and a body\n * of two separately-headed regions \u2014 arguments and result \u2014 each with its own\n * `part`. {@link settle} fills in the result and flips the pill. Both payloads\n * are pretty-printed and never concatenated into one block.\n *\n * The card renders one DOM shape in every display mode and lets CSS decide what\n * shows, selecting visibility from the host attribute rather than a value\n * copied onto the card at construction. That is what lets `data-tool-display`\n * be flipped on the host and re-read by every card already on screen; building\n * a different structure per mode would leave existing cards stale.\n *\n * The leading icon carries no text: the shadow CSS draws its glyph or spinner\n * from the card's `data-status`, so a host themes it through the\n * `--ag-ui-tool-icon-*` custom properties or the `tool-card-icon` part without\n * the card reaching into the host stylesheet.\n *\n * Pure DOM. The host appends {@link element} into its shadow root; all visible\n * text comes from {@link UiStrings}.\n */\nexport class ToolCallCard {\n /** The card's root element; append this into the message list. */\n readonly element: HTMLDivElement;\n\n /**\n * Where a question about *this* call renders \u2014 the approval prompt for a\n * server-side tool the run deferred.\n *\n * It belongs to the card rather than to the transcript because a run can defer\n * several calls at once, and a prompt written per *tool* (\"Add this event to\n * the board?\") is identical for every one of them. Rendered into the answer\n * group they were three anonymous copies of one question, below the three\n * cards they gated; rendered here, position identifies them and the arguments\n * are already on screen above the question.\n *\n * Empty until used, and hidden while empty by the shadow CSS.\n */\n readonly approvalSlot: HTMLDivElement;\n\n readonly #status: HTMLSpanElement;\n readonly #decision: HTMLSpanElement;\n readonly #toggle: HTMLButtonElement;\n readonly #resultSection: HTMLDivElement;\n readonly #resultLabel: HTMLSpanElement;\n readonly #resultBody: HTMLPreElement;\n readonly #strings: UiStrings;\n #settled = false;\n\n constructor(\n name: string,\n args: Record<string, unknown>,\n summary?: string,\n strings: UiStrings = DEFAULT_UI_STRINGS,\n ) {\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"tool-call\";\n this.element.setAttribute(\"part\", \"tool-card\");\n this.element.setAttribute(\"data-tool-name\", name);\n this.element.setAttribute(\"data-status\", TOOL_CALL_STATUS.PENDING);\n this.element.setAttribute(\"data-expanded\", \"false\");\n\n const head = document.createElement(\"div\");\n head.className = \"tool-call-head\";\n head.setAttribute(\"part\", \"tool-card-head\");\n\n // Left empty in the DOM on purpose: the shadow CSS draws the spinner or\n // settled mark from `data-status`, keeping the glyphs themeable.\n const icon = document.createElement(\"span\");\n icon.className = \"tool-call-icon\";\n icon.setAttribute(\"part\", \"tool-card-icon\");\n icon.setAttribute(\"aria-hidden\", \"true\");\n\n const label = document.createElement(\"span\");\n label.className = \"tool-call-name\";\n label.setAttribute(\"part\", \"tool-card-name\");\n // A server-provided `x-summary` label reads better than the raw tool name.\n label.textContent = summary ?? name;\n\n this.#status = document.createElement(\"span\");\n this.#status.className = \"tool-call-status\";\n this.#status.setAttribute(\"part\", \"tool-card-status\");\n this.#status.textContent = statusLabels(strings)[TOOL_CALL_STATUS.PENDING];\n\n this.#decision = document.createElement(\"span\");\n this.#decision.className = \"tool-call-decision\";\n this.#decision.setAttribute(\"part\", \"tool-card-decision\");\n this.#decision.hidden = true;\n\n head.append(icon, label, this.#status, this.#decision);\n\n const argsSection = this.#section(\"args\", strings.argumentsLabel);\n argsSection.body.textContent = JSON.stringify(args, null, 2);\n // Drop the region rather than frame an empty object.\n argsSection.root.hidden = Object.keys(args).length === 0;\n\n const resultSection = this.#section(\"result\", strings.resultLabel);\n this.#resultSection = resultSection.root;\n this.#resultLabel = resultSection.label;\n this.#resultBody = resultSection.body;\n // Nothing to show until `settle` supplies it, or a pending card expands\n // onto an empty region.\n resultSection.root.hidden = true;\n\n this.#toggle = document.createElement(\"button\");\n this.#toggle.type = \"button\";\n this.#toggle.className = \"tool-call-toggle\";\n this.#toggle.setAttribute(\"part\", \"tool-card-toggle\");\n this.#toggle.setAttribute(\"aria-expanded\", \"false\");\n this.#toggle.textContent = strings.details;\n this.#toggle.addEventListener(\"click\", () => this.#setExpanded(!this.#expanded()));\n\n const body = document.createElement(\"div\");\n body.className = \"tool-call-body\";\n body.setAttribute(\"part\", \"tool-card-body\");\n body.append(argsSection.root, resultSection.root);\n\n this.approvalSlot = document.createElement(\"div\");\n this.approvalSlot.className = \"tool-call-approval\";\n this.approvalSlot.setAttribute(\"part\", \"tool-card-approval\");\n\n this.element.append(head, this.#toggle, body, this.approvalSlot);\n }\n\n /**\n * Move between the two states that are not an outcome \u2014 `pending` (running)\n * and `deferred` (gated, waiting on a person).\n *\n * Ignored once {@link settle} has run: a card that was declined must not be\n * talked back into looking live by a late event.\n */\n mark(status: UnsettledStatus): void {\n if (this.#settled) {\n return;\n }\n this.element.setAttribute(\"data-status\", status);\n this.#status.textContent = statusLabels(this.#strings)[status];\n }\n\n /**\n * Record that a human approved or declined this call, as a line in the card.\n * The prompt disappears once answered, so this is the only lasting trace that\n * the call was gated at all.\n */\n recordDecision(kind: \"approved\" | \"declined\"): void {\n this.element.setAttribute(\"data-decision\", kind);\n this.#decision.textContent =\n kind === \"approved\" ? this.#strings.decisionApproved : this.#strings.decisionDeclined;\n this.#decision.hidden = false;\n }\n\n /** Whether {@link settle} has already run (so a terminal sweep can skip it). */\n get settled(): boolean {\n return this.#settled;\n }\n\n /**\n * Flip the status pill to `status` and fill in the result region, whose\n * heading names the outcome (result / error / declined).\n */\n settle(status: SettledStatus, text: string): void {\n // Idempotent: a duplicate `TOOL_CALL_RESULT`, or a replayed tool message\n // for an already-settled card, must not overwrite the first outcome.\n if (this.#settled) {\n return;\n }\n this.#settled = true;\n this.element.setAttribute(\"data-status\", status);\n this.#status.textContent = statusLabels(this.#strings)[status];\n this.#resultLabel.textContent = resultLabels(this.#strings)[status];\n this.#resultBody.textContent = formatPayload(text);\n this.#resultSection.hidden = false;\n }\n\n /** Build one labelled region of the body: a heading plus a payload block. */\n #section(\n kind: string,\n labelText: string,\n ): {\n root: HTMLDivElement;\n label: HTMLSpanElement;\n body: HTMLPreElement;\n } {\n const root = document.createElement(\"div\");\n root.className = `tool-call-section tool-call-section--${kind}`;\n root.setAttribute(\"part\", `tool-card-section tool-card-${kind}-section`);\n\n const label = document.createElement(\"span\");\n label.className = \"tool-call-section-label\";\n label.setAttribute(\"part\", `tool-card-section-label tool-card-${kind}-label`);\n label.textContent = labelText;\n\n const body = document.createElement(\"pre\");\n body.className = `tool-call-${kind}`;\n body.setAttribute(\"part\", `tool-card-${kind}`);\n\n root.append(label, body);\n return { root, label, body };\n }\n\n #expanded(): boolean {\n return this.element.getAttribute(\"data-expanded\") === \"true\";\n }\n\n #setExpanded(expand: boolean): void {\n this.element.setAttribute(\"data-expanded\", String(expand));\n this.#toggle.setAttribute(\"aria-expanded\", String(expand));\n }\n}\n", "import { ICON_VOICE } from \"../constants.js\";\nimport type { TranscribeHandler } from \"../core/transcribe_audio.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Lifecycle of the mic button, reflected on its `data-state` for CSS. */\ntype VoiceState = \"idle\" | \"recording\" | \"transcribing\";\n\n/** Construction options for {@link VoiceInput}. */\nexport interface VoiceInputOptions {\n /** Turns a recorded clip into text (the built-in or a custom transport). */\n readonly transcribe: TranscribeHandler;\n /** Called with the transcript when a recording transcribes successfully. */\n readonly onText: (text: string) => void;\n /** UI string table (labels/tooltips). */\n readonly strings?: UiStrings;\n}\n\n/**\n * The composer's voice-input control: a mic button that records via\n * `MediaRecorder`, then POSTs the clip through a {@link TranscribeHandler} and\n * hands the transcript back via `onText`.\n *\n * Click to start recording, which prompts for mic permission, and again to stop\n * and transcribe. The button reflects its `idle` / `recording` / `transcribing`\n * state on `data-state` for theming and is exposed as `part=\"voice-button\"`; a\n * capture or transcription failure returns it to idle and surfaces the message\n * on its tooltip.\n *\n * Pure DOM. The host mounts {@link element} in the input row.\n */\nexport class VoiceInput {\n /** The mic button; mount this in the composer. */\n readonly element: HTMLButtonElement;\n\n readonly #transcribe: TranscribeHandler;\n readonly #onText: (text: string) => void;\n readonly #strings: UiStrings;\n #state: VoiceState = \"idle\";\n #recorder: MediaRecorder | null = null;\n #stream: MediaStream | null = null;\n #chunks: Blob[] = [];\n #disposed = false;\n\n constructor(options: VoiceInputOptions) {\n this.#transcribe = options.transcribe;\n this.#onText = options.onText;\n this.#strings = options.strings ?? DEFAULT_UI_STRINGS;\n\n this.element = document.createElement(\"button\");\n this.element.type = \"button\";\n this.element.className = \"voice-btn\";\n this.element.setAttribute(\"part\", \"voice-button\");\n // The mic glyph, in a slot so a host can project its own mark. Author-written\n // constant markup, never user or server data.\n const glyph = document.createElement(\"slot\");\n glyph.name = \"icon-voice\";\n glyph.innerHTML = ICON_VOICE;\n this.element.append(glyph);\n this.#setState(\"idle\");\n this.element.addEventListener(\"click\", () => {\n void this.toggle();\n });\n }\n\n /** Start recording when idle, stop (and transcribe) when recording. */\n async toggle(): Promise<void> {\n if (this.#state === \"recording\") {\n this.#stop();\n return;\n }\n if (this.#state === \"transcribing\") {\n return;\n }\n await this.#start();\n }\n\n async #start(): Promise<void> {\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch {\n this.#fail(this.#strings.transcriptionFailed);\n return;\n }\n this.#stream = stream;\n this.#chunks = [];\n const recorder = new MediaRecorder(stream);\n recorder.addEventListener(\"dataavailable\", (event) => {\n this.#chunks.push(event.data);\n });\n recorder.addEventListener(\"stop\", () => {\n void this.#finish(recorder.mimeType);\n });\n this.#recorder = recorder;\n recorder.start();\n this.#setState(\"recording\");\n }\n\n #stop(): void {\n // ``stop`` flushes a final ``dataavailable`` then fires ``stop`` \u2192 #finish.\n this.#recorder?.stop();\n }\n\n /**\n * Tear the control down, for a host element removed mid-recording. Stops any\n * live `MediaRecorder`, releases the mic tracks so the browser's recording\n * indicator clears, and suppresses the pending transcription \u2014 a\n * disconnected control must not fire `onText` into a detached element.\n */\n dispose(): void {\n this.#disposed = true;\n if (this.#recorder !== null && this.#recorder.state !== \"inactive\") {\n this.#recorder.stop();\n }\n this.#recorder = null;\n this.#releaseStream();\n }\n\n async #finish(mimeType: string): Promise<void> {\n if (this.#disposed) {\n return;\n }\n this.#releaseStream();\n this.#setState(\"transcribing\");\n const audio = new Blob(this.#chunks, { type: mimeType || \"audio/webm\" });\n try {\n const text = await this.#transcribe(audio);\n this.#setState(\"idle\");\n if (text !== \"\") {\n this.#onText(text);\n }\n } catch (error) {\n this.#fail(error instanceof Error ? error.message : this.#strings.transcriptionFailed);\n } finally {\n this.#recorder = null;\n }\n }\n\n /** Stop the mic tracks so the browser's recording indicator clears. */\n #releaseStream(): void {\n for (const track of this.#stream?.getTracks() ?? []) {\n track.stop();\n }\n this.#stream = null;\n }\n\n #fail(message: string): void {\n this.#releaseStream();\n this.#recorder = null;\n this.#setState(\"idle\");\n this.element.title = message;\n }\n\n #setState(state: VoiceState): void {\n this.#state = state;\n this.element.dataset[\"state\"] = state;\n const label = this.#labelFor(state);\n this.element.title = label;\n this.element.setAttribute(\"aria-label\", label);\n this.element.setAttribute(\"aria-pressed\", String(state === \"recording\"));\n // The control is inert while a clip transcribes (no second recording yet).\n this.element.disabled = state === \"transcribing\";\n }\n\n #labelFor(state: VoiceState): string {\n if (state === \"recording\") {\n return this.#strings.stopRecording;\n }\n if (state === \"transcribing\") {\n return this.#strings.transcribing;\n }\n return this.#strings.recordVoice;\n }\n}\n", "import {\n type AbstractAgent,\n type AgentSubscriber,\n buildResumeArray,\n type RunAgentParameters,\n randomUUID,\n} from \"@ag-ui/client\";\nimport type { Context, Interrupt, Message, ResumeEntry, Tool } from \"@ag-ui/core\";\nimport { MAX_TOOL_ROUNDS } from \"../constants.js\";\nimport type { AttachmentRef } from \"./attachment.js\";\n\n/** A tool call surfaced to the host by {@link AgUiClient}. */\nexport interface AgUiToolCall {\n readonly id: string;\n readonly name: string;\n readonly args: Record<string, unknown>;\n}\n\n/** The result of executing a frontend tool, destined for a tool-result message. */\nexport interface ToolExecution {\n /** String content for the AG-UI tool-result message. */\n content: string;\n /** Present when the handler failed; surfaced for logging. */\n error?: string;\n /**\n * When `true`, a navigating tool triggered a page reload. The loop stops\n * without appending a result \u2014 the result is supplied after the next mount\n * (see the resume path). Mutually exclusive with a usable `content`.\n */\n halt?: boolean;\n}\n\n/**\n * Executes a frontend tool call.\n *\n * Returns the {@link ToolExecution} to post back to the agent, or `null` when\n * the call is not a frontend tool the host owns \u2014 a server-side tool the server\n * already executed, which the client must not re-run.\n */\nexport type ExecuteTool = (call: AgUiToolCall) => Promise<ToolExecution | null>;\n\n/**\n * One user decision for a server-side-tool approval interrupt. Structurally\n * matches `@ag-ui/client`'s (non-exported) `ResumeResponse`, the payload\n * {@link buildResumeArray} turns into a `ResumeEntry`: `resolved` approves (with\n * an optional `payload`, e.g. `{ approved: true }`), `cancelled` denies.\n */\nexport type InterruptResponse = { status: \"resolved\"; payload?: unknown } | { status: \"cancelled\" };\n\n/**\n * Resolves the approval interrupts a run finished on, keyed by interrupt id.\n *\n * A gated server-side tool defers instead of executing, so the run finishes on\n * an interrupt outcome; the host collects one decision per interrupt and the\n * loop resumes with the answers. Omit for agents that never gate server-side\n * tools \u2014 an unresolved interrupt then ends the loop.\n */\nexport type ResolveInterrupts = (\n interrupts: readonly Interrupt[],\n) => Promise<Record<string, InterruptResponse>>;\n\n/**\n * Callbacks the {@link AgUiClient} invokes as a run progresses. The host\n * (the `<ag-ui-chat>` element) implements these to render streaming text and\n * tool activity into the chat.\n */\nexport interface AgUiClientHandlers {\n onRunStart(): void;\n /** Fired on every streamed token; `buffer` is the full text so far. */\n onTextDelta(buffer: string): void;\n /** Fired when the assistant message completes; `buffer` is the final text. */\n onTextEnd(buffer: string): void;\n /** Fired when the agent finishes calling a tool (server- or frontend-side). */\n onToolCall(call: AgUiToolCall): void;\n /**\n * Fired when a server-side tool's result streams back (AG-UI's\n * `TOOL_CALL_RESULT`). Frontend tools don't emit this \u2014 the client supplies\n * their result itself \u2014 so this is the channel for server-executed output.\n */\n onToolResult(toolCallId: string, content: string): void;\n /**\n * Fired for AG-UI activity events \u2014 ambient notices about what the *run* did,\n * as opposed to work the agent asked for. `django-ag-ui` emits one with\n * `activityType: \"compaction\"` when it condensed the history.\n */\n onActivity(activityType: string, content: unknown): void;\n /** Fired when a reasoning model starts emitting its chain-of-thought. */\n onReasoningStart(): void;\n /** Fired on every reasoning token; ``buffer`` is the full reasoning text so far. */\n onReasoningDelta(buffer: string): void;\n /** Fired when the reasoning block ends (before the answer text streams). */\n onReasoningEnd(): void;\n onRunEnd(): void;\n onError(message: string): void;\n /**\n * Fired when the user cancelled the run ({@link AgUiClient.cancel}) \u2014 the\n * deliberate-stop sibling of `onError`. Partial assistant text already\n * streamed stays valid, so the host keeps the bubble and shows a stopped\n * affordance rather than an error. `onSettled` still follows.\n */\n onCancelled(): void;\n /**\n * Fired exactly once when the interaction settles, however the run loop ended\n * \u2014 server-only round, rounds exhausted, cancellation, or error. The terminal\n * guarantee that the UI returns to rest.\n */\n onSettled(): void;\n}\n\n/**\n * Provider of the per-run frontend tool catalog and context. Both are read\n * fresh on every {@link AgUiClient.send} so the catalog reflects the current\n * page state.\n */\nexport interface AgUiRunInputs {\n getTools?: () => Tool[];\n getContext?: () => Context[];\n}\n\nexport interface AgUiClientConfig extends AgUiRunInputs {\n /** The AG-UI agent to drive. Injected so it can be faked in tests. */\n agent: AbstractAgent;\n handlers: AgUiClientHandlers;\n /** Executes frontend tool calls. Omit for server-only tool sets. */\n executeTool?: ExecuteTool;\n /**\n * Resolves server-side-tool approval interrupts. Omit when no server-side\n * tool is gated for approval \u2014 an interrupt then ends the loop unanswered.\n */\n resolveInterrupts?: ResolveInterrupts;\n /**\n * Invoked with the latest history whenever it changes, so the host can\n * persist it for durability across page reloads. Omit to keep the\n * conversation in-memory only.\n */\n onPersist?: (messages: readonly Message[]) => void;\n /**\n * Called whenever AG-UI shared state changes \u2014 a streamed `STATE_SNAPSHOT` /\n * `STATE_DELTA`, or {@link AgUiClient.setState}. `@ag-ui/client` owns applying\n * those events; this only forwards the result.\n */\n onStateChanged?: (state: Readonly<Record<string, unknown>>) => void;\n /**\n * Error text for {@link AgUiClientHandlers.onError} when a run's stream closes\n * without a terminal AG-UI event. Defaults to `\"Connection lost\"`; the host\n * passes its localized string.\n */\n connectionLostMessage?: string;\n}\n\n/**\n * Raised when a run's stream closes cleanly at the transport level but never\n * emits a terminal AG-UI event, so the run neither finished nor errored. Routed\n * to {@link AgUiClientHandlers.onError} (it is not an abort), turning a silent\n * \"stuck pending\" into a visible \"connection lost\".\n */\nexport class ConnectionLostError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConnectionLostError\";\n }\n}\n\n/**\n * Thin orchestration layer over an AG-UI {@link AbstractAgent}.\n *\n * Translates AG-UI's subscriber callbacks into the host's\n * {@link AgUiClientHandlers}, and appends the user message + current frontend\n * tool catalog + context to each run.\n */\nexport class AgUiClient {\n readonly #agent: AbstractAgent;\n readonly #handlers: AgUiClientHandlers;\n readonly #getTools: () => Tool[];\n readonly #getContext: () => Context[];\n readonly #executeTool: ExecuteTool | null;\n readonly #resolveInterrupts: ResolveInterrupts | null;\n readonly #onPersist: (messages: readonly Message[]) => void;\n /**\n * Message ids the server has already closed, so a reuse can be reported. Per\n * client rather than per run \u2014 the merge happens across runs, which a per-run\n * set would miss entirely.\n */\n readonly #closedMessageIds = new Set<string>();\n readonly #connectionLostMessage: string;\n // Set by cancel(); reset at the top of each #run(). Checked by the loop so\n // a cancel between frontend-tool rounds doesn't start another round.\n #cancelled = false;\n\n constructor(config: AgUiClientConfig) {\n this.#agent = config.agent;\n this.#handlers = config.handlers;\n this.#getTools = config.getTools ?? (() => []);\n this.#getContext = config.getContext ?? (() => []);\n this.#executeTool = config.executeTool ?? null;\n this.#resolveInterrupts = config.resolveInterrupts ?? null;\n this.#onPersist = config.onPersist ?? (() => {});\n this.#connectionLostMessage = config.connectionLostMessage ?? \"Connection lost\";\n const onStateChanged = config.onStateChanged;\n if (onStateChanged !== undefined) {\n // The agent applies STATE_SNAPSHOT / STATE_DELTA itself; subscribing is\n // how the result is learned rather than re-derived from the event stream.\n // Lives for the agent's lifetime, which is this client's.\n this.#agent.subscribe({\n onStateChanged: ({ state }) => {\n onStateChanged(state as Record<string, unknown>);\n },\n });\n }\n }\n\n /** The current AG-UI shared state, as the agent last applied it. */\n get state(): Readonly<Record<string, unknown>> {\n return this.#agent.state as Record<string, unknown>;\n }\n\n /** Replace the shared state; the next run sends it as `RunAgentInput.state`. */\n setState(state: Readonly<Record<string, unknown>>): void {\n this.#agent.setState({ ...state });\n }\n\n /** Whether a run is currently in flight. */\n get running(): boolean {\n return this.#agent.isRunning;\n }\n\n /** The current conversation history (for persistence / rehydration). */\n get messages(): readonly Message[] {\n return this.#agent.messages;\n }\n\n /**\n * Append a user message and run the agent to completion.\n *\n * When the agent calls frontend tools, this executes them and re-runs the\n * agent with the results, looping until the agent stops calling frontend\n * tools (bounded by {@link MAX_TOOL_ROUNDS}).\n *\n * `attachments` ride on the user message as a non-standard field so the\n * default store round-trips them for history replay; see\n * {@link messageAttachments}.\n */\n async send(content: string, attachments: readonly AttachmentRef[] = []): Promise<void> {\n // Cast at the AG-UI boundary: `attachments` is a web-component augmentation\n // the strict `Message` union doesn't declare, but `addMessage` /\n // `structuredClone` preserve it verbatim.\n const message = { id: randomUUID(), role: \"user\", content } as Message;\n if (attachments.length > 0) {\n (message as { attachments?: readonly AttachmentRef[] }).attachments = attachments;\n }\n this.#agent.addMessage(message);\n this.#onPersist(this.#agent.messages);\n await this.#run();\n }\n\n /**\n * Resume the run loop after a navigating tool's result was supplied\n * post-reload (via {@link addToolResult}). Unlike {@link send}, adds no user\n * message; it continues the conversation already in history.\n */\n async resume(): Promise<void> {\n await this.#run();\n }\n\n /** Append a frontend tool result to history (used by the resume path). */\n addToolResult(toolCallId: string, content: string): void {\n this.#agent.addMessage({ id: randomUUID(), role: \"tool\", content, toolCallId });\n this.#onPersist(this.#agent.messages);\n }\n\n /**\n * Cancel the in-flight run (AG-UI has no server cancel route \u2014 aborting the\n * streaming request is the protocol's cancel; the server observes the\n * disconnect). Safe to call with no run in flight. Partial text already\n * streamed stays in history; {@link AgUiClientHandlers.onCancelled} fires\n * instead of `onError`, and `onSettled` still follows.\n */\n cancel(): void {\n this.#cancelled = true;\n this.#agent.abortRun();\n }\n\n async #run(): Promise<void> {\n this.#cancelled = false;\n try {\n await this.#runLoop();\n // `@ag-ui/client` filters abort errors inside `runAgent` (it resolves\n // rather than rejects on a cancelled fetch), so a cancelled run usually\n // ends here, not in the catch.\n if (this.#cancelled) {\n this.#onCancelled();\n }\n } catch (error) {\n if (this.#cancelled || isAbortError(error)) {\n this.#onCancelled();\n } else {\n this.#handlers.onError(error instanceof Error ? error.message : String(error));\n }\n } finally {\n this.#handlers.onSettled();\n }\n }\n\n #onCancelled(): void {\n // Persist so the truncated exchange, partial assistant text included,\n // survives a reload.\n this.#onPersist(this.#agent.messages);\n this.#handlers.onCancelled();\n }\n\n async #runLoop(): Promise<void> {\n // Carries resolved approval answers into the next run when a round finished\n // on a server-side-tool interrupt. Distinct from the public resume(), which\n // continues an unfinished frontend-tool round after a page load; this stays\n // inside one #run().\n let resume: ResumeEntry[] | undefined;\n for (let round = 0; round < MAX_TOOL_ROUNDS; round += 1) {\n // A cancel during the previous round's tool execution lands here: the\n // running handler completed, but no further round starts.\n if (this.#cancelled) {\n return;\n }\n const pending: AgUiToolCall[] = [];\n const runState: RunState = { terminal: false, errored: false, interrupts: [] };\n const params: RunAgentParameters = {\n tools: this.#getTools(),\n context: this.#getContext(),\n };\n if (resume !== undefined) {\n params.resume = resume;\n }\n await this.#agent.runAgent(params, this.#buildSubscriber(pending, runState));\n resume = undefined;\n this.#onPersist(this.#agent.messages);\n // Cancelled mid-stream: don't execute the tool calls collected before the\n // abort.\n if (this.#cancelled) {\n return;\n }\n // The stream resolved without RUN_FINISHED / RUN_ERROR, so the transport\n // dropped mid-run. Surface it as an error (via #run) rather than resting\n // silently with a stuck pending indicator.\n if (!runState.terminal) {\n throw new ConnectionLostError(this.#connectionLostMessage);\n }\n // RUN_ERROR is terminal and the agent already reported it via onError.\n // Executing the calls collected before it, or starting another round,\n // would run into a broken context and raise a confusing second error.\n // Pending tool cards are swept at onSettled.\n if (runState.errored) {\n return;\n }\n // A gated server-side tool deferred, so the run finished on an interrupt\n // outcome: resolve each interrupt, then re-enter carrying the answers so\n // the follow-up run executes or denies the tool. Must precede the\n // frontend-tool sweep below \u2014 a server-side tool isn't ours to run.\n if (runState.interrupts.length > 0) {\n if (this.#resolveInterrupts === null) {\n return;\n }\n const responses = await this.#resolveInterrupts(runState.interrupts);\n if (this.#cancelled) {\n return;\n }\n resume = buildResumeArray(runState.interrupts, responses);\n continue;\n }\n if (this.#executeTool === null || pending.length === 0) {\n return;\n }\n let executed = false;\n for (const call of pending) {\n const result = await this.#executeTool(call);\n if (result === null) {\n continue;\n }\n if (result.halt === true) {\n // A navigating tool reloaded the page; the result arrives on the\n // next mount. Stop here rather than re-running into a dead context.\n return;\n }\n this.#agent.addMessage({\n id: randomUUID(),\n role: \"tool\",\n content: result.content,\n toolCallId: call.id,\n });\n this.#onPersist(this.#agent.messages);\n executed = true;\n }\n if (!executed) {\n return;\n }\n }\n }\n\n #buildSubscriber(pending: AgUiToolCall[], runState: RunState): AgentSubscriber {\n const h = this.#handlers;\n const closed = this.#closedMessageIds;\n return {\n onRunInitialized() {\n h.onRunStart();\n },\n onTextMessageStartEvent({ event }) {\n // A reused message id merges two answers into one persisted transcript\n // entry. The protocol has no rule to enforce and refusing the event\n // would be worse than the merge, so warn and continue \u2014 but do not stay\n // silent, since the corruption outlives the session.\n if (closed.has(event.messageId)) {\n console.warn(\n `<ag-ui-chat>: the server reused message id \"${event.messageId}\", which was ` +\n \"already closed. Its content will be appended to that earlier message rather \" +\n \"than starting a new one, and the merged result is what gets persisted. \" +\n \"Issue a fresh id per message.\",\n );\n }\n },\n onTextMessageContentEvent({ textMessageBuffer }) {\n h.onTextDelta(textMessageBuffer);\n },\n onTextMessageEndEvent({ event, textMessageBuffer }) {\n closed.add(event.messageId);\n h.onTextEnd(textMessageBuffer);\n },\n onToolCallEndEvent({ event, toolCallName, toolCallArgs }) {\n const call: AgUiToolCall = {\n id: event.toolCallId,\n name: toolCallName,\n args: toolCallArgs,\n };\n pending.push(call);\n h.onToolCall(call);\n },\n onToolCallResultEvent({ event }) {\n h.onToolResult(event.toolCallId, event.content);\n },\n onActivitySnapshotEvent({ event }) {\n h.onActivity(event.activityType, event.content);\n },\n // `@ag-ui/client` maps the deprecated THINKING_* events onto these\n // REASONING_* callbacks, so the reasoning family alone covers both\n // protocol versions.\n onReasoningStartEvent() {\n h.onReasoningStart();\n },\n onReasoningMessageContentEvent({ reasoningMessageBuffer }) {\n h.onReasoningDelta(reasoningMessageBuffer);\n },\n onReasoningEndEvent() {\n h.onReasoningEnd();\n },\n onRunFinishedEvent(params) {\n // RUN_FINISHED is terminal for both a normal finish and an interrupt.\n // Capture the interrupts here rather than reading the agent's\n // `pendingInterrupts` afterwards, to stay independent of that field's\n // cross-run clearing semantics.\n runState.terminal = true;\n if (params.outcome === \"interrupt\") {\n runState.interrupts = params.interrupts;\n }\n },\n onRunErrorEvent({ event }) {\n runState.terminal = true;\n runState.errored = true;\n h.onError(event.message);\n },\n onRunFinalized() {\n runState.terminal = true;\n h.onRunEnd();\n },\n };\n }\n}\n\n/** Per-run mutable flags the subscriber writes and {@link AgUiClient} reads. */\ninterface RunState {\n terminal: boolean;\n errored: boolean;\n /** Approval interrupts a run finished on (empty for a normal finish). */\n interrupts: Interrupt[];\n}\n\n/**\n * Whether a rejection came from aborting the run's fetch. Belt-and-suspenders\n * with the `#cancelled` flag: some `@ag-ui/client` versions re-throw the\n * `AbortError` instead of filtering it.\n */\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === \"AbortError\";\n}\n", "import type { Message } from \"@ag-ui/core\";\n\n/**\n * A durable, lightweight reference to one uploaded file \u2014 what an upload\n * returns and what rides on a sent message, never the bytes.\n *\n * Mirrors django-ag-ui's `AttachmentRef`: the file uploads out-of-band to the\n * attachments endpoint, the server hands back this ref, and the agent reads the\n * content server-side via the `read_attachment` tool.\n */\nexport interface AttachmentRef {\n /** Opaque, owner-scoped handle the server resolves back to bytes. */\n readonly id: string;\n /** Original filename, for display on the chip. */\n readonly name: string;\n /** Declared content type (a hint \u2014 the server is authoritative). */\n readonly mime: string;\n /** Size in bytes. */\n readonly size: number;\n /** Optional direct fetch URL (the owner-checked download endpoint). */\n readonly url?: string;\n}\n\n/**\n * The attachment refs a user message carries.\n *\n * Refs ride on the message as a non-standard `attachments` field, which the\n * default store round-trips and `@ag-ui/client` preserves through `addMessage`\n * / `structuredClone`, so a restored conversation re-renders its chips. The\n * server's strict `RunAgentInput` validation ignores the unknown field.\n *\n * Storage is untrusted \u2014 hand-edited, truncated, or corrupted \u2014 so malformed\n * entries are dropped here; a shapeless one would throw in `iconFor` and abort\n * the whole history replay.\n */\nexport function messageAttachments(message: Message): readonly AttachmentRef[] {\n const refs = (message as { attachments?: unknown }).attachments;\n return Array.isArray(refs) ? refs.filter(isAttachmentRef) : [];\n}\n\n/** Whether an unknown value is a structurally valid {@link AttachmentRef}. */\nfunction isAttachmentRef(value: unknown): value is AttachmentRef {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const ref = value as Record<string, unknown>;\n return (\n typeof ref[\"id\"] === \"string\" &&\n typeof ref[\"name\"] === \"string\" &&\n typeof ref[\"mime\"] === \"string\" &&\n typeof ref[\"size\"] === \"number\" &&\n (ref[\"url\"] === undefined || typeof ref[\"url\"] === \"string\")\n );\n}\n", "import { randomUUID } from \"@ag-ui/client\";\nimport type { Message } from \"@ag-ui/core\";\n\n/**\n * A checkpoint recorded just before a navigating tool reloads the page.\n *\n * The reload destroys the in-memory run loop, so the element persists this\n * marker first; on the next mount it supplies the tool's result and resumes.\n */\nexport interface NavigationCheckpoint {\n /** The tool-call id whose result must be supplied after the reload. */\n readonly toolCallId: string;\n}\n\n/**\n * Lightweight metadata for one conversation \u2014 the thread-drawer row shape, so\n * the drawer renders without loading message bodies. `title` defaults to a\n * truncation of the first user message until an explicit rename, `preview` is a\n * one-line excerpt of the latest message, and `updatedAt` is epoch ms of the\n * last change, which orders the list.\n */\nexport interface ThreadMeta {\n readonly threadId: string;\n readonly title: string;\n readonly updatedAt: number;\n readonly preview: string;\n}\n\n/**\n * Client-side persistence seam for the conversation and a pending-navigation\n * checkpoint, keyed by `thread_id`.\n *\n * The default {@link SessionStorageStore} keeps everything per-tab. A host may\n * inject a server-backed store instead, which is why `loadMessages` and\n * `listThreads` are async. The checkpoint methods stay synchronous: the marker\n * is a small local hint a server store can derive from history and no-op.\n *\n * Thread enumeration backs the chat-history drawer; deleting a thread reuses\n * {@link clear} and \"new chat\" reuses {@link threadId} after clearing the\n * active thread.\n */\nexport interface ClientConversationStore {\n /** The active conversation id, generated and persisted on first read. */\n threadId(): string;\n /** Load the persisted message history, or `null` when none exists. */\n loadMessages(threadId: string): Promise<readonly Message[] | null>;\n /** Persist the message history (and refresh the thread's drawer metadata). */\n saveMessages(threadId: string, messages: readonly Message[]): void;\n /** Load the pending-navigation checkpoint, or `null` when none is set. */\n loadCheckpoint(threadId: string): NavigationCheckpoint | null;\n /** Set the pending-navigation checkpoint, or clear it when given `null`. */\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void;\n /** Forget the conversation and checkpoint (a \"delete thread\" / \"new chat\"). */\n clear(threadId: string): void;\n /** The user's threads as drawer metadata (no message bodies), newest first. */\n listThreads(): Promise<readonly ThreadMeta[]>;\n /** Make `threadId` the active conversation (the drawer selecting a row). */\n setActiveThread(threadId: string): void;\n /** Set a thread's display title (the drawer renaming a row). */\n renameThread(threadId: string, title: string): void;\n /**\n * Whether `threadId` was minted here and has never been saved \u2014 a thread in\n * which nothing has been sent yet.\n *\n * Exists so a server-backed store can skip asking a server for history that\n * cannot be there: the element mints an id on first mount and immediately tries\n * to restore it, which answers `404` and logs one in the console on every first\n * visit. Nothing is wrong, and it looks exactly like something being wrong.\n *\n * Optional, and deliberately narrow. A store that cannot tell omits it and the\n * fetch happens as before, which is also the right answer for a store that\n * holds nothing locally: \"I have no messages for this id\" is not the same claim\n * as \"this id is new\", and only the store that minted the id can make the\n * second one. A thread picked from the drawer was never minted here, so it is\n * still fetched.\n */\n isUnsent?(threadId: string): boolean;\n}\n\nconst KEY_ROOT = \"ag-ui-chat\";\nconst THREAD_SUFFIX = \"thread\";\nconst THREADS_SUFFIX = \"threads\";\nconst MESSAGES_SUFFIX = \"messages:\";\nconst CHECKPOINT_SUFFIX = \"checkpoint:\";\n// Marks an id this store minted and nothing has been sent in yet. Dropped on\n// the first save, so it never outlives the one question it answers.\nconst MINTED_SUFFIX = \"minted:\";\n\nconst TITLE_LIMIT = 60;\nconst PREVIEW_LIMIT = 100;\nconst DEFAULT_TITLE = \"New conversation\";\n\n/** The drawer-index entry; `titleCustom` (private) freezes a renamed title. */\ninterface StoredThread {\n threadId: string;\n title: string;\n titleCustom: boolean;\n preview: string;\n updatedAt: number;\n}\n\n/**\n * Default {@link ClientConversationStore}: per-tab `sessionStorage`.\n *\n * Survives full page reloads and same-tab navigation, clears on tab close.\n * Tracks multiple threads per tab: the active id under one key, message history\n * and checkpoint namespaced by id, and a small index feeding the drawer with no\n * server involved.\n *\n * An optional `namespace` scopes every key to one element, so two\n * `<ag-ui-chat>` instances on the same origin keep separate active-thread\n * pointers and drawer indexes instead of clobbering each other. The default\n * empty namespace keeps the origin-global keys; see {@link #migrateLegacyKeys}.\n */\nexport class SessionStorageStore implements ClientConversationStore {\n readonly #root: string;\n\n constructor(namespace = \"\") {\n this.#root = namespace === \"\" ? KEY_ROOT : `${KEY_ROOT}@${namespace}`;\n if (namespace !== \"\") {\n this.#migrateLegacyKeys();\n }\n }\n\n threadId(): string {\n const key = this.#key(THREAD_SUFFIX);\n const existing = sessionStorage.getItem(key);\n if (existing !== null) {\n return existing;\n }\n const id = randomUUID();\n sessionStorage.setItem(key, id);\n sessionStorage.setItem(this.#key(MINTED_SUFFIX + id), \"1\");\n return id;\n }\n\n isUnsent(threadId: string): boolean {\n return (\n sessionStorage.getItem(this.#key(MINTED_SUFFIX + threadId)) !== null &&\n sessionStorage.getItem(this.#key(MESSAGES_SUFFIX + threadId)) === null\n );\n }\n\n loadMessages(threadId: string): Promise<readonly Message[] | null> {\n return Promise.resolve(this.#readJson<Message[]>(this.#key(MESSAGES_SUFFIX + threadId)));\n }\n\n saveMessages(threadId: string, messages: readonly Message[]): void {\n sessionStorage.setItem(this.#key(MESSAGES_SUFFIX + threadId), JSON.stringify(messages));\n sessionStorage.removeItem(this.#key(MINTED_SUFFIX + threadId));\n this.#touchThread(threadId, messages);\n }\n\n loadCheckpoint(threadId: string): NavigationCheckpoint | null {\n return this.#readJson<NavigationCheckpoint>(this.#key(CHECKPOINT_SUFFIX + threadId));\n }\n\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void {\n const key = this.#key(CHECKPOINT_SUFFIX + threadId);\n if (checkpoint === null) {\n sessionStorage.removeItem(key);\n return;\n }\n sessionStorage.setItem(key, JSON.stringify(checkpoint));\n }\n\n clear(threadId: string): void {\n sessionStorage.removeItem(this.#key(MESSAGES_SUFFIX + threadId));\n sessionStorage.removeItem(this.#key(CHECKPOINT_SUFFIX + threadId));\n sessionStorage.removeItem(this.#key(MINTED_SUFFIX + threadId));\n this.#writeThreads(this.#readThreads().filter((thread) => thread.threadId !== threadId));\n // Only drop the active pointer when the active thread itself is cleared, so\n // the next `threadId()` mints a fresh one. Deleting another thread from the\n // drawer must not disturb the conversation on screen.\n if (sessionStorage.getItem(this.#key(THREAD_SUFFIX)) === threadId) {\n sessionStorage.removeItem(this.#key(THREAD_SUFFIX));\n }\n }\n\n listThreads(): Promise<readonly ThreadMeta[]> {\n const metas = this.#readThreads()\n .sort((a, b) => b.updatedAt - a.updatedAt)\n .map(({ threadId, title, updatedAt, preview }) => ({ threadId, title, updatedAt, preview }));\n return Promise.resolve(metas);\n }\n\n setActiveThread(threadId: string): void {\n sessionStorage.setItem(this.#key(THREAD_SUFFIX), threadId);\n }\n\n renameThread(threadId: string, title: string): void {\n const threads = this.#readThreads();\n const entry = threads.find((thread) => thread.threadId === threadId);\n if (entry === undefined) {\n return;\n }\n entry.title = title;\n entry.titleCustom = true;\n this.#writeThreads(threads);\n }\n\n /** Add or refresh a thread's drawer metadata from its latest messages. */\n #touchThread(threadId: string, messages: readonly Message[]): void {\n const threads = this.#readThreads();\n const entry = threads.find((thread) => thread.threadId === threadId);\n const preview = derivePreview(messages);\n const updatedAt = Date.now();\n if (entry === undefined) {\n threads.push({\n threadId,\n title: deriveTitle(messages),\n titleCustom: false,\n preview,\n updatedAt,\n });\n } else {\n entry.preview = preview;\n entry.updatedAt = updatedAt;\n if (!entry.titleCustom) {\n entry.title = deriveTitle(messages);\n }\n }\n this.#writeThreads(threads);\n }\n\n #readThreads(): StoredThread[] {\n return this.#readJson<StoredThread[]>(this.#key(THREADS_SUFFIX)) ?? [];\n }\n\n #writeThreads(threads: readonly StoredThread[]): void {\n const key = this.#key(THREADS_SUFFIX);\n if (threads.length === 0) {\n sessionStorage.removeItem(key);\n return;\n }\n sessionStorage.setItem(key, JSON.stringify(threads));\n }\n\n /** This store's fully-qualified key for a suffix (namespaced when set). */\n #key(suffix: string): string {\n return `${this.#root}:${suffix}`;\n }\n\n /**\n * One-time move of un-namespaced `ag-ui-chat:*` keys into this instance's\n * namespace, so an existing conversation isn't orphaned. Only this store's own\n * keys move \u2014 the element's `collapsed` / `theme` keys are left alone. The\n * first namespaced instance to mount adopts the data; a second namespace\n * finds it gone and starts fresh.\n */\n #migrateLegacyKeys(): void {\n const legacyRoot = `${KEY_ROOT}:`;\n const moves: Array<readonly [string, string]> = [];\n for (let i = 0; i < sessionStorage.length; i += 1) {\n const key = sessionStorage.key(i);\n if (key === null || !key.startsWith(legacyRoot)) {\n continue;\n }\n const suffix = key.slice(legacyRoot.length);\n if (isOwnedSuffix(suffix)) {\n moves.push([key, this.#key(suffix)]);\n }\n }\n // Collected first, mutated second \u2014 writing while iterating by index skips\n // entries as the key list shifts.\n for (const [from, to] of moves) {\n const value = sessionStorage.getItem(from);\n if (value !== null && sessionStorage.getItem(to) === null) {\n sessionStorage.setItem(to, value);\n }\n sessionStorage.removeItem(from);\n }\n }\n\n /** Parse a stored JSON value, returning `null` when absent or corrupt. */\n #readJson<T>(key: string): T | null {\n const raw = sessionStorage.getItem(key);\n if (raw === null) {\n return null;\n }\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n }\n}\n\n/** Whether a legacy key suffix belongs to the store (vs the element's own keys). */\nfunction isOwnedSuffix(suffix: string): boolean {\n return (\n suffix === THREAD_SUFFIX ||\n suffix === THREADS_SUFFIX ||\n suffix.startsWith(MESSAGES_SUFFIX) ||\n suffix.startsWith(CHECKPOINT_SUFFIX)\n );\n}\n\n/** The thread title: the first user message, collapsed + truncated. */\nfunction deriveTitle(messages: readonly Message[]): string {\n for (const message of messages) {\n if (message.role === \"user\") {\n const text = cleanText(message.content);\n if (text !== \"\") {\n return truncate(text, TITLE_LIMIT);\n }\n }\n }\n return DEFAULT_TITLE;\n}\n\n/** A one-line preview: the latest message with text, collapsed + truncated. */\nfunction derivePreview(messages: readonly Message[]): string {\n for (const message of [...messages].reverse()) {\n const text = cleanText(message.content);\n if (text !== \"\") {\n return truncate(text, PREVIEW_LIMIT);\n }\n }\n return \"\";\n}\n\n/** Whitespace-collapsed message text, or `\"\"` for non-string content. */\nfunction cleanText(content: unknown): string {\n return typeof content === \"string\" ? content.replace(/\\s+/g, \" \").trim() : \"\";\n}\n\nfunction truncate(text: string, limit: number): string {\n return text.length <= limit ? text : `${text.slice(0, limit - 1).trimEnd()}\u2026`;\n}\n", "import { type AbstractAgent, HttpAgent } from \"@ag-ui/client\";\nimport type { Message } from \"@ag-ui/core\";\nimport { withCredentials } from \"./utils.js\";\n\n/** Config for {@link createHttpAgent}. */\nexport interface HttpAgentOptions {\n endpoint: string;\n headers?: Record<string, string>;\n /**\n * Cookie policy for the run request, as `fetch`'s own `credentials` mode.\n * Unset leaves the browser default (`same-origin`), which sends no cookies\n * to an agent endpoint on a different origin or subdomain. A\n * cookie-authenticated cross-origin deployment needs `\"include\"` here plus a\n * server answering with `Access-Control-Allow-Credentials: true` and a\n * concrete origin.\n */\n credentials?: RequestCredentials;\n /**\n * Live header source, re-read on every request, overlaid on `headers`.\n * `HttpAgent` bakes static `headers` in at construction and the element\n * caches the agent for the whole conversation, so rotating credentials (CSRF,\n * short-lived JWT) must come through here.\n */\n getHeaders?: () => Record<string, string>;\n /** Stable conversation id, so the agent's runs share a thread. */\n threadId?: string;\n /** Rehydrated history to seed the agent with (durable conversation). */\n initialMessages?: readonly Message[];\n /**\n * AG-UI shared state to seed the agent with. `@ag-ui/client` sends it as\n * `RunAgentInput.state` on every run and replaces it in place when the\n * server streams `STATE_SNAPSHOT` / `STATE_DELTA`.\n */\n initialState?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Build an AG-UI {@link HttpAgent} pointed at `endpoint`.\n *\n * The default agent factory for `<ag-ui-chat>`; tests and advanced hosts\n * override the element's `agentFactory` to inject a different\n * {@link AbstractAgent}.\n */\nexport function createHttpAgent(options: HttpAgentOptions): AbstractAgent {\n return new HttpAgent({\n url: options.endpoint,\n headers: options.headers ?? {},\n initialState: { ...(options.initialState ?? {}) },\n // HttpAgent invokes its configured fetch as a method (`this.fetch(...)`),\n // rebinding the global `fetch` to the agent instance \u2014 \"Illegal invocation\"\n // in browsers. The wrapper keeps `fetch` a free call, and is also where the\n // per-request `getHeaders()` overlay and the cookie policy go, the agent's\n // own config having no seam for either.\n fetch: (url, init) => {\n const fresh = options.getHeaders?.();\n if (fresh === undefined) {\n return fetch(url, withCredentials(init, options.credentials));\n }\n const headers = new Headers(init?.headers);\n for (const [name, value] of Object.entries(fresh)) {\n headers.set(name, value);\n }\n return fetch(url, withCredentials({ ...init, headers }, options.credentials));\n },\n // Spread conditionally: under `exactOptionalPropertyTypes` an explicit\n // `undefined` is not assignable to an optional field.\n ...(options.threadId !== undefined ? { threadId: options.threadId } : {}),\n ...(options.initialMessages !== undefined\n ? { initialMessages: [...options.initialMessages] }\n : {}),\n });\n}\n\n/** Signature of the agent factory the element calls to build its agent. */\nexport type AgentFactory = (options: HttpAgentOptions) => AbstractAgent;\n", "// Non-exported-from-index helpers shared by the core transport modules.\n\n/**\n * Overlay a `credentials` mode onto a fetch `init`, or hand the `init` back\n * untouched when none is configured.\n *\n * Absent and `undefined` differ: `exactOptionalPropertyTypes` rejects an\n * explicit `credentials: undefined`, and writing one anyway would state a mode\n * where the point is to leave the browser's own default in place.\n */\nexport function withCredentials(\n init: RequestInit | undefined,\n credentials: RequestCredentials | undefined,\n): RequestInit | undefined {\n return credentials === undefined ? init : { ...init, credentials };\n}\n", "import type { Message } from \"@ag-ui/core\";\nimport {\n type ClientConversationStore,\n type NavigationCheckpoint,\n SessionStorageStore,\n type ThreadMeta,\n} from \"./conversation_store.js\";\nimport { withCredentials } from \"./utils.js\";\n\n/** One row of the server thread index (django-ag-ui's `ThreadsView` wire shape). */\ninterface ServerThreadRow {\n readonly thread_id: string;\n readonly title: string;\n readonly updated_at: string | null;\n readonly preview: string;\n}\n\n/** Live header source, read per request so rotated tokens / CSRF reach the server. */\ntype HeadersProvider = () => Record<string, string>;\n\n/**\n * Live cookie policy, read per request. A provider rather than a value: the\n * store is built once on connect, but a host may configure the element after\n * inserting it, and a captured value would pin that first frame's setting.\n */\ntype CredentialsProvider = () => RequestCredentials | undefined;\n\n/**\n * A {@link ClientConversationStore} backed by a server thread-index endpoint \u2014\n * django-ag-ui's owner-scoped `ThreadsView`, the URL passed to `<ag-ui-chat>`\n * as `data-threads-url`:\n *\n * - `GET <url>` \u2192 list the user's threads (metadata only);\n * - `GET <url><id>/` \u2192 that thread's messages;\n * - `PATCH <url><id>/` \u2192 rename (`{ \"title\": \u2026 }`);\n * - `DELETE <url><id>/` \u2192 delete.\n *\n * Wraps a local store (default {@link SessionStorageStore}) for the client-only\n * concerns \u2014 active thread id, navigation checkpoint, message cache \u2014 and as\n * the fallback when a request fails. Rename and delete apply optimistically via\n * a local overlay, so the drawer reflects them before the fire-and-forget\n * round-trip lands.\n */\nexport class RemoteConversationStore implements ClientConversationStore {\n readonly #url: string;\n readonly #headers: HeadersProvider;\n readonly #local: ClientConversationStore;\n readonly #credentials: CredentialsProvider;\n readonly #dropped = new Set<string>();\n readonly #renamed = new Map<string, string>();\n\n constructor(\n url: string,\n headers: HeadersProvider = () => ({}),\n local: ClientConversationStore = new SessionStorageStore(),\n credentials: CredentialsProvider = () => undefined,\n ) {\n this.#url = url.endsWith(\"/\") ? url : `${url}/`;\n this.#headers = headers;\n this.#local = local;\n this.#credentials = credentials;\n }\n\n threadId(): string {\n return this.#local.threadId();\n }\n\n setActiveThread(threadId: string): void {\n this.#local.setActiveThread(threadId);\n }\n\n /** Delegated, so wrapping a store does not lose what it knows about its own ids. */\n isUnsent(threadId: string): boolean {\n return this.#local.isUnsent?.(threadId) === true;\n }\n\n saveMessages(threadId: string, messages: readonly Message[]): void {\n // The agent run persists server-side; keep a local cache for offline replay.\n this.#local.saveMessages(threadId, messages);\n }\n\n loadCheckpoint(threadId: string): NavigationCheckpoint | null {\n return this.#local.loadCheckpoint(threadId);\n }\n\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void {\n this.#local.saveCheckpoint(threadId, checkpoint);\n }\n\n renameThread(threadId: string, title: string): void {\n this.#local.renameThread(threadId, title);\n this.#renamed.set(threadId, title);\n void this.#mutate(threadId, \"PATCH\", { title });\n }\n\n clear(threadId: string): void {\n this.#local.clear(threadId);\n this.#dropped.add(threadId);\n void this.#mutate(threadId, \"DELETE\");\n }\n\n async listThreads(): Promise<readonly ThreadMeta[]> {\n const rows = await this.#fetchThreads();\n if (rows === null) {\n return this.#local.listThreads();\n }\n return rows.filter((row) => !this.#dropped.has(row.thread_id)).map((row) => this.#toMeta(row));\n }\n\n async loadMessages(threadId: string): Promise<readonly Message[] | null> {\n // Don't ask the server for a thread it cannot have. The element mints an id\n // on first mount and immediately tries to restore it, so every first visit\n // spent a request to be told `404` \u2014 and logged one in the console, on a page\n // where nothing had gone wrong. Only the store that minted the id can say\n // that; a thread chosen from the drawer, or one created on another device, is\n // still fetched. See `ClientConversationStore.isUnsent`.\n if (this.#local.isUnsent?.(threadId) === true) {\n return null;\n }\n const response = await this.#get(`${this.#url}${encodeURIComponent(threadId)}/`);\n if (response === null || !response.ok) {\n return this.#local.loadMessages(threadId);\n }\n // A 200 whose body isn't JSON (a proxy's HTML error page, a truncated\n // stream) must not throw an unhandled rejection that the caller's\n // `void #rehydrate()` swallows; fall back to the local cache.\n const body = await this.#readJson<{ messages?: readonly Message[] }>(response);\n if (body === null) {\n return this.#local.loadMessages(threadId);\n }\n return body.messages ?? null;\n }\n\n async #fetchThreads(): Promise<readonly ServerThreadRow[] | null> {\n const response = await this.#get(this.#url);\n if (response === null || !response.ok) {\n return null;\n }\n const body = await this.#readJson<{ threads?: readonly ServerThreadRow[] }>(response);\n if (body === null) {\n return null;\n }\n return body.threads ?? [];\n }\n\n /** Parse a `Response` body as JSON, or `null` when it isn't valid JSON. */\n async #readJson<T>(response: Response): Promise<T | null> {\n try {\n return (await response.json()) as T;\n } catch {\n return null;\n }\n }\n\n #toMeta(row: ServerThreadRow): ThreadMeta {\n return {\n threadId: row.thread_id,\n title: this.#renamed.get(row.thread_id) ?? row.title,\n // `null` and an unparseable date both become NaN, Date.parse's own\n // signal, which `relativeTime` renders as a neutral label rather than an\n // epoch-0 or NaN duration.\n updatedAt: row.updated_at === null ? Number.NaN : Date.parse(row.updated_at),\n preview: row.preview,\n };\n }\n\n /** GET that resolves to the `Response`, or `null` on a network error. */\n async #get(url: string): Promise<Response | null> {\n try {\n return await fetch(url, withCredentials({ headers: this.#headers() }, this.#credentials()));\n } catch {\n return null;\n }\n }\n\n /** Fire a best-effort write to the thread endpoint; failures are tolerated. */\n async #mutate(\n threadId: string,\n method: \"PATCH\" | \"DELETE\",\n body?: { title: string },\n ): Promise<void> {\n const headers = this.#headers();\n try {\n await fetch(\n `${this.#url}${encodeURIComponent(threadId)}/`,\n withCredentials(\n {\n method,\n headers:\n body === undefined ? headers : { ...headers, \"content-type\": \"application/json\" },\n body: body === undefined ? null : JSON.stringify(body),\n },\n this.#credentials(),\n ),\n );\n } catch {\n // Best-effort; the optimistic overlay keeps the drawer consistent.\n }\n }\n}\n", "import { withCredentials } from \"./utils.js\";\n\n/** One row of the server run index (django-ag-ui's `RunsView` wire shape). */\nexport interface RunRow {\n readonly run_id: string;\n readonly thread_id: string | null;\n readonly parent_run_id: string | null;\n readonly started_at: string | null;\n /** Whether the run has a snapshot to seed from \u2014 see {@link RunIndex}. */\n readonly continuable: boolean;\n /**\n * The run's first user message, one line, already truncated by the server \u2014\n * the only field in a row a person recognises a conversation by.\n *\n * Optional because a server predating the field does not send it, and\n * `null` where the run holds no words to show (seeded from history alone, or\n * opened with an image and no caption). A row without one falls back to the\n * time plus a short id, which is what every row used to be.\n */\n readonly preview?: string | null;\n}\n\n/** Live header source, read per request so rotated tokens / CSRF reach the server. */\ntype HeadersProvider = () => Record<string, string>;\n\n/** Live cookie policy, read per request; see `RemoteConversationStore`'s note. */\ntype CredentialsProvider = () => RequestCredentials | undefined;\n\n/**\n * Reads the server's run index and derives the resume / fork URLs beside it.\n *\n * Backed by django-ag-ui's owner-scoped `RunsView` \u2014 the URL passed to\n * `<ag-ui-chat>` as `data-runs-url`:\n *\n * - `GET <url>` \u2192 the user's runs, newest first.\n *\n * Only `continuable` rows can be resumed: the server reports whether a run has\n * a saved snapshot to seed from, and a run that never reached a provider-valid\n * boundary has none. Offer the action only for those rows ({@link continuable}\n * filters them) and treat the rest as informational.\n *\n * Resume and fork are siblings of the index rather than separate configuration\n * \u2014 django-ag-ui mounts `runs/`, `resume/<id>/` and `fork/<id>/` under one\n * prefix \u2014 so this one URL locates all three.\n */\nexport class RunIndex {\n readonly #url: string;\n readonly #headers: HeadersProvider;\n readonly #credentials: CredentialsProvider;\n\n constructor(\n url: string,\n headers: HeadersProvider = () => ({}),\n credentials: CredentialsProvider = () => undefined,\n ) {\n this.#url = url.endsWith(\"/\") ? url : `${url}/`;\n this.#headers = headers;\n this.#credentials = credentials;\n }\n\n /**\n * The user's runs, or `[]` when the endpoint is unreachable or errors \u2014 the\n * caller renders its empty state rather than a transport fault the user can\n * do nothing about.\n */\n async list(): Promise<readonly RunRow[]> {\n try {\n const response = await fetch(\n this.#url,\n withCredentials(\n {\n method: \"GET\",\n headers: { Accept: \"application/json\", ...this.#headers() },\n },\n this.#credentials(),\n ),\n );\n if (!response.ok) {\n return [];\n }\n const body = (await response.json()) as { runs?: readonly RunRow[] };\n return body.runs ?? [];\n } catch {\n return [];\n }\n }\n\n /** The rows a client may actually continue. */\n async continuable(): Promise<readonly RunRow[]> {\n return (await this.list()).filter((run) => run.continuable);\n }\n\n /** The endpoint that continues `runId` as a new run. */\n resumeUrl(runId: string): string {\n return this.#sibling(\"resume\", runId);\n }\n\n /** The endpoint that branches `runId` into a new run, leaving the source untouched. */\n forkUrl(runId: string): string {\n return this.#sibling(\"fork\", runId);\n }\n\n /**\n * `<mount>/<verb>/<runId>/`, derived from the index URL's own prefix.\n *\n * String surgery on the trailing `runs/` rather than `new URL`, because the\n * configured value may be root-relative (`/agent/runs/`), the common case in\n * a Django template, and `new URL` needs an absolute base.\n */\n #sibling(verb: string, runId: string): string {\n const prefix = this.#url.slice(0, -\"runs/\".length);\n return `${prefix}${verb}/${encodeURIComponent(runId)}/`;\n }\n}\n", "import { withCredentials } from \"./utils.js\";\n\n/**\n * The composer's voice-transcription contract: take a recorded audio `Blob` and\n * resolve to the transcript text. The built-in handler is\n * {@link transcribeAudio}; a host swaps in its own (a Web Speech adapter, a\n * direct-to-provider call) via `AgUiChat.transcribeHandler` without touching\n * the mic button.\n */\nexport type TranscribeHandler = (audio: Blob) => Promise<string>;\n\n/** Options for {@link transcribeAudio}. */\nexport interface TranscribeOptions {\n /** The transcription endpoint (`data-transcribe-url`). */\n readonly url: string;\n /** Extra HTTP headers (CSRF / auth), read fresh per request. */\n readonly headers?: Record<string, string>;\n /**\n * Cookie policy, as `fetch`'s own `credentials` mode. Unset leaves the\n * browser default (`same-origin`), which sends no cookies to an endpoint on\n * another origin; a cookie-authenticated cross-origin deployment needs\n * `\"include\"`.\n */\n readonly credentials?: RequestCredentials;\n}\n\n/**\n * POST a recorded clip to the transcription endpoint and resolve to its text.\n *\n * The clip goes as multipart under the `audio` field with the element's\n * `headers`, mirroring {@link uploadAttachment}, and the server replies\n * `{ \"text\": \"<transcript>\" }`. A non-2xx response or a network error rejects\n * so the mic button can surface the failure.\n */\nexport async function transcribeAudio(audio: Blob, options: TranscribeOptions): Promise<string> {\n const form = new FormData();\n // The extension is cosmetic: the server reads the blob's content type.\n form.append(\"audio\", audio, \"recording.webm\");\n\n const response = await fetch(\n options.url,\n withCredentials(\n {\n method: \"POST\",\n headers: { ...(options.headers ?? {}) },\n body: form,\n },\n options.credentials,\n ),\n );\n if (!response.ok) {\n throw new Error(await errorMessage(response));\n }\n const body: unknown = await response.json();\n if (\n typeof body === \"object\" &&\n body !== null &&\n typeof (body as { text?: unknown }).text === \"string\"\n ) {\n return (body as { text: string }).text;\n }\n throw new Error(\"transcription returned an unreadable response\");\n}\n\n/** A human-readable message from a non-2xx transcription response. */\nasync function errorMessage(response: Response): Promise<string> {\n try {\n const body = (await response.json()) as { error?: unknown };\n if (typeof body.error === \"string\") {\n return body.error;\n }\n } catch {\n // Non-JSON error body \u2014 fall through to the status code.\n }\n return `transcription failed (${response.status})`;\n}\n", "import type { AttachmentRef } from \"./attachment.js\";\n\n/**\n * The composer's upload contract: take a `File`, report `0..1` progress, and\n * resolve to a durable {@link AttachmentRef}. The built-in handler is\n * {@link uploadAttachment}; a host swaps in its own (a `tus-js-client` or\n * direct-to-S3 adapter) via `AgUiChat.uploadHandler` without touching the tray,\n * the chips, or the AG-UI wire, refs being transport-agnostic.\n *\n * The optional `signal` fires when the tray removes a chip or the element is\n * torn down; a handler that honours it should abort its own transport, so a\n * cancelled upload doesn't orphan a server-side file.\n */\nexport type UploadHandler = (\n file: File,\n onProgress: (fraction: number) => void,\n signal?: AbortSignal,\n) => Promise<AttachmentRef>;\n\n/** Options for {@link uploadAttachment}. */\nexport interface UploadOptions {\n /** The attachments endpoint (`data-attachments-url`). */\n readonly url: string;\n /** Extra HTTP headers (CSRF / auth), read fresh per upload. */\n readonly headers?: Record<string, string>;\n /**\n * Cookie policy, spelled as `fetch`'s `credentials` mode for consistency with\n * the other endpoints, but carried by `XMLHttpRequest`'s two-state\n * `withCredentials`: `\"include\"` sets it and every other value leaves it off,\n * matching `\"same-origin\"`. `\"omit\"` therefore cannot be honoured for a\n * same-origin upload, XHR always sending cookies there; use a custom\n * {@link UploadHandler} if that matters.\n */\n readonly credentials?: RequestCredentials;\n /** Progress callback, `0..1`, fired as the body uploads. */\n readonly onProgress?: (fraction: number) => void;\n /** Abort signal to cancel the in-flight upload. */\n readonly signal?: AbortSignal | undefined;\n}\n\n/**\n * Upload one file to the attachments endpoint and resolve to its durable\n * {@link AttachmentRef}.\n *\n * Uses `XMLHttpRequest` rather than `fetch` for real upload-progress events.\n * The file goes as multipart under the `file` field with the element's\n * `headers`, so CSRF / auth ride along; a non-2xx response or a network/abort\n * error rejects, letting the tray show an error chip.\n */\nexport function uploadAttachment(file: File, options: UploadOptions): Promise<AttachmentRef> {\n return new Promise<AttachmentRef>((resolve, reject) => {\n const form = new FormData();\n form.append(\"file\", file);\n\n const xhr = new XMLHttpRequest();\n xhr.open(\"POST\", options.url);\n // Cross-origin cookies ride only when asked for, as at the fetch sites.\n // Without this an upload to another subdomain goes anonymous and 401s while\n // the run itself succeeds.\n xhr.withCredentials = options.credentials === \"include\";\n for (const [key, value] of Object.entries(options.headers ?? {})) {\n xhr.setRequestHeader(key, value);\n }\n\n const onProgress = options.onProgress;\n if (onProgress !== undefined) {\n xhr.upload.addEventListener(\"progress\", (event) => {\n if (event.lengthComputable) {\n onProgress(event.total === 0 ? 0 : event.loaded / event.total);\n }\n });\n }\n\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(parseRef(JSON.parse(xhr.responseText)));\n } catch {\n reject(new Error(\"upload returned an unreadable response\"));\n }\n } else {\n reject(new Error(errorMessage(xhr)));\n }\n });\n xhr.addEventListener(\"error\", () => reject(new Error(\"upload failed\")));\n xhr.addEventListener(\"abort\", () => reject(new Error(\"upload cancelled\")));\n\n const signal = options.signal;\n if (signal !== undefined) {\n signal.addEventListener(\"abort\", () => xhr.abort());\n }\n\n xhr.send(form);\n });\n}\n\n/** Validate + narrow the server's `201` body into an {@link AttachmentRef}. */\nfunction parseRef(body: unknown): AttachmentRef {\n if (typeof body !== \"object\" || body === null) {\n throw new Error(\"not an object\");\n }\n const o = body as Record<string, unknown>;\n const id = o[\"id\"];\n const name = o[\"name\"];\n const mime = o[\"mime\"];\n const size = o[\"size\"];\n const url = o[\"url\"];\n if (\n typeof id !== \"string\" ||\n typeof name !== \"string\" ||\n typeof mime !== \"string\" ||\n typeof size !== \"number\"\n ) {\n throw new Error(\"missing fields\");\n }\n return typeof url === \"string\" ? { id, name, mime, size, url } : { id, name, mime, size };\n}\n\n/** A human-readable message from a non-2xx upload response. */\nfunction errorMessage(xhr: XMLHttpRequest): string {\n try {\n const body = JSON.parse(xhr.responseText) as { error?: unknown };\n if (typeof body.error === \"string\") {\n return body.error;\n }\n } catch {\n // Non-JSON error body \u2014 fall through to the status text.\n }\n return `upload failed (${xhr.status})`;\n}\n", "import type { Context, Interrupt, Message, Tool } from \"@ag-ui/core\";\nimport {\n ATTACHMENT_EVENT,\n COMPACTION_ACTIVITY_TYPE,\n DEFAULT_ATTACHMENT_MAX_BYTES,\n ICON_ATTACH,\n ICON_LAUNCHER,\n ICON_SEND,\n ICON_STOP,\n LOAD_CAPABILITY_TOOL,\n MESSAGE_ROLE,\n READ_PAGE_TOOL,\n RUN_FINISHED_EVENT,\n STATE_EVENT,\n SUBMIT_EVENT,\n TOGGLE_EVENT,\n TOOL_CALL_STATUS,\n TOOL_DISPLAY,\n UNREAD_EVENT,\n X_CONFIRM_KEY,\n X_SUMMARY_KEY,\n} from \"../constants.js\";\nimport { fillTemplate } from \"../skills/fill_template.js\";\nimport { parseSkills } from \"../skills/parse_skills.js\";\nimport type { Skill } from \"../skills/skill.js\";\nimport { type ClientTool, ClientToolRegistry } from \"../tools/client_tool_registry.js\";\nimport { isDestructive } from \"../tools/is_destructive.js\";\nimport { isNavigates } from \"../tools/is_navigates.js\";\nimport { createPageActionTools, type ResolvePageTarget } from \"../tools/page_action_tools.js\";\nimport { createPageMapContext, type PageMap } from \"../tools/page_map.js\";\nimport { createPageStateTools, type PageState } from \"../tools/page_state.js\";\nimport { parseToolCatalog } from \"../tools/parse_tool_catalog.js\";\nimport { createRouteTools, type RouteMap } from \"../tools/route_map.js\";\nimport {\n type ApprovalRenderer,\n type ApprovalRequest,\n requestApproval,\n} from \"../ui/approval_card.js\";\nimport { attachCopyButtons } from \"../ui/attach_copy_buttons.js\";\nimport { renderAttachmentChips } from \"../ui/attachment_chips.js\";\nimport { AttachmentTray } from \"../ui/attachment_tray.js\";\nimport { CheckpointMenu, type CheckpointVerb } from \"../ui/checkpoint_menu.js\";\nimport { type ConfirmationRequest, requestConfirmation } from \"../ui/confirmation_card.js\";\nimport { prettifyToolName } from \"../ui/prettify_tool_name.js\";\nimport {\n type QuestionRenderer,\n type QuestionRequest,\n requestQuestion,\n} from \"../ui/question_card.js\";\nimport { renderMarkdown } from \"../ui/render_markdown.js\";\nimport {\n createResizeHandle,\n type ResizeAnchor,\n type ResizeAxis,\n type ResizeSize,\n} from \"../ui/resize_handle.js\";\nimport { wrapWords } from \"../ui/reveal_words.js\";\nimport { renderRunNotice } from \"../ui/run_notice.js\";\nimport { SkillsMenu } from \"../ui/skills_menu.js\";\nimport { STYLES } from \"../ui/styles.js\";\nimport { ThoughtsBlock } from \"../ui/thoughts_block.js\";\nimport { ThreadDrawer } from \"../ui/thread_drawer.js\";\nimport { ToolCallCard, type ToolDisplayMode } from \"../ui/tool_call_card.js\";\nimport { DEFAULT_UI_STRINGS, mergeUiStrings, type UiStrings } from \"../ui/ui_strings.js\";\nimport { VoiceInput } from \"../ui/voice_input.js\";\nimport {\n AgUiClient,\n type AgUiClientHandlers,\n type AgUiToolCall,\n type InterruptResponse,\n type ToolExecution,\n} from \"./agui_client.js\";\nimport { type AttachmentRef, messageAttachments } from \"./attachment.js\";\nimport {\n type ClientConversationStore,\n type NavigationCheckpoint,\n SessionStorageStore,\n} from \"./conversation_store.js\";\nimport { type AgentFactory, createHttpAgent } from \"./create_http_agent.js\";\nimport { RemoteConversationStore } from \"./remote_conversation_store.js\";\nimport { RunIndex } from \"./run_index.js\";\nimport { type TranscribeHandler, transcribeAudio } from \"./transcribe_audio.js\";\nimport { type UploadHandler, uploadAttachment } from \"./upload_attachment.js\";\nimport { withCredentials } from \"./utils.js\";\n\n/** The role a rendered chat message takes. */\nexport type MessageRole = (typeof MESSAGE_ROLE)[keyof typeof MESSAGE_ROLE];\n\n/** `detail` shape of the {@link SUBMIT_EVENT} CustomEvent. */\nexport interface SubmitDetail {\n readonly content: string;\n /** Durable refs for the files attached to this message (empty when none). */\n readonly attachments: readonly AttachmentRef[];\n}\n\n/** `detail` shape of the {@link ATTACHMENT_EVENT} CustomEvent. */\nexport interface AttachmentsDetail {\n /** Durable refs for every file that has finished uploading. */\n readonly attachments: readonly AttachmentRef[];\n /** How many files are still uploading; a send now would leave these behind. */\n readonly pending: number;\n}\n\n/** `detail` shape of the {@link STATE_EVENT} CustomEvent. */\nexport interface StateDetail {\n readonly state: Readonly<Record<string, unknown>>;\n}\n\n/** One tool that ran during an interaction, as {@link RunFinishedDetail} lists it. */\nexport interface ToolRun {\n readonly name: string;\n /**\n * Where it executed. `\"server\"` is the one a data-rendering host cares about:\n * a `\"client\"` tool ran in the host's own handler, so the host already knows\n * whatever it did.\n */\n readonly side: \"server\" | \"client\";\n}\n\n/** `detail` shape of the {@link RUN_FINISHED_EVENT} CustomEvent. */\nexport interface RunFinishedDetail {\n /** In settle order. Empty when the interaction called no tools. */\n readonly tools: readonly ToolRun[];\n}\n\n/** `detail` shape of the {@link TOGGLE_EVENT} CustomEvent. */\nexport interface ToggleDetail {\n readonly collapsed: boolean;\n}\n\n/** `detail` shape of the {@link UNREAD_EVENT} CustomEvent. */\nexport interface UnreadDetail {\n readonly unread: number;\n}\n\n/**\n * Attributes read once while connecting, to decide what chrome exists at all.\n *\n * Changing one afterwards is silently ignored: the tray, the mic, the skills\n * menu and the header icon are built during connect and no later read revisits\n * the decision. Observed only so `attributeChangedCallback` can warn.\n *\n * Excludes the attributes that are re-read per use, where a late change works\n * and a warning would be wrong: `data-runs-url`, `data-page-actions`,\n * `data-text-animation`, `data-tool-display`, `endpoint`, and the CSS-reactive\n * `theme` / `collapsed`.\n */\nconst CONNECT_TIME_ATTRIBUTES = [\n \"data-attachments-url\",\n \"data-attachment-accept\",\n \"data-attachment-max-bytes\",\n \"data-transcribe-url\",\n \"data-threads-url\",\n \"data-tools-url\",\n \"data-skills-url\",\n \"data-skills\",\n \"data-prompt-chips\",\n \"data-slash-commands\",\n \"data-theme-toggle\",\n \"data-strings\",\n \"data-icon-url\",\n] as const;\n\n/**\n * The cookie policies `fetch` accepts. Anything else is a configuration\n * mistake, and one that would otherwise surface as an unexplained 401 from a\n * request the browser silently sent anonymously.\n */\nconst CREDENTIALS_MODES: readonly string[] = [\"omit\", \"same-origin\", \"include\"];\n\n/** Whether `value` is one of the three modes `fetch` understands. */\nfunction isCredentialsMode(value: string): value is RequestCredentials {\n return CREDENTIALS_MODES.includes(value);\n}\n\n/** Per-tab persistence key for the collapsed state (survives MPA reloads). */\nconst COLLAPSED_KEY = \"ag-ui-chat:collapsed\";\n\n/** Per-tab persistence key for a dragged panel size. */\nconst SIZE_KEY = \"ag-ui-chat:size\";\n\n/** Per-tab persistence key for the built-in theme toggle. */\nconst THEME_KEY = \"ag-ui-chat:theme\";\n\n/**\n * `<ag-ui-chat>` \u2014 a framework-free chat sidebar Web Component over AG-UI.\n *\n * Owns the Shadow DOM shell (header, scrolling message list, input row),\n * builds an {@link AgUiClient} on first send via the overridable\n * {@link agentFactory}, and renders streaming assistant text plus tool-call\n * activity. Emits a {@link SUBMIT_EVENT} for host visibility.\n *\n * The per-run frontend tool catalog and context come from {@link getTools} and\n * {@link getContext}.\n */\nexport class AgUiChat extends HTMLElement {\n /** Agent factory; override to inject a custom or fake agent (tests). */\n agentFactory: AgentFactory = createHttpAgent;\n\n /**\n * Static extra HTTP headers, sent with every request this element makes: the\n * agent run, the thread index and its messages, the tool and skill catalogs,\n * the run index, uploads and transcription.\n *\n * For values fixed for the element's lifetime. A rotating credential belongs\n * in {@link getHeaders} instead \u2014 only a re-assignment updates this, so a\n * token captured here is pinned until the host assigns again.\n */\n headers: Record<string, string> = {};\n\n /**\n * Live header source, called afresh immediately before every request \u2014 the\n * way to supply rotating credentials, with nothing to re-assign or keep in\n * sync.\n *\n * Composes with {@link headers} rather than replacing it: merged per key with\n * `getHeaders()` winning, so a static `X-Client` and a rotating\n * `Authorization` are configured independently and neither drops the other.\n */\n getHeaders: (() => Record<string, string>) | null = null;\n\n /**\n * Permit `<img>` in rendered assistant markdown. **Off by default**: a\n * model-controlled image URL is fetched with no user interaction, which\n * makes it a zero-click exfiltration channel for prompt-injected page\n * data. Enable only when the content source is trusted.\n */\n allowImages = false;\n\n /** When true, destructive tools execute without a confirmation modal. */\n autoConfirm = false;\n\n /**\n * When true, the built-in `ask_user` frontend tool is offered to the agent:\n * calling it renders an inline question card and returns the user's answer.\n * Off by default, like the other built-in tool groups, so the advertised\n * catalog does not change until a host asks for it.\n */\n askUser = false;\n\n /**\n * Optional full replacement for the `ask_user` question UI, resolving with\n * the answer; the same seam as {@link approvalRenderer}, styled via `strings`\n * and the `question*` `::part()`s when left unset. Requires {@link askUser}.\n */\n askUserRenderer: QuestionRenderer | null = null;\n\n /**\n * Optional full replacement for the server-side-tool approval UI: an approval\n * interrupt invokes this instead of the built-in {@link requestApproval}\n * card, resolving `true` to approve or `false` to deny. Style the built-in\n * card via `strings` and the `approval*` `::part()`s instead. The gate itself\n * is enabled server-side; this only changes how the decision is collected.\n */\n approvalRenderer: ApprovalRenderer | null = null;\n\n /**\n * Optional per-call confirmation predicate. When set it is authoritative,\n * deciding from the tool name and args whether this particular call needs\n * confirmation \u2014 so one tool can be instant for some args and confirmed for\n * others, which a static `x-destructive` flag cannot express. When unset the\n * `x-destructive` flag decides. `autoConfirm` short-circuits both.\n */\n confirmPredicate:\n | ((toolName: string, args: Record<string, unknown>) => boolean | Promise<boolean>)\n | null = null;\n\n /**\n * Per-run frontend tool catalog provider. Defaults to the built-in\n * `route.*` tools (when a {@link routeMap} is set) plus the tools registered\n * via {@link registerTool} / {@link registerPageState}; override to supply a\n * fully custom catalog.\n */\n getTools: () => Tool[] = () => [\n ...this.#builtinTools().map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n ...this.#toolRegistry.tools(),\n ];\n\n /**\n * Per-run context provider. Defaults to the compact page map, when a\n * {@link getPageMap} provider is set and {@link autoInjectPageMap} is on.\n *\n * Attachments are deliberately not restated here: the server derives its own\n * manifest from the refs riding the messages.\n */\n getContext: () => Context[] = () => [\n ...createPageMapContext(this.getPageMap, this.autoInjectPageMap),\n ];\n\n /**\n * Navigable routes the agent can jump to via the built-in `route.*` tools.\n * A compact summary also rides in each run's context.\n */\n routeMap: RouteMap = [];\n\n /**\n * Optional client-side router. When set (an SPA), `navigate_to_route` routes\n * in-page and the run loop continues; when unset (an MPA like the admin), it\n * falls back to `window.location` and the resumable-loop machinery applies.\n */\n navigate: ((path: string) => void) | null = null;\n\n /** Provider for the per-run page map; see {@link getContext}. */\n getPageMap: (() => PageMap) | null = null;\n\n /** Whether to auto-inject the page map into context each run. */\n autoInjectPageMap = true;\n\n /**\n * Persistence for the conversation + navigation checkpoint. Defaults to\n * per-tab `sessionStorage` so the chat survives full page reloads; inject a\n * server-backed store for cross-tab/device durability.\n */\n conversationStore: ClientConversationStore = new SessionStorageStore();\n\n /**\n * How attached files are uploaded. `null` (default) uses the built-in\n * multipart `POST` to `data-attachments-url`; a custom {@link UploadHandler}\n * swaps the transport without changing the tray, the chips, or the AG-UI\n * wire. When set, the \uD83D\uDCCE affordance appears even with no\n * `data-attachments-url`, and the handler owns its own endpoint and headers.\n */\n uploadHandler: UploadHandler | null = null;\n\n /**\n * How recorded voice clips are transcribed. `null` (default) POSTs the clip\n * to `data-transcribe-url`; a custom {@link TranscribeHandler} swaps the\n * transport without touching the mic button. When set, the \uD83C\uDFA4 affordance\n * appears even with no `data-transcribe-url`.\n */\n transcribeHandler: TranscribeHandler | null = null;\n\n /**\n * Builds the tool result a navigating tool resumes with after the page\n * reloads. Defaults to the landed URL; a host (e.g. the admin package) can\n * override to include a page snapshot or post-reload validation errors.\n */\n navigationResult: (checkpoint: NavigationCheckpoint) => unknown = () => ({\n navigated: true,\n url: window.location.href,\n });\n\n /**\n * Named values used to fill a skill prompt's `{placeholder}`s before send\n * (e.g. `{ model: \"Order\", selected_ids: \"1,2\" }`). A host (the admin) sets\n * this from the current page; a missing placeholder blocks the send.\n */\n skillContext: () => Record<string, unknown> = () => ({});\n\n /**\n * Friendly display labels for tool-call cards, keyed by tool name. The\n * fallback when a tool has no `x-summary` in its own schema, which chiefly\n * means server-side tools: AG-UI streams only the tool-call name, so their\n * schema never reaches the browser. Client tools should prefer `x-summary`.\n */\n toolSummaries: Record<string, string> = {};\n\n /**\n * Localizable UI strings \u2014 a partial override merged over the English\n * {@link DEFAULT_UI_STRINGS}. Resolved once on connect (so set it before the\n * element is appended); the `data-strings` JSON attribute is the markup\n * equivalent, and this property wins key-by-key over it.\n */\n strings: Partial<UiStrings> = {};\n\n /**\n * Resolve a `scroll_to` / `drag_and_drop` target string to a host-page\n * element (or `null`). Defaults to a CSS-selector lookup; override to map\n * page-map element ids. The page-action tools are opt-in via the\n * `data-page-actions` attribute (`\"scroll\"` / `\"drag\"`).\n */\n resolvePageTarget: ResolvePageTarget = (target) => document.querySelector<HTMLElement>(target);\n\n /**\n * Card labels fetched from a server tool catalog (`data-tools-url`), keyed by\n * tool name. The base layer behind {@link toolSummaries}: an explicit entry in\n * `toolSummaries` wins, this fills the rest. Populated once on connect.\n */\n #toolCatalog: Record<string, string> = {};\n /** The resolved string table (defaults \u2190 `data-strings` \u2190 `strings`). */\n #strings: UiStrings = DEFAULT_UI_STRINGS;\n\n readonly #toolRegistry = new ClientToolRegistry();\n /** Tool-call cards awaiting execution, keyed by call id. */\n readonly #toolCards = new Map<string, ToolCallCard>();\n /**\n * Call ids whose card was already settled from a streamed server-side result\n * (`TOOL_CALL_RESULT`), so the post-run executeTool sweep doesn't overwrite\n * the real output with the generic \"executed on the server\" fallback.\n */\n readonly #serverSettled = new Set<string>();\n /**\n * Tool calls made during the current interaction, in the order they started,\n * so {@link RUN_FINISHED_EVENT} can report them once the whole thing settles.\n * Spans tool rounds and an approval interrupt; cleared when the event fires.\n */\n #runTools: { readonly id: string; readonly name: string }[] = [];\n readonly #root: ShadowRoot;\n readonly #chat: HTMLDivElement;\n readonly #messages: HTMLDivElement;\n readonly #input: HTMLTextAreaElement;\n readonly #send: HTMLButtonElement;\n readonly #title: HTMLSpanElement;\n readonly #skillsMenu: SkillsMenu;\n readonly #drawer: ThreadDrawer;\n /** Checkpoint panel; rows load only when `data-runs-url` is set. */\n readonly #checkpoints: CheckpointMenu;\n /** Built lazily from `data-runs-url`; `null` when the host didn't opt in. */\n #runIndex: RunIndex | null = null;\n readonly #skillHint: HTMLDivElement;\n /** File-picker button + hidden input + tray slot; the tray mounts on connect. */\n readonly #attachButton: HTMLButtonElement;\n readonly #fileInput: HTMLInputElement;\n readonly #attachSlot: HTMLDivElement;\n /** Optional built-in header theme toggle; shown only with `data-theme-toggle`. */\n readonly #themeToggle: HTMLButtonElement;\n /** What the collapsed widget shrinks to: the floating launcher, or the sidebar rail. */\n readonly #launcher: HTMLButtonElement;\n /** The launcher's unread badge; hidden at zero, and when the host opts out. */\n readonly #badge: HTMLSpanElement;\n // Answers that finished while the widget was collapsed. Expanding clears it.\n #unread = 0;\n /** Empty-state region at the top of the message list; hidden once anything renders. */\n readonly #emptyWrap: HTMLDivElement;\n /** Upload tray; created on connect only when `data-attachments-url` is set. */\n #attachTray: AttachmentTray | null = null;\n /** Mic button mount point (input row); the control mounts on connect when enabled. */\n readonly #voiceSlot: HTMLSpanElement;\n /** Voice-input control; created on connect when transcription is available. */\n #voice: VoiceInput | null = null;\n /** Whether the element is currently in the DOM; gates the connect-time warning. */\n #connected = false;\n\n #client: AgUiClient | null = null;\n // Seed for the next client. Once one exists it owns the live value (the\n // agent applies STATE_SNAPSHOT / STATE_DELTA into it), so this is only the\n // starting point \u2014 `sharedState` reads through to the client when present.\n #sharedState: Record<string, unknown> = {};\n // Whether an interaction is in flight (first onRunStart \u2192 onSettled). Drives\n // the Send\u21C4Stop button: `agent.isRunning` is false between frontend-tool\n // rounds, but the user must still be able to stop there.\n #running = false;\n // The page the current round's context describes, captured when that context\n // was built. `null` until the first round. Compared in `#executeTool` to\n // catch a page that moved under a round still in flight.\n #contextHref: string | null = null;\n // Aborting this dismisses (declines) an open confirmation card when the run\n // is cancelled while the card awaits a decision. One controller per card.\n #confirmAbort: AbortController | null = null;\n #streamingBubble: HTMLDivElement | null = null;\n // Text deltas applied to the current streaming bubble. >1 \u21D2 the message\n // revealed progressively as it streamed, so the word reveal must not re-animate\n // it; \u22641 \u21D2 it arrived at once and the word reveal is appropriate.\n #streamDeltas = 0;\n #pending: HTMLDivElement | null = null;\n // The current assistant turn's grouping container. One `.answer`\n // wraps everything a single answer produces \u2014 streamed text, tool cards, the\n // pending indicator \u2014 so it can be boxed as one \"well\" by CSS. Opened on the\n // turn's first run start, closed at settle, so it spans the whole multi-round\n // frontend-tool loop (which is several AG-UI runs), not one run. `null`\n // between turns; user bubbles never enter it.\n #currentGroup: HTMLDivElement | null = null;\n // The current turn's streamed-reasoning region, shown at the top of\n // the answer group while a reasoning model thinks and collapsed once the\n // answer's first text token arrives. `null` outside a reasoning turn.\n #thoughts: ThoughtsBlock | null = null;\n #threadId = \"\";\n // Per-instance suffix for the origin-scoped storage keys (collapsed / theme /\n // active thread), so two instances on one origin don't clobber each other.\n // Empty \u21D2 the pre-namespacing global keys (back-compat). Resolved on connect.\n #storageNs = \"\";\n // Bumped on every #rehydrate; a replay whose generation is stale (a newer\n // thread switch started while it awaited a slow store) drops its result.\n #rehydrateGeneration = 0;\n #initialMessages: readonly Message[] = [];\n // Skill catalog by source; merged backend \u2192 embed \u2192 client (later wins).\n #backendSkills: readonly Skill[] = [];\n #embedSkills: readonly Skill[] = [];\n #clientSkills: readonly Skill[] = [];\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: \"open\" });\n this.#chat = document.createElement(\"div\");\n this.#messages = document.createElement(\"div\");\n this.#input = document.createElement(\"textarea\");\n this.#send = document.createElement(\"button\");\n this.#title = document.createElement(\"span\");\n this.#skillHint = document.createElement(\"div\");\n this.#attachButton = document.createElement(\"button\");\n this.#fileInput = document.createElement(\"input\");\n this.#attachSlot = document.createElement(\"div\");\n this.#voiceSlot = document.createElement(\"span\");\n this.#themeToggle = document.createElement(\"button\");\n this.#launcher = document.createElement(\"button\");\n this.#badge = document.createElement(\"span\");\n this.#emptyWrap = document.createElement(\"div\");\n this.#skillsMenu = new SkillsMenu((skill) => this.#applySkill(skill));\n this.#drawer = new ThreadDrawer({\n onSelect: (threadId) => {\n void this.#switchThread(threadId);\n },\n onNew: () => {\n this.newChat();\n void this.#refreshDrawer();\n },\n onRename: (threadId, title) => {\n this.conversationStore.renameThread(threadId, title);\n void this.#refreshDrawer();\n },\n onDelete: (threadId) => {\n this.#deleteThread(threadId);\n },\n });\n this.#checkpoints = new CheckpointMenu((runId, verb) => {\n void this.#continueRun(runId, verb);\n });\n }\n\n /** The run index, built once from `data-runs-url`; `null` when unset. */\n #runs(): RunIndex | null {\n const url = this.getAttribute(\"data-runs-url\");\n if (url === null || url === \"\") {\n return null;\n }\n if (this.#runIndex === null) {\n this.#runIndex = new RunIndex(\n url,\n () => this.#requestHeaders(),\n () => this.#requestCredentials(),\n );\n }\n return this.#runIndex;\n }\n\n /**\n * Continue `runId` as a **new** run, seeded server-side from its snapshot.\n *\n * Uses a short-lived agent pointed at the resume / fork endpoint and seeded\n * with no history, because those endpoints supply the prior turns from the\n * snapshot and re-sending them would duplicate. A separate agent makes that\n * structural \u2014 the main agent keeps its own history \u2014 and mints the fresh\n * `run_id` the endpoints also require.\n *\n * Handlers are the element's own, so the continuation streams into the same\n * transcript the user is looking at.\n */\n async #continueRun(runId: string, verb: CheckpointVerb): Promise<void> {\n const index = this.#runs();\n if (index === null) {\n return;\n }\n const content = this.#input.value.trim();\n if (content === \"\") {\n return;\n }\n this.#input.value = \"\";\n this.#autoGrow();\n const endpoint = verb === \"resume\" ? index.resumeUrl(runId) : index.forkUrl(runId);\n const agent = this.agentFactory({\n endpoint,\n headers: this.#requestHeaders(),\n getHeaders: () => this.#requestHeaders(),\n ...this.#credentialsOption(),\n threadId: this.#threadId,\n // The seed the endpoints assume: nothing. The snapshot is the history.\n initialMessages: [],\n });\n const client = new AgUiClient({\n agent,\n handlers: this.#handlers(),\n getTools: () => this.getTools(),\n getContext: () => this.#buildContext(),\n executeTool: (call) => this.#executeTool(call),\n resolveInterrupts: (interrupts) => this.#resolveInterrupts(interrupts),\n connectionLostMessage: this.#strings.connectionLost,\n });\n await client.send(content);\n }\n\n /** Load the checkpoint panel with the runs that can actually be continued. */\n async #refreshCheckpoints(): Promise<void> {\n const index = this.#runs();\n this.#checkpoints.setRuns(index === null ? [] : await index.continuable());\n }\n\n /** Attributes the element reacts to after it has been connected. */\n static get observedAttributes(): string[] {\n return [\"title-text\", \"placement\", \"credentials\", ...CONNECT_TIME_ATTRIBUTES];\n }\n\n attributeChangedCallback(name: string, previous: string | null, value: string | null): void {\n if (name === \"credentials\") {\n // Reported the moment the attribute is written \u2014 before connect, and\n // whether it came from markup or the property setter. An unrecognised\n // mode is otherwise inert, and the request it was meant to authorise\n // goes out anonymously with nothing to show for it.\n if (value !== null && !isCredentialsMode(value)) {\n console.error(\n `<ag-ui-chat>: credentials=\"${value}\" is not a fetch credentials mode ` +\n `(${CREDENTIALS_MODES.join(\" / \")}) \u2014 it is being ignored, so requests use ` +\n \"the browser default and cross-origin cookies will not be sent.\",\n );\n }\n return;\n }\n if (name === \"placement\") {\n // A placement owns the axes it fixes, so hand those back before anything\n // else: a size dragged under the previous placement would otherwise sit\n // inline and outrank the new one.\n this.#releaseOwnedAxes();\n // Placement also moves the panel, so the edges its layout holds still\n // change with it. Deferred a frame so the new rules have applied.\n requestAnimationFrame(() => this.#syncResizeAnchor());\n return;\n }\n if (name === \"title-text\") {\n // `#strings` is the resolved table once connected, the English defaults\n // before then.\n this.#title.textContent = value ?? this.#strings.title;\n return;\n }\n // Everything else here is read once, in connectedCallback, to build chrome\n // that then exists or does not. A later change is silently ignored and the\n // symptom is an affordance that never appears, which reads as a broken\n // component rather than a mis-timed assignment \u2014 the common React/Vue shape,\n // where the element mounts on one render pass and attributes are patched in\n // on the next. Observed purely so this can be said out loud.\n if (previous === value || !this.#connected) {\n return;\n }\n console.warn(\n `<ag-ui-chat>: \"${name}\" was changed after the element connected, and is ` +\n \"read only while connecting \u2014 this assignment has no effect. Set it \" +\n \"before the element enters the DOM (in the markup, or on the element \" +\n \"before appending it); frameworks that patch attributes after mount \" +\n \"should bind it at creation. To apply a new value now, remove and \" +\n \"re-insert the element.\",\n );\n }\n\n /** Declare a frontend tool the agent may call. */\n registerTool(tool: ClientTool): void {\n this.#toolRegistry.register(tool);\n }\n\n /**\n * AG-UI **shared state** for this conversation \u2014 the protocol's own state\n * channel, sent as `RunAgentInput.state` on every run and replaced in place\n * when the server streams `STATE_SNAPSHOT` / `STATE_DELTA`. Assigning seeds\n * the next run; reading returns whatever the agent last applied.\n *\n * Listen for {@link STATE_EVENT} to react to server-driven changes. Distinct\n * from {@link registerPageState}, which exposes host state as ordinary tools.\n */\n get sharedState(): Readonly<Record<string, unknown>> {\n return this.#client?.state ?? this.#sharedState;\n }\n\n set sharedState(state: Readonly<Record<string, unknown>>) {\n this.#sharedState = { ...state };\n // A client already exists for this conversation \u2014 push it through so the\n // next run sends it, rather than silently waiting for a new conversation.\n this.#client?.setState(this.#sharedState);\n }\n\n /** Bind a piece of host page state to `read_<name>` / `set_<name>` tools. */\n registerPageState(binding: PageState): void {\n for (const tool of createPageStateTools(binding)) {\n this.#toolRegistry.register(tool);\n }\n }\n\n /**\n * @deprecated Renamed to {@link registerPageState} \u2014 the old name read as\n * AG-UI shared-state sync. Behaviour is unchanged; the alias will be removed\n * in a future major.\n */\n registerStateHook(binding: PageState): void {\n this.registerPageState(binding);\n }\n\n /** The built-in `route.*` tools, present only when a route map is set. */\n #routeTools(): ClientTool[] {\n if (this.routeMap.length === 0) {\n return [];\n }\n return createRouteTools(\n () => this.routeMap,\n () => this.navigate,\n );\n }\n\n /**\n * The built-in `read_page` tool, present only when a {@link getPageMap}\n * provider is set. A *pull* the agent can call mid-turn to see the page after\n * it has acted (the auto-injected context is a send-time snapshot).\n */\n #pageTools(): ClientTool[] {\n const getPageMap = this.getPageMap;\n if (getPageMap === null) {\n return [];\n }\n return [\n {\n name: READ_PAGE_TOOL,\n description:\n \"Read the current page's structure (fields, buttons, route). Call after \" +\n \"acting to observe the result within the same turn.\",\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n [X_SUMMARY_KEY]: \"Read the page\",\n },\n handler: () => getPageMap(),\n },\n ];\n }\n\n /**\n * Opt-in page-action tools (`scroll_to` / `drag_and_drop`), enabled per token\n * via the `data-page-actions` attribute (e.g. `\"scroll,drag\"`). Targets resolve\n * through {@link resolvePageTarget} so a host controls the agent's interaction\n * surface; absent attribute \u21D2 no tools registered.\n */\n #pageActionTools(): ClientTool[] {\n const attr = this.getAttribute(\"data-page-actions\");\n if (attr === null) {\n return [];\n }\n const enabled = new Set(\n attr\n .split(\",\")\n .map((token) => token.trim())\n .filter((token) => token !== \"\"),\n );\n return createPageActionTools(enabled, (target) => this.resolvePageTarget(target));\n }\n\n /** All built-in (route + page + page-action + ask_user) frontend tools. */\n #builtinTools(): ClientTool[] {\n return [\n ...this.#routeTools(),\n ...this.#pageTools(),\n ...this.#pageActionTools(),\n ...this.#askUserTool(),\n ];\n }\n\n /**\n * The built-in `ask_user` frontend tool, or `[]` when {@link askUser} is off.\n *\n * The agent calls it, the client executes it locally through the normal\n * frontend-tool path by rendering a {@link requestQuestion} card, and the\n * answer flows back as the tool result. No new protocol.\n */\n #askUserTool(): ClientTool[] {\n if (!this.askUser) {\n return [];\n }\n return [\n {\n name: \"ask_user\",\n description:\n \"Ask the user a question and wait for their answer. Provide `options` for a \" +\n \"multiple-choice prompt; set `allow_custom` to also accept a free-text answer.\",\n parameters: {\n type: \"object\",\n properties: {\n question: { type: \"string\", description: \"The question to ask the user.\" },\n options: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Preset choices offered as radio buttons.\",\n },\n allow_custom: {\n type: \"boolean\",\n description: \"Allow a free-text answer in addition to any options.\",\n },\n },\n required: [\"question\"],\n },\n handler: (args) => this.#askUser(args),\n },\n ];\n }\n\n /** Render the `ask_user` question card and resolve with the user's answer. */\n async #askUser(args: Record<string, unknown>): Promise<string> {\n const question = typeof args[\"question\"] === \"string\" ? args[\"question\"] : \"\";\n const request: QuestionRequest = { question };\n const rawOptions = args[\"options\"];\n if (Array.isArray(rawOptions)) {\n request.options = rawOptions.filter((option): option is string => typeof option === \"string\");\n }\n if (args[\"allow_custom\"] === true) {\n request.allowCustom = true;\n }\n // The run is suspended on the card; a Stop aborts the controller, resolving\n // it with an empty answer (the run is then cancelled).\n this.#confirmAbort = new AbortController();\n const signal = this.#confirmAbort.signal;\n this.#hidePending();\n // A host-supplied renderer takes full control of the UI; otherwise the\n // built-in inline card renders into the current answer group.\n const answer =\n this.askUserRenderer !== null\n ? await this.askUserRenderer(request, { signal })\n : await requestQuestion(this.#ensureGroup(), request, {\n signal,\n strings: this.#strings,\n });\n this.#confirmAbort = null;\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return answer;\n }\n\n /** Resolve a tool by name: built-in tools first, then the registry. */\n #resolveTool(name: string): ClientTool | null {\n const builtin = this.#builtinTools().find((t) => t.name === name);\n if (builtin !== undefined) {\n return builtin;\n }\n return this.#toolRegistry.has(name) ? this.#toolRegistry.get(name) : null;\n }\n\n /** The AG-UI endpoint URL, read from the `endpoint` attribute. */\n get endpoint(): string {\n return this.getAttribute(\"endpoint\") ?? \"\";\n }\n\n // Reflecting setter so frameworks (e.g. React 19) that assign matching\n // props as element *properties* don't hit a read-only property. Read at\n // use-time, so a runtime change applies to the next run.\n set endpoint(value: string) {\n this.setAttribute(\"endpoint\", value);\n }\n\n /**\n * Cookie policy for **every** request this element makes, as `fetch`'s own\n * `credentials` mode (`\"omit\"` / `\"same-origin\"` / `\"include\"`). Mirrored to\n * the `credentials` attribute, so markup embeds can set it without script.\n *\n * `null` (the default) leaves the browser's `same-origin` default in place,\n * which sends no cookies at all to an endpoint on a different origin \u2014 and\n * the request goes out anonymously rather than failing, so the symptom is a\n * 401 from a server that looks correctly configured. A cookie-authenticated\n * cross-origin deployment wants `\"include\"`, plus\n * `Access-Control-Allow-Credentials: true` and a concrete, non-wildcard\n * `Access-Control-Allow-Origin` on the server.\n *\n * Read per request, so a late assignment applies to everything after it.\n * `\"omit\"` cannot be honoured by the built-in upload transport, an\n * `XMLHttpRequest` with only a two-state cookie switch; every other endpoint\n * honours all three modes.\n */\n get credentials(): RequestCredentials | null {\n const attr = this.getAttribute(\"credentials\");\n return attr !== null && isCredentialsMode(attr) ? attr : null;\n }\n\n set credentials(value: RequestCredentials | null) {\n if (value === null) {\n this.removeAttribute(\"credentials\");\n return;\n }\n // Thrown, not warned: an unrecognised mode is inert at request time, and\n // the whole failure this option exists to fix is a request that goes out\n // wrong without saying so. Fail where the mistake was made instead.\n if (!isCredentialsMode(value)) {\n throw new TypeError(\n `<ag-ui-chat>: credentials must be one of ${CREDENTIALS_MODES.map((mode) => `\"${mode}\"`).join(\", \")} ` +\n `(got ${JSON.stringify(value)}).`,\n );\n }\n this.setAttribute(\"credentials\", value);\n }\n\n /**\n * The headers for the request about to go out: the static {@link headers}\n * with {@link getHeaders}'s live values overlaid, per key.\n *\n * Every request site goes through here, so \"how this element authenticates\"\n * is one answer rather than one per endpoint.\n */\n #requestHeaders(): Record<string, string> {\n return { ...this.headers, ...this.getHeaders?.() };\n }\n\n /** The configured cookie policy as `fetch` spells it; `undefined` when unset. */\n #requestCredentials(): RequestCredentials | undefined {\n return this.credentials ?? undefined;\n }\n\n /**\n * The `credentials` entry for an {@link AgentFactory} call, or nothing at all.\n *\n * Spread rather than assigned: `exactOptionalPropertyTypes` rejects an\n * explicit `credentials: undefined`, and a factory should see the field\n * absent \u2014 not present-and-empty \u2014 when no policy is configured. The agent\n * reads it when it is built (first send, thread switch, continuation), by\n * which time any host configuration has landed.\n */\n #credentialsOption(): { credentials?: RequestCredentials } {\n const credentials = this.#requestCredentials();\n return credentials === undefined ? {} : { credentials };\n }\n\n /** The `fetch` init for the element's own plain GETs (catalogs). */\n #fetchInit(): RequestInit | undefined {\n return withCredentials({ headers: this.#requestHeaders() }, this.#requestCredentials());\n }\n\n /**\n * How much detail tool-call cards show, from the `data-tool-display`\n * attribute (`minimal` / `inline` / `compact` / `full`). Defaults to `full`.\n *\n * Applied by the shadow CSS from the attribute itself, so changing it\n * restyles every card already in the transcript rather than only the ones\n * built afterwards.\n */\n get toolDisplay(): ToolDisplayMode {\n const attr = this.getAttribute(\"data-tool-display\");\n if (\n attr === TOOL_DISPLAY.INLINE ||\n attr === TOOL_DISPLAY.MINIMAL ||\n attr === TOOL_DISPLAY.COMPACT\n ) {\n return attr;\n }\n return TOOL_DISPLAY.FULL;\n }\n\n set toolDisplay(value: ToolDisplayMode) {\n this.setAttribute(\"data-tool-display\", value);\n }\n\n connectedCallback(): void {\n // Resolve the per-instance storage namespace (id, else endpoint) before any\n // key read/write, so this instance doesn't share collapsed/theme/thread\n // state with another on the same origin.\n this.#storageNs = this.id !== \"\" ? this.id : this.endpoint;\n // Restore a dragged size before the panel paints, so it does not snap from\n // the placement default to the user's width on the first frame.\n this.#applySize(this.#readSize());\n // Position the grip at the corner this layout grows toward. Deferred to a\n // frame so the host's own stylesheet has applied; re-measured on every drag\n // anyway, so a wrong first guess costs a grip in the wrong corner and never\n // a wrong resize.\n requestAnimationFrame(() => this.#syncResizeAnchor());\n // Resolve the string table before rendering any chrome (defaults are the\n // floor; `data-strings` then the `strings` property layer over them).\n this.#strings = mergeUiStrings({ ...this.#readStringOverrides(), ...this.strings });\n // Restore a theme the built-in toggle persisted last visit (opt-in only, so\n // it never overrides a host that drives `theme` itself).\n if (this.getAttribute(\"data-theme-toggle\") !== null) {\n const saved = this.#readScopedItem(THEME_KEY);\n if (saved !== null) {\n this.setAttribute(\"theme\", saved);\n }\n }\n this.#render();\n this.#drawer.setStrings(this.#strings);\n this.#checkpoints.setStrings(this.#strings);\n if (this.#readScopedItem(COLLAPSED_KEY) === \"1\") {\n this.setAttribute(\"collapsed\", \"\");\n }\n this.#syncLauncher();\n this.#initSkills();\n // Namespace the built-in default store too (a host-injected store is used\n // verbatim). Must precede #wireThreadStore, which wraps the current store.\n if (this.#storageNs !== \"\" && this.conversationStore instanceof SessionStorageStore) {\n this.conversationStore = new SessionStorageStore(this.#storageNs);\n }\n this.#wireThreadStore();\n this.#wireAttachments();\n this.#wireVoice();\n this.#threadId = this.conversationStore.threadId();\n // The catalog requests go out a microtask later, so a host configuring\n // through a framework ref still has a chance to be heard \u2014 see #startup.\n queueMicrotask(() => this.#startup());\n void this.#rehydrate();\n // Last: everything above reads (and some of it sets) attributes, and none\n // of that should trip the connect-time warning.\n this.#connected = true;\n }\n\n /**\n * The catalog requests the element issues on startup: the tool labels\n * (`data-tools-url`) and the backend skills (`data-skills-url`).\n *\n * Deliberately one microtask behind `connectedCallback`. A framework ref is\n * attached after the node is inserted but within the same commit, so a\n * request issued from `connectedCallback` itself goes out before `headers`,\n * {@link getHeaders} or {@link credentials} exist and 401s in a way that\n * reads as a server fault. A microtask lands after that commit, still before\n * paint.\n *\n * It is not a fix for configuration arriving later than the commit (a passive\n * effect, an awaited token fetch): configure before insertion, or call\n * {@link reload}, since a longer timer would hide that race rather than close\n * it.\n *\n * The history replay stays in `connectedCallback` on purpose. It renders into\n * the transcript, so deferring it would let a `sendMessage()` in the same\n * task land first and be duplicated by the replay.\n */\n #startup(): void {\n // An element can be inserted and removed inside one task (a discarded\n // render, a double-mount); nothing should go out for a node that has\n // already left the document.\n if (!this.#connected) {\n return;\n }\n void this.#fetchToolCatalog();\n void this.#fetchSkills();\n }\n\n /**\n * Re-run everything the element loads on startup \u2014 the tool-label catalog,\n * the backend skill catalog and the thread's history \u2014 with the transport\n * configuration as it stands now.\n *\n * For a host that can only configure the element after the fact (a token\n * fetched in a passive effect, an async auth handshake), this re-issues the\n * startup requests authenticated, without removing and re-inserting the node.\n *\n * A reload, not a merge: the in-flight run is cancelled and the transcript is\n * rebuilt from persisted history, so anything streamed since is dropped. Call\n * it once, when configuration lands, not between turns.\n */\n async reload(): Promise<void> {\n this.#cancelRun();\n this.#resetState();\n this.#setRunning(false);\n await Promise.all([this.#fetchToolCatalog(), this.#fetchSkills(), this.#rehydrate()]);\n }\n\n /**\n * Tear down live resources when the element leaves the DOM: cancel the\n * in-flight run so its stream closes, abort in-flight uploads so they do not\n * orphan server-side files, and release the mic so the browser's recording\n * indicator clears. Without this a removed element leaks all three.\n */\n disconnectedCallback(): void {\n this.#connected = false;\n this.#cancelRun();\n this.#attachTray?.dispose();\n this.#voice?.dispose();\n }\n\n /**\n * Read an opt-in flag attribute the way HTML reads a boolean attribute.\n *\n * Present means on: bare (`data-prompt-chips`), empty (`=\"\"`), or any value\n * except the literal `\"false\"`. Comparing against `\"true\"` instead would make\n * the bare spelling every native boolean attribute uses silently disable the\n * feature it names. `=\"false\"` still turns it off.\n */\n #flag(name: string): boolean {\n const value = this.getAttribute(name);\n return value !== null && value !== \"false\";\n }\n\n /** Parse the inline `data-strings` JSON overrides (empty when absent/malformed). */\n #readStringOverrides(): Partial<UiStrings> {\n const raw = this.getAttribute(\"data-strings\");\n if (raw === null) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null) {\n return parsed as Partial<UiStrings>;\n }\n } catch {\n // Malformed JSON \u2014 fall back to the defaults rather than failing to mount.\n }\n return {};\n }\n\n /**\n * Enable the composer's file-upload tray when uploads are possible \u2014 either a\n * custom {@link uploadHandler} is set or `data-attachments-url` provides the\n * built-in multipart endpoint: reveal the \uD83D\uDCCE button, wire the hidden file\n * input + drag-and-drop, and mount the tray. With neither, the affordance\n * stays hidden and the chat degrades to text-only.\n */\n #wireAttachments(): void {\n const url = this.getAttribute(\"data-attachments-url\");\n const upload = this.uploadHandler ?? this.#defaultUploadHandler(url);\n if (upload === null) {\n return;\n }\n const accept = this.getAttribute(\"data-attachment-accept\") ?? \"\";\n // Bound to the local rather than the field: the hook can only fire from a\n // tray that exists, so passing it removes a null check no caller can reach.\n const tray: AttachmentTray = new AttachmentTray({\n upload,\n maxBytes: this.#attachmentMaxBytes(),\n accept,\n strings: this.#strings,\n // The tray's change hook, surfaced to the host as an event. A host\n // driving its own composer could otherwise not tell a settled upload from\n // one still in flight, which is the state sendMessage() has to be called\n // with knowledge of.\n onChange: () => this.#dispatchAttachments(tray),\n });\n this.#attachTray = tray;\n this.#attachSlot.appendChild(this.#attachTray.element);\n this.#fileInput.accept = accept;\n this.#attachButton.hidden = false;\n this.#enableDragAndDrop();\n }\n\n /** The built-in multipart upload handler for `data-attachments-url`, or `null`. */\n #defaultUploadHandler(url: string | null): UploadHandler | null {\n if (url === null) {\n return null;\n }\n // Forward the tray's abort signal so removing a chip (or tearing the\n // element down) cancels the XHR.\n return (file, onProgress, signal) =>\n uploadAttachment(file, {\n url,\n headers: this.#requestHeaders(),\n ...this.#credentialsOption(),\n onProgress,\n signal,\n });\n }\n\n /**\n * Reveal the composer's \uD83C\uDFA4 mic button when transcription is possible \u2014 either\n * a custom {@link transcribeHandler} is set or `data-transcribe-url` provides\n * the built-in POST endpoint. The control records via `MediaRecorder` and\n * drops the transcript into the composer; with neither configured the mic\n * stays hidden and the chat is text-only.\n */\n #wireVoice(): void {\n const url = this.getAttribute(\"data-transcribe-url\");\n const transcribe = this.transcribeHandler ?? this.#defaultTranscribeHandler(url);\n if (transcribe === null) {\n return;\n }\n this.#voice = new VoiceInput({\n transcribe,\n onText: (text) => this.#insertVoiceText(text),\n strings: this.#strings,\n });\n this.#voiceSlot.appendChild(this.#voice.element);\n }\n\n /** The built-in transcription handler for `data-transcribe-url`, or `null`. */\n #defaultTranscribeHandler(url: string | null): TranscribeHandler | null {\n if (url === null) {\n return null;\n }\n return (audio) =>\n transcribeAudio(audio, {\n url,\n headers: this.#requestHeaders(),\n ...this.#credentialsOption(),\n });\n }\n\n /** Drop a voice transcript into the composer (appended to any typed text). */\n #insertVoiceText(text: string): void {\n const current = this.#input.value.trim();\n this.#input.value = current === \"\" ? text : `${current} ${text}`;\n this.#onInput();\n this.#input.focus();\n }\n\n /** The client-side upload size cap from `data-attachment-max-bytes`. */\n #attachmentMaxBytes(): number {\n const attr = this.getAttribute(\"data-attachment-max-bytes\");\n if (attr === null) {\n return DEFAULT_ATTACHMENT_MAX_BYTES;\n }\n const parsed = Number.parseInt(attr, 10);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_ATTACHMENT_MAX_BYTES;\n }\n\n /** Queue every file from the picker into the tray, then reset the input. */\n #onFilesPicked(): void {\n const files = this.#fileInput.files;\n if (files !== null) {\n for (const file of Array.from(files)) {\n this.#attachTray?.add(file);\n }\n }\n // Reset so re-picking the same file fires `change` again.\n this.#fileInput.value = \"\";\n }\n\n /** Accept files dropped anywhere on the chat shell into the tray. */\n #enableDragAndDrop(): void {\n this.#chat.addEventListener(\"dragover\", (event) => {\n event.preventDefault();\n this.#chat.classList.add(\"chat--dragover\");\n });\n this.#chat.addEventListener(\"dragleave\", () => {\n this.#chat.classList.remove(\"chat--dragover\");\n });\n this.#chat.addEventListener(\"drop\", (event) => {\n event.preventDefault();\n this.#chat.classList.remove(\"chat--dragover\");\n const files = event.dataTransfer?.files;\n if (files !== undefined) {\n for (const file of Array.from(files)) {\n this.#attachTray?.add(file);\n }\n }\n });\n }\n\n /**\n * When `data-threads-url` is set, route thread enumeration / load / rename /\n * delete through that server endpoint (wrapping the current store as the\n * client-only fallback), so the history drawer shows durable, cross-device\n * threads. Without it, the client store's per-tab threads are used.\n */\n #wireThreadStore(): void {\n const url = this.getAttribute(\"data-threads-url\");\n if (url !== null) {\n this.conversationStore = new RemoteConversationStore(\n url,\n () => this.#requestHeaders(),\n this.conversationStore,\n () => this.#requestCredentials(),\n );\n }\n }\n\n /** Fetch the server tool-label catalog from `data-tools-url`, if set. */\n async #fetchToolCatalog(): Promise<void> {\n const url = this.getAttribute(\"data-tools-url\");\n if (url === null) {\n return;\n }\n try {\n const response = await fetch(url, this.#fetchInit());\n this.#toolCatalog = parseToolCatalog(await response.json());\n } catch {\n // Network/parse failure: cards fall back to toolSummaries / raw names.\n }\n }\n\n /**\n * Replace the host-supplied (client) skill catalog. Merged after the embedded\n * and fetched skills (so a client skill overrides a same-named server one).\n */\n setSkills(skills: readonly Skill[]): void {\n this.#clientSkills = skills;\n this.#recomputeSkills();\n }\n\n /**\n * Wire the skill surfaces: opt-in flags and the embedded catalog. The backend\n * catalog is fetched from `#startup`, a microtask later, so it carries the\n * host's transport configuration.\n */\n #initSkills(): void {\n this.#skillsMenu.enableChips(this.#flag(\"data-prompt-chips\"));\n this.#skillsMenu.enableSlash(this.#flag(\"data-slash-commands\"));\n this.#embedSkills = this.#readEmbeddedSkills();\n this.#recomputeSkills();\n }\n\n /** Parse the inline `data-skills` JSON catalog (empty when absent/malformed). */\n #readEmbeddedSkills(): readonly Skill[] {\n const raw = this.getAttribute(\"data-skills\");\n if (raw === null) {\n return [];\n }\n try {\n return parseSkills(JSON.parse(raw));\n } catch {\n return [];\n }\n }\n\n /** Fetch the backend skills catalog from `data-skills-url`, if set. */\n async #fetchSkills(): Promise<void> {\n const url = this.getAttribute(\"data-skills-url\");\n if (url === null) {\n return;\n }\n try {\n const response = await fetch(url, this.#fetchInit());\n this.#backendSkills = parseSkills(await response.json());\n this.#recomputeSkills();\n } catch {\n // Network/parse failure: skills just stay as the embedded/client set.\n }\n }\n\n /** Merge the three sources (backend \u2192 embed \u2192 client; later wins by name). */\n #recomputeSkills(): void {\n const merged = new Map<string, Skill>();\n for (const skill of [...this.#backendSkills, ...this.#embedSkills, ...this.#clientSkills]) {\n merged.set(skill.name, skill);\n }\n this.#skillsMenu.setSkills([...merged.values()]);\n }\n\n /**\n * Act on a picked skill.\n *\n * A skill with no `prompt` is server-resolved: picking it sends the bare\n * `/name` token for the agent to expand, so the wording never reaches the\n * browser. Prefer that shape \u2014 a skill often states a project's internal\n * workflow most plainly, and a catalog endpoint is a plain GET.\n *\n * A skill carrying a `prompt` has the client fill its `{placeholder}`s from\n * the page instead, which is right for placeholders only the page can supply.\n *\n * Either way a pick sends; `sendImmediately: false` opts into pre-filling the\n * composer instead.\n */\n #applySkill(skill: Skill): void {\n if (skill.prompt === undefined) {\n this.#skillHint.hidden = true;\n void this.sendMessage(`/${skill.name}`);\n return;\n }\n const { text, missing } = fillTemplate(skill.prompt, this.skillContext());\n if (missing.length > 0) {\n // Hand the user something to work with rather than only a refusal. The\n // partially-filled template goes into the composer with its unresolved\n // `{placeholder}`s intact and the first one selected, so the next\n // keystroke replaces it. Blocking with a hint alone left whatever the\n // user had typed to open the palette \u2014 a lone \"/\" \u2014 sitting there, which\n // says nothing about what the skill wanted or how to give it.\n this.#skillHint.textContent = this.#strings.skillNeeds\n .replace(\"{title}\", skill.title)\n .replace(\"{fields}\", missing.join(\", \"));\n this.#skillHint.hidden = false;\n this.#input.value = text;\n this.#autoGrow();\n this.#input.focus();\n this.#selectFirstPlaceholder(text);\n return;\n }\n this.#skillHint.hidden = true;\n this.#input.value = text;\n this.#autoGrow();\n if (skill.sendImmediately === false) {\n this.#input.focus();\n return;\n }\n void this.#submit();\n }\n\n /**\n * Put the caret on the first unresolved placeholder, selected.\n *\n * Typing then replaces it, which is the shortest path from \"this skill needs\n * a topic\" to a sendable prompt.\n */\n #selectFirstPlaceholder(text: string): void {\n // The first surviving brace *is* the first unresolved placeholder \u2014 a\n // resolved one was substituted away \u2014 so this needs no search through the\n // missing keys and no not-found branch to defend.\n const start = text.indexOf(\"{\");\n this.#input.setSelectionRange(start, text.indexOf(\"}\", start) + 1);\n }\n\n /** Whether the widget is collapsed (reflected as the `collapsed` attribute). */\n get collapsed(): boolean {\n return this.hasAttribute(\"collapsed\");\n }\n\n // Property setter (framework interop) \u2014 delegates to setCollapsed so a\n // `collapsed` prop assignment persists + emits the toggle event.\n set collapsed(value: boolean) {\n this.setCollapsed(value);\n }\n\n /**\n * Set the collapsed state: reflect the `collapsed` attribute, persist it\n * per-tab, and emit a {@link TOGGLE_EVENT} so a host can mirror the state in\n * its own chrome.\n */\n setCollapsed(collapsed: boolean): void {\n if (collapsed) {\n this.setAttribute(\"collapsed\", \"\");\n } else {\n this.removeAttribute(\"collapsed\");\n }\n sessionStorage.setItem(this.#storageKey(COLLAPSED_KEY), collapsed ? \"1\" : \"0\");\n // Expanding is what marks the waiting answers read; collapsing starts a\n // fresh count. Either way the badge is cleared and the host told.\n this.#setUnread(0);\n this.dispatchEvent(\n new CustomEvent<ToggleDetail>(TOGGLE_EVENT, {\n detail: { collapsed },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /**\n * Answers that finished while the widget was collapsed, and that the user has\n * therefore not seen. Expanding (or {@link newChat}) clears it. The launcher's\n * badge renders this; {@link UNREAD_EVENT} announces every change, so a host\n * chrome can render its own instead.\n */\n get unread(): number {\n return this.#unread;\n }\n\n /** Flip the collapsed state. Bound to the built-in header toggle. */\n toggleCollapsed(): void {\n this.setCollapsed(!this.collapsed);\n }\n\n /**\n * Flip the `theme` attribute between `light` and `dark` and persist the choice\n * per tab. Bound to the optional built-in header theme toggle\n * (`data-theme-toggle`); any non-dark theme (incl. `auto` / `code`) flips to\n * `dark` first.\n */\n toggleTheme(): void {\n const next = this.getAttribute(\"theme\") === \"dark\" ? \"light\" : \"dark\";\n this.setAttribute(\"theme\", next);\n sessionStorage.setItem(this.#storageKey(THEME_KEY), next);\n this.#syncThemeGlyph();\n }\n\n /**\n * Which axes the current placement allows.\n *\n * A full-bleed layout is `100vw`/`100vh` by definition and cannot be resized\n * at all; a docked panel owns its height, leaving only its inner edge. Read\n * per interaction, because `placement` is a live attribute.\n */\n #resizeAxis(): ResizeAxis {\n switch (this.getAttribute(\"placement\")) {\n case \"full\":\n case \"page\":\n return \"none\";\n case \"sidebar\":\n case \"side\":\n return \"width\";\n default:\n return \"both\";\n }\n }\n\n /**\n * Which edges the layout is holding still, by measuring rather than guessing:\n * nudge the size by a pixel, see which edges stayed put, and undo. One forced\n * reflow per drag.\n *\n * `placement` cannot answer this \u2014 an embedded panel goes wherever the page's\n * CSS puts it \u2014 and see {@link createResizeHandle} for why guessing produces\n * a visibly broken control.\n */\n #measureAnchor(): ResizeAnchor {\n const before = this.getBoundingClientRect();\n const width = this.style.getPropertyValue(\"--ag-ui-width\");\n const height = this.style.getPropertyValue(\"--ag-ui-height\");\n this.#applySize({ width: before.width + 1, height: before.height + 1 });\n const after = this.getBoundingClientRect();\n // Restore exactly what was there, including \"nothing\" \u2014 leaving a probe\n // value behind would pin a panel that had been sizing itself.\n this.#restoreProperty(\"--ag-ui-width\", width);\n this.#restoreProperty(\"--ag-ui-height\", height);\n return {\n x: Math.abs(after.left - before.left) < 0.5 ? \"left\" : \"right\",\n y: Math.abs(after.top - before.top) < 0.5 ? \"top\" : \"bottom\",\n };\n }\n\n /** Stamp the measured anchor so the shadow CSS can place the grip. */\n #syncResizeAnchor(): void {\n if (!this.#connected) {\n return;\n }\n const anchor = this.#measureAnchor();\n this.setAttribute(\"data-resize-anchor\", `${anchor.y}-${anchor.x}`);\n }\n\n /** Put a custom property back to a previous value, or remove it if there was none. */\n #restoreProperty(name: string, value: string): void {\n if (value === \"\") {\n this.style.removeProperty(name);\n return;\n }\n this.style.setProperty(name, value);\n }\n\n /**\n * Write a dragged size onto the host, on the axes this placement leaves free.\n *\n * Writing the custom property rather than inline `width` / `height` does not\n * by itself leave placement in charge: an inline custom property still\n * outranks a `:host([placement=\u2026])` rule setting the same property, so a\n * height dragged while floating would cap a docked sidebar asking for\n * `100vh`. The cascade cannot arbitrate this, so the axis check must \u2014 a\n * placement owns the axes it fixes, and a persisted size is applied only to\n * the ones it leaves free.\n */\n #applySize(size: ResizeSize): void {\n const axis = this.#resizeAxis();\n if (axis === \"none\") {\n return;\n }\n if (size.width !== undefined) {\n this.style.setProperty(\"--ag-ui-width\", `${size.width}px`);\n }\n if (size.height !== undefined && axis === \"both\") {\n this.style.setProperty(\"--ag-ui-height\", `${size.height}px`);\n }\n }\n\n /**\n * Drop any dragged size the new placement has taken ownership of.\n *\n * Without this a size survives the switch as an inline property and silently\n * overrides the placement it moved to \u2014 the panel keeps a floating height\n * while docked, and reads as a component that cannot do full height.\n */\n #releaseOwnedAxes(): void {\n const axis = this.#resizeAxis();\n if (axis !== \"both\") {\n this.style.removeProperty(\"--ag-ui-height\");\n }\n if (axis === \"none\") {\n this.style.removeProperty(\"--ag-ui-width\");\n }\n }\n\n /** Persist a dragged size per tab, alongside the collapsed/theme preferences. */\n #persistSize(size: ResizeSize): void {\n const stored = { ...this.#readSize(), ...size };\n sessionStorage.setItem(this.#storageKey(SIZE_KEY), JSON.stringify(stored));\n }\n\n /** The persisted size for this instance, or an empty record. */\n #readSize(): ResizeSize {\n const raw = this.#readScopedItem(SIZE_KEY);\n if (raw === null) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as ResizeSize) : {};\n } catch {\n // A corrupt entry is not worth failing a mount over; fall back to the\n // placement's own size.\n return {};\n }\n }\n\n /** This instance's namespaced form of an origin-scoped storage key. */\n #storageKey(base: string): string {\n return this.#storageNs === \"\" ? base : `${base}:${this.#storageNs}`;\n }\n\n /**\n * Read a namespaced origin-scoped value, falling back once to the legacy\n * pre-namespacing global key (left in place) so an existing collapsed/theme\n * preference survives the upgrade.\n */\n #readScopedItem(base: string): string | null {\n const scoped = sessionStorage.getItem(this.#storageKey(base));\n if (scoped !== null || this.#storageNs === \"\") {\n return scoped;\n }\n return sessionStorage.getItem(base);\n }\n\n /** Reflect the current theme on the toggle: show the destination's glyph. */\n #syncThemeGlyph(): void {\n const dark = this.getAttribute(\"theme\") === \"dark\";\n this.#themeToggle.textContent = dark ? \"\u2600\uFE0F\" : \"\uD83C\uDF19\";\n }\n\n /**\n * Open the thread-history drawer: the imperative route to the control that\n * renders as `::part(history-button)`.\n *\n * A host that hides `::part(header)` for its own title bar hides the history,\n * new-chat and collapse buttons with it. Each has a method so that chrome can\n * be rebuilt: this one, {@link openCheckpoints}, {@link newChat},\n * {@link toggleCollapsed} and {@link toggleTheme}.\n */\n openThreads(): void {\n // Two overlapping surfaces, so opening one dismisses the other. Clicking away\n // already covers the built-in buttons, but a host driving its own chrome\n // through these methods raises no pointer event \u2014 and the drawer would then\n // open *underneath* a popover still floating over it.\n this.#checkpoints.close();\n void this.#refreshDrawer();\n this.#drawer.open();\n }\n\n /**\n * Open the checkpoints panel (the `::part(checkpoints-button)` route).\n *\n * It lists the runs the `data-runs-url` server reports as continuable;\n * without that attribute the built-in button is never rendered and this opens\n * an empty panel.\n */\n openCheckpoints(): void {\n // The other half of the pair \u2014 see `openThreads`.\n this.#drawer.close();\n void this.#refreshCheckpoints();\n this.#checkpoints.open();\n }\n\n /** Close the checkpoints panel, if it is open. */\n closeCheckpoints(): void {\n this.#checkpoints.close();\n }\n\n /**\n * Open the checkpoints panel, or close it if it is already open \u2014 what the\n * built-in \u2B6F button does, because a control that opens a panel is read as the\n * control that also dismisses it. {@link openCheckpoints} stays open-only for a\n * host that means exactly that.\n */\n toggleCheckpoints(): void {\n if (this.#checkpoints.open_) {\n this.#checkpoints.close();\n return;\n }\n this.openCheckpoints();\n }\n\n /**\n * Start a fresh conversation: forget the persisted history, drop the\n * in-memory run state, clear the transcript, and mint a new thread id.\n */\n newChat(): void {\n // Stop any in-flight run first \u2014 discarding the client mid-run would\n // leave the old agent streaming into a cleared transcript.\n this.#cancelRun();\n this.conversationStore.clear(this.#threadId);\n this.#resetState();\n this.#threadId = this.conversationStore.threadId();\n this.#setRunning(false);\n this.#setUnread(0);\n }\n\n /** Drop the in-memory run + transcript, leaving the thread id untouched. */\n #resetState(): void {\n this.#client = null;\n this.#streamingBubble = null;\n this.#currentGroup = null;\n this.#thoughts = null;\n this.#hidePending();\n this.#toolCards.clear();\n this.#serverSettled.clear();\n this.#initialMessages = [];\n this.#attachTray?.clear();\n // Keep the empty-state region; everything else clears.\n this.#messages.replaceChildren(this.#emptyWrap);\n this.#updateEmptyState();\n }\n\n /** Switch the active conversation to an existing thread and replay it. */\n async #switchThread(threadId: string): Promise<void> {\n if (threadId === this.#threadId) {\n return;\n }\n this.#cancelRun();\n this.#resetState();\n this.conversationStore.setActiveThread(threadId);\n this.#threadId = threadId;\n this.#setRunning(false);\n await this.#rehydrate();\n }\n\n /** Delete a thread; if it was the active one, fall back to a fresh chat. */\n #deleteThread(threadId: string): void {\n const wasActive = threadId === this.#threadId;\n if (wasActive) {\n this.#cancelRun();\n }\n this.conversationStore.clear(threadId);\n if (wasActive) {\n this.#resetState();\n this.#threadId = this.conversationStore.threadId();\n this.#setRunning(false);\n }\n void this.#refreshDrawer();\n }\n\n /** Reload the drawer's thread list, marking the active thread. */\n async #refreshDrawer(): Promise<void> {\n this.#drawer.setThreads(await this.conversationStore.listThreads(), this.#threadId);\n }\n\n /**\n * Restore the conversation from the store on mount, then \u2014 if a navigating\n * tool reloaded the page mid-run \u2014 resume the loop by supplying that tool's\n * result from the page we landed on.\n */\n async #rehydrate(): Promise<void> {\n // Guard against a thread-switch race: with a slow remote store, picking\n // thread B then C would interleave both replays into one transcript. Each\n // rehydrate claims a generation before awaiting and bails if a newer one\n // started meanwhile (its `#resetState` already cleared the transcript).\n this.#rehydrateGeneration += 1;\n const generation = this.#rehydrateGeneration;\n const messages = await this.conversationStore.loadMessages(this.#threadId);\n if (generation !== this.#rehydrateGeneration) {\n return;\n }\n if (messages !== null) {\n this.#initialMessages = messages;\n for (const message of messages) {\n this.#renderHistoricMessage(message);\n }\n }\n const checkpoint = this.conversationStore.loadCheckpoint(this.#threadId);\n if (checkpoint !== null) {\n await this.#resumeFrom(checkpoint);\n return;\n }\n this.#noticeIfRunUnfinished(messages);\n }\n\n /**\n * Notice a previous run that never produced a response.\n *\n * {@link AgUiClient.send} persists the user's message before starting the\n * run, so a transcript ending on that user message means nothing came back.\n * The transcript's shape alone detects it, needing no store method and no\n * `pagehide` listener \u2014 neither of which fires on a crash or force-quit.\n *\n * An agent-initiated reload is not this case: a navigating tool leaves a\n * checkpoint and resumes, so the caller returns early on one.\n *\n * Deliberately a notice, never a resume. AG-UI has no resume-an-aborted-run\n * primitive, and re-sending the accumulated messages is semantically a new\n * run, so any server-side tool already executed would run a second time.\n */\n /**\n * Build a round's context, recording which page it describes.\n *\n * The AG-UI client re-invokes this at the top of **every** tool round, not\n * once per `send()`, so the page map the agent sees is already refreshed\n * between rounds and the href captured here is the page it was shown for\n * *this* round. {@link #executeTool} compares against it to catch a page that\n * moved under a round still in flight.\n */\n #buildContext(): Context[] {\n this.#contextHref = window.location.href;\n return this.getContext();\n }\n\n /**\n * Whether the page moved since the current round's context was built.\n *\n * `null` means no round has built context yet (nothing to compare), which is\n * not a move.\n */\n #pageMoved(): boolean {\n return this.#contextHref !== null && this.#contextHref !== window.location.href;\n }\n\n #noticeIfRunUnfinished(messages: readonly Message[] | null): void {\n const last = messages?.at(-1);\n if (last === undefined || last.role !== MESSAGE_ROLE.USER) {\n return;\n }\n this.#appendNotice(\"\u26A0\", this.#strings.runInterrupted, \"interrupted\");\n }\n\n /**\n * Replay a restored message: text bubbles *and* tool activity. An assistant\n * turn may carry `toolCalls` (rendered as cards) and/or text; a `tool` turn\n * carries a result that settles the matching card. So a refreshed page shows\n * the full transcript \u2014 tool calls and their results \u2014 not just the prose.\n */\n #renderHistoricMessage(message: Message): void {\n const text = typeof message.content === \"string\" ? message.content : \"\";\n if (message.role === MESSAGE_ROLE.USER) {\n const attachments = messageAttachments(message);\n if (text !== \"\" || attachments.length > 0) {\n const bubble = this.appendMessage(MESSAGE_ROLE.USER, text);\n if (attachments.length > 0) {\n bubble.appendChild(renderAttachmentChips(attachments));\n }\n }\n return;\n }\n if (message.role === MESSAGE_ROLE.ASSISTANT) {\n if (text !== \"\") {\n // Restored history must appear statically \u2014 entrance animations\n // (fade / word) are for freshly-arriving messages. On reload the whole\n // transcript mounts at once, so animating every bubble's text in\n // parallel looks wrong. Mark it so the fade CSS skips it, and don't\n // wrap words.\n this.appendMessage(MESSAGE_ROLE.ASSISTANT, text).classList.add(\"message--restored\");\n }\n // Narrowed rather than trusted, for the same reason `messageAttachments`\n // narrows the neighbouring field: anything that throws in this loop aborts\n // the replay at this message, and every later turn silently disappears from\n // the transcript. See `restoredToolCalls`.\n for (const call of restoredToolCalls(message.toolCalls)) {\n const restored = {\n id: call.id,\n name: call.function.name,\n args: this.#parseArgs(call.function.arguments),\n };\n // Restored history goes through the same interception as the live\n // stream \u2014 otherwise a reload resurrects the raw `load_capability`\n // card the live path deliberately replaced.\n if (this.#noticeIfSkillLoad(restored)) {\n continue;\n }\n this.#cardFor(restored);\n }\n return;\n }\n if (message.role === \"tool\") {\n const card = this.#toolCards.get(message.toolCallId);\n if (card !== undefined) {\n card.settle(TOOL_CALL_STATUS.DONE, message.content);\n }\n }\n }\n\n /** Parse a tool call's JSON `arguments` from history into an object. */\n #parseArgs(raw: unknown): Record<string, unknown> {\n if (typeof raw !== \"string\") {\n // A restored call whose `arguments` are missing or not a string still has\n // a name worth showing, so this renders an empty-args card rather than\n // dropping the card.\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // Malformed history \u2014 fall back to empty args rather than failing replay.\n }\n return {};\n }\n\n /**\n * Word-by-word reveal for the `word` text-animation mode, applied to a\n * completed assistant bubble. `fade` is pure CSS (no JS); `none` is a no-op.\n */\n #revealWords(bubble: HTMLDivElement): void {\n if (this.getAttribute(\"data-text-animation\") === \"word\") {\n wrapWords(bubble);\n }\n }\n\n /** Complete the checkpointed navigating tool call and continue the run. */\n async #resumeFrom(checkpoint: NavigationCheckpoint): Promise<void> {\n this.conversationStore.saveCheckpoint(this.#threadId, null);\n const client = this.#ensureClient();\n client.addToolResult(checkpoint.toolCallId, JSON.stringify(this.navigationResult(checkpoint)));\n await client.resume();\n }\n\n /**\n * Append a message bubble and return it.\n *\n * Assistant content renders as sanitised markdown/HTML; user content stays\n * literal text, which also avoids rendering user-authored markup.\n *\n * Assistant bubbles land in the current answer group, opening one if needed;\n * a user bubble closes the prior group and sits directly in the list, the\n * well wrapping only the assistant turn.\n */\n appendMessage(role: MessageRole, content: string): HTMLDivElement {\n const bubble = document.createElement(\"div\");\n bubble.className = `message message--${role}`;\n bubble.setAttribute(\"part\", `message message-${role}`);\n if (role === MESSAGE_ROLE.ASSISTANT) {\n bubble.innerHTML = renderMarkdown(content, { allowImages: this.allowImages });\n // A finished bubble: rehydrated history, or a whole message appended at\n // once. The streaming bubble gets its buttons in onTextEnd instead.\n attachCopyButtons(bubble, this.#strings);\n this.#ensureGroup().appendChild(bubble);\n } else {\n this.#currentGroup = null;\n bubble.textContent = content;\n this.#messages.appendChild(bubble);\n }\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return bubble;\n }\n\n /**\n * The open answer group, creating and appending it on first use. Everything a\n * single assistant turn renders (text, tool cards, the pending indicator)\n * goes inside it, so the opt-in `data-answer-well` styling can box the whole\n * turn. Idempotent across the turn's runs \u2014 it persists until {@link #handlers}'\n * `onSettled` nulls it.\n */\n #ensureGroup(): HTMLDivElement {\n if (this.#currentGroup === null) {\n const group = document.createElement(\"div\");\n group.className = \"answer\";\n group.setAttribute(\"part\", \"answer\");\n this.#currentGroup = group;\n this.#messages.appendChild(group);\n this.#updateEmptyState();\n }\n return this.#currentGroup;\n }\n\n #render(): void {\n const style = document.createElement(\"style\");\n style.textContent = STYLES;\n\n this.#chat.className = \"chat\";\n this.#chat.setAttribute(\"part\", \"panel\");\n\n const header = document.createElement(\"div\");\n header.className = \"header\";\n header.setAttribute(\"part\", \"header\");\n\n const title = this.#title;\n title.className = \"header-title\";\n title.setAttribute(\"part\", \"title\");\n title.textContent = this.getAttribute(\"title-text\") ?? this.#strings.title;\n\n // Optional header icon: a slot (any markup) with a `data-icon-url` <img>\n // fallback. Rendered only when one of the two is provided, so the header has\n // no phantom gap otherwise.\n if (\n this.querySelector('[slot=\"icon\"]') !== null ||\n this.getAttribute(\"data-icon-url\") !== null\n ) {\n header.append(this.#iconElement(\"icon\", \"icon\", null));\n }\n\n // A coarse slot for host-provided header actions, between title and controls.\n const headerActions = document.createElement(\"slot\");\n headerActions.name = \"header-actions\";\n\n const controls = document.createElement(\"div\");\n controls.className = \"header-controls\";\n controls.setAttribute(\"part\", \"header-controls\");\n\n // Both controls delegate to the public methods, so a host chrome driving\n // them imperatively takes exactly the path the built-in button takes.\n const history = this.#headerButton(\"history\", this.#strings.chatHistory, \"\u2630\");\n history.addEventListener(\"click\", () => this.openThreads());\n\n // \u21BA rather than \u2B6F: the same idea in a glyph that has a font behind it in\n // every browser. The obscure one rendered as an unreadable mark at 14px, and a\n // header control nobody can name is one nobody presses.\n const checkpoints = this.#headerButton(\"checkpoints\", this.#strings.checkpoints, \"\u21BA\");\n checkpoints.addEventListener(\"click\", () => this.toggleCheckpoints());\n\n const newChat = this.#headerButton(\"new\", this.#strings.newChat, \"\u271A\");\n newChat.addEventListener(\"click\", () => this.newChat());\n\n const collapse = this.#headerButton(\"collapse\", this.#strings.collapse, \"\u2014\");\n collapse.addEventListener(\"click\", () => this.toggleCollapsed());\n\n // Only offered when the server actually indexes runs \u2014 without\n // `data-runs-url` there is nothing to continue and the button would open\n // a permanently empty panel. Asks `#runs()` rather than re-testing the\n // attribute, so \"configured\" means one thing everywhere (an empty value\n // is unset, not a relative URL to the current page).\n if (this.#runs() !== null) {\n controls.append(history, checkpoints, newChat);\n } else {\n controls.append(history, newChat);\n }\n // Optional built-in theme toggle: off unless the host opts in, so\n // it never competes with a host-supplied switch in `slot=\"header-actions\"`.\n if (this.getAttribute(\"data-theme-toggle\") !== null) {\n this.#themeToggle.type = \"button\";\n this.#themeToggle.className = \"header-btn header-btn--theme\";\n this.#themeToggle.setAttribute(\"part\", \"header-button theme-toggle\");\n this.#themeToggle.title = this.#strings.toggleTheme;\n this.#themeToggle.setAttribute(\"aria-label\", this.#strings.toggleTheme);\n this.#themeToggle.addEventListener(\"click\", () => this.toggleTheme());\n this.#syncThemeGlyph();\n controls.append(this.#themeToggle);\n }\n controls.append(collapse);\n header.append(title, headerActions, controls);\n\n this.#messages.className = \"messages\";\n this.#messages.setAttribute(\"part\", \"messages\");\n // Screen readers announce streamed messages as they arrive.\n this.#messages.setAttribute(\"role\", \"log\");\n this.#messages.setAttribute(\"aria-live\", \"polite\");\n this.#messages.setAttribute(\"aria-label\", this.#strings.conversation);\n\n // Empty-state region: a host slot at the top of the list, hidden as soon as\n // anything renders.\n this.#emptyWrap.className = \"empty\";\n this.#emptyWrap.setAttribute(\"part\", \"empty\");\n const emptySlot = document.createElement(\"slot\");\n emptySlot.name = \"empty\";\n this.#emptyWrap.append(emptySlot);\n this.#messages.append(this.#emptyWrap);\n\n const inputRow = document.createElement(\"div\");\n inputRow.className = \"input-row\";\n inputRow.setAttribute(\"part\", \"composer\");\n\n // One bordered surface holds the field and the tool row under it, so the\n // icon buttons stop competing with the field for weight.\n const composer = document.createElement(\"div\");\n composer.className = \"composer\";\n composer.setAttribute(\"part\", \"composer-surface\");\n\n const tools = document.createElement(\"div\");\n tools.className = \"composer-tools\";\n tools.setAttribute(\"part\", \"composer-tools\");\n\n this.#input.className = \"input\";\n this.#input.setAttribute(\"part\", \"input\");\n this.#input.setAttribute(\"aria-label\", this.#strings.message);\n this.#input.rows = 1;\n this.#input.placeholder = this.#strings.inputPlaceholder;\n this.#input.addEventListener(\"keydown\", (event) => this.#onKeydown(event));\n this.#input.addEventListener(\"input\", () => this.#onInput());\n\n // Icon-only, with both glyphs mounted at once and CSS showing the one the\n // state calls for \u2014 swapping a single glyph would leave a host that slotted\n // its own Send mark holding a stop icon mid-run.\n this.#send.className = \"send\";\n this.#send.type = \"button\";\n this.#send.setAttribute(\"part\", \"send\");\n this.#send.append(\n this.#glyphSlot(\"icon-send\", \"send-send\", ICON_SEND),\n this.#glyphSlot(\"icon-stop\", \"send-stop\", ICON_STOP),\n );\n this.#send.title = this.#strings.send;\n this.#send.setAttribute(\"aria-label\", this.#strings.send);\n this.#send.dataset[\"state\"] = \"idle\";\n this.#send.addEventListener(\"click\", () => {\n // One button, two states: Send while idle, Stop while a run is in\n // flight (no layout change).\n if (this.#running) {\n this.#cancelRun();\n return;\n }\n void this.#submit();\n });\n\n this.#skillHint.className = \"skill-hint\";\n this.#skillHint.setAttribute(\"part\", \"skill-hint\");\n this.#skillHint.hidden = true;\n\n // File-upload affordance: a paperclip button (hidden until\n // `data-attachments-url` is wired) opening a hidden multi-file input.\n // Drag-and-drop covers the whole shell (wired in #enableDragAndDrop).\n this.#attachButton.className = \"attach-btn\";\n this.#attachButton.type = \"button\";\n this.#attachButton.setAttribute(\"part\", \"attach-button\");\n this.#attachButton.append(this.#glyphSlot(\"icon-attach\", \"attach-glyph\", ICON_ATTACH));\n this.#attachButton.title = this.#strings.attachFiles;\n this.#attachButton.setAttribute(\"aria-label\", this.#strings.attachFiles);\n this.#attachButton.hidden = true;\n this.#attachButton.addEventListener(\"click\", () => this.#fileInput.click());\n\n this.#fileInput.className = \"attach-input\";\n this.#fileInput.type = \"file\";\n this.#fileInput.multiple = true;\n this.#fileInput.hidden = true;\n this.#fileInput.addEventListener(\"change\", () => this.#onFilesPicked());\n\n this.#attachSlot.className = \"attachment-slot\";\n\n // Mic button mount point (kept empty until #wireVoice mounts the control).\n this.#voiceSlot.className = \"voice-slot\";\n\n // A coarse footer slot below the composer.\n const footer = document.createElement(\"slot\");\n footer.name = \"footer\";\n\n tools.append(this.#attachButton, this.#voiceSlot, this.#send);\n composer.append(this.#input, tools);\n inputRow.append(composer, this.#fileInput);\n // Skill surfaces sit just above the input: palette (opens on `/`), chips,\n // the missing-placeholder hint, and the pending-attachments tray.\n this.#chat.append(\n header,\n this.#messages,\n this.#skillsMenu.palette,\n this.#skillsMenu.chips,\n this.#skillHint,\n this.#attachSlot,\n inputRow,\n footer,\n this.#drawer.element,\n this.#checkpoints.element,\n );\n\n // Clicking away dismisses the checkpoints popover. Escape already did, and the\n // drawer has a backdrop that swallows the click \u2014 this popover has neither, so\n // it could only be closed by answering it.\n //\n // `pointerdown`, and the header button excluded: pointerdown runs *before* the\n // button's own click, so closing here and toggling there would land back open.\n // Composed path rather than `target`, because the event is retargeted at the\n // shadow boundary and every one of these nodes is inside it.\n this.#chat.addEventListener(\"pointerdown\", (event) => {\n if (!this.#checkpoints.open_) {\n return;\n }\n const path = event.composedPath();\n if (path.includes(this.#checkpoints.element) || path.includes(checkpoints)) {\n return;\n }\n this.#checkpoints.close();\n });\n\n // What a collapsed widget shrinks to: a round floating button, or the slim\n // edge rail under `placement=\"sidebar\"` \u2014 one element, shaped by CSS.\n // A sibling of the panel, so it survives the panel being hidden.\n this.#launcher.className = \"launcher\";\n this.#launcher.type = \"button\";\n this.#launcher.setAttribute(\"part\", \"launcher\");\n this.#launcher.setAttribute(\"aria-label\", this.#strings.expand);\n this.#badge.className = \"launcher-badge\";\n this.#badge.setAttribute(\"part\", \"launcher-badge\");\n // The count is announced through the launcher's own label, so the badge is\n // decoration to a screen reader rather than a second, context-free number.\n this.#badge.setAttribute(\"aria-hidden\", \"true\");\n this.#badge.hidden = true;\n this.#launcher.append(\n this.#iconElement(\"launcher\", \"launcher-icon\", ICON_LAUNCHER, this.#launcherIconUrl()),\n this.#badge,\n );\n this.#launcher.addEventListener(\"click\", () => this.setCollapsed(false));\n\n this.#chat.append(\n createResizeHandle({\n axis: () => this.#resizeAxis(),\n anchor: () => this.#measureAnchor(),\n rect: () => this.getBoundingClientRect(),\n apply: (size) => this.#applySize(size),\n commit: (size) => {\n this.#persistSize(size);\n // Re-stamp after the drag: a host whose layout changed underneath us\n // would otherwise keep the grip in the old corner, which reads as the\n // control being in the wrong place even though the drag was right.\n this.#syncResizeAnchor();\n },\n label: this.#strings.resizePanel,\n }),\n );\n this.#root.append(style, this.#chat, this.#launcher);\n }\n\n /**\n * Build a header control button: a named slot a host can project markup into,\n * with the built-in glyph as the slot's fallback.\n *\n * The slot is what lets a host replace the mark with its own `<img>` or\n * `<svg>` rather than only restyle it through the `part`; the same\n * slot-with-fallback idiom the header icon uses.\n */\n #headerButton(modifier: string, label: string, glyph: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `header-btn header-btn--${modifier}`;\n button.setAttribute(\"part\", `header-button ${modifier}-button`);\n button.title = label;\n button.setAttribute(\"aria-label\", label);\n const slot = document.createElement(\"slot\");\n slot.name = `icon-${modifier}`;\n slot.append(document.createTextNode(glyph));\n button.append(slot);\n return button;\n }\n\n /**\n * A `<slot>` a host can project its own mark into, falling back to one of the\n * built-in glyphs. The markup is an author-written constant, never user or\n * server data, so it is assigned directly rather than sanitised.\n */\n #glyphSlot(slotName: string, className: string, markup: string): HTMLSlotElement {\n const slot = document.createElement(\"slot\");\n slot.name = slotName;\n slot.className = className;\n slot.innerHTML = markup;\n return slot;\n }\n\n /**\n * The launcher's own image URL. `data-launcher-icon-url` lets the collapsed\n * button carry a different mark from the header's \u2014 a product logo reads at\n * 22px in a header bar but rarely at 26px in a circle \u2014 and falls back to the\n * header icon so a single `data-icon-url` still feeds both.\n */\n #launcherIconUrl(): string | null {\n return this.getAttribute(\"data-launcher-icon-url\") ?? this.getAttribute(\"data-icon-url\");\n }\n\n /**\n * An icon holder wrapping a `<slot>` so a host can project custom markup;\n * with an `<img>` as the slot's fallback when an icon URL is configured, or\n * the given glyph markup when it is not.\n */\n #iconElement(\n slotName: string,\n part: string,\n fallbackGlyph: string | null,\n iconUrl: string | null = this.getAttribute(\"data-icon-url\"),\n ): HTMLSpanElement {\n const holder = document.createElement(\"span\");\n holder.className = \"icon-holder\";\n holder.setAttribute(\"part\", part);\n const slot = document.createElement(\"slot\");\n slot.name = slotName;\n if (iconUrl !== null) {\n const img = document.createElement(\"img\");\n img.className = \"icon-img\";\n img.src = iconUrl;\n img.alt = \"\";\n slot.append(img);\n } else if (fallbackGlyph !== null) {\n slot.innerHTML = fallbackGlyph;\n }\n holder.append(slot);\n return holder;\n }\n\n /**\n * Reflect the collapsed state and the unread count on the launcher.\n *\n * The count is also the launcher's accessible name: a badge that only exists\n * as a coloured dot says nothing to a screen reader, and \"Expand\" alone would\n * be a lie once answers are waiting behind it.\n */\n #syncLauncher(): void {\n this.#launcher.setAttribute(\"aria-expanded\", String(!this.collapsed));\n const unread = this.#unread;\n // Past 9 the exact number stops being information and starts being a\n // layout problem \u2014 the badge is a circle, not a field.\n this.#badge.textContent = unread > 9 ? \"9+\" : String(unread);\n this.#badge.hidden = unread === 0 || !this.#badgeEnabled();\n const label = this.#badge.hidden\n ? this.#strings.expand\n : this.#strings.expandUnread.replace(\"{count}\", String(unread));\n this.#launcher.setAttribute(\"aria-label\", label);\n this.#launcher.title = label;\n }\n\n /**\n * The unread badge, unlike every other affordance here, is on by default:\n * a collapsed widget is the one state where an answer can arrive with nothing\n * on screen to say so. `data-unread-badge=\"false\"` turns it off for a host\n * that drives its own chrome from the `ag-ui-unread` event.\n */\n #badgeEnabled(): boolean {\n return this.getAttribute(\"data-unread-badge\") !== \"false\";\n }\n\n /**\n * Set the unread count, repaint the badge, and tell the host.\n *\n * The count is kept whether or not the badge renders it, so `unread` stays\n * truthful for a host chrome and switching the badge on mid-session doesn't\n * start from a number that was never counted.\n */\n #setUnread(count: number): void {\n this.#unread = count;\n this.#syncLauncher();\n this.dispatchEvent(\n new CustomEvent<UnreadDetail>(UNREAD_EVENT, {\n detail: { unread: count },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /**\n * Count an answer the user cannot have seen: one that finished while the\n * widget was collapsed. Expanding is what marks them read.\n */\n #noteUnread(): void {\n if (!this.collapsed) {\n return;\n }\n this.#setUnread(this.#unread + 1);\n }\n\n /** Hide the empty-state region once the message list holds anything else. */\n #updateEmptyState(): void {\n this.#emptyWrap.hidden = this.#messages.childElementCount > 1;\n }\n\n /** Forward input changes to the skills palette and clear any stale hint. */\n #onInput(): void {\n this.#skillsMenu.onInput(this.#input.value);\n this.#skillHint.hidden = true;\n this.#autoGrow();\n }\n\n #onKeydown(event: KeyboardEvent): void {\n // The skills palette consumes arrows/enter/escape while open.\n if (this.#skillsMenu.onKeydown(event)) {\n event.preventDefault();\n return;\n }\n // Escape-to-cancel \u2014 only reachable when the palette is closed (it\n // consumed the key above otherwise), so the two Escapes don't clash.\n if (event.key === \"Escape\" && this.#running) {\n event.preventDefault();\n this.#cancelRun();\n return;\n }\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n void this.#submit();\n }\n }\n\n /**\n * Stop the in-flight run: decline any confirmation card awaiting a decision\n * (the loop is suspended on it), then cancel the client run \u2014 the abort\n * closes the streaming request, which is AG-UI's cancel (the server\n * observes the disconnect).\n */\n #cancelRun(): void {\n this.#confirmAbort?.abort();\n this.#client?.cancel();\n }\n\n /**\n * Swap the composer button between Send (idle) and Stop (running).\n *\n * The glyph is swapped by CSS from `data-state` \u2014 both are mounted \u2014 so this\n * only has to move the accessible name, which is the button's whole label now\n * that it carries no text.\n */\n #setRunning(running: boolean): void {\n this.#running = running;\n const label = running ? this.#strings.stop : this.#strings.send;\n this.#send.title = label;\n this.#send.setAttribute(\"aria-label\", label);\n this.#send.dataset[\"state\"] = running ? \"running\" : \"idle\";\n }\n\n /**\n * Size the field to its content: one row when empty, growing with what is\n * typed until the CSS ceiling takes over and it scrolls.\n *\n * Resetting to `auto` first is what makes it shrink again \u2014 `scrollHeight`\n * never reports less than the current height, so measuring without the reset\n * would ratchet the composer taller and never back down.\n */\n #autoGrow(): void {\n this.#input.style.height = \"auto\";\n this.#input.style.height = `${this.#input.scrollHeight}px`;\n }\n\n async #submit(): Promise<void> {\n // Ignore a submit while a run is in flight \u2014 the single choke point for\n // both Enter and the Send button. The button already turns into Stop, but\n // Enter has no such guard; without this it would start a second concurrent\n // SSE run that orphans the first (unabortable) and lets the second run's\n // settle sweep corrupt the first's still-pending tool cards.\n if (this.#running) {\n return;\n }\n const content = this.#input.value.trim();\n const attachments = this.#attachTray?.readyRefs() ?? [];\n // Allow an attachments-only message (no typed text), but nothing empty.\n if (content === \"\" && attachments.length === 0) {\n return;\n }\n this.#input.value = \"\";\n this.#autoGrow();\n // A file still uploading does not ride along \u2014 `readyRefs()` returns only\n // settled ones, and `clearReady()` deliberately keeps the rest for a\n // follow-up. Nothing said so, which is the whole defect: attachments are\n // frequently the entire point of the message, and the user had no way to\n // tell theirs had been left behind. Say it before dropping the chips,\n // while `hasPending()` still describes this send.\n if (this.#attachTray?.hasPending() === true) {\n this.#appendNotice(\n \"\\u{1F4CE}\",\n this.#strings.attachmentsStillUploading.replace(\n \"{n}\",\n String(this.#attachTray.pendingCount()),\n ),\n \"attachment-pending\",\n );\n }\n // The refs ride the message from here; drop the settled chips, keep any\n // still uploading for a follow-up message.\n this.#attachTray?.clearReady();\n await this.sendMessage(content, attachments);\n }\n\n /**\n * Send a message as if the user had typed it \u2014 renders the user bubble,\n * dispatches {@link SUBMIT_EVENT}, and starts the run.\n *\n * The programmatic half of the composer, for a host driving its own input.\n * Everything the built-in Send does happens here; Send reads the composer,\n * clears it, and calls this.\n *\n * `attachments` are durable {@link AttachmentRef}s \u2014 what {@link attachFile}\n * resolves to and what {@link ATTACHMENT_EVENT} reports.\n *\n * No-ops on an empty message, and while a run is in flight, since a second\n * concurrent run would orphan the first. Unlike the built-in Send it does not\n * consult the tray: what you pass is what is sent.\n */\n async sendMessage(content: string, attachments: readonly AttachmentRef[] = []): Promise<void> {\n if (this.#running || (content === \"\" && attachments.length === 0)) {\n return;\n }\n const bubble = this.appendMessage(MESSAGE_ROLE.USER, content);\n if (attachments.length > 0) {\n bubble.appendChild(renderAttachmentChips(attachments));\n }\n this.dispatchEvent(\n new CustomEvent<SubmitDetail>(SUBMIT_EVENT, {\n detail: { content, attachments },\n bubbles: true,\n composed: true,\n }),\n );\n await this.#client_send(content, attachments);\n }\n\n /**\n * Queue a file for upload into the attachment tray, exactly as the file\n * picker and drag-and-drop do \u2014 validation, progress chip, and all.\n *\n * Returns `false` when uploads are not configured (no `data-attachments-url`\n * and no {@link uploadHandler}) \u2014 the only signal a host gets, since the tray\n * does not exist to report anything then.\n *\n * Uploading is asynchronous: watch {@link ATTACHMENT_EVENT} for the resulting\n * {@link AttachmentRef} and pass it to {@link sendMessage} once `pending`\n * reaches zero.\n */\n attachFile(file: File): boolean {\n if (this.#attachTray === null) {\n return false;\n }\n this.#attachTray.add(file);\n return true;\n }\n\n /** Tell the host what the tray now holds \u2014 see {@link ATTACHMENT_EVENT}. */\n #dispatchAttachments(tray: AttachmentTray): void {\n this.dispatchEvent(\n new CustomEvent<AttachmentsDetail>(ATTACHMENT_EVENT, {\n detail: { attachments: tray.readyRefs(), pending: tray.pendingCount() },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n async #client_send(content: string, attachments: readonly AttachmentRef[]): Promise<void> {\n if (this.endpoint === \"\") {\n return;\n }\n await this.#ensureClient().send(content, attachments);\n }\n\n #ensureClient(): AgUiClient {\n if (this.#client === null) {\n const agent = this.agentFactory({\n endpoint: this.endpoint,\n headers: this.#requestHeaders(),\n // Live getter: the client is built once and cached, but a rotated\n // token must still reach every request \u2014 the factory's fetch wrapper\n // re-reads this on each call.\n getHeaders: () => this.#requestHeaders(),\n ...this.#credentialsOption(),\n threadId: this.#threadId,\n initialMessages: this.#initialMessages,\n initialState: this.#sharedState,\n });\n this.#client = new AgUiClient({\n agent,\n handlers: this.#handlers(),\n getTools: () => this.getTools(),\n getContext: () => this.#buildContext(),\n executeTool: (call) => this.#executeTool(call),\n resolveInterrupts: (interrupts) => this.#resolveInterrupts(interrupts),\n onPersist: (messages) => this.conversationStore.saveMessages(this.#threadId, messages),\n onStateChanged: (state) => this.#onSharedStateChanged(state),\n connectionLostMessage: this.#strings.connectionLost,\n });\n }\n return this.#client;\n }\n\n /** Mirror the agent's applied state and tell the host it moved. */\n #onSharedStateChanged(state: Readonly<Record<string, unknown>>): void {\n this.#sharedState = { ...state };\n this.dispatchEvent(\n new CustomEvent<StateDetail>(STATE_EVENT, {\n detail: { state: this.#sharedState },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /** Whether ``call`` should be gated behind the confirmation card. */\n async #needsConfirmation(call: AgUiToolCall, tool: ClientTool): Promise<boolean> {\n if (this.autoConfirm) {\n return false;\n }\n if (this.confirmPredicate !== null) {\n return (await this.confirmPredicate(call.name, call.args)) === true;\n }\n return isDestructive(tool.parameters);\n }\n\n async #executeTool(call: AgUiToolCall): Promise<ToolExecution | null> {\n // A skill load already rendered as a notice on the stream; it is never a\n // client tool and its result is pydantic-ai's business, so it must not\n // acquire a card here on the way to the no-result fallback below.\n if (skillNameFrom(call) !== null) {\n return null;\n }\n const card = this.#cardFor(call);\n this.#toolCards.delete(call.id);\n const tool = this.#resolveTool(call.name);\n if (tool === null) {\n // Not a client tool. A server-side tool's real output arrives via\n // `onToolResult` (TOOL_CALL_RESULT) and already settled the card \u2014 only\n // fall back when it didn't. When no result ever arrived, the call wasn't\n // executed by either side (no handler, no server result), so say so\n // honestly rather than claiming server execution. We do NOT show the\n // pending indicator: nothing here triggers another client round, so it\n // would hang after the run ended.\n if (!this.#serverSettled.has(call.id)) {\n card.settle(TOOL_CALL_STATUS.DONE, this.#strings.noResult);\n }\n return null;\n }\n // The page moved under this round. Acting now would target whatever\n // matches on the new page, and the case worth preventing is a same-named\n // control matching silently \u2014 the only way the agent acts on the wrong page\n // without either side noticing.\n //\n // Must precede the confirmation prompt, so the user is never asked to\n // approve an action about to be refused. Navigating tools are exempt, since\n // moving the page is their job, as is read_page, the documented recovery.\n // Gated on a page-map provider: without one there is no read_page to\n // recommend and the host's tools are not page-scoped anyway.\n if (\n this.getPageMap !== null &&\n call.name !== READ_PAGE_TOOL &&\n !isNavigates(tool.parameters) &&\n this.#pageMoved()\n ) {\n const message = this.#strings.pageMoved;\n card.settle(TOOL_CALL_STATUS.ERROR, message);\n this.#showPending();\n return { content: `Error: ${message}`, error: message };\n }\n if (await this.#needsConfirmation(call, tool)) {\n const request: ConfirmationRequest = { toolName: call.name, args: call.args };\n const confirmText = tool.parameters[X_CONFIRM_KEY];\n if (typeof confirmText === \"string\") {\n request.message = confirmText;\n }\n // The run loop is suspended on this card; a Stop while it's open aborts\n // the controller, resolving the decision as declined.\n this.#confirmAbort = new AbortController();\n // Into the turn's answer group, like every other inline card. Appending\n // to the message list made it a sibling *after* the group, so anything\n // that streamed afterwards rendered above it and the prompt drifted to\n // the foot of the turn no matter when it was asked.\n const decision = requestConfirmation(this.#ensureGroup(), request, {\n signal: this.#confirmAbort.signal,\n strings: this.#strings,\n });\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n const accepted = await decision;\n this.#confirmAbort = null;\n card.recordDecision(accepted ? \"approved\" : \"declined\");\n if (!accepted) {\n const message = this.#strings.declinedAction;\n card.settle(TOOL_CALL_STATUS.DECLINED, message);\n this.#showPending();\n return { content: message };\n }\n }\n // A navigating tool reloads only without a client-side router; with a\n // host `navigate()` (SPA) it routes in-page and the loop just continues.\n const navigates = isNavigates(tool.parameters) && this.navigate === null;\n if (navigates) {\n // Checkpoint before the handler reloads the page; the history (incl.\n // this tool call) was already persisted when the run that produced it\n // settled. The result is supplied on the next mount via the resume path.\n this.conversationStore.saveCheckpoint(this.#threadId, { toolCallId: call.id });\n }\n try {\n const result = await tool.handler(call.args);\n if (navigates) {\n card.settle(TOOL_CALL_STATUS.DONE, this.#strings.navigating);\n return { content: \"\", halt: true };\n }\n const content = JSON.stringify(result ?? null);\n card.settle(TOOL_CALL_STATUS.DONE, content);\n this.#showPending();\n return { content };\n } catch (error) {\n if (navigates) {\n // The navigation never happened; drop the dangling checkpoint.\n this.conversationStore.saveCheckpoint(this.#threadId, null);\n }\n const message = error instanceof Error ? error.message : String(error);\n card.settle(TOOL_CALL_STATUS.ERROR, message);\n this.#showPending();\n return { content: `Error: ${message}`, error: message };\n }\n }\n\n /**\n * Render an approval card per server-side-tool interrupt and collect the\n * user's decisions (approve \u2192 run it, deny \u2192 decline it).\n *\n * **One card per gated call, in that call's own tool card, all at once.** A run\n * can defer several calls, and the wire answers each independently \u2014 so the UI\n * has to let a person answer each independently, which means saying which is\n * which. The prompt cannot: it comes from the tool's `x-confirm` and is\n * identical for every call of that tool. The tool card can, by position, and it\n * is already showing the arguments. Asking them serially was the other half of\n * the problem: the second question only appeared once the first was answered,\n * so a person could neither compare them nor tell that more were coming.\n *\n * Each gated card is marked `deferred` for the wait. That is not cosmetic \u2014 at\n * `pending` it read \"running\u2026\" while the stream was over and the server idle.\n *\n * The run is suspended on these cards. A Stop while any is open aborts the\n * shared {@link #confirmAbort} controller, resolving every still-open card as\n * denied. An approved tool runs on the follow-up resume run and streams its\n * result into the same card (returned to `pending`, since it now really is\n * running); a denied one settles here, as no result will ever arrive.\n */\n async #resolveInterrupts(\n interrupts: readonly Interrupt[],\n ): Promise<Record<string, InterruptResponse>> {\n // One controller covers the whole batch: a single Stop denies all of them.\n this.#confirmAbort = new AbortController();\n this.#hidePending();\n const signal = this.#confirmAbort.signal;\n const answered = await Promise.all(\n interrupts.map(async (interrupt) => {\n const card =\n interrupt.toolCallId !== undefined\n ? this.#toolCards.get(interrupt.toolCallId)\n : undefined;\n const request: ApprovalRequest = {};\n const phrase = confirmPhrase(interrupt) ?? interrupt.message;\n if (phrase !== undefined) {\n request.message = phrase;\n }\n const toolName = card?.element.getAttribute(\"data-tool-name\");\n if (toolName !== null && toolName !== undefined) {\n request.toolName = toolName;\n }\n card?.mark(TOOL_CALL_STATUS.DEFERRED);\n // A host-supplied renderer takes full control of the approval UI. The\n // built-in card renders into the gated call's own card, falling back to\n // the answer group when the interrupt names no call we hold one for.\n const approved =\n this.approvalRenderer !== null\n ? await this.approvalRenderer(request, { signal })\n : await requestApproval(card?.approvalSlot ?? this.#ensureGroup(), request, {\n signal,\n strings: this.#strings,\n });\n // Same annotation as the client-side confirmation gate. Without it the\n // two gates read differently for the same act: a locally-confirmed call\n // said who let it through and a server-gated one said nothing, which is\n // backwards, since the server-side gate is the one guarding the tools\n // that actually run on the backend.\n card?.recordDecision(approved ? \"approved\" : \"declined\");\n if (approved) {\n card?.mark(TOOL_CALL_STATUS.PENDING);\n } else {\n // No TOOL_CALL_RESULT will stream for a denied tool \u2014 settle its card\n // now rather than leaving it hanging until the onSettled sweep.\n card?.settle(TOOL_CALL_STATUS.DECLINED, this.#strings.declinedAction);\n }\n return { id: interrupt.id, approved };\n }),\n );\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n this.#confirmAbort = null;\n const responses: Record<string, InterruptResponse> = {};\n for (const { id, approved } of answered) {\n responses[id] = approved\n ? { status: \"resolved\", payload: { approved: true } }\n : { status: \"cancelled\" };\n }\n return responses;\n }\n\n #handlers(): AgUiClientHandlers {\n return {\n onRunStart: () => {\n this.#setRunning(true);\n // Open the answer group on the turn's first run so the pending\n // indicator (and everything after) lands inside the well. Idempotent:\n // later rounds of the same turn reuse it.\n this.#ensureGroup();\n this.#showPending();\n },\n onReasoningStart: () => {\n // The model is thinking: swap the pending dots for a live thoughts\n // region at the top of the turn's answer group.\n this.#hidePending();\n this.#showThoughts();\n },\n onReasoningDelta: (buffer) => {\n this.#showThoughts().stream(buffer);\n },\n onReasoningEnd: () => {\n // Leave the region expanded until the answer text starts \u2014 it collapses\n // on the first text delta (onTextDelta).\n },\n onTextDelta: (buffer) => {\n this.#hidePending();\n // The answer has begun \u2014 fold the thoughts away so they don't crowd it.\n this.#thoughts?.collapse();\n this.#streamInto(buffer);\n this.#streamDeltas += 1;\n },\n onTextEnd: (buffer) => {\n const bubble = this.#streamInto(buffer);\n // Only reveal word-by-word when the message arrived at once. If it\n // streamed across multiple deltas it already revealed progressively, so\n // wrapping it now would re-animate the whole message \u2014 the awkward\n // \"finished response replays one word at a time\" bug.\n if (this.#streamDeltas <= 1) {\n this.#revealWords(bubble);\n }\n attachCopyButtons(bubble, this.#strings);\n this.#streamingBubble = null;\n this.#noteUnread();\n },\n onToolCall: (call) => {\n this.#hidePending();\n // A skill activation is an ordinary `load_capability` tool call \u2014 the\n // deferred-capability mechanism pydantic-ai already uses \u2014 so it arrives\n // here rather than on a channel of its own. Render it as a notice and\n // *return*: falling through would show a raw tool card beside the chip,\n // which is worse than the card alone.\n if (this.#noticeIfSkillLoad(call)) {\n return;\n }\n // Recorded after the skill-load return: a capability load is the agent\n // arranging itself, not work a host's data could have moved under.\n this.#runTools.push({ id: call.id, name: call.name });\n this.#cardFor(call);\n },\n onActivity: (activityType, content) => {\n if (activityType !== COMPACTION_ACTIVITY_TYPE) {\n return;\n }\n const removed = compactionRemoved(content);\n if (removed === null) {\n return;\n }\n this.#appendNotice(\n \"\uD83D\uDDDC\",\n this.#strings.historyCompacted.replace(\"{count}\", String(removed)),\n \"compaction\",\n );\n },\n onToolResult: (toolCallId, content) => {\n const card = this.#toolCards.get(toolCallId);\n if (card === undefined) {\n return;\n }\n card.settle(TOOL_CALL_STATUS.DONE, content);\n this.#serverSettled.add(toolCallId);\n // The card stops being the live thing the moment it settles, and the\n // server goes straight back to the model with the result -- a wait with\n // nothing on screen to own it, and the longest one in a run when the\n // result is a large inlined attachment being re-sent with every request.\n // The dots go back where ``onToolCall`` took them from, after the card,\n // and whatever comes next clears them: reasoning, the first text delta,\n // the round ending, or ``onSettled``'s terminal guarantee.\n //\n // Not the same case as the one ``#executeTool`` refuses to show them\n // for. That runs after the run has ended, so there is nothing left to\n // clear them and they would hang -- which is what happened before 0.2.1\n // and is why they were removed from here too. The terminal guarantee\n // that shipped in the same release is what makes showing them safe now.\n this.#showPending();\n },\n onRunEnd: () => {\n // Per-round end; the button stays on Stop until the whole interaction\n // settles \u2014 the user must be able to cancel between tool rounds.\n this.#hidePending();\n this.#streamingBubble = null;\n },\n onError: (message) => {\n this.#hidePending();\n this.#revealWords(this.appendMessage(MESSAGE_ROLE.ASSISTANT, `\u26A0\uFE0F ${message}`));\n this.#streamingBubble = null;\n },\n onCancelled: () => {\n // Deliberate stop, not a failure: keep whatever partial text already\n // streamed and add a muted note instead of an error bubble.\n this.#hidePending();\n this.#appendStoppedNote();\n this.#streamingBubble = null;\n },\n onSettled: () => {\n // Terminal guarantee: whatever path ended the run, return to rest.\n this.#hidePending();\n this.#setRunning(false);\n this.#streamingBubble = null;\n // Belt-and-suspenders: a tool card still pending at settle (e.g. a\n // server tool whose result never streamed because the connection\n // dropped) would hang forever \u2014 settle it to the no-result fallback.\n for (const card of this.#toolCards.values()) {\n if (!card.settled) {\n card.settle(TOOL_CALL_STATUS.DONE, this.#strings.noResult);\n }\n }\n // Close the turn's answer group. Drop it if the turn rendered nothing\n // (e.g. a server-only round that streamed no text/card) so an opted-in\n // well leaves no empty box behind.\n if (this.#currentGroup !== null && this.#currentGroup.childElementCount === 0) {\n this.#currentGroup.remove();\n this.#updateEmptyState();\n }\n this.#currentGroup = null;\n this.#thoughts = null;\n this.#dispatchRunFinished();\n },\n };\n }\n\n /**\n * Tell the host the interaction is over and what ran in it.\n *\n * Last thing in `onSettled`, so a listener that refetches sees a transcript\n * that has already stopped changing. `side` is read from the streamed-result\n * bookkeeping rather than from the tool list: whether a call executed on the\n * server is a fact about the run, and a name can appear on both sides across a\n * conversation.\n */\n #dispatchRunFinished(): void {\n const tools: ToolRun[] = this.#runTools.map(({ id, name }) => ({\n name,\n side: this.#serverSettled.has(id) ? \"server\" : \"client\",\n }));\n this.#runTools = [];\n this.dispatchEvent(\n new CustomEvent<RunFinishedDetail>(RUN_FINISHED_EVENT, {\n detail: { tools },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /** A muted \"\u23F9 Stopped\" line in the transcript (distinct from the \u26A0\uFE0F error bubble). */\n #appendStoppedNote(): void {\n const note = document.createElement(\"div\");\n note.className = \"stopped-note\";\n note.setAttribute(\"part\", \"stopped\");\n note.setAttribute(\"role\", \"status\");\n note.textContent = this.#strings.stopped;\n this.#ensureGroup().appendChild(note);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n /**\n * Show a \"thinking\" indicator while the agent is being awaited \u2014 both the\n * silent stretch before the first token and the gap after a tool result\n * while the next round is requested. Idempotent.\n */\n #showPending(): void {\n if (this.#pending !== null) {\n return;\n }\n const pending = document.createElement(\"div\");\n pending.className = \"pending\";\n pending.setAttribute(\"part\", \"pending\");\n pending.setAttribute(\"role\", \"status\");\n pending.setAttribute(\"aria-label\", this.#strings.thinking);\n for (let i = 0; i < 3; i += 1) {\n const dot = document.createElement(\"span\");\n dot.className = \"pending-dot\";\n pending.appendChild(dot);\n }\n this.#pending = pending;\n this.#ensureGroup().appendChild(pending);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n /** Remove the pending indicator if shown. */\n #hidePending(): void {\n this.#pending?.remove();\n this.#pending = null;\n }\n\n /**\n * The current turn's thoughts region, creating it (at the top of the answer\n * group, above any streamed text or tool cards) on first sight. Idempotent\n * across a turn's reasoning tokens.\n */\n #showThoughts(): ThoughtsBlock {\n if (this.#thoughts === null) {\n this.#thoughts = new ThoughtsBlock(this.#strings);\n const group = this.#ensureGroup();\n group.insertBefore(this.#thoughts.element, group.firstChild);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n return this.#thoughts;\n }\n\n #streamInto(buffer: string): HTMLDivElement {\n if (this.#streamingBubble === null) {\n this.#streamingBubble = this.appendMessage(MESSAGE_ROLE.ASSISTANT, \"\");\n this.#streamDeltas = 0;\n }\n this.#streamingBubble.innerHTML = renderMarkdown(buffer, { allowImages: this.allowImages });\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return this.#streamingBubble;\n }\n\n /**\n * The card for ``call``, creating and appending it on first sight.\n *\n * {@link AgUiClientHandlers.onToolCall} creates the card (pending) during the\n * run; {@link #executeTool} later retrieves the same card to settle it.\n */\n /**\n * Append an ambient run notice to the current group.\n *\n * Goes through {@link #ensureGroup} like a tool card so it lands *inside* the\n * assistant turn it annotates rather than floating between turns, and shares\n * the same pending-hide / scroll behaviour.\n */\n /**\n * Render a skill notice for a `load_capability` call; ``true`` when handled.\n *\n * Shared by the live stream and history replay so the transcript looks the\n * same before and after a reload.\n */\n #noticeIfSkillLoad(call: AgUiToolCall): boolean {\n const skill = skillNameFrom(call);\n if (skill === null) {\n return false;\n }\n this.#appendNotice(\"\u2728\", this.#strings.usingSkill.replace(\"{name}\", skill), \"skill\");\n return true;\n }\n\n #appendNotice(icon: string, text: string, kind: string): void {\n this.#ensureGroup().appendChild(renderRunNotice(icon, text, kind));\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n #cardFor(call: AgUiToolCall): ToolCallCard {\n const existing = this.#toolCards.get(call.id);\n if (existing !== undefined) {\n return existing;\n }\n // Prefer the tool's own `x-summary`; then an explicit `toolSummaries`\n // entry; then the fetched server catalog (`data-tools-url`). All cover\n // server-side tools whose schema never reached the browser.\n const labelled = this.#resolveTool(call.name)?.parameters[X_SUMMARY_KEY];\n const summary =\n typeof labelled === \"string\"\n ? labelled\n : (this.toolSummaries[call.name] ??\n this.#toolCatalog[call.name] ??\n prettifyToolName(call.name));\n const card = new ToolCallCard(call.name, call.args, summary, this.#strings);\n this.#toolCards.set(call.id, card);\n this.#ensureGroup().appendChild(card.element);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return card;\n }\n}\n\n/**\n * A server-authored question for a gated call, read off the interrupt's metadata.\n *\n * The question an AG-UI interrupt carries by default is the call itself, spelled\n * out: `Approve create_event({\"title\": \"Design sync\", \u2026})?`. Accurate, and not\n * something to put in front of a person. A client-side confirmation has\n * `x-confirm` on the tool's schema for exactly this, so the same key is read here\n * \u2014 whichever end gates a call, the phrase comes from one place, and a server\n * that supplies none keeps the generated text.\n *\n * Narrowed rather than trusted: `metadata` is `Record<string, any>` on the wire,\n * so anything at all can arrive under that key, and a non-string would render as\n * \"[object Object]\" in the one place a person is being asked to allow a write.\n */\nfunction confirmPhrase(interrupt: Interrupt): string | undefined {\n const phrase = interrupt.metadata?.[X_CONFIRM_KEY];\n return typeof phrase === \"string\" && phrase.trim() !== \"\" ? phrase : undefined;\n}\n\n/** One tool call as a restored assistant message carries it. */\ninterface RestoredToolCall {\n readonly id: string;\n readonly function: { readonly name: string; readonly arguments?: unknown };\n}\n\n/**\n * The tool calls a restored assistant turn carries, with anything shapeless dropped.\n *\n * Narrowing here rather than trusting the declared type, for three reasons that\n * point the same way.\n *\n * **`null` is a value this field really takes.** `@ag-ui/core` types `toolCalls`\n * as optional (`z.ZodOptional`), so TypeScript offers only `undefined` \u2014 but the\n * protocol's Python models declare `tool_calls: list[ToolCall] | None`, and a\n * server dumping them without `exclude_none` sends `null`. The two SDKs disagree\n * about the wire, and a client cannot afford to take either one's word for it.\n *\n * **A throw here costs the rest of the transcript.** This runs inside the replay\n * of stored history, one message at a time; an exception aborts the whole replay,\n * so a single bad entry silently truncates the conversation from that point on \u2014\n * with no error state and nothing on screen to explain the gap.\n *\n * **Storage is untrusted anyway** \u2014 hand-edited, truncated, written by an older\n * version, or supplied by a host's own store. `messageAttachments` already takes\n * exactly this stance for the neighbouring field on the same message.\n */\nfunction restoredToolCalls(value: unknown): readonly RestoredToolCall[] {\n return Array.isArray(value) ? value.filter(isRestoredToolCall) : [];\n}\n\n/** Whether an unknown history entry has enough shape to render a tool card. */\nfunction isRestoredToolCall(value: unknown): value is RestoredToolCall {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const call = value as { id?: unknown; function?: { name?: unknown } };\n return typeof call.id === \"string\" && typeof call.function?.name === \"string\";\n}\n\n/**\n * The skill name a `load_capability` call activated, or `null` when the call is\n * something else.\n *\n * Every deferred capability loads through this one tool, so the id is a skill\n * name only when the project wired agent skills; another project's capability\n * id surfaces here too. Acceptable for a muted notice, and better than a\n * parallel signal \u2014 the id is exactly what the model selected.\n */\nfunction skillNameFrom(call: AgUiToolCall): string | null {\n if (call.name !== LOAD_CAPABILITY_TOOL) {\n return null;\n }\n const id = (call.args as { id?: unknown } | null | undefined)?.id;\n return typeof id === \"string\" && id !== \"\" ? id : null;\n}\n\n/** The `removed` count from a compaction activity payload, or `null` if absent. */\nfunction compactionRemoved(content: unknown): number | null {\n const removed = (content as { removed?: unknown } | null | undefined)?.removed;\n return typeof removed === \"number\" ? removed : null;\n}\n", "import { ELEMENT_TAG } from \"../constants.js\";\nimport { AgUiChat } from \"./ag_ui_chat.js\";\n\n/**\n * Register the `<ag-ui-chat>` Custom Element.\n *\n * Idempotent: calling it more than once (or after another module already\n * registered the tag) is a no-op. Registration is an explicit step rather\n * than an import side effect so the package is SSR-safe and tree-shakeable.\n */\nexport function defineAgUiChat(): void {\n if (customElements.get(ELEMENT_TAG) === undefined) {\n customElements.define(ELEMENT_TAG, AgUiChat);\n }\n}\n", "import {\n type FlashOptions,\n focusWithFlash,\n type HighlightClickOptions,\n highlightThenClick,\n type PressOptions,\n pressThenClick,\n type SelectOptions,\n scrollIntoCenterView,\n selectOption,\n type TextLikeElement,\n type ToggleOptions,\n type TypeOptions,\n toggleControl,\n typeInto,\n} from \"./animations.js\";\nimport { setNativeChecked, setNativeValue } from \"./native_setter.js\";\n\n/**\n * Generic, framework-free DOM-driving primitives.\n *\n * Each operates on an element the caller has already located. Host packages\n * (e.g. `django-admin-agent`) wrap these with environment-aware lookups \u2014\n * `fill_field(name, value)` finds `#id_<name>` then calls {@link fillField}.\n */\n\n/**\n * Every flash option except `focus`, which is not on offer: a field has to hold\n * focus to be typed into.\n */\nexport interface FillFieldOptions extends TypeOptions, Omit<FlashOptions, \"focus\"> {}\n\n/**\n * Scroll to, focus (with a flash), and type `value` into a text field.\n *\n * The scroll is awaited \u2014 typing into an element still gliding past shows the\n * user nothing.\n */\nexport async function fillField(\n el: TextLikeElement,\n value: string,\n options: FillFieldOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await focusWithFlash(el, { ...options, flashMs: options.flashMs ?? 0 });\n await typeInto(el, value, options);\n}\n\n/** Scroll to, highlight, and click an element. */\nexport async function clickElement(\n el: HTMLElement,\n options: HighlightClickOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await highlightThenClick(el, options);\n}\n\n/** Scroll to a button/control and click it with a visible \"press\" animation. */\nexport async function pressButton(el: HTMLElement, options: PressOptions = {}): Promise<void> {\n await scrollIntoCenterView(el);\n await pressThenClick(el, options);\n}\n\n/** Scroll to a `<select>`, highlight it, and pick the matching option (animated). */\nexport async function selectControl(\n el: HTMLSelectElement,\n value: string,\n options: SelectOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await selectOption(el, value, options);\n}\n\n/** Scroll to a checkbox/radio, flash it, and set its checked state (animated). */\nexport async function toggleCheckbox(\n el: HTMLInputElement,\n checked: boolean,\n options: ToggleOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await toggleControl(el, checked, options);\n}\n\n/**\n * Set a `<select>` or checkbox value without animation, dispatching the `input`\n * and `change` events frameworks listen for.\n */\nexport function setControlValue(\n el: HTMLInputElement | HTMLSelectElement,\n value: string | boolean,\n): void {\n if (el instanceof HTMLInputElement && el.type === \"checkbox\") {\n setNativeChecked(el, Boolean(value));\n } else {\n setNativeValue(el, String(value));\n }\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n", "export const VERSION: string = \"0.25.2\";\n"],
|
|
5
|
-
"mappings": "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MACA,MACA,MACA,MACA,MACA,MACA,QACA,UACA,UACA,MACA,QACA,KACA,OACA,SACA,OACA,OACA,SACA,UACA,MACA,QACA,OACA,QACA,WACA,QACA,YACA,SACA,OACA,QACA,MACA,YACA,UACA,UACA,KACA,WACA,OACA,YACA,KACA,MACA,MACA,QACA,KACA,QACA,UACA,WACA,UACA,UACA,QACA,SACA,UACA,UACA,QACA,UACA,UACA,SACA,OACA,WACA,OACA,SACA,SACA,MACA,YACA,YACA,SACA,MACA,SACA,QACA,MACA,SACA,MACA,KACA,MACA,OACA,SACA,KAAK,CACG;AAEH,IAAMmG,QAAMnG,OAAO,CACxB,OACA,KACA,YACA,eACA,gBACA,gBACA,iBACA,oBACA,UACA,YACA,QACA,QACA,WACA,gBACA,eACA,UACA,QACA,KACA,SACA,YACA,SACA,SACA,aACA,QACA,kBACA,UACA,QACA,YACA,SACA,QACA,QACA,WACA,WACA,YACA,kBACA,QACA,QACA,SACA,UACA,UACA,QACA,YACA,SACA,QACA,SACA,QACA,OAAO,CACC;AAEH,IAAMoG,aAAapG,OAAO,CAC/B,WACA,iBACA,uBACA,eACA,oBACA,qBACA,qBACA,kBACA,gBACA,WACA,WACA,WACA,WACA,WACA,kBACA,WACA,WACA,eACA,gBACA,YACA,gBACA,sBACA,eACA,UACA,cAAc,CACN;AAMH,IAAMqG,gBAAgBrG,OAAO,CAClC,WACA,iBACA,UACA,WACA,aACA,oBACA,kBACA,iBACA,iBACA,iBACA,SACA,aACA,QACA,gBACA,aACA,WACA,iBACA,UACA,OACA,cACA,WACA,KAAK,CACG;AAEH,IAAMsG,WAAStG,OAAO,CAC3B,QACA,YACA,UACA,WACA,SACA,UACA,MACA,cACA,iBACA,MACA,MACA,SACA,WACA,YACA,SACA,QACA,MACA,UACA,SACA,UACA,QACA,QACA,WACA,UACA,OACA,SACA,OACA,UACA,cACA,aAAa,CACL;AAIH,IAAMuG,mBAAmBvG,OAAO,CACrC,WACA,eACA,cACA,YACA,aACA,WACA,WACA,UACA,UACA,SACA,aACA,cACA,kBACA,eACA,MAAM,CACE;AAEH,IAAMwG,OAAOxG,OAAO,CAAC,OAAO,CAAU;AC1RtC,IAAMkG,OAAOlG,OAAO,CACzB,UACA,UACA,SACA,OACA,kBACA,gBACA,wBACA,YACA,cACA,WACA,UACA,WACA,eACA,eACA,WACA,QACA,SACA,SACA,SACA,QACA,WACA,WACA,cACA,YACA,gBACA,UACA,eACA,YACA,YACA,WACA,OACA,YACA,2BACA,yBACA,YACA,aACA,WACA,gBACA,eACA,QACA,OACA,WACA,UACA,UACA,QACA,QACA,YACA,MACA,SACA,aACA,aACA,SACA,QACA,SACA,QACA,QACA,WACA,QACA,OACA,OACA,aACA,SACA,UACA,OACA,aACA,YACA,SACA,QACA,SACA,WACA,cACA,UACA,QACA,WACA,QACA,WACA,eACA,eACA,WACA,iBACA,uBACA,UACA,WACA,WACA,cACA,YACA,OACA,YACA,OACA,YACA,QACA,QACA,WACA,cACA,SACA,YACA,SACA,QACA,SACA,QACA,QACA,WACA,SACA,OACA,UACA,QACA,SACA,WACA,YACA,SACA,aACA,QACA,UACA,UACA,SACA,SACA,QACA,OAAO,CACC;AAEH,IAAMmG,MAAMnG,OAAO,CACxB,iBACA,cACA,YACA,sBACA,aACA,UACA,iBACA,iBACA,WACA,iBACA,kBACA,SACA,QACA,MACA,SACA,QACA,iBACA,aACA,aACA,SACA,uBACA,+BACA,iBACA,mBACA,MACA,MACA,KACA,MACA,MACA,mBACA,aACA,WACA,WACA,qBACA,OACA,YACA,aACA,OACA,YACA,QACA,gBACA,aACA,UACA,eACA,eACA,iBACA,eACA,aACA,oBACA,gBACA,cACA,gBACA,eACA,MACA,MACA,MACA,MACA,cACA,YACA,iBACA,qBACA,UACA,QACA,MACA,mBACA,MACA,OACA,aACA,KACA,MACA,MACA,MACA,MACA,WACA,aACA,cACA,YACA,QACA,gBACA,kBACA,gBACA,oBACA,kBACA,SACA,cACA,cACA,gBACA,gBACA,eACA,eACA,oBACA,aACA,OACA,QACA,aACA,SACA,UACA,QACA,OACA,QACA,cACA,UACA,YACA,WACA,SACA,UACA,eACA,UACA,YACA,eACA,QACA,cACA,uBACA,oBACA,gBACA,UACA,iBACA,uBACA,kBACA,KACA,MACA,MACA,UACA,QACA,QACA,eACA,aACA,WACA,UACA,UACA,SACA,QACA,mBACA,SACA,oBACA,oBACA,gBACA,eACA,gBACA,eACA,cACA,gBACA,oBACA,qBACA,kBACA,mBACA,qBACA,kBACA,UACA,gBACA,SACA,gBACA,kBACA,YACA,eACA,WACA,WACA,aACA,oBACA,eACA,mBACA,oBACA,kBACA,cACA,QACA,MACA,MACA,WACA,UACA,WACA,cACA,WACA,cACA,iBACA,iBACA,SACA,gBACA,QACA,gBACA,oBACA,oBACA,KACA,MACA,MACA,SACA,KACA,MACA,MACA,KACA,YAAY,CACJ;AAEH,IAAMsG,SAAStG,OAAO,CAC3B,UACA,eACA,SACA,YACA,SACA,eACA,eACA,iBACA,cACA,cACA,SACA,OACA,WACA,gBACA,YACA,SACA,SACA,UACA,QACA,MACA,WACA,UACA,iBACA,UACA,UACA,kBACA,aACA,YACA,eACA,WACA,WACA,iBACA,YACA,YACA,QACA,YACA,YACA,cACA,WACA,UACA,UACA,eACA,iBACA,wBACA,aACA,aACA,cACA,YACA,kBACA,kBACA,aACA,WACA,SACA,OAAO,CACR;AAEM,IAAMyG,MAAMzG,OAAO,CACxB,cACA,UACA,eACA,aACA,aAAa,CACL;ACzXH,IAAM0G,gBAAgBzG,KAAK,uBAAuB;AAClD,IAAM0G,WAAW1G,KAAK,uBAAuB;AAC7C,IAAM2G,cAAc3G,KAAK,aAAa;AACtC,IAAM4G,YAAY5G,KAAK,8BAA8B;AACrD,IAAM6G,YAAY7G,KAAK,gBAAgB;AACvC,IAAM8G,iBAAiB9G;EAC5B;;;AAEK,IAAM+G,oBAAoB/G,KAAK,uBAAuB;AACtD,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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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",
|
|
6
|
-
"names": ["text", "button", "text", "button", "actionButton", "button", "confirm", "text", "entries", "Object", "setPrototypeOf", "isFrozen", "getPrototypeOf", "getOwnPropertyDescriptor", "freeze", "seal", "create", "_ref", "Reflect", "apply", "construct", "x", "func", "thisArg", "_len", "arguments", "length", "args", "Array", "_key", "Func", "_len2", "_key2", "arrayForEach", "unapply", "prototype", "forEach", "arrayLastIndexOf", "lastIndexOf", "arrayPop", "pop", "arrayPush", "push", "arraySplice", "splice", "arrayIsArray", "isArray", "stringToLowerCase", "String", "toLowerCase", "stringToString", "toString", "stringMatch", "match", "stringReplace", "replace", "stringIndexOf", "indexOf", "stringTrim", "trim", "numberToString", "Number", "booleanToString", "Boolean", "bigintToString", "BigInt", "symbolToString", "Symbol", "objectHasOwnProperty", "hasOwnProperty", "objectToString", "regExpTest", "RegExp", "test", "typeErrorCreate", "unconstruct", "TypeError", "lastIndex", "_len3", "_key3", "_len4", "_key4", "addToSet", "set", "array", "transformCaseFunc", "l", "element", "lcElement", "cleanArray", "index", "isPropertyExist", "clone", "object", "newObject", "_ref2", "_ref3", "_slicedToArray", "property", "value", "constructor", "stringifyValue", "valueAsRecord", "valueToString", "lookupGetter", "stringified", "prop", "desc", "get", "fallbackValue", "isRegex", "_unused", "html", "svg", "svgFilters", "svgDisallowed", "mathMl", "mathMlDisallowed", "text", "xml", "MUSTACHE_EXPR", "ERB_EXPR", "TMPLIT_EXPR", "DATA_ATTR", "ARIA_ATTR", "IS_ALLOWED_URI", "IS_SCRIPT_OR_DATA", "ATTR_WHITESPACE", "DOCTYPE_NAME", "CUSTOM_ELEMENT", "ELEMENT_MARKUP_PROBE", "COMMENT_MARKUP_PROBE", "FALLBACK_TAG_CLOSE", "SELF_CLOSING_TAG", "NODE_TYPE", "attribute", "cdataSection", "entityReference", "entityNode", "processingInstruction", "comment", "document", "documentType", "documentFragment", "notation", "getGlobal", "window", "_createTrustedTypesPolicy", "trustedTypes", "purifyHostElement", "createPolicy", "suffix", "ATTR_NAME", "hasAttribute", "getAttribute", "policyName", "createHTML", "createScriptURL", "scriptUrl", "_", "console", "warn", "_createHooksMap", "afterSanitizeAttributes", "afterSanitizeElements", "afterSanitizeShadowDOM", "beforeSanitizeAttributes", "beforeSanitizeElements", "beforeSanitizeShadowDOM", "uponSanitizeAttribute", "uponSanitizeElement", "uponSanitizeShadowNode", "_resolveSetOption", "cfg", "key", "fallback", "options", "base", "transform", "createDOMPurify", "undefined", "DOMPurify", "root", "version", "VERSION", "removed", "nodeType", "Element", "isSupported", "originalDocument", "currentScript", "DocumentFragment", "HTMLTemplateElement", "Node", "NodeFilter", "_window$NamedNodeMap", "NamedNodeMap", "MozNamedAttrMap", "HTMLFormElement", "DOMParser", "ElementPrototype", "cloneNode", "remove", "getNextSibling", "getChildNodes", "getParentNode", "getShadowRoot", "getAttributes", "getNodeType", "getNodeName", "getOwnerDocument", "template", "createElement", "content", "ownerDocument", "trustedTypesPolicy", "emptyHTML", "defaultTrustedTypesPolicy", "defaultTrustedTypesPolicyResolved", "IN_TRUSTED_TYPES_POLICY", "_assertNotInTrustedTypesPolicy", "_createTrustedHTML", "_createTrustedScriptURL", "_getDefaultTrustedTypesPolicy", "_document", "implementation", "createNodeIterator", "createDocumentFragment", "getElementsByTagName", "importNode", "hooks", "createHTMLDocument", "EXPRESSIONS", "ALLOWED_TAGS", "DEFAULT_ALLOWED_TAGS", "TAGS", "ALLOWED_ATTR", "DEFAULT_ALLOWED_ATTR", "ATTRS", "CUSTOM_ELEMENT_HANDLING", "tagNameCheck", "writable", "configurable", "enumerable", "attributeNameCheck", "allowCustomizedBuiltInElements", "FORBID_TAGS", "FORBID_ATTR", "EXTRA_ELEMENT_HANDLING", "tagCheck", "attributeCheck", "ALLOW_ARIA_ATTR", "ALLOW_DATA_ATTR", "ALLOW_UNKNOWN_PROTOCOLS", "ALLOW_SELF_CLOSE_IN_ATTR", "SAFE_FOR_TEMPLATES", "SAFE_FOR_XML", "WHOLE_DOCUMENT", "SET_CONFIG", "SET_CONFIG_ALLOWED_TAGS", "SET_CONFIG_ALLOWED_ATTR", "FORCE_BODY", "RETURN_DOM", "RETURN_DOM_FRAGMENT", "RETURN_TRUSTED_TYPE", "SANITIZE_DOM", "SANITIZE_NAMED_PROPS", "SANITIZE_NAMED_PROPS_PREFIX", "KEEP_CONTENT", "IN_PLACE", "USE_PROFILES", "FORBID_CONTENTS", "DEFAULT_FORBID_CONTENTS", "DATA_URI_TAGS", "DEFAULT_DATA_URI_TAGS", "URI_SAFE_ATTRIBUTES", "DEFAULT_URI_SAFE_ATTRIBUTES", "MATHML_NAMESPACE", "SVG_NAMESPACE", "HTML_NAMESPACE", "NAMESPACE", "IS_EMPTY_INPUT", "ALLOWED_NAMESPACES", "DEFAULT_ALLOWED_NAMESPACES", "DEFAULT_MATHML_TEXT_INTEGRATION_POINTS", "MATHML_TEXT_INTEGRATION_POINTS", "DEFAULT_HTML_INTEGRATION_POINTS", "HTML_INTEGRATION_POINTS", "COMMON_SVG_AND_HTML_ELEMENTS", "PARSER_MEDIA_TYPE", "SUPPORTED_PARSER_MEDIA_TYPES", "DEFAULT_PARSER_MEDIA_TYPE", "CONFIG", "formElement", "isRegexOrFunction", "testValue", "Function", "_parseConfig", "ALLOWED_URI_REGEXP", "customElementHandling", "ADD_TAGS", "ADD_ATTR", "ADD_URI_SAFE_ATTR", "ADD_FORBID_CONTENTS", "table", "tbody", "TRUSTED_TYPES_POLICY", "previousTrustedTypesPolicy", "error", "ALL_SVG_TAGS", "ALL_MATHML_TAGS", "_checkSvgNamespace", "tagName", "parent", "parentTagName", "namespaceURI", "_checkMathMlNamespace", "_checkHtmlNamespace", "_checkValidNamespace", "_forceRemove", "node", "removeChild", "_neutralizeRoot", "_neutralizeSubtree", "childNodes", "snapshot", "child", "attributes", "i", "name", "removeAttribute", "_removeAttribute", "getAttributeNode", "from", "setAttribute", "_stripDisallowedAttributes", "stack", "_neutralizePatchLinkage", "data", "lcTag", "nodeName", "_initDocument", "dirty", "doc", "leadingWhitespace", "matches", "dirtyPayload", "parseFromString", "documentElement", "createDocument", "innerHTML", "body", "insertBefore", "createTextNode", "call", "_createNodeIterator", "SHOW_ELEMENT", "SHOW_COMMENT", "SHOW_TEXT", "SHOW_PROCESSING_INSTRUCTION", "SHOW_CDATA_SECTION", "_stripTemplateExpressions", "_scrubTemplateExpressions", "_node$querySelectorAl", "normalize", "walker", "currentNode", "nextNode", "templates", "querySelectorAll", "tmpl", "_isDocumentFragment", "_isClobbered", "realTagName", "textContent", "hasChildNodes", "_isNode", "_executeHooks", "hook", "_isUnsafeNode", "firstElementChild", "_sanitizeDisallowedNode", "_isBasicCustomElement", "parentNode", "childCount", "hoisted", "_forkSharedAllowlist", "hookList", "defaultSet", "setConfigSet", "_sanitizeElements", "allowedTags", "nt", "_isValidAttribute", "lcName", "nameIsPermitted", "RESERVED_CUSTOM_ELEMENT_NAMES", "_applyTrustedTypesToAttribute", "getAttributeType", "_setAttributeValue", "setAttributeNS", "_sanitizeAttributes", "hookEvent", "attrName", "attrValue", "keepAttr", "allowedAttributes", "forceKeepAttr", "attr", "initValue", "_sanitizeShadowDOM", "fragment", "shadowNode", "shadowIterator", "shadowNodeType", "innerSr", "_sanitizeAttachedShadowRoots", "shadow", "item", "isElement", "rootName", "sr", "sanitize", "importedNode", "returnNode", "inPlace", "nn", "appendChild", "firstChild", "walkRoot", "nodeIterator", "entry", "shadowroot", "shadowrootmode", "serializedHTML", "outerHTML", "doctype", "setConfig", "clearConfig", "isValidAttribute", "tag", "addHook", "entryPoint", "hookFunction", "removeHook", "removeHooks", "removeAllHooks", "_getDefaults", "_defaults", "changeDefaults", "newDefaults", "noopTest", "cachedIndentRegex", "createRegex", "cache", "indent", "cacheIndex", "regex", "edit", "opt", "source", "obj", "name", "val", "valSource", "other", "supportsLookbehind", "a", "bull", "newline", "blockCode", "fences", "hr", "heading", "bullet", "lheadingCore", "lheading", "lheadingGfm", "_paragraph", "blockText", "_blockLabel", "def", "list", "_tag", "_comment", "html", "createParagraph", "listInterrupt", "paragraph", "blockquoteParagraph", "blockquote", "blockNormal", "gfmTable", "blockGfm", "blockPedantic", "escape", "inlineCode", "br", "inlineText", "_punctuation", "_punctuationOrSpace", "_notPunctuationOrSpace", "punctuation", "_openQuote", "_punctuationGfmStrongEm", "_punctuationOrSpaceGfmStrongEm", "_notPunctuationOrSpaceGfmStrongEm", "blockSkip", "emStrongLDelimCore", "emStrongLDelim", "emStrongLDelimGfm", "emStrongLDelimPedanticCore", "emStrongLDelimPedantic", "emStrongRDelimAstCore", "emStrongRDelimAst", "emStrongRDelimAstGfm", "emStrongRDelimAstPedanticCore", "emStrongRDelimAstPedantic", "emStrongRDelimUnd", "emStrongRDelimUndPedanticCore", "emStrongRDelimUndPedantic", "delLDelim", "delRDelimCore", "delRDelim", "anyPunctuation", "autolink", "_inlineComment", "tag", "_inlineLabel", "link", "reflink", "nolink", "reflinkSearch", "_caseInsensitiveProtocol", "inlineNormal", "inlinePedantic", "inlineGfm", "inlineBreaks", "block", "inline", "escapeReplacements", "getEscapeReplacement", "ch", "escapeHtmlEntities", "encode", "cleanUrl", "href", "splitCells", "tableRow", "count", "row", "match", "offset", "str", "escaped", "curr", "cells", "i", "rtrim", "c", "invert", "l", "suffLen", "currChar", "trimTrailingBlankLines", "lines", "end", "findClosingBracket", "b", "level", "expandTabs", "line", "col", "expanded", "char", "added", "outputLink", "cap", "raw", "lexer", "rules", "title", "text", "token", "indentCodeCompensation", "matchIndentToCode", "indentToCode", "node", "matchIndentInNode", "indentInNode", "_Tokenizer", "options", "src", "trimmed", "tokens", "inBlockquote", "currentLines", "currentRaw", "currentText", "top", "lastToken", "oldToken", "continuation", "newText", "newToken", "isordered", "itemRegex", "endsWithBlankLine", "endEarly", "itemContents", "nextLine", "blankLine", "nextBulletRegex", "hrRegex", "fencesBeginRegex", "headingBeginRegex", "htmlBeginRegex", "blockquoteBeginRegex", "rawLine", "nextLineWithoutTabs", "lastItem", "item", "itemToken", "taskRaw", "checkboxToken", "spacers", "t", "hasMultipleLineBreaks", "headers", "aligns", "rows", "align", "cell", "trimmedUrl", "rtrimSlash", "lastParenIndex", "linkLen", "links", "linkString", "maskedSrc", "prevChar", "lLength", "rDelim", "rLength", "delimTotal", "midDelimTotal", "delimChar", "midRun", "endReg", "lastCharLength", "hasNonSpaceChars", "hasSpaceCharsOnBothEnds", "prevCapZero", "_Lexer", "__Lexer", "next", "lastParagraphClipped", "srcLength", "extTokenizer", "cutSrc", "startIndex", "tempSrc", "tempStart", "getStartIndex", "match0", "_link", "context", "keepPrevChar", "byte", "errMsg", "_Renderer", "lang", "langString", "code", "depth", "ordered", "start", "body", "j", "type", "startAttr", "checked", "header", "k", "content", "cleanHref", "out", "_TextRenderer", "_Parser", "__Parser", "anyToken", "genericToken", "ret", "renderer", "_Hooks", "markdown", "Marked", "args", "callback", "values", "tableToken", "listToken", "childTokens", "extensions", "pack", "opts", "ext", "prevRenderer", "extLevel", "prop", "rendererProp", "rendererFunc", "tokenizer", "tokenizerProp", "tokenizerFunc", "prevTokenizer", "hooks", "hooksProp", "hooksFunc", "prevHook", "arg", "walkTokens", "packWalktokens", "blockType", "origOpt", "throwError", "processedSrc", "processedTokens", "e", "silent", "async", "msg", "markedInstance", "marked", "useExtension", "setOptions", "parseInline", "parser", "_Parser", "lexer", "_Lexer", "text", "x", "y", "text", "button", "confirm", "text", "text", "randomUUID", "randomUUID", "randomUUID", "b", "text", "errorMessage", "text", "button"]
|
|
3
|
+
"sources": ["../src/constants.ts", "../src/skills/fill_template.ts", "../src/skills/parse_skills.ts", "../src/tools/client_tool_registry.ts", "../src/tools/is_destructive.ts", "../src/tools/is_navigates.ts", "../src/dom/native_setter.ts", "../src/dom/animations.ts", "../src/tools/page_action_tools.ts", "../src/tools/page_map.ts", "../src/tools/page_state.ts", "../src/tools/parse_tool_catalog.ts", "../src/tools/route_map.ts", "../src/ui/ui_strings.ts", "../src/ui/approval_card.ts", "../src/ui/attach_copy_buttons.ts", "../src/ui/attachment_chips.ts", "../src/ui/attachment_tray.ts", "../src/ui/chart_block.ts", "../src/ui/chart_spec_from.ts", "../src/ui/chart_tool.ts", "../src/ui/relative_time.ts", "../src/ui/checkpoint_menu.ts", "../src/ui/confirmation_card.ts", "../src/ui/prettify_tool_name.ts", "../src/ui/question_card.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/utils.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/tags.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/attrs.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/regexp.ts", "../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/src/purify.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/defaults.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/rules.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/helpers.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Tokenizer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Lexer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Renderer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/TextRenderer.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Parser.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Hooks.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/Instance.ts", "../node_modules/.pnpm/marked@18.0.9/node_modules/marked/src/marked.ts", "../src/ui/render_markdown.ts", "../src/ui/resize_handle.ts", "../src/ui/reveal_words.ts", "../src/ui/run_notice.ts", "../src/ui/skills_menu.ts", "../src/ui/styles.ts", "../src/ui/thoughts_block.ts", "../src/ui/thread_drawer.ts", "../src/ui/tool_call_card.ts", "../src/ui/voice_input.ts", "../src/core/agui_client.ts", "../src/core/attachment.ts", "../src/core/conversation_store.ts", "../src/core/create_http_agent.ts", "../src/core/utils.ts", "../src/core/remote_conversation_store.ts", "../src/core/run_index.ts", "../src/core/transcribe_audio.ts", "../src/core/upload_attachment.ts", "../src/core/ag_ui_chat.ts", "../src/core/define_ag_ui_chat.ts", "../src/dom/dom_driver.ts", "../src/version.ts"],
|
|
4
|
+
"sourcesContent": ["// The package's single home for enums and constant-like values, and per\n// CLAUDE.md the only file allowed to export multiple symbols.\n\n/** The Custom Element tag name registered by {@link defineAgUiChat}. */\nexport const ELEMENT_TAG = \"ag-ui-chat\";\n\n/** User submitted a message. `detail` is {@link SubmitDetail}. */\nexport const SUBMIT_EVENT = \"ag-ui-submit\";\n\n/**\n * Collapsed state changed, via the built-in toggle or `setCollapsed`.\n * `detail` is {@link ToggleDetail}.\n */\nexport const TOGGLE_EVENT = \"ag-ui-toggle\";\n\n/**\n * The count of answers that arrived while collapsed changed. `detail` is\n * {@link UnreadDetail}. The built-in launcher badge renders exactly this; a\n * host driving its own chrome sets `data-unread-badge=\"false\"` and listens.\n */\nexport const UNREAD_EVENT = \"ag-ui-unread\";\n\n/**\n * AG-UI shared state changed \u2014 a streamed `STATE_SNAPSHOT` / `STATE_DELTA`, or\n * a host assignment to `sharedState`. `detail` is {@link StateDetail}.\n *\n * The protocol's own state channel, distinct from `registerPageState`, which\n * exposes host state to the agent as ordinary tools.\n */\nexport const STATE_EVENT = \"ag-ui-state\";\n\n/**\n * The attachment tray changed \u2014 a file queued, an upload finishing or failing,\n * a chip removed, the tray cleared after a send. `detail` is\n * {@link AttachmentsDetail}, carrying the refs that finished uploading and how\n * many are still in flight. A host driving its own composer uses this to know\n * whether a send would leave files behind.\n */\nexport const ATTACHMENT_EVENT = \"ag-ui-attachments\";\n\n/**\n * An interaction has finished, whatever ended it. `detail` is\n * {@link RunFinishedDetail}, listing the tools that ran and which side ran them.\n *\n * For hosts that render data the agent can change. A server-side tool writes\n * without the page's knowledge \u2014 nothing else the element dispatches implies\n * \"something may have moved underneath you\", so a page showing that data has no\n * reason to refetch and quietly goes stale. Shared state\n * ({@link STATE_EVENT}) is the richer channel, but it needs the agent to emit\n * state; this needs nothing of the agent at all.\n *\n * Fires once per interaction rather than once per tool round, on completion,\n * error and cancellation alike, since a partial write is still a write.\n */\nexport const RUN_FINISHED_EVENT = \"ag-ui-run-finished\";\n\n/** Roles a chat message can take. */\nexport const MESSAGE_ROLE = {\n USER: \"user\",\n ASSISTANT: \"assistant\",\n} as const;\n\n/**\n * Schema-root key marking a tool destructive: the element gates its execution\n * behind the confirmation card unless `autoConfirm` is set. All four `x-*` keys\n * below mirror the `django-ag-ui` server side.\n */\nexport const X_DESTRUCTIVE_KEY = \"x-destructive\";\n\n/**\n * Schema-root key holding a confirmation prompt (e.g. `\"Activate this\n * project?\"`), shown instead of the generic `Run \"<tool>\"?`.\n */\nexport const X_CONFIRM_KEY = \"x-confirm\";\n\n/**\n * Schema-root key holding a short label for a tool (e.g. `\"Query orders\"` for\n * `query_model`), shown on the card instead of the raw tool name.\n */\nexport const X_SUMMARY_KEY = \"x-summary\";\n\n/**\n * Schema-root key marking a tool as navigating \u2014 its handler triggers a full\n * page reload. The element checkpoints the call before the reload and resumes\n * the run loop once the next page mounts.\n */\nexport const X_NAVIGATES_KEY = \"x-navigates\";\n\n/**\n * The built-in tool that re-reads the current page, registered only when a\n * page-map provider is set. Named here because the stale-page guard must exempt\n * it: refusing the one call that would refresh the agent's view deadlocks.\n */\nexport const READ_PAGE_TOOL = \"read_page\";\n\n/** Upper bound on frontend tool-call \u2192 re-run rounds within one send. */\nexport const MAX_TOOL_ROUNDS = 10;\n\n/**\n * Lifecycle status of a rendered tool-call card. A card opens as `PENDING`\n * while the call runs, then settles to `DONE`, `ERROR`, or `DECLINED`.\n *\n * `DEFERRED` is the one non-terminal state that is not \"running\": a server-side\n * tool a `ToolGuard` gated never executed, the run finished on an interrupt, and\n * the call is waiting on a person. Without it such a card sat at `PENDING` and\n * read \"running\u2026\" while the stream was over and the server idle \u2014 a status enum\n * missing a state does not omit that state, it renders it as whichever neighbour\n * is closest, and here the closest one claimed the opposite of the truth. A\n * *frontend* tool waiting on its own card (`ask_user`) stays `PENDING`, because\n * the browser really is running it.\n */\nexport const TOOL_CALL_STATUS = {\n PENDING: \"pending\",\n DEFERRED: \"deferred\",\n DONE: \"done\",\n ERROR: \"error\",\n DECLINED: \"declined\",\n} as const;\n\n/**\n * Lifecycle status of a pending-attachment chip in the composer tray. A chip\n * opens as `UPLOADING` (with a progress bar), then settles to `READY` (a durable\n * ref) or `ERROR` (with a retry control).\n */\nexport const ATTACHMENT_STATUS = {\n UPLOADING: \"uploading\",\n READY: \"ready\",\n ERROR: \"error\",\n} as const;\n\n/**\n * Default client-side upload size cap (10 MiB), matching django-ag-ui's\n * `ATTACHMENT_MAX_BYTES`. Overridable via `data-attachment-max-bytes`; the\n * server stays authoritative.\n */\nexport const DEFAULT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;\n\n/**\n * How much detail a tool-call card shows. Set via `data-tool-display`; the\n * default is `full`.\n *\n * - `inline` \u2014 one status row (icon + summary), no card chrome, result behind\n * its own toggle. Reads as a line of the answer rather than a boxed card.\n * - `minimal` \u2014 tool name + status pill only. No args, no result body.\n * - `compact` \u2014 name + status, args and result behind one \"Details\" toggle.\n * - `full` \u2014 args inline, result behind its own toggle.\n */\nexport const TOOL_DISPLAY = {\n INLINE: \"inline\",\n MINIMAL: \"minimal\",\n COMPACT: \"compact\",\n FULL: \"full\",\n} as const;\n\n/**\n * `activityType` of the `ACTIVITY_SNAPSHOT` event django-ag-ui emits when a\n * compaction capability trimmed the history. `content` carries\n * `{ removed, before, after }`.\n */\nexport const COMPACTION_ACTIVITY_TYPE = \"compaction\";\n\n/**\n * Pydantic-AI's built-in tool for loading a deferred capability, with `{ id }`\n * naming it. Agent skills are deferred capabilities keyed by skill name, so a\n * call to this tool is the only signal that the agent picked a skill.\n *\n * Distinct from the host-provided {@link Skill} catalog, which is a human\n * affordance launched from the slash palette.\n */\nexport const LOAD_CAPABILITY_TOOL = \"load_capability\";\n\n/**\n * The chrome's glyphs, as inline SVG markup.\n *\n * Static author-written markup assigned as a `<slot>`'s fallback content, so it\n * never passes through the sanitiser \u2014 nothing here is user or server data, and\n * nothing user-supplied may be interpolated into it. Each icon is a 24x24\n * viewBox carrying the shared `glyph` class, which `STYLES` sizes and paints\n * from `currentColor`; `glyph--solid` fills instead of stroking. A host wanting\n * its own mark projects a matching `slot=\"icon-\u2026\"` child instead of editing\n * these.\n */\nexport const ICON_SEND = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 19.5V5m-6.5 6.5L12 5l6.5 6.5\"/></svg>`;\n\n/** The Stop glyph the composer button wears while a run is in flight. */\nexport const ICON_STOP = `<svg class=\"glyph glyph--solid\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"2.5\"/></svg>`;\n\n/** The file-picker glyph (a paperclip). */\nexport const ICON_ATTACH = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M17 8.5V15a5 5 0 0 1-10 0V7a3 3 0 0 1 6 0v7.5a1 1 0 0 1-2 0V8.5\"/></svg>`;\n\n/** The voice-input glyph (a microphone on its stand). */\nexport const ICON_VOICE = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 4a3 3 0 0 1 3 3v5a3 3 0 0 1-6 0V7a3 3 0 0 1 3-3z\"/><path d=\"M5 11v1a7 7 0 0 0 14 0v-1\"/><path d=\"M12 19v3\"/></svg>`;\n\n/** The default launcher mark (a speech bubble), shown when the host slots none. */\nexport const ICON_LAUNCHER = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H9l-5 4z\"/></svg>`;\n\n/**\n * The generic attachment-chip mark, for a file family with nothing more\n * specific to say. The chip marks share the contract of the chrome glyphs\n * above; `iconFor` selects one by MIME family, never interpolating the MIME\n * string into the markup.\n */\nexport const ICON_FILE = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"/><path d=\"M14 3v5h5\"/></svg>`;\n\n/** An image attachment: a framed picture with a horizon and a sun. */\nexport const ICON_FILE_IMAGE = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"4.5\" width=\"17\" height=\"15\" rx=\"2.5\"/><circle cx=\"9\" cy=\"10\" r=\"1.5\"/><path d=\"M4.5 17.5 9 13.5l3.5 3 3-2.5 4.5 4\"/></svg>`;\n\n/** A PDF: the generic page, banded to read as a labelled document. */\nexport const ICON_FILE_PDF = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"/><path d=\"M14 3v5h5\"/><rect class=\"glyph--solid\" x=\"7.5\" y=\"13.5\" width=\"9\" height=\"4.5\" rx=\"1\"/></svg>`;\n\n/** A text document: the generic page, ruled. */\nexport const ICON_FILE_TEXT = `<svg class=\"glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"/><path d=\"M14 3v5h5\"/><path d=\"M8.5 13.5h7M8.5 17h4.5\"/></svg>`;\n\n/**\n * ``activityType`` of the ``ACTIVITY_SNAPSHOT`` / ``ACTIVITY_DELTA`` events a\n * server sends to draw a chart.\n *\n * A convention inside an extension point the protocol already provides, not a\n * protocol extension: AG-UI defines the envelope and leaves ``activityType`` an\n * open string. Another vendor's client does not know this name and ignores the\n * event, which is the graceful outcome.\n */\nexport const CHART_ACTIVITY_TYPE = \"chart\";\n", "/** Result of {@link fillTemplate}: the filled text plus any unresolved keys. */\nexport interface TemplateResult {\n /** The prompt with resolved `{placeholder}`s substituted. */\n readonly text: string;\n /** Placeholder names with no value available (deduped, in first-seen order). */\n readonly missing: readonly string[];\n}\n\nconst PLACEHOLDER_RE = /\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g;\n\n/**\n * Substitute `{name}` placeholders in `template` from `values`.\n *\n * A placeholder whose value is missing, `null`, or an empty string is left\n * verbatim and reported in `missing`, so the caller can block the send rather\n * than dispatch a half-filled prompt.\n */\nexport function fillTemplate(template: string, values: Record<string, unknown>): TemplateResult {\n const missing: string[] = [];\n const text = template.replace(PLACEHOLDER_RE, (token, key: string) => {\n const value = values[key];\n if (value === undefined || value === null || value === \"\") {\n if (!missing.includes(key)) {\n missing.push(key);\n }\n return token;\n }\n return String(value);\n });\n return { text, missing };\n}\n", "import type { Skill } from \"./skill.js\";\n\n/**\n * Whether `value` has the required string fields of a {@link Skill}.\n *\n * `prompt` must stay optional: a server-resolved skill omits it, and requiring\n * it would silently drop exactly the skills kept off the client.\n */\nfunction isSkill(value: unknown): value is Skill {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const record = value as Record<string, unknown>;\n return (\n typeof record[\"name\"] === \"string\" &&\n typeof record[\"title\"] === \"string\" &&\n (record[\"prompt\"] === undefined || typeof record[\"prompt\"] === \"string\")\n );\n}\n\n/**\n * Parse an untrusted value (parsed JSON from `data-skills` or a skills\n * endpoint) into a list of {@link Skill}s, dropping anything malformed. Never\n * throws \u2014 a bad payload yields an empty list.\n */\nexport function parseSkills(value: unknown): Skill[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value.filter(isSkill);\n}\n", "import type { Tool } from \"@ag-ui/core\";\n\n/**\n * A tool the frontend declares and executes itself.\n *\n * `parameters` is a JSON Schema (and may carry the `x-destructive` extension).\n * `handler` receives the parsed arguments and returns a result that is\n * JSON-serialised into the AG-UI tool-result message sent back to the agent.\n */\nexport interface ClientTool {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n /**\n * Run the tool. `callId` identifies the call being executed, for a handler\n * that renders into the transcript and needs to place itself against its own\n * card; handlers that only act on the page ignore it.\n */\n handler: (args: Record<string, unknown>, callId?: string) => unknown | Promise<unknown>;\n /**\n * Draw this call, from its arguments alone.\n *\n * Optional, and **the only half that is replayed**. A restored transcript\n * redraws by calling `render`; it never calls {@link handler}. That is what\n * keeps a replayable tool apart from an effectful one *structurally* rather\n * than by promise: the restore path holds no reference to the half that acts,\n * so re-running `fill_field` on every reload is not a mistake anyone can make.\n *\n * The contract this must keep, because it runs again on every restore:\n *\n * - a pure function of `args` \u2014 no host state, no network, no clock;\n * - deterministic, so a reload reproduces what was there before;\n * - free of effects outside the node it returns, which the component places.\n *\n * Return `null` for arguments that say nothing worth drawing.\n */\n render?: (args: Record<string, unknown>) => Node | null;\n}\n\n/**\n * Holds the frontend tools a host has declared on an `<ag-ui-chat>` element.\n *\n * Produces AG-UI {@link Tool} definitions for `RunAgentInput.tools` and looks\n * up handlers when the agent calls a tool. Pure (no DOM); the element owns one\n * instance.\n */\nexport class ClientToolRegistry {\n readonly #tools = new Map<string, ClientTool>();\n\n /**\n * Register a tool, replacing any existing one with the same name.\n *\n * Idempotent on the name so a re-fired host ref or React StrictMode's\n * double-invoke replaces rather than throws.\n */\n register(tool: ClientTool): void {\n this.#tools.set(tool.name, tool);\n }\n\n has(name: string): boolean {\n return this.#tools.has(name);\n }\n\n /** Return a registered tool or throw. */\n get(name: string): ClientTool {\n const tool = this.#tools.get(name);\n if (tool === undefined) {\n throw new Error(`tool \"${name}\" is not registered`);\n }\n return tool;\n }\n\n /** AG-UI tool definitions for `RunAgentInput.tools`. */\n tools(): Tool[] {\n return [...this.#tools.values()].map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }));\n }\n}\n", "import { X_DESTRUCTIVE_KEY } from \"../constants.js\";\n\n/**\n * Whether a tool's JSON-Schema `parameters` marks it destructive.\n *\n * Reads the `x-destructive` extension stamped by the server (`django-ag-ui`'s\n * `build_input_schema`) or by a host declaring a tool directly.\n */\nexport function isDestructive(parameters: Record<string, unknown>): boolean {\n return parameters[X_DESTRUCTIVE_KEY] === true;\n}\n", "import { X_NAVIGATES_KEY } from \"../constants.js\";\n\n/**\n * Whether a tool's JSON-Schema `parameters` marks it as navigating.\n *\n * Reads the `x-navigates` extension. A navigating tool's handler reloads the\n * page (MPA navigation), so the element checkpoints the call and resumes the\n * run loop after the next page mounts, rather than awaiting a result inline.\n */\nexport function isNavigates(parameters: Record<string, unknown>): boolean {\n return parameters[X_NAVIGATES_KEY] === true;\n}\n", "// Set a control's `value` / `checked` through the native prototype setter, so\n// framework value-tracking sees the change. React (and Vue/Svelte) replace the\n// element's own setter with a tracked one, so `el.value = x` hits that override\n// and the following `input` event carries no change: the field looks filled\n// while the framework's state stays empty. Calling the original prototype\n// setter and then dispatching `input` avoids that.\n\ntype ValueSetter = (this: HTMLElement, value: string) => void;\ntype CheckedSetter = (this: HTMLElement, checked: boolean) => void;\n\n/** The original prototype setter for `prop` on `proto`. */\nfunction prototypeSetter(proto: object, prop: string): (this: HTMLElement, value: never) => void {\n // Captured once at module load; DOM environments always define these, which\n // is what makes the descriptor cast safe.\n const setter = (Object.getOwnPropertyDescriptor(proto, prop) as PropertyDescriptor).set;\n return setter as unknown as (this: HTMLElement, value: never) => void;\n}\n\nconst setInputValue = prototypeSetter(HTMLInputElement.prototype, \"value\") as ValueSetter;\nconst setTextareaValue = prototypeSetter(HTMLTextAreaElement.prototype, \"value\") as ValueSetter;\nconst setSelectValue = prototypeSetter(HTMLSelectElement.prototype, \"value\") as ValueSetter;\nconst setInputChecked = prototypeSetter(HTMLInputElement.prototype, \"checked\") as CheckedSetter;\n\n/** Set `el.value` via the element's native prototype setter. */\nexport function setNativeValue(\n el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement,\n value: string,\n): void {\n if (el instanceof HTMLTextAreaElement) {\n setTextareaValue.call(el, value);\n } else if (el instanceof HTMLSelectElement) {\n setSelectValue.call(el, value);\n } else {\n setInputValue.call(el, value);\n }\n}\n\n/** Set `el.checked` via the native prototype setter. */\nexport function setNativeChecked(el: HTMLInputElement, checked: boolean): void {\n setInputChecked.call(el, checked);\n}\n", "/**\n * Visible-action animation primitives.\n *\n * These run against the **host page** DOM (not the element's shadow root) so a\n * user watches the agent type, highlight, and click at human-readable speed.\n * Each is configurable; pass small/zero durations in tests (or use fake timers).\n */\n\nimport { setNativeChecked, setNativeValue } from \"./native_setter.js\";\n\n/** Ring colour when the host page has not themed `--ag-ui-accent`. */\nconst ACCENT = \"#4f46e5\";\n\n/**\n * Fallback for the box-shadow rings, which read as a soft halo rather than a\n * line and so carry their own alpha.\n */\nconst ACCENT_HALO = \"rgba(79, 70, 229, 0.4)\";\n\nconst ACCENT_PROPERTY = \"--ag-ui-accent\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\n/**\n * Whether the user has asked the OS/browser to minimise motion.\n *\n * Honoured by every primitive that moves something: hold delays are skipped,\n * `scrollIntoCenterView` jumps instead of gliding, and the flash drops its fade\n * but still holds the ring long enough to be seen \u2014 reduced motion asks for no\n * animation, not for no feedback. `typeInto` and `highlightThenClick` keep\n * their explicit-duration contract instead.\n */\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/** Like {@link delay}, but resolves immediately under reduced motion. */\nfunction motionDelay(ms: number): Promise<void> {\n if (ms <= 0 || prefersReducedMotion()) {\n return Promise.resolve();\n }\n return delay(ms);\n}\n\n/**\n * Resolve the accent colour from the target's own computed style.\n *\n * `--ag-ui-accent` inherits, so reading it off the element about to be touched\n * picks up whatever the host's cascade produced there, and a themed page is\n * flashed in its own colour rather than this package's indigo.\n */\nfunction accentColor(el: HTMLElement, fallback: string): string {\n const themed = window.getComputedStyle(el).getPropertyValue(ACCENT_PROPERTY).trim();\n return themed === \"\" ? fallback : themed;\n}\n\nfunction ringShadow(el: HTMLElement): string {\n return `0 0 0 3px ${accentColor(el, ACCENT_HALO)}`;\n}\n\n/** An element whose `value` can be typed into. */\nexport type TextLikeElement = HTMLInputElement | HTMLTextAreaElement;\n\nexport interface TypeOptions {\n /** Milliseconds between characters. Default 35. */\n charDelayMs?: number;\n}\n\n/**\n * Clear `el` and type `value` one character at a time, firing an `input` event\n * per character as a real user would, then a final `change`.\n */\nexport async function typeInto(\n el: TextLikeElement,\n value: string,\n options: TypeOptions = {},\n): Promise<void> {\n const charDelayMs = options.charDelayMs ?? 35;\n setNativeValue(el, \"\");\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n for (const char of value) {\n setNativeValue(el, el.value + char);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n if (charDelayMs > 0) {\n await delay(charDelayMs);\n }\n }\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\nexport interface HighlightClickOptions {\n /** Milliseconds to hold the highlight before clicking. Default 280. */\n highlightMs?: number;\n}\n\n/** Outline `el`, pause so the user sees it, then click and restore. */\nexport async function highlightThenClick(\n el: HTMLElement,\n options: HighlightClickOptions = {},\n): Promise<void> {\n const highlightMs = options.highlightMs ?? 280;\n const previousOutline = el.style.outline;\n const previousOffset = el.style.outlineOffset;\n el.style.outline = `2px solid ${accentColor(el, ACCENT)}`;\n el.style.outlineOffset = \"2px\";\n await delay(highlightMs);\n el.style.outline = previousOutline;\n el.style.outlineOffset = previousOffset;\n el.click();\n}\n\nexport interface ScrollOptions {\n /**\n * How long to wait for a moving scroll to settle before giving up.\n * Default 600.\n */\n settleMs?: number;\n}\n\nconst SCROLL_SETTLE_MS = 600;\n\n/** How long to give a smooth scroll to start moving before assuming it will not. */\nconst SCROLL_START_MS = 100;\n\n/**\n * Scroll `el` to the vertical centre of the viewport.\n *\n * Resolves once the scroll settles, so a caller can hold its animation until\n * the element stops moving \u2014 a ring drawn mid-glide lands where the user is not\n * looking yet. Awaiting is optional; the scroll is requested synchronously.\n */\nexport function scrollIntoCenterView(el: HTMLElement, options: ScrollOptions = {}): Promise<void> {\n const reduced = prefersReducedMotion();\n el.scrollIntoView({\n block: \"center\",\n inline: \"nearest\",\n behavior: reduced ? \"auto\" : \"smooth\",\n });\n if (reduced) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n let timer: ReturnType<typeof setTimeout>;\n const settle = (): void => {\n clearTimeout(timer);\n document.removeEventListener(\"scroll\", started, true);\n document.removeEventListener(\"scrollend\", settle, true);\n resolve();\n };\n const started = (): void => {\n document.removeEventListener(\"scroll\", started, true);\n clearTimeout(timer);\n timer = setTimeout(settle, options.settleMs ?? SCROLL_SETTLE_MS);\n };\n // Neither event bubbles, and both fire on whichever ancestor actually\n // scrolled, so listen on the document in the capture phase.\n //\n // Two timeouts, for two failure modes: an element already in view never\n // scrolls and so never fires scrollend (the short did-anything-move probe),\n // and once something is moving the longer budget covers browsers without\n // scrollend at all.\n timer = setTimeout(settle, SCROLL_START_MS);\n document.addEventListener(\"scroll\", started, true);\n document.addEventListener(\"scrollend\", settle, true);\n });\n}\n\n/** Total on-screen life of the flash ring, hold plus fade. */\nconst FLASH_MS = 1200;\n\n/** Share of {@link FLASH_MS} spent fading out rather than holding. */\nconst FLASH_FADE_RATIO = 1 / 3;\n\nexport interface FlashOptions {\n /** Total milliseconds the ring is on screen, hold plus fade. Default 1200. */\n flashMs?: number;\n /** Ring colour. Defaults to the target's `--ag-ui-accent`, else the package accent. */\n color?: string;\n /**\n * Move keyboard focus to the element as well. Defaults to false for\n * {@link flash} and true for {@link focusWithFlash}.\n */\n focus?: boolean;\n}\n\nasync function flashRing(\n el: HTMLElement,\n options: FlashOptions,\n focusByDefault: boolean,\n): Promise<void> {\n if (options.focus ?? focusByDefault) {\n // preventScroll: a caller's smooth scroll is typically still in flight, and\n // the instant scroll focus() would otherwise do fights it.\n el.focus({ preventScroll: true });\n }\n const flashMs = options.flashMs ?? FLASH_MS;\n if (flashMs <= 0) {\n return;\n }\n const previousOutline = el.style.outline;\n const previousOffset = el.style.outlineOffset;\n const previousTransition = el.style.transition;\n const color = options.color ?? accentColor(el, ACCENT);\n // outline, not box-shadow: a shadow paints outside the border box, so any\n // overflow:hidden ancestor sharing the target's box (a card, a table cell)\n // clips the whole ring away while the helper still reports success.\n el.style.outline = `3px solid ${color}`;\n el.style.outlineOffset = \"2px\";\n const fadeMs = prefersReducedMotion() ? 0 : Math.round(flashMs * FLASH_FADE_RATIO);\n await delay(flashMs - fadeMs);\n if (fadeMs > 0) {\n // Transition and new colour in the same task is fine: the browser starts\n // transitions from the after-change style.\n el.style.transition = `outline-color ${fadeMs}ms ease-out`;\n el.style.outline = \"3px solid transparent\";\n await delay(fadeMs);\n }\n el.style.outline = previousOutline;\n el.style.outlineOffset = previousOffset;\n el.style.transition = previousTransition;\n}\n\n/**\n * Flash a ring around `el` without touching focus.\n *\n * Prefer this over {@link focusWithFlash} when the point is to show the user\n * something: moving focus steals it from the composer, can fire blur validation\n * on whatever they were mid-edit in, and can close an open menu.\n */\nexport function flash(el: HTMLElement, options: FlashOptions = {}): Promise<void> {\n return flashRing(el, options, false);\n}\n\n/**\n * Focus `el` and flash a ring around it. Focus moves unless `options.focus`\n * says otherwise; use {@link flash} to leave focus where the user put it.\n */\nexport function focusWithFlash(el: HTMLElement, options: FlashOptions = {}): Promise<void> {\n return flashRing(el, options, true);\n}\n\nexport interface PressOptions {\n /** Milliseconds to hold the pressed state before clicking. Default 140. */\n pressMs?: number;\n}\n\n/**\n * Show a brief pressed affordance on a control \u2014 a slight scale-down plus\n * accent ring \u2014 then click it and restore. Reads as a press rather than the\n * plain outline {@link highlightThenClick} draws.\n */\nexport async function pressThenClick(el: HTMLElement, options: PressOptions = {}): Promise<void> {\n const pressMs = options.pressMs ?? 140;\n const previousTransform = el.style.transform;\n const previousTransition = el.style.transition;\n const previousShadow = el.style.boxShadow;\n el.style.transition = \"transform 80ms ease\";\n el.style.transform = \"scale(0.96)\";\n el.style.boxShadow = ringShadow(el);\n await motionDelay(pressMs);\n el.style.transform = previousTransform;\n el.style.transition = previousTransition;\n el.style.boxShadow = previousShadow;\n el.click();\n}\n\nexport interface SelectOptions {\n /** Milliseconds to hold the highlight before committing. Default 220. */\n highlightMs?: number;\n}\n\n/** Find an option in `el` whose value or visible text equals `value`. */\nfunction findOption(el: HTMLSelectElement, value: string): HTMLOptionElement | null {\n for (const option of Array.from(el.options)) {\n if (option.value === value || option.text === value) {\n return option;\n }\n }\n return null;\n}\n\n/**\n * Outline a `<select>`, pause so the user sees the pick, then set it to the\n * option matching `value` (by value or visible text) and fire `input` +\n * `change`. Throws when no option matches.\n */\nexport async function selectOption(\n el: HTMLSelectElement,\n value: string,\n options: SelectOptions = {},\n): Promise<void> {\n const option = findOption(el, value);\n if (option === null) {\n throw new Error(`no <option> matching \"${value}\"`);\n }\n const highlightMs = options.highlightMs ?? 220;\n const previousOutline = el.style.outline;\n const previousOffset = el.style.outlineOffset;\n el.style.outline = `2px solid ${accentColor(el, ACCENT)}`;\n el.style.outlineOffset = \"2px\";\n await motionDelay(highlightMs);\n setNativeValue(el, option.value);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n el.style.outline = previousOutline;\n el.style.outlineOffset = previousOffset;\n}\n\nexport interface ToggleOptions {\n /** Milliseconds to hold the flash. Default 200. */\n flashMs?: number;\n}\n\n/**\n * Flash a ring around a checkbox/radio, set its `checked` state, and fire\n * `input` + `change` so frameworks observe the flip.\n */\nexport async function toggleControl(\n el: HTMLInputElement,\n checked: boolean,\n options: ToggleOptions = {},\n): Promise<void> {\n const flashMs = options.flashMs ?? 200;\n const previousShadow = el.style.boxShadow;\n el.style.boxShadow = ringShadow(el);\n await motionDelay(flashMs);\n setNativeChecked(el, checked);\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n el.style.boxShadow = previousShadow;\n}\n", "import { X_SUMMARY_KEY } from \"../constants.js\";\nimport { scrollIntoCenterView } from \"../dom/animations.js\";\nimport type { ClientTool } from \"./client_tool_registry.js\";\n\n/**\n * Resolve a page-action target string to a host-page element, or `null` when it\n * matches nothing. The default treats the string as a CSS selector; a host with\n * a page map overrides it to map its own element ids.\n */\nexport type ResolvePageTarget = (target: string) => HTMLElement | null;\n\n/** The built-in page-action tool tokens, opted in via `data-page-actions`. */\nexport const PAGE_ACTIONS = {\n SCROLL: \"scroll\",\n DRAG: \"drag\",\n} as const;\n\n/**\n * The opt-in page-action tools selected by `enabled` (a set of\n * {@link PAGE_ACTIONS} tokens), bound to a {@link ResolvePageTarget}.\n *\n * - `scroll_to` \u2014 scroll a target (`top` / `bottom` / a resolver target) into\n * view. Benign; no confirmation.\n * - `drag_and_drop` \u2014 drag one element onto another, firing the standard HTML5\n * drag sequence so the host page's own drop handler reacts. Deliberately not\n * stamped destructive: a drag rearranges transient state, and the durable\n * change happens at the page's explicit commit. A host whose page persists on\n * drop must gate it with the element's `confirmPredicate`.\n *\n * Both report a model-readable error when a target resolves to nothing.\n */\nexport function createPageActionTools(\n enabled: ReadonlySet<string>,\n resolveTarget: ResolvePageTarget,\n): ClientTool[] {\n const tools: ClientTool[] = [];\n if (enabled.has(PAGE_ACTIONS.SCROLL)) {\n tools.push(scrollTool(resolveTarget));\n }\n if (enabled.has(PAGE_ACTIONS.DRAG)) {\n tools.push(dragTool(resolveTarget));\n }\n return tools;\n}\n\nfunction scrollTool(resolveTarget: ResolvePageTarget): ClientTool {\n return {\n name: \"scroll_to\",\n description:\n \"Scroll a target into view. `target` is `top`, `bottom`, or a CSS \" +\n \"selector / page-map element id. Read-only: it changes nothing on the page.\",\n parameters: {\n type: \"object\",\n properties: { target: { type: \"string\" } },\n required: [\"target\"],\n [X_SUMMARY_KEY]: \"Scroll into view\",\n },\n handler: (args) => {\n const target = String(args[\"target\"] ?? \"\");\n if (target === \"top\" || target === \"bottom\") {\n const top = target === \"top\" ? 0 : document.body.scrollHeight;\n window.scrollTo({ top, behavior: \"smooth\" });\n return { scrolled: true, target };\n }\n const element = resolveTarget(target);\n if (element === null) {\n throw new Error(`no element matching \"${target}\"`);\n }\n scrollIntoCenterView(element);\n return { scrolled: true, target };\n },\n };\n}\n\nfunction dragTool(resolveTarget: ResolvePageTarget): ClientTool {\n return {\n name: \"drag_and_drop\",\n description:\n \"Drag the `from` element onto the `to` element (CSS selectors or page-map \" +\n \"element ids), firing the page's native drag-and-drop. Use for reordering \" +\n \"sortable lists. The page decides what the drop commits.\",\n parameters: {\n type: \"object\",\n properties: { from: { type: \"string\" }, to: { type: \"string\" } },\n required: [\"from\", \"to\"],\n [X_SUMMARY_KEY]: \"Drag and drop\",\n },\n handler: (args) => {\n const fromTarget = String(args[\"from\"] ?? \"\");\n const toTarget = String(args[\"to\"] ?? \"\");\n const from = resolveTarget(fromTarget);\n if (from === null) {\n throw new Error(`no element matching \"${fromTarget}\"`);\n }\n const to = resolveTarget(toTarget);\n if (to === null) {\n throw new Error(`no element matching \"${toTarget}\"`);\n }\n dispatchDragSequence(from, to);\n return { dragged: true, from: fromTarget, to: toTarget };\n },\n };\n}\n\n/**\n * Fire the standard HTML5 drag sequence in the order a page's own handlers\n * expect \u2014 `dragstart` on the source, `dragenter` / `dragover` / `drop` on the\n * target, `dragend` on the source \u2014 all sharing one {@link DataTransfer}, which\n * is attached to each event explicitly so a drop handler reads it in every\n * environment.\n */\nfunction dispatchDragSequence(from: HTMLElement, to: HTMLElement): void {\n const dataTransfer = new DataTransfer();\n fire(from, \"dragstart\", dataTransfer);\n fire(to, \"dragenter\", dataTransfer);\n fire(to, \"dragover\", dataTransfer);\n fire(to, \"drop\", dataTransfer);\n fire(from, \"dragend\", dataTransfer);\n}\n\nfunction fire(target: HTMLElement, type: string, dataTransfer: DataTransfer): void {\n const event = new Event(type, { bubbles: true, cancelable: true }) as Event & {\n dataTransfer: DataTransfer;\n };\n event.dataTransfer = dataTransfer;\n target.dispatchEvent(event);\n}\n", "import type { Context } from \"@ag-ui/core\";\n\n/**\n * A compact snapshot of the current page's actionable surface (field\n * names/types/labels, button labels+handles \u2014 not values). Host-defined shape;\n * kept small because it rides in every `RunAgentInput.context`.\n */\nexport type PageMap = Record<string, unknown>;\n\n/**\n * Build the per-run context entry for the page map.\n *\n * Returns a single `page_map` context item when auto-injection is on and a\n * provider is set, else nothing. Recomputed each run so it reflects the page\n * the agent is currently looking at.\n */\nexport function createPageMapContext(\n getPageMap: (() => PageMap) | null,\n autoInject: boolean,\n): Context[] {\n if (!autoInject || getPageMap === null) {\n return [];\n }\n return [{ description: \"page_map\", value: JSON.stringify(getPageMap()) }];\n}\n", "import { X_DESTRUCTIVE_KEY, X_SUMMARY_KEY } from \"../constants.js\";\nimport type { ClientTool } from \"./client_tool_registry.js\";\n\n/**\n * A binding from a named piece of host page state to agent tools.\n *\n * Ergonomic sugar over `registerTool` for SPA state (Redux/Zustand/signals):\n * generates a read tool and, when `write` is given, a destructive set tool.\n *\n * Not AG-UI shared state. `STATE_SNAPSHOT` / `STATE_DELTA` are protocol events\n * carrying state between agent and client; these are ordinary client tools the\n * agent calls like any other.\n */\nexport interface PageState {\n /** Base name; tools become `read_<name>` and `set_<name>`. */\n readonly name: string;\n /** Returns the current state value. */\n readonly read: () => unknown;\n /** Mutates the state from the agent-supplied args. Omit for read-only. */\n readonly write?: (args: Record<string, unknown>) => unknown;\n /** JSON-Schema for the set tool's args. Defaults to an open object. */\n readonly schema?: Record<string, unknown>;\n}\n\n/**\n * Build the tools for a {@link PageState}: always a `read_<name>` (read-only)\n * tool, plus a `set_<name>` (`x-destructive`) tool when `write` is supplied.\n */\nexport function createPageStateTools(binding: PageState): ClientTool[] {\n const tools: ClientTool[] = [\n {\n name: `read_${binding.name}`,\n description: `Read the \"${binding.name}\" state.`,\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n [X_SUMMARY_KEY]: `Read ${binding.name}`,\n },\n handler: () => binding.read(),\n },\n ];\n const write = binding.write;\n if (write !== undefined) {\n tools.push({\n name: `set_${binding.name}`,\n description: `Update the \"${binding.name}\" state.`,\n parameters: {\n ...(binding.schema ?? { type: \"object\" }),\n [X_DESTRUCTIVE_KEY]: true,\n [X_SUMMARY_KEY]: `Update ${binding.name}`,\n },\n handler: (args) => write(args),\n });\n }\n return tools;\n}\n\n/**\n * @deprecated Renamed to {@link PageState} \u2014 the old name read as AG-UI\n * shared-state sync. Will be removed in a future major.\n */\nexport type StateHook = PageState;\n\n/**\n * @deprecated Renamed to {@link createPageStateTools}. Will be removed in a\n * future major.\n */\nexport const createStateHookTools = createPageStateTools;\n", "/**\n * One entry in the server-tool catalog served by django-ag-ui's `tools/`\n * endpoint and fetched via the `data-tools-url` attribute.\n */\nexport interface ToolCatalogEntry {\n /** The tool's wire name (matches the name in `TOOL_CALL_START`). */\n readonly name: string;\n /** A friendly card label for the tool. */\n readonly summary: string;\n /** Optional longer blurb (e.g. for a future tooltip). */\n readonly description?: string;\n}\n\n/**\n * Parse a fetched tool catalog into a `name \u2192 summary` map, skipping any entry\n * that isn't a `{ name: string, summary: string }` object. Tolerant by design:\n * a malformed payload yields an empty map rather than throwing.\n */\nexport function parseToolCatalog(data: unknown): Record<string, string> {\n const out: Record<string, string> = {};\n if (!Array.isArray(data)) {\n return out;\n }\n for (const entry of data) {\n if (entry === null || typeof entry !== \"object\") {\n continue;\n }\n const record = entry as Record<string, unknown>;\n const name = record[\"name\"];\n const summary = record[\"summary\"];\n if (typeof name === \"string\" && typeof summary === \"string\") {\n out[name] = summary;\n }\n }\n return out;\n}\n", "import { X_NAVIGATES_KEY, X_SUMMARY_KEY } from \"../constants.js\";\nimport type { ClientTool } from \"./client_tool_registry.js\";\n\n/** A single navigable route the host declares for the agent. */\nexport interface Route {\n /** Stable id the agent uses with `navigate_to_route`. */\n readonly id: string;\n /**\n * The URL path to navigate to. May contain `:name` placeholders for dynamic\n * segments (e.g. `/admin/shop/book/:pk/change/`), which the agent fills via\n * `navigate_to_route`'s `params` argument.\n */\n readonly path: string;\n /** Human label shown to the agent. */\n readonly title?: string;\n /** Optional grouping (e.g. an app or section). */\n readonly group?: string;\n /** Optional longer description of when to use the route. */\n readonly description?: string;\n}\n\n/** The host-declared catalog of navigable routes. */\nexport type RouteMap = readonly Route[];\n\n/** A route enriched with its derived dynamic-segment parameter names. */\nexport interface RouteWithParams extends Route {\n /** Names of the `:name` placeholders in {@link Route.path} (may be empty). */\n readonly pathParams: readonly string[];\n}\n\nconst PATH_PARAM_RE = /:([A-Za-z_][A-Za-z0-9_]*)/g;\n\n/** The `:name` path-parameter names declared in a path template, in order. */\nfunction pathParamNames(path: string): string[] {\n // Slice the \":\" off the whole match rather than read the capture group: under\n // `noUncheckedIndexedAccess`, indexing the group forces an `undefined` guard\n // on a case the regex cannot produce, which no test can cover.\n return [...path.matchAll(PATH_PARAM_RE)].map((match) => match[0].slice(1));\n}\n\n/**\n * Substitute `:name` placeholders in `path` from `params`.\n *\n * Returns the concrete path plus the params no placeholder consumed, for the\n * caller to append as a query string. Throws (naming `routeId`) when a declared\n * path param is missing or empty \u2014 a half-filled path must never be navigated\n * to.\n */\nfunction fillPath(\n routeId: string,\n path: string,\n params: Record<string, unknown>,\n): { path: string; leftover: Record<string, unknown> } {\n const leftover: Record<string, unknown> = { ...params };\n const filled = path.replace(PATH_PARAM_RE, (_match, name: string) => {\n const value = params[name];\n if (value === undefined || value === null || String(value) === \"\") {\n throw new Error(`route \"${routeId}\" requires path param \"${name}\"`);\n }\n delete leftover[name];\n return encodeURIComponent(String(value));\n });\n return { path: filled, leftover };\n}\n\n/** Append `params` to `path` as a query string (no-op when empty). */\nfunction withQuery(path: string, params: Record<string, unknown>): string {\n const usp = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n usp.set(key, String(value));\n }\n const query = usp.toString();\n return query === \"\" ? path : `${path}?${query}`;\n}\n\n/**\n * The built-in `route.*` tools, bound to live getters so a host can set\n * `routeMap` / `navigate` before or after mount.\n *\n * `list_routes` is read-only and advertises each route's `pathParams` so the\n * model knows what to supply. `navigate_to_route` fills those params, appends\n * the rest as a query string, and is stamped `x-navigates` so an MPA reload\n * checkpoints and resumes; with a host `navigate(path)` callback (an SPA) it\n * routes client-side and the run loop continues instead.\n */\nexport function createRouteTools(\n getRouteMap: () => RouteMap,\n getNavigate: () => ((path: string) => void) | null,\n): ClientTool[] {\n return [\n {\n name: \"list_routes\",\n description:\n \"List the routes the app can navigate to. Each route's `pathParams` \" +\n \"names the dynamic segments to pass as `params` to `navigate_to_route`.\",\n parameters: { type: \"object\", properties: {}, required: [], [X_SUMMARY_KEY]: \"List pages\" },\n handler: (): RouteWithParams[] =>\n getRouteMap().map((route) => ({ ...route, pathParams: pathParamNames(route.path) })),\n },\n {\n name: \"navigate_to_route\",\n description:\n \"Navigate to one of the app's routes by its id, filling any dynamic \" +\n \"`:name` path segments (and extra query params) from `params`.\",\n parameters: {\n type: \"object\",\n properties: {\n route_id: { type: \"string\" },\n params: { type: \"object\" },\n },\n required: [\"route_id\"],\n [X_NAVIGATES_KEY]: true,\n [X_SUMMARY_KEY]: \"Navigate\",\n },\n handler: (args) => {\n const routeId = args[\"route_id\"];\n const route = getRouteMap().find((r) => r.id === routeId);\n if (route === undefined) {\n throw new Error(`unknown route \"${String(routeId)}\"`);\n }\n const provided = (args[\"params\"] as Record<string, unknown> | undefined) ?? {};\n const { path: filledPath, leftover } = fillPath(route.id, route.path, provided);\n const path = withQuery(filledPath, leftover);\n const navigate = getNavigate();\n if (navigate !== null) {\n navigate(path);\n } else {\n window.location.assign(path);\n }\n return { navigated: true, path };\n },\n },\n ];\n}\n", "/**\n * The flat table of every user-facing string the chat shell renders \u2014 labels,\n * placeholders, `aria-label`s, and `title` tooltips. A localizable seam, not a\n * framework: a host overrides any subset (via the element's `strings` property\n * or its `data-strings` JSON attribute) and the rest fall back to the English\n * defaults.\n *\n * Some values are templates carrying `{token}` placeholders the call site fills\n * in; the token names are noted on each key, and a translation must keep them\n * verbatim.\n */\nexport interface UiStrings {\n // \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Default header title (the `title-text` attribute overrides per element). */\n title: string;\n /** History button + drawer dialog label. */\n chatHistory: string;\n /** New-chat button (header + drawer). */\n newChat: string;\n /** Collapse button. */\n collapse: string;\n /** Expand affordance (the launcher, and the sidebar rail). */\n expand: string;\n /**\n * The launcher's label while unread answers wait behind it. Token: `{count}`.\n * Replaces {@link expand} rather than appending to it, so a translation can\n * order the two parts as its language needs.\n */\n expandUnread: string;\n /** Built-in header theme toggle (light \u21C4 dark). */\n toggleTheme: string;\n\n // \u2500\u2500 Messages region \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the scrolling message log. */\n conversation: string;\n /** `aria-label` of the \"thinking\" pending indicator, and the thoughts region's\n * header while the model is still reasoning. */\n thinking: string;\n /** The thoughts region's header once reasoning has streamed (collapsed label). */\n thoughts: string;\n /** The muted note after a cancelled run. */\n stopped: string;\n /** Error shown when the stream drops without a terminal AG-UI event. */\n connectionLost: string;\n /** Fallback when a tool call produced no result. */\n noResult: string;\n /** Tool-result content when the user declines a confirmed action. */\n declinedAction: string;\n /** A navigating tool's card text while the page reloads. */\n navigating: string;\n /** Missing-placeholder skill hint. Tokens: `{title}`, `{fields}`. */\n skillNeeds: string;\n /** Notice shown when the agent condensed earlier turns. Token: `{count}`. */\n historyCompacted: string;\n /** Notice shown when the agent loads an agent skill. Token: `{name}`. */\n usingSkill: string;\n /** Notice shown on mount when the previous run never produced a response. */\n runInterrupted: string;\n /** Tool-result content (and card text) when the page moved mid-run. */\n pageMoved: string;\n /** Notice when Send ran while a file was still uploading. Token: `{n}`. */\n attachmentsStillUploading: string;\n\n // \u2500\u2500 Composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the message textarea. */\n message: string;\n /** Placeholder of the message textarea. */\n inputPlaceholder: string;\n /** Send button (idle composer). */\n send: string;\n /** Stop button (composer while a run is in flight). */\n stop: string;\n /** Attach-files button. */\n attachFiles: string;\n /** Mic button while idle (start recording). */\n recordVoice: string;\n /** Mic button while recording (stop + transcribe). */\n stopRecording: string;\n /** Mic button while the clip is being transcribed. */\n transcribing: string;\n /** Mic button fallback message when transcription fails. */\n transcriptionFailed: string;\n\n // \u2500\u2500 Tool-call card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Status pill while the call runs. */\n toolRunning: string;\n /** Status pill on a gated call the run deferred, waiting on a person. */\n toolDeferred: string;\n /** Status pill on success. */\n toolDone: string;\n /** Status pill on error. */\n toolError: string;\n /** Status pill on a declined call. */\n toolDeclined: string;\n /** Accessible label on the panel resize handle. */\n resizePanel: string;\n /** Note on a tool card whose call a human approved. */\n decisionApproved: string;\n /** Note on a tool card whose call a human declined. */\n decisionDeclined: string;\n /** Heading over a tool card's arguments region. */\n argumentsLabel: string;\n /** Heading over a tool card's result region when the call succeeded. */\n resultLabel: string;\n /** Heading over a tool card's result region when the call failed. */\n errorLabel: string;\n /** Heading over a tool card's result region when the call was declined. */\n declinedLabel: string;\n /** Label on the toggle that expands a tool card's body. */\n details: string;\n\n // \u2500\u2500 Confirmation card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the inline confirmation card. */\n confirmAction: string;\n /** Generic confirmation prompt when a tool has no `x-confirm`. Token: `{tool}`. */\n confirmRun: string;\n /** Confirm button. */\n confirm: string;\n /** Cancel button (confirmation + delete confirm). */\n cancel: string;\n\n // \u2500\u2500 Approval card (server-side tool gate) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the inline server-side-tool approval card. */\n approveAction: string;\n /** Fallback approval prompt when the interrupt carries no message. */\n approvalPrompt: string;\n /** Approve button (runs the gated server-side tool). */\n approve: string;\n /** Deny button (declines the gated server-side tool). */\n deny: string;\n\n // \u2500\u2500 Question card (the `ask_user` frontend tool) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** `aria-label` of the inline question card. */\n askUserAction: string;\n /** Radio label for the free-text \"other\" choice (when custom answers are allowed). */\n otherOption: string;\n /** Placeholder for the free-text answer field. */\n answerPlaceholder: string;\n /** Submit button for the question card. */\n submit: string;\n\n // \u2500\u2500 Chat-history drawer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Drawer heading. */\n chats: string;\n /** Empty-state line when there are no threads. */\n noConversations: string;\n /** Rename row button (`title`). */\n rename: string;\n /** Rename row button `aria-label`. */\n renameConversation: string;\n /** Delete row button (`title`) + the inline-confirm action. */\n delete: string;\n /** Delete row button `aria-label`. */\n deleteConversation: string;\n /** Inline delete-confirm prompt. */\n deletePrompt: string;\n\n // \u2500\u2500 Attachments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Oversize rejection. Token: `{size}`. */\n tooLarge: string;\n /** Disallowed-type rejection. */\n fileTypeNotAllowed: string;\n /** Generic upload failure (when the error carries no message). */\n uploadFailed: string;\n /** Retry-upload button (`title`). */\n retry: string;\n /** Retry-upload button `aria-label`. */\n retryUpload: string;\n /** Remove-attachment button (`title`). */\n remove: string;\n /** Remove-attachment button `aria-label`. */\n removeAttachment: string;\n\n // \u2500\u2500 Relative time (drawer rows) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Under a minute ago. */\n justNow: string;\n /** Minutes ago. Token: `{n}`. */\n minutesAgo: string;\n /** Hours ago. Token: `{n}`. */\n hoursAgo: string;\n /** Title of the checkpoint panel. */\n /** Label on a code block's copy button. */\n copyCode: string;\n /** Shown on the copy button after the code reached the clipboard. */\n copied: string;\n /** Shown when the clipboard was unavailable or refused the write. */\n copyFailed: string;\n checkpoints: string;\n /** Empty state when no run can be continued. */\n noCheckpoints: string;\n /** Action: continue a run from its last checkpoint. */\n resumeRun: string;\n /** Action: branch a run without touching the original. */\n forkRun: string;\n /** Badge on a run that branched from another. */\n forkedRun: string;\n /** Days ago. Token: `{n}`. */\n daysAgo: string;\n /** Weeks ago. Token: `{n}`. */\n weeksAgo: string;\n}\n\n/** The built-in English strings \u2014 the fallback every override merges over. */\nexport const DEFAULT_UI_STRINGS: UiStrings = {\n title: \"Assistant\",\n chatHistory: \"Chat history\",\n newChat: \"New chat\",\n collapse: \"Collapse\",\n expand: \"Expand\",\n expandUnread: \"Expand \u2014 {count} unread\",\n toggleTheme: \"Toggle theme\",\n copyCode: \"Copy\",\n copied: \"Copied\",\n copyFailed: \"Copy failed\",\n checkpoints: \"Continue a run\",\n noCheckpoints: \"Nothing to continue yet.\",\n resumeRun: \"Resume\",\n forkRun: \"Fork\",\n forkedRun: \"branched\",\n\n conversation: \"Conversation\",\n thinking: \"Assistant is thinking\u2026\",\n thoughts: \"Thoughts\",\n stopped: \"\u23F9 Stopped\",\n connectionLost: \"Connection lost\",\n noResult: \"No result returned.\",\n declinedAction: \"User declined the action.\",\n navigating: \"Navigating\u2026\",\n historyCompacted: \"Earlier turns condensed to fit the context window ({count} removed)\",\n usingSkill: \"Using skill {name}\",\n runInterrupted: \"The previous response didn\u2019t finish \u2014 the page changed before it arrived.\",\n pageMoved:\n \"The page changed since you last looked at it. Call read_page to see the current page, then retry.\",\n attachmentsStillUploading:\n \"{n} file still uploading \u2014 it was not sent with this message and is still attached.\",\n skillNeeds: \"\u201C{title}\u201D needs {fields} \u2014 fill it in below, then send.\",\n\n message: \"Message\",\n inputPlaceholder: \"Ask anything\u2026\",\n send: \"Send\",\n stop: \"Stop\",\n attachFiles: \"Attach files\",\n recordVoice: \"Record voice\",\n stopRecording: \"Stop recording\",\n transcribing: \"Transcribing\u2026\",\n transcriptionFailed: \"Transcription failed\",\n\n toolRunning: \"running\u2026\",\n toolDeferred: \"waiting for you\",\n toolDone: \"\u2713 done\",\n toolError: \"\u26A0 error\",\n toolDeclined: \"\u2298 declined\",\n resizePanel: \"Resize the chat panel\",\n decisionApproved: \"approved by you\",\n decisionDeclined: \"declined by you\",\n argumentsLabel: \"Arguments\",\n resultLabel: \"Result\",\n errorLabel: \"Error\",\n declinedLabel: \"Declined\",\n details: \"Details\",\n\n confirmAction: \"Confirm action\",\n confirmRun: \"Run \u201C{tool}\u201D?\",\n confirm: \"Confirm\",\n cancel: \"Cancel\",\n\n approveAction: \"Approve action\",\n approvalPrompt: \"Approve this action?\",\n approve: \"Approve\",\n deny: \"Deny\",\n\n askUserAction: \"Question\",\n otherOption: \"Other\u2026\",\n answerPlaceholder: \"Type your answer\u2026\",\n submit: \"Submit\",\n\n chats: \"Chats\",\n noConversations: \"No conversations yet.\",\n rename: \"Rename\",\n renameConversation: \"Rename conversation\",\n delete: \"Delete\",\n deleteConversation: \"Delete conversation\",\n deletePrompt: \"Delete?\",\n\n tooLarge: \"Too large (max {size})\",\n fileTypeNotAllowed: \"File type not allowed\",\n uploadFailed: \"upload failed\",\n retry: \"Retry\",\n retryUpload: \"Retry upload\",\n remove: \"Remove\",\n removeAttachment: \"Remove attachment\",\n\n justNow: \"just now\",\n minutesAgo: \"{n}m ago\",\n hoursAgo: \"{n}h ago\",\n daysAgo: \"{n}d ago\",\n weeksAgo: \"{n}w ago\",\n};\n\n/**\n * Merge a partial set of overrides over {@link DEFAULT_UI_STRINGS}, yielding a\n * complete {@link UiStrings}. Keys whose override is `undefined` keep the\n * default (so a `data-strings` JSON with only a few keys \u2014 or a property carrying\n * explicit `undefined` \u2014 leaves the rest English).\n */\nexport function mergeUiStrings(overrides: Partial<UiStrings>): UiStrings {\n const merged: UiStrings = { ...DEFAULT_UI_STRINGS };\n for (const key of Object.keys(overrides) as (keyof UiStrings)[]) {\n const value = overrides[key];\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n return merged;\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** What the inline approval card displays for one server-side-tool interrupt. */\nexport interface ApprovalRequest {\n /**\n * Human-readable prompt from the AG-UI interrupt (e.g.\n * `Approve delete_thing({\u2026})?`). Falls back to the generic\n * {@link UiStrings.approvalPrompt} when the interrupt carries no message.\n */\n message?: string;\n /** Tool name, surfaced as a `data-tool-name` attribute for styling/tests. */\n toolName?: string;\n}\n\n/** Build a labelled action button. */\nfunction actionButton(modifier: string, label: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `approval-btn approval-btn--${modifier}`;\n button.setAttribute(\"part\", `approval-button approval-${modifier}`);\n button.textContent = label;\n return button;\n}\n\n/** Options for {@link requestApproval}. */\nexport interface ApprovalOptions {\n /**\n * Aborting this signal resolves the card as denied, with buttons disabled and\n * `data-resolved=\"denied\"` \u2014 how a Stop control dismisses a pending approval.\n */\n signal?: AbortSignal;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n strings?: UiStrings;\n}\n\n/**\n * A fully custom renderer for a server-side-tool approval, set via\n * `AgUiChat.approvalRenderer`. Receives the {@link ApprovalRequest} and an\n * `AbortSignal` that fires when the run is stopped, and resolves `true` to\n * approve or `false` to deny. Replaces the built-in {@link requestApproval}\n * card entirely, the host owning the DOM; to restyle the built-in card instead,\n * use the `strings` and `::part()` seams.\n */\nexport type ApprovalRenderer = (\n request: ApprovalRequest,\n options: { signal: AbortSignal },\n) => Promise<boolean>;\n\n/**\n * Append an inline approval card to `host` and resolve `true` to run a gated\n * server-side tool or `false` to deny it.\n *\n * Distinct from the client-tool confirmation card\n * ({@link requestConfirmation}): a gated server tool defers instead of\n * executing, so the run finishes on an AG-UI interrupt the client answers with\n * `resume[]`, and this is the browser half of that loop. Unlike the\n * confirmation card, this one stays in the transcript as a resolved record,\n * buttons disabled and `data-resolved` set.\n */\nexport function requestApproval(\n host: Node & ParentNode,\n request: ApprovalRequest,\n options: ApprovalOptions = {},\n): Promise<boolean> {\n const strings = options.strings ?? DEFAULT_UI_STRINGS;\n return new Promise<boolean>((resolve) => {\n const card = document.createElement(\"div\");\n card.className = \"approval\";\n card.setAttribute(\"part\", \"approval\");\n if (request.toolName !== undefined) {\n card.setAttribute(\"data-tool-name\", request.toolName);\n }\n card.setAttribute(\"role\", \"group\");\n card.setAttribute(\"aria-label\", strings.approveAction);\n\n const body = document.createElement(\"div\");\n body.className = \"approval-body\";\n body.setAttribute(\"part\", \"approval-body\");\n body.textContent = request.message ?? strings.approvalPrompt;\n\n const actions = document.createElement(\"div\");\n actions.className = \"approval-actions\";\n actions.setAttribute(\"part\", \"approval-actions\");\n\n const deny = actionButton(\"deny\", strings.deny);\n const approve = actionButton(\"approve\", strings.approve);\n\n let settled = false;\n const close = (approved: boolean): void => {\n if (settled) {\n return;\n }\n settled = true;\n deny.disabled = true;\n approve.disabled = true;\n card.setAttribute(\"data-resolved\", approved ? \"approved\" : \"denied\");\n resolve(approved);\n };\n\n deny.addEventListener(\"click\", () => close(false));\n approve.addEventListener(\"click\", () => close(true));\n options.signal?.addEventListener(\"abort\", () => close(false), { once: true });\n\n actions.append(deny, approve);\n card.append(body, actions);\n host.appendChild(card);\n if (options.signal?.aborted === true) {\n // The run was cancelled before the card could ask; record the denial.\n close(false);\n return;\n }\n approve.focus();\n });\n}\n", "import type { UiStrings } from \"./ui_strings.js\";\n\n/** How long the button shows its \"copied\" confirmation before reverting. */\nconst CONFIRM_MS = 1500;\n\n/**\n * Give every fenced code block in `root` a copy button.\n *\n * Call only on finished bubbles: the streaming bubble reassigns its `innerHTML`\n * on every delta, so a button attached mid-stream is discarded and rebuilt for\n * each one.\n *\n * Idempotent \u2014 a bubble already processed is skipped, so a re-render or a second\n * call cannot stack buttons.\n */\nexport function attachCopyButtons(root: ParentNode, strings: UiStrings): void {\n for (const pre of Array.from(root.querySelectorAll(\"pre\"))) {\n const code = pre.querySelector(\"code\");\n if (code === null || pre.querySelector(\".code-copy\") !== null) {\n continue;\n }\n pre.classList.add(\"has-copy\");\n pre.append(button(code, strings));\n }\n}\n\nfunction button(code: Element, strings: UiStrings): HTMLButtonElement {\n // Never null: `textContent` is nullable only on documents and doctypes,\n // and this is always the `code` element `querySelector` just returned.\n const text = code.textContent as string;\n const copy = document.createElement(\"button\");\n copy.type = \"button\";\n copy.className = \"code-copy\";\n copy.setAttribute(\"part\", \"code-copy\");\n copy.textContent = strings.copyCode;\n copy.title = strings.copyCode;\n copy.setAttribute(\"aria-label\", strings.copyCode);\n copy.addEventListener(\"click\", () => {\n void writeText(text).then((ok) => {\n // Report the real outcome: a button that always claims success leaves the\n // reader pasting stale clipboard content.\n confirm(copy, ok ? strings.copied : strings.copyFailed, strings);\n });\n });\n return copy;\n}\n\n/**\n * Copy `text`, reporting whether it landed. The Clipboard API needs a secure\n * context and a user gesture and is absent in some embeddings, so failure is an\n * ordinary outcome rather than an error to throw at the host page.\n */\nasync function writeText(text: string): Promise<boolean> {\n const clipboard = navigator.clipboard;\n if (clipboard === undefined) {\n return false;\n }\n try {\n await clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction confirm(copy: HTMLButtonElement, message: string, strings: UiStrings): void {\n copy.textContent = message;\n copy.dataset[\"state\"] = message === strings.copied ? \"copied\" : \"failed\";\n setTimeout(() => {\n copy.textContent = strings.copyCode;\n delete copy.dataset[\"state\"];\n }, CONFIRM_MS);\n}\n", "import { ICON_FILE, ICON_FILE_IMAGE, ICON_FILE_PDF, ICON_FILE_TEXT } from \"../constants.js\";\nimport type { AttachmentRef } from \"../core/attachment.js\";\n\n/**\n * Render the read-only attachment chips on a sent user message bubble and on\n * restored history \u2014 one chip per ref with a type icon, filename, and human\n * size. Static: no progress and no remove, both of which live in the composer\n * tray.\n */\nexport function renderAttachmentChips(refs: readonly AttachmentRef[]): HTMLDivElement {\n const list = document.createElement(\"div\");\n list.className = \"attachment-chips\";\n list.setAttribute(\"part\", \"attachment-chips\");\n for (const ref of refs) {\n list.appendChild(renderChip(ref));\n }\n return list;\n}\n\nfunction renderChip(ref: AttachmentRef): HTMLDivElement {\n const chip = document.createElement(\"div\");\n chip.className = \"attachment-chip attachment-chip--ready\";\n chip.setAttribute(\"part\", \"attachment-chip\");\n\n const icon = document.createElement(\"span\");\n icon.className = \"attachment-chip-icon\";\n icon.setAttribute(\"part\", \"attachment-chip-icon\");\n icon.innerHTML = iconFor(ref.mime);\n icon.setAttribute(\"aria-hidden\", \"true\");\n\n const name = document.createElement(\"span\");\n name.className = \"attachment-chip-name\";\n name.setAttribute(\"part\", \"attachment-chip-name\");\n name.textContent = ref.name;\n name.title = ref.name;\n\n const size = document.createElement(\"span\");\n size.className = \"attachment-chip-size\";\n size.setAttribute(\"part\", \"attachment-chip-size\");\n size.textContent = formatBytes(ref.size);\n\n chip.append(icon, name, size);\n return chip;\n}\n\n/**\n * A coarse type mark for a chip \u2014 image, PDF, text document, or generic file \u2014\n * as inline SVG markup rather than a character, so it matches the composer's\n * SVG buttons in weight and takes the glyph size and `currentColor`, which\n * emoji do not.\n *\n * The MIME string only selects among author-written constants and is never\n * interpolated into one, so the result is safe to assign as markup.\n */\nexport function iconFor(mime: string): string {\n if (mime.startsWith(\"image/\")) {\n return ICON_FILE_IMAGE;\n }\n if (mime === \"application/pdf\") {\n return ICON_FILE_PDF;\n }\n if (mime.startsWith(\"text/\")) {\n return ICON_FILE_TEXT;\n }\n return ICON_FILE;\n}\n\n/** A compact human-readable byte size (e.g. `1.2 MB`). */\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = [\"KB\", \"MB\", \"GB\"];\n let value = bytes / 1024;\n let unit = 0;\n while (value >= 1024 && unit < units.length - 1) {\n value /= 1024;\n unit += 1;\n }\n const rounded = value < 10 ? Math.round(value * 10) / 10 : Math.round(value);\n return `${rounded} ${units[unit]}`;\n}\n", "import { randomUUID } from \"@ag-ui/client\";\nimport { ATTACHMENT_STATUS } from \"../constants.js\";\nimport type { AttachmentRef } from \"../core/attachment.js\";\nimport type { UploadHandler } from \"../core/upload_attachment.js\";\nimport { formatBytes, iconFor } from \"./attachment_chips.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Status of a pending tray chip. */\ntype AttachmentStatus = (typeof ATTACHMENT_STATUS)[keyof typeof ATTACHMENT_STATUS];\n\n/** Config the host ({@link AgUiChat}) hands the tray. */\nexport interface AttachmentTrayConfig {\n /** Upload one file, reporting `0..1` progress; resolves to a durable ref. */\n readonly upload: UploadHandler;\n /** Client-side size cap in bytes (`0` = no cap). The server stays authoritative. */\n readonly maxBytes: number;\n /** Client-side accept list (`<input accept>` syntax; `\"\"` = any). */\n readonly accept: string;\n /** Fired when the set of attachments changes (add / settle / remove). */\n readonly onChange?: () => void;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n readonly strings?: UiStrings;\n}\n\n/** One pending file in the tray, from pick to ready/error. */\ninterface TrayItem {\n readonly localId: string;\n readonly file: File;\n status: AttachmentStatus;\n progress: number;\n ref: AttachmentRef | null;\n error: string;\n /** Aborts the in-flight upload when the chip is removed / the tray cleared. */\n controller: AbortController | null;\n}\n\n/**\n * The composer's pending-attachments tray: a chip per picked file with a\n * progress bar while it uploads, settling to a ready chip holding the durable\n * ref or an error chip with retry. A stateful view like {@link ThreadDrawer}:\n * the host appends {@link element}, calls {@link add} on pick or drop, reads\n * {@link readyRefs} on send, and clears it.\n *\n * Client-side size and type guards reject a bad file into an error chip without\n * uploading, for instant feedback, but the server stays the authority.\n */\nexport class AttachmentTray {\n /** The tray root; append above the input row. Hidden while empty. */\n readonly element: HTMLDivElement;\n\n readonly #config: AttachmentTrayConfig;\n readonly #strings: UiStrings;\n #items: TrayItem[] = [];\n\n constructor(config: AttachmentTrayConfig) {\n this.#config = config;\n this.#strings = config.strings ?? DEFAULT_UI_STRINGS;\n this.element = document.createElement(\"div\");\n this.element.className = \"attachment-tray\";\n this.element.setAttribute(\"part\", \"attachment-tray\");\n this.element.hidden = true;\n }\n\n /** Queue a file: reject oversize/disallowed into an error chip, else upload. */\n add(file: File): void {\n const item: TrayItem = {\n localId: randomUUID(),\n file,\n status: ATTACHMENT_STATUS.UPLOADING,\n progress: 0,\n ref: null,\n error: \"\",\n controller: null,\n };\n this.#items.push(item);\n const rejection = this.#reject(file);\n if (rejection !== null) {\n item.status = ATTACHMENT_STATUS.ERROR;\n item.error = rejection;\n this.#render();\n this.#config.onChange?.();\n return;\n }\n this.#render();\n this.#config.onChange?.();\n this.#upload(item);\n }\n\n /** The durable refs of every chip that finished uploading. */\n readyRefs(): readonly AttachmentRef[] {\n const refs: AttachmentRef[] = [];\n for (const item of this.#items) {\n if (item.ref !== null) {\n refs.push(item.ref);\n }\n }\n return refs;\n }\n\n /** Whether any chip is still uploading (a send would drop nothing if false). */\n hasPending(): boolean {\n return this.#items.some((item) => item.status === ATTACHMENT_STATUS.UPLOADING);\n }\n\n /** How many chips are still uploading \u2014 the count a send-time notice names. */\n pendingCount(): number {\n return this.#items.filter((item) => item.status === ATTACHMENT_STATUS.UPLOADING).length;\n }\n\n /** Whether the tray holds no chips. */\n isEmpty(): boolean {\n return this.#items.length === 0;\n }\n\n /** Drop the settled (ready / error) chips, leaving any still uploading. */\n clearReady(): void {\n this.#items = this.#items.filter((item) => item.status === ATTACHMENT_STATUS.UPLOADING);\n this.#render();\n }\n\n /** Drop every chip (a reset / new-chat), aborting any in-flight upload. */\n clear(): void {\n for (const item of this.#items) {\n item.controller?.abort();\n }\n this.#items = [];\n this.#render();\n }\n\n /**\n * Abort every in-flight upload without touching the rendered chips \u2014 the\n * teardown path when the host element is removed mid-upload, so a cancelled\n * transfer doesn't orphan a server-side file.\n */\n dispose(): void {\n for (const item of this.#items) {\n item.controller?.abort();\n }\n }\n\n /** The size/type rejection reason for a file, or `null` when accepted. */\n #reject(file: File): string | null {\n if (this.#config.maxBytes > 0 && file.size > this.#config.maxBytes) {\n return this.#strings.tooLarge.replace(\"{size}\", formatBytes(this.#config.maxBytes));\n }\n if (!accepts(this.#config.accept, file)) {\n return this.#strings.fileTypeNotAllowed;\n }\n return null;\n }\n\n #upload(item: TrayItem): void {\n // Re-apply the client guard on every attempt, not just the first `add` \u2014 an\n // ERROR chip always renders retry, so without this a size/type-rejected file\n // would upload in full on \u21BB.\n const rejection = this.#reject(item.file);\n if (rejection !== null) {\n item.status = ATTACHMENT_STATUS.ERROR;\n item.error = rejection;\n this.#render();\n this.#config.onChange?.();\n return;\n }\n item.status = ATTACHMENT_STATUS.UPLOADING;\n item.progress = 0;\n item.error = \"\";\n const controller = new AbortController();\n item.controller = controller;\n this.#render();\n this.#config\n .upload(\n item.file,\n (fraction) => {\n item.progress = fraction;\n this.#render();\n },\n controller.signal,\n )\n .then((ref) => {\n item.status = ATTACHMENT_STATUS.READY;\n item.ref = ref;\n })\n .catch((error: unknown) => {\n item.status = ATTACHMENT_STATUS.ERROR;\n item.error = error instanceof Error ? error.message : this.#strings.uploadFailed;\n })\n .finally(() => {\n item.controller = null;\n this.#render();\n this.#config.onChange?.();\n });\n }\n\n #remove(item: TrayItem): void {\n // Abort an in-flight upload so removing its chip doesn't orphan the file.\n item.controller?.abort();\n this.#items = this.#items.filter((other) => other !== item);\n this.#render();\n this.#config.onChange?.();\n }\n\n #render(): void {\n this.element.replaceChildren();\n this.element.hidden = this.#items.length === 0;\n for (const item of this.#items) {\n this.element.appendChild(this.#renderChip(item));\n }\n }\n\n #renderChip(item: TrayItem): HTMLDivElement {\n const chip = document.createElement(\"div\");\n chip.className = `attachment-chip attachment-chip--${item.status}`;\n chip.setAttribute(\"part\", \"attachment-chip\");\n\n const icon = document.createElement(\"span\");\n icon.className = \"attachment-chip-icon\";\n icon.setAttribute(\"part\", \"attachment-chip-icon\");\n // Author-written glyph markup, selected by MIME family \u2014 see iconFor.\n icon.innerHTML = iconFor(item.file.type);\n icon.setAttribute(\"aria-hidden\", \"true\");\n\n const name = document.createElement(\"span\");\n name.className = \"attachment-chip-name\";\n name.setAttribute(\"part\", \"attachment-chip-name\");\n name.textContent = item.file.name;\n name.title = item.file.name;\n\n const meta = document.createElement(\"span\");\n meta.className = \"attachment-chip-size\";\n meta.setAttribute(\"part\", \"attachment-chip-size\");\n meta.textContent =\n item.status === ATTACHMENT_STATUS.ERROR ? item.error : formatBytes(item.file.size);\n\n chip.append(icon, name, meta);\n\n if (item.status === ATTACHMENT_STATUS.UPLOADING) {\n const bar = document.createElement(\"div\");\n bar.className = \"attachment-chip-bar\";\n bar.setAttribute(\"part\", \"attachment-chip-bar\");\n const fill = document.createElement(\"div\");\n fill.className = \"attachment-chip-bar-fill\";\n fill.setAttribute(\"part\", \"attachment-chip-bar-fill\");\n fill.style.width = `${Math.round(item.progress * 100)}%`;\n bar.appendChild(fill);\n chip.appendChild(bar);\n }\n\n if (item.status === ATTACHMENT_STATUS.ERROR) {\n const retry = document.createElement(\"button\");\n retry.type = \"button\";\n retry.className = \"attachment-chip-retry\";\n retry.setAttribute(\"part\", \"attachment-chip-retry\");\n retry.title = this.#strings.retry;\n retry.setAttribute(\"aria-label\", this.#strings.retryUpload);\n retry.textContent = \"\u21BB\";\n retry.addEventListener(\"click\", () => this.#upload(item));\n chip.appendChild(retry);\n }\n\n const remove = document.createElement(\"button\");\n remove.type = \"button\";\n remove.className = \"attachment-chip-remove\";\n remove.setAttribute(\"part\", \"attachment-chip-remove\");\n remove.title = this.#strings.remove;\n remove.setAttribute(\"aria-label\", this.#strings.removeAttachment);\n remove.textContent = \"\u2715\";\n remove.addEventListener(\"click\", () => this.#remove(item));\n chip.appendChild(remove);\n\n return chip;\n }\n}\n\n/** Whether `file` matches an `<input accept>` list (`\"\"` accepts anything). */\nfunction accepts(accept: string, file: File): boolean {\n const tokens = accept\n .split(\",\")\n .map((token) => token.trim().toLowerCase())\n .filter((token) => token !== \"\");\n if (tokens.length === 0) {\n return true;\n }\n const mime = file.type.toLowerCase();\n const name = file.name.toLowerCase();\n return tokens.some((token) => {\n if (token.startsWith(\".\")) {\n return name.endsWith(token);\n }\n if (token.endsWith(\"/*\")) {\n return mime.startsWith(token.slice(0, -1));\n }\n return mime === token;\n });\n}\n", "/**\n * Draw a {@link ChartSpec} as SVG.\n *\n * Every node is built with `createElement`, never parsed from a string, so this\n * path never reaches the markdown sanitiser and cannot be widened by model\n * output. That is the argument for taking a *spec* rather than markup: the model\n * chooses the numbers, this module chooses the DOM. It is why a chart can be\n * shown on a surface that keeps `img` off by default, a model-controlled URL\n * being a zero-click exfiltration channel.\n *\n * Hand-rolled rather than a charting library, and the difference is not\n * marginal: the whole renderer costs single-digit kilobytes where a library\n * costs roughly half this bundle again, in a component distributed over a CDN.\n */\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/** One named series of numbers. */\nexport interface ChartSeries {\n readonly label: string;\n readonly points: readonly number[];\n}\n\n/** How a spec is drawn. */\nexport type ChartKind = \"bar\" | \"line\" | \"pie\" | \"scatter\" | \"stacked\";\n\n/** A chart, as data. */\nexport interface ChartSpec {\n readonly kind: ChartKind;\n readonly title?: string;\n readonly labels: readonly string[];\n readonly series: readonly ChartSeries[];\n}\n\nconst WIDTH = 480;\nconst HEIGHT = 220;\nconst PAD = { top: 20, right: 12, bottom: 30, left: 44 };\nconst PLOT_W = WIDTH - PAD.left - PAD.right;\nconst PLOT_H = HEIGHT - PAD.top - PAD.bottom;\n\n// Read from the host's own palette rather than a fixed ramp: the component\n// themes through custom properties everywhere else, and a chart that ignored\n// that would be the one element a host could not restyle.\nconst SERIES_COLORS: readonly string[] = [\n \"var(--ag-ui-chart-1, #4f7cff)\",\n \"var(--ag-ui-chart-2, #21b573)\",\n \"var(--ag-ui-chart-3, #e0803c)\",\n \"var(--ag-ui-chart-4, #b563d8)\",\n \"var(--ag-ui-chart-5, #d84f6e)\",\n \"var(--ag-ui-chart-6, #3ba7c4)\",\n];\n\n/** The colour for series `index`, wrapping when there are more series than colours. */\nexport function seriesColor(index: number): string {\n // Cast rather than a `??` fallback: the modulo guarantees a hit, so a\n // fallback would be a branch no test could ever reach.\n return SERIES_COLORS[index % SERIES_COLORS.length] as string;\n}\n\nfunction el<K extends keyof SVGElementTagNameMap>(\n name: K,\n attrs: Record<string, string | number>,\n): SVGElementTagNameMap[K] {\n const node = document.createElementNS(SVG_NS, name);\n for (const [key, value] of Object.entries(attrs)) {\n node.setAttribute(key, String(value));\n }\n return node;\n}\n\nfunction text(value: string, attrs: Record<string, string | number>): SVGTextElement {\n const node = el(\"text\", {\n \"font-size\": 10,\n fill: \"currentColor\",\n \"fill-opacity\": 0.65,\n ...attrs,\n });\n // `textContent`, so a model-supplied label is text and never markup.\n node.textContent = value;\n return node;\n}\n\n/** Every running subtotal a stack passes through, column by column. */\nfunction stackRunning(spec: ChartSpec): number[] {\n const seen: number[] = [];\n spec.labels.forEach((_label, i) => {\n let running = 0;\n for (const series of spec.series) {\n running += series.points[i] ?? 0;\n seen.push(running);\n }\n });\n return seen;\n}\n\nfunction extent(spec: ChartSpec): { min: number; max: number } {\n // A stack's extent has to cover every *running subtotal*, not just the column\n // totals: with mixed signs the running value swings wider than the total it\n // ends on, and scaling to the total alone puts segments far off the canvas.\n const values =\n spec.kind === \"stacked\"\n ? stackRunning(spec)\n : spec.series.flatMap((series) => [...series.points]);\n const max = Math.max(0, ...values);\n const min = Math.min(0, ...values);\n // A flat series would divide by zero when scaling; give it a nominal span so\n // it draws as a flat line rather than vanishing.\n return max === min ? { min, max: max + 1 } : { min, max };\n}\n\nfunction scaleY(value: number, min: number, max: number): number {\n return PAD.top + PLOT_H - ((value - min) / (max - min)) * PLOT_H;\n}\n\nfunction bandCentre(index: number, count: number): number {\n const step = PLOT_W / count;\n return PAD.left + step * index + step / 2;\n}\n\nfunction drawAxes(svg: SVGSVGElement, spec: ChartSpec, min: number, max: number): void {\n for (const value of [min, max]) {\n const y = scaleY(value, min, max);\n svg.appendChild(\n el(\"line\", {\n x1: PAD.left,\n y1: y,\n x2: WIDTH - PAD.right,\n y2: y,\n stroke: \"currentColor\",\n \"stroke-opacity\": value === min ? 0.35 : 0.12,\n }),\n );\n svg.appendChild(\n text(String(Math.round(value)), { x: PAD.left - 6, y: y + 4, \"text-anchor\": \"end\" }),\n );\n }\n spec.labels.forEach((label, i) => {\n svg.appendChild(\n text(label, {\n x: bandCentre(i, spec.labels.length),\n y: HEIGHT - PAD.bottom + 16,\n \"text-anchor\": \"middle\",\n }),\n );\n });\n}\n\nfunction drawBars(svg: SVGSVGElement, spec: ChartSpec, min: number, max: number): void {\n const step = PLOT_W / spec.labels.length;\n const width = (step * 0.7) / spec.series.length;\n const base = scaleY(min, min, max);\n spec.series.forEach((series, s) => {\n series.points.forEach((value, i) => {\n const y = scaleY(value, min, max);\n svg.appendChild(\n el(\"rect\", {\n x: PAD.left + step * i + step * 0.15 + width * s,\n y,\n width,\n height: Math.max(1, base - y),\n fill: seriesColor(s),\n rx: 2,\n }),\n );\n });\n });\n}\n\nfunction drawStacked(svg: SVGSVGElement, spec: ChartSpec, min: number, max: number): void {\n const step = PLOT_W / spec.labels.length;\n const width = step * 0.7;\n // Indexed by the same `i` it was built from, so every read is a hit; cast\n // rather than defaulting, which would add a branch nothing can reach.\n const running = spec.labels.map(() => 0);\n spec.series.forEach((series, s) => {\n series.points.forEach((value, i) => {\n const from = running[i] as number;\n const to = from + value;\n running[i] = to;\n const y = scaleY(to, min, max);\n svg.appendChild(\n el(\"rect\", {\n x: PAD.left + step * i + step * 0.15,\n y,\n width,\n height: Math.max(1, scaleY(from, min, max) - y),\n fill: seriesColor(s),\n }),\n );\n });\n });\n}\n\nfunction drawLines(svg: SVGSVGElement, spec: ChartSpec, min: number, max: number): void {\n spec.series.forEach((series, s) => {\n const points = series.points\n .map((value, i) => `${bandCentre(i, spec.labels.length)},${scaleY(value, min, max)}`)\n .join(\" \");\n svg.appendChild(\n el(\"polyline\", {\n points,\n fill: \"none\",\n stroke: seriesColor(s),\n \"stroke-width\": 2,\n \"stroke-linejoin\": \"round\",\n }),\n );\n });\n}\n\nfunction drawScatter(svg: SVGSVGElement, spec: ChartSpec, min: number, max: number): void {\n spec.series.forEach((series, s) => {\n series.points.forEach((value, i) => {\n svg.appendChild(\n el(\"circle\", {\n cx: bandCentre(i, spec.labels.length),\n cy: scaleY(value, min, max),\n r: 4,\n fill: seriesColor(s),\n \"fill-opacity\": 0.85,\n }),\n );\n });\n });\n}\n\n/**\n * Pie draws the **first** series' points as shares of their own total, one\n * wedge per label \u2014 the only kind whose slices are the labels rather than the\n * series, so a second series has nowhere to go and is ignored rather than\n * silently summed into the first.\n */\nfunction drawPie(svg: SVGSVGElement, points: readonly number[]): void {\n const total = points.reduce((sum, value) => sum + value, 0);\n const cx = WIDTH / 2;\n const cy = PAD.top + PLOT_H / 2;\n const r = Math.min(PLOT_W, PLOT_H) / 2;\n if (total === 0) {\n // Every share is zero, so there is no wedge to draw and a full circle would\n // claim one slice owns everything. An outline says \"nothing here\" honestly.\n svg.appendChild(\n el(\"circle\", { cx, cy, r, fill: \"none\", stroke: \"currentColor\", \"stroke-opacity\": 0.3 }),\n );\n return;\n }\n let angle = -Math.PI / 2;\n points.forEach((value, i) => {\n const sweep = (value / total) * Math.PI * 2;\n const end = angle + sweep;\n // A wedge of the whole circle cannot be drawn as one arc (start and end\n // coincide, so the path collapses); draw it as a plain circle instead.\n if (sweep >= Math.PI * 2) {\n svg.appendChild(el(\"circle\", { cx, cy, r, fill: seriesColor(i) }));\n } else {\n const x1 = cx + r * Math.cos(angle);\n const y1 = cy + r * Math.sin(angle);\n const x2 = cx + r * Math.cos(end);\n const y2 = cy + r * Math.sin(end);\n const large = sweep > Math.PI ? 1 : 0;\n svg.appendChild(\n el(\"path\", {\n d: `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} Z`,\n fill: seriesColor(i),\n }),\n );\n }\n angle = end;\n });\n}\n\nfunction buildLegend(entries: readonly string[]): HTMLDivElement | null {\n if (entries.length < 2) {\n return null;\n }\n const row = document.createElement(\"div\");\n row.className = \"chart-legend\";\n row.setAttribute(\"part\", \"chart-legend\");\n entries.forEach((label, i) => {\n const item = document.createElement(\"span\");\n item.className = \"chart-legend-item\";\n const swatch = document.createElement(\"span\");\n swatch.className = \"chart-legend-swatch\";\n swatch.style.background = seriesColor(i);\n item.append(swatch, document.createTextNode(label));\n row.appendChild(item);\n });\n return row;\n}\n\n/**\n * Render one spec as a self-contained block, or `null` when it says nothing.\n *\n * A spec with no labels or no series is not drawn: an empty frame reads as\n * \"there is no data\" when the truth is \"the caller sent nothing\", and the two\n * deserve different answers.\n */\nexport function renderChart(spec: ChartSpec): HTMLDivElement | null {\n if (spec.labels.length === 0 || spec.series.length === 0) {\n return null;\n }\n const block = document.createElement(\"div\");\n block.className = \"chart-block\";\n block.setAttribute(\"part\", \"chart-block\");\n\n if (spec.title !== undefined && spec.title !== \"\") {\n const heading = document.createElement(\"div\");\n heading.className = \"chart-title\";\n heading.setAttribute(\"part\", \"chart-title\");\n heading.textContent = spec.title;\n block.appendChild(heading);\n }\n\n const svg = el(\"svg\", { viewBox: `0 0 ${WIDTH} ${HEIGHT}`, width: \"100%\", role: \"img\" });\n svg.setAttribute(\"aria-label\", spec.title ?? `${spec.kind} chart`);\n\n if (spec.kind === \"pie\") {\n // `series[0]` is guaranteed by the early return above; a pie's slices are\n // its labels, so a second series has nowhere to go and is ignored rather\n // than silently summed into the first. Negative shares are floored, since a\n // wedge cannot sweep backwards.\n const first = spec.series[0] as ChartSeries;\n drawPie(\n svg,\n first.points.map((value) => Math.max(0, value)),\n );\n } else {\n const { min, max } = extent(spec);\n drawAxes(svg, spec, min, max);\n if (spec.kind === \"bar\") {\n drawBars(svg, spec, min, max);\n } else if (spec.kind === \"stacked\") {\n drawStacked(svg, spec, min, max);\n } else if (spec.kind === \"line\") {\n drawLines(svg, spec, min, max);\n } else {\n drawScatter(svg, spec, min, max);\n }\n }\n block.appendChild(svg);\n\n // Pie's slices are its labels; every other kind's are its series.\n const legend = buildLegend(\n spec.kind === \"pie\" ? spec.labels : spec.series.map((series) => series.label),\n );\n if (legend !== null) {\n block.appendChild(legend);\n }\n return block;\n}\n", "/**\n * Narrow untrusted input into a {@link ChartSpec}.\n *\n * Both arrival routes are untrusted in the same way \u2014 a model writes one, a\n * server the other \u2014 so neither is taken on shape. Kept out of the renderer\n * because the renderer's job is drawing, and a value that reaches it has\n * already been vouched for.\n */\n\nimport type { ChartKind, ChartSpec } from \"./chart_block.js\";\n\nconst KINDS: readonly ChartKind[] = [\"bar\", \"line\", \"pie\", \"scatter\", \"stacked\"];\n\n/**\n * Most points a spec may carry, across every series.\n *\n * Not a taste limit. `Math.max(0, ...values)` throws `RangeError` on a large\n * enough spread, and the renderer runs inside the history replay, where a throw\n * abandons the replay and takes every later turn of the transcript with it \u2014\n * permanently, on every reload. A chart nobody can read is a far smaller\n * problem than a conversation that silently loses its tail.\n */\nconst MAX_POINTS = 20_000;\n\n/**\n * Largest magnitude a point may carry.\n *\n * `Number.isFinite` is not enough on its own: two finite extremes still give an\n * infinite *range*, and `(value - min) / Infinity` is `NaN`, which reaches the\n * DOM as `y=\"NaN\"`. Bounding the values bounds the range.\n */\nconst MAX_MAGNITUDE = 1e15;\n\nfunction asKind(value: unknown): ChartKind {\n // Anything unrecognised falls back to `bar` rather than refusing the spec: an\n // unknown kind is a caller reaching for a chart type we do not draw, and the\n // data is still worth showing.\n return KINDS.includes(value as ChartKind) ? (value as ChartKind) : \"bar\";\n}\n\nfunction asNumbers(value: unknown): number[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n const out: number[] = [];\n for (const item of value) {\n // `Number.isFinite` rather than `typeof === \"number\"`: JSON encoders render\n // NaN and Infinity as nulls or strings depending on the encoder, and either\n // would scale into a chart with no visible extent.\n if (typeof item !== \"number\" || !Number.isFinite(item)) {\n return null;\n }\n if (Math.abs(item) > MAX_MAGNITUDE) {\n return null;\n }\n out.push(item);\n }\n return out;\n}\n\nfunction asStrings(value: unknown): string[] | null {\n if (!Array.isArray(value) || value.some((item) => typeof item !== \"string\")) {\n return null;\n }\n return value as string[];\n}\n\n/** A well-formed spec, or `null` for anything that cannot be drawn honestly. */\nexport function chartSpecFrom(value: unknown): ChartSpec | null {\n if (typeof value !== \"object\" || value === null) {\n return null;\n }\n const raw = value as Record<string, unknown>;\n const labels = asStrings(raw[\"labels\"]);\n if (labels === null || !Array.isArray(raw[\"series\"])) {\n return null;\n }\n\n const series: { label: string; points: number[] }[] = [];\n for (const entry of raw[\"series\"]) {\n if (typeof entry !== \"object\" || entry === null) {\n return null;\n }\n const item = entry as Record<string, unknown>;\n const points = asNumbers(item[\"points\"]);\n // A series with a different number of points than there are labels would\n // silently misalign every value after the gap. A chart that is subtly wrong\n // still reads as authoritative, which is worse than no chart at all.\n if (points === null || points.length !== labels.length) {\n return null;\n }\n series.push({ label: typeof item[\"label\"] === \"string\" ? item[\"label\"] : \"\", points });\n }\n if (series.length === 0) {\n return null;\n }\n if (series.length * labels.length > MAX_POINTS) {\n return null;\n }\n\n const kind = asKind(raw[\"kind\"]);\n const title = raw[\"title\"];\n // The key is omitted rather than set to `undefined`: `title` is genuinely\n // optional and this tsconfig distinguishes absent from present-and-undefined.\n return typeof title === \"string\" ? { kind, title, labels, series } : { kind, labels, series };\n}\n", "/**\n * The built-in `render_chart` tool: the agent-called route to a chart.\n *\n * A thin thing on purpose. It carries no `handler` of its own beyond reporting\n * back to the model, because everything it does is drawing \u2014 which lives in\n * `render`, the half the component replays. A consumer wanting charts gets this\n * without writing a renderer; a consumer wanting something else writes their own\n * tool against the same seam.\n */\n\nimport type { ClientTool } from \"../tools/client_tool_registry.js\";\nimport { renderChart } from \"./chart_block.js\";\nimport { chartSpecFrom } from \"./chart_spec_from.js\";\n\n/** The name the built-in chart tool registers under. */\nexport const CHART_TOOL_NAME = \"render_chart\";\n\nfunction draw(args: Record<string, unknown>): HTMLDivElement | null {\n const spec = chartSpecFrom(args);\n return spec === null ? null : renderChart(spec);\n}\n\nconst REJECTED =\n \"chart not rendered: expected labels (strings) and series, each with one finite number per label\";\n\n/** The built-in chart tool. */\nexport function createChartTool(): ClientTool {\n return {\n name: CHART_TOOL_NAME,\n description:\n \"Show a chart in the conversation. Supply the data and the page draws it. \" +\n \"Every series must have exactly one point per label.\",\n parameters: {\n type: \"object\",\n properties: {\n kind: { type: \"string\", enum: [\"bar\", \"line\", \"pie\", \"scatter\", \"stacked\"] },\n title: { type: \"string\" },\n labels: { type: \"array\", items: { type: \"string\" } },\n series: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n label: { type: \"string\" },\n points: { type: \"array\", items: { type: \"number\" } },\n },\n required: [\"points\"],\n },\n },\n },\n required: [\"labels\", \"series\"],\n \"x-summary\": \"Draw a chart\",\n },\n // Says what happened and nothing else; the drawing is `render`'s job. Told\n // plainly when the arguments are unusable, because the model can fix that\n // and retry \u2014 a silent no-op would leave it believing the chart is on screen.\n // Answers on what was actually drawn, not on what validated. A spec can\n // pass validation and still have nothing to show -- zero labels matches zero\n // points -- and reporting success then would leave the model believing a\n // chart is on screen.\n handler: (args: Record<string, unknown>) => (draw(args) === null ? REJECTED : \"chart rendered\"),\n render: draw,\n };\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/**\n * A compact relative timestamp for a thread row \u2014 e.g. `\"just now\"`, `\"5m ago\"`,\n * `\"3h ago\"`, `\"2d ago\"`, `\"4w ago\"`.\n *\n * `now` is injectable so callers and tests can pin the reference point. A\n * future timestamp (clock skew) and a non-finite one (an unparseable or missing\n * `updated_at`, arriving as `NaN`) both read as `justNow`, rather than\n * rendering a nonsense age. Unit words come from {@link UiStrings} with `{n}`\n * filled in here; the bucketing stays integer-rounded and locale-neutral.\n */\nexport function relativeTime(\n timestamp: number,\n now: number = Date.now(),\n strings: UiStrings = DEFAULT_UI_STRINGS,\n): string {\n if (!Number.isFinite(timestamp)) {\n return strings.justNow;\n }\n const seconds = Math.round((now - timestamp) / 1000);\n if (seconds < 60) {\n return strings.justNow;\n }\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) {\n return strings.minutesAgo.replace(\"{n}\", String(minutes));\n }\n const hours = Math.round(minutes / 60);\n if (hours < 24) {\n return strings.hoursAgo.replace(\"{n}\", String(hours));\n }\n const days = Math.round(hours / 24);\n if (days < 7) {\n return strings.daysAgo.replace(\"{n}\", String(days));\n }\n return strings.weeksAgo.replace(\"{n}\", String(Math.round(days / 7)));\n}\n", "import type { RunRow } from \"../core/run_index.js\";\nimport { relativeTime } from \"./relative_time.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** How the host continues a picked run. */\nexport type CheckpointVerb = \"resume\" | \"fork\";\n\n/** The run's first message, or `null` where the row has no words to show. */\nfunction previewOf(run: RunRow): string | null {\n return run.preview !== undefined && run.preview !== null && run.preview !== \"\"\n ? run.preview\n : null;\n}\n\n/**\n * A preview reduced to what the row puts on screen, for comparing two rows.\n *\n * Whitespace is collapsed because the rendered row collapses it anyway, so two\n * previews that differ only there are one label to the eye. Case is kept: two\n * spellings a person can tell apart are two labels, and an id beside them would\n * answer a question nobody asked.\n */\nfunction asShown(preview: string): string {\n return preview.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * The checkpoint panel: continuable runs, each offering **resume** or **fork**.\n *\n * Deliberately separate from the thread drawer: a thread is a conversation you\n * switch to, a checkpoint is a run you continue from, and one thread holds\n * many. One list would make \"resume\" read as \"open\", when resuming starts a new\n * run seeded from a snapshot.\n *\n * The host feeds only rows the server marked `continuable`, a run without a\n * snapshot having nothing to resume from. Pure DOM, like {@link SkillsMenu}:\n * append {@link element}, toggle it, feed {@link setRuns}, act on\n * {@link onPick}.\n */\nexport class CheckpointMenu {\n /** The panel root. Append to the chat shell; hidden until opened. */\n readonly element: HTMLDivElement;\n\n readonly #onPick: (runId: string, verb: CheckpointVerb) => void;\n readonly #list: HTMLDivElement;\n readonly #heading: HTMLSpanElement;\n /** What had focus before the panel opened, restored on close. */\n #lastFocused: HTMLElement | null = null;\n #strings: UiStrings;\n #runs: readonly RunRow[] = [];\n\n constructor(\n onPick: (runId: string, verb: CheckpointVerb) => void,\n strings: UiStrings = DEFAULT_UI_STRINGS,\n ) {\n this.#onPick = onPick;\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"checkpoints\";\n this.element.setAttribute(\"part\", \"checkpoints\");\n this.element.setAttribute(\"role\", \"dialog\");\n this.element.setAttribute(\"aria-label\", strings.checkpoints);\n // Focusable as a fallback: with no continuable runs the panel holds no\n // controls at all, and a dialog that cannot take focus strands the\n // keyboard user outside it with no way back except Tab-ing blind.\n this.element.tabIndex = -1;\n this.element.hidden = true;\n\n const header = document.createElement(\"div\");\n header.className = \"checkpoints-header\";\n header.setAttribute(\"part\", \"checkpoints-header\");\n this.#heading = document.createElement(\"span\");\n this.#heading.className = \"checkpoints-title\";\n this.#heading.setAttribute(\"part\", \"checkpoints-title\");\n this.#heading.textContent = strings.checkpoints;\n header.append(this.#heading);\n\n this.#list = document.createElement(\"div\");\n this.#list.className = \"checkpoints-list\";\n this.#list.setAttribute(\"part\", \"checkpoints-list\");\n\n this.element.append(header, this.#list);\n this.element.addEventListener(\"keydown\", (event) => this.#onKeydown(event));\n }\n\n /** Replace the rows. The host passes only `continuable` runs. */\n setRuns(runs: readonly RunRow[]): void {\n this.#runs = runs;\n this.#render();\n }\n\n /** Re-localize a panel built before the host's strings resolved. */\n setStrings(strings: UiStrings): void {\n this.#strings = strings;\n this.element.setAttribute(\"aria-label\", strings.checkpoints);\n this.#heading.textContent = strings.checkpoints;\n this.#render();\n }\n\n open(): void {\n if (this.open_) {\n return;\n }\n // Remember what had focus so it is restored on close, then move focus into\n // the panel so a keyboard user lands inside the dialog rather than being\n // left behind it. The thread drawer already does this; a dialog that takes\n // no focus is one a keyboard user cannot reach and a screen reader does not\n // announce, however correct its role and label.\n this.#lastFocused = this.#activeElement() as HTMLElement | null;\n this.element.hidden = false;\n (this.#focusables()[0] ?? this.element).focus();\n }\n\n close(): void {\n if (!this.open_) {\n return;\n }\n this.element.hidden = true;\n this.#lastFocused?.focus();\n this.#lastFocused = null;\n }\n\n /** The focused element within this panel's root (shadow-aware). */\n #activeElement(): Element | null {\n return (this.element.getRootNode() as Document | ShadowRoot).activeElement;\n }\n\n /** The panel's tabbable controls, in document order. */\n #focusables(): HTMLElement[] {\n return Array.from(this.element.querySelectorAll<HTMLElement>(\"button, [tabindex]\")).filter(\n (el) => !el.hidden,\n );\n }\n\n /** Escape closes; Tab is trapped so focus cannot wander behind the dialog. */\n #onKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n event.stopPropagation();\n this.close();\n return;\n }\n if (event.key !== \"Tab\") {\n return;\n }\n const focusables = this.#focusables();\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = this.#activeElement();\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first?.focus();\n }\n }\n\n get open_(): boolean {\n return !this.element.hidden;\n }\n\n #render(): void {\n this.#list.replaceChildren();\n if (this.#runs.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"checkpoints-empty\";\n empty.setAttribute(\"part\", \"checkpoints-empty\");\n empty.textContent = this.#strings.noCheckpoints;\n this.#list.append(empty);\n return;\n }\n const repeated = this.#repeatedPreviews();\n for (const run of this.#runs) {\n this.#list.append(this.#row(run, repeated));\n }\n }\n\n /**\n * The previews more than one row shows.\n *\n * A preview identifies a run only while it is that run's alone. A real index\n * answered with five runs opening on the same sentence, and those rows read\n * alike exactly as bare timestamps used to \u2014 so where the words repeat the\n * short id comes back, and where they do not the row is left as it is.\n */\n #repeatedPreviews(): ReadonlySet<string> {\n const seen = new Set<string>();\n const repeated = new Set<string>();\n for (const run of this.#runs) {\n const preview = previewOf(run);\n if (preview === null) {\n continue;\n }\n const shown = asShown(preview);\n if (seen.has(shown)) {\n repeated.add(shown);\n }\n seen.add(shown);\n }\n return repeated;\n }\n\n #row(run: RunRow, repeated: ReadonlySet<string>): HTMLDivElement {\n const row = document.createElement(\"div\");\n row.className = \"checkpoint-row\";\n row.setAttribute(\"part\", \"checkpoint-row\");\n\n const preview = previewOf(run);\n const time =\n run.started_at === null\n ? null\n : relativeTime(Date.parse(run.started_at), Date.now(), this.#strings);\n\n const label = document.createElement(\"span\");\n label.className = \"checkpoint-label\";\n label.setAttribute(\"part\", \"checkpoint-label\");\n // What the run was about, if the server says. Otherwise the time, and only\n // then the id \u2014 a person recognises the first, reads the second, and\n // recognises nothing at all in the third.\n label.textContent = preview ?? time ?? run.run_id;\n row.append(label);\n\n if (preview !== null && time !== null) {\n // Demoted to a chip: with words in the label the time is no longer what\n // identifies the run, but it still orders it.\n const when = document.createElement(\"span\");\n when.className = \"checkpoint-time\";\n when.setAttribute(\"part\", \"checkpoint-time\");\n when.textContent = time;\n row.append(when);\n }\n\n // The id, for a row whose label does not identify the run on its own: two\n // runs a few seconds apart both read \"just now\", and words another row also\n // opens with name neither of them. Picking between either pair is picking\n // blind. Shown rather than left in a tooltip, since a hover is not an\n // identity either \u2014 and eight characters beats a full id on the row. A\n // label that already is the id needs no second copy, and a run that arrived\n // without one has nothing better to offer than the words it shares.\n const ambiguous = preview === null ? time !== null : repeated.has(asShown(preview));\n if (ambiguous && run.run_id !== \"\") {\n const short = document.createElement(\"span\");\n short.className = \"checkpoint-id\";\n short.setAttribute(\"part\", \"checkpoint-id\");\n short.textContent = run.run_id.slice(0, 8);\n short.title = run.run_id;\n row.append(short);\n }\n\n if (run.parent_run_id !== null) {\n // Lineage, so a branch doesn't read as a duplicate of its parent.\n const branch = document.createElement(\"span\");\n branch.className = \"checkpoint-branch\";\n branch.setAttribute(\"part\", \"checkpoint-branch\");\n branch.textContent = this.#strings.forkedRun;\n branch.title = run.parent_run_id;\n row.append(branch);\n }\n\n row.append(\n this.#action(run.run_id, \"resume\", this.#strings.resumeRun),\n this.#action(run.run_id, \"fork\", this.#strings.forkRun),\n );\n return row;\n }\n\n #action(runId: string, verb: CheckpointVerb, label: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `checkpoint-action checkpoint-${verb}`;\n button.setAttribute(\"part\", `checkpoint-action checkpoint-${verb}`);\n button.textContent = label;\n button.addEventListener(\"click\", () => {\n this.close();\n this.#onPick(runId, verb);\n });\n return button;\n }\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** What the inline confirmation card displays. */\nexport interface ConfirmationRequest {\n toolName: string;\n args: Record<string, unknown>;\n /**\n * Human-readable prompt (from the tool's `x-confirm` metadata), e.g.\n * \"Activate this project?\". Falls back to the generic `confirmRun` template.\n */\n message?: string;\n}\n\n/** Build a labelled action button. */\nfunction actionButton(modifier: string, label: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `confirm-btn confirm-btn--${modifier}`;\n button.setAttribute(\"part\", `confirm-button confirm-${modifier}`);\n button.textContent = label;\n return button;\n}\n\n/** Options for {@link requestConfirmation}. */\nexport interface ConfirmationOptions {\n /**\n * Aborting this signal resolves the card as declined, with buttons disabled\n * and `data-resolved=\"declined\"` \u2014 how a Stop control dismisses a pending\n * confirmation.\n */\n signal?: AbortSignal;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n strings?: UiStrings;\n}\n\n/**\n * Append an inline confirmation card to `host` (the chat message list) and\n * resolve `true` on confirm, `false` on cancel.\n *\n * The card lives in the transcript rather than in a modal overlay, so it reads\n * after the assistant's explanation and never steals focus from the page.\n *\n * Answering it removes it: the record of the decision belongs to the tool card\n * this gates, which settles to `done` or `declined` and carries it. A spent\n * form left in place reads as still outstanding.\n */\nexport function requestConfirmation(\n host: Node & ParentNode,\n request: ConfirmationRequest,\n options: ConfirmationOptions = {},\n): Promise<boolean> {\n const strings = options.strings ?? DEFAULT_UI_STRINGS;\n return new Promise<boolean>((resolve) => {\n const card = document.createElement(\"div\");\n card.className = \"confirm\";\n card.setAttribute(\"part\", \"confirm\");\n card.setAttribute(\"data-tool-name\", request.toolName);\n card.setAttribute(\"role\", \"group\");\n card.setAttribute(\"aria-label\", strings.confirmAction);\n\n const body = document.createElement(\"div\");\n body.className = \"confirm-body\";\n body.setAttribute(\"part\", \"confirm-body\");\n body.textContent = request.message ?? strings.confirmRun.replace(\"{tool}\", request.toolName);\n\n const args = document.createElement(\"pre\");\n args.className = \"confirm-args\";\n args.setAttribute(\"part\", \"confirm-args\");\n args.textContent = JSON.stringify(request.args, null, 2);\n // A call with no arguments rendered the string \"{}\" in a box of its own.\n args.hidden = Object.keys(request.args).length === 0;\n\n const actions = document.createElement(\"div\");\n actions.className = \"confirm-actions\";\n actions.setAttribute(\"part\", \"confirm-actions\");\n\n const cancel = actionButton(\"cancel\", strings.cancel);\n const confirm = actionButton(\"confirm\", strings.confirm);\n\n let settled = false;\n const close = (accepted: boolean): void => {\n if (settled) {\n return;\n }\n settled = true;\n // The prompt leaves once it has been answered. What stays is the tool\n // card next to it, which settles to the outcome and scrolls with the rest\n // of the transcript -- a record of the action rather than a spent form\n // sitting there as a standing reminder of one.\n card.remove();\n resolve(accepted);\n };\n\n cancel.addEventListener(\"click\", () => close(false));\n confirm.addEventListener(\"click\", () => close(true));\n options.signal?.addEventListener(\"abort\", () => close(false), { once: true });\n\n actions.append(cancel, confirm);\n card.append(body, args, actions);\n host.appendChild(card);\n if (options.signal?.aborted === true) {\n // The run was cancelled before the card could ask; record the decline.\n close(false);\n return;\n }\n confirm.focus();\n });\n}\n", "/**\n * Prettify a raw tool name for display: separators become spaces and the\n * first letter is capitalised \u2014 `list_projects` \u2192 \"List projects\",\n * `invoices.retrieve` \u2192 \"Invoices retrieve\".\n *\n * Final fallback of the tool-card label chain (`x-summary` \u2192\n * `toolSummaries` \u2192 fetched catalog \u2192 this). Purely cosmetic: the original\n * name still rides on the card's dataset for debugging.\n */\nexport function prettifyToolName(name: string): string {\n const spaced = name.replace(/[._-]+/g, \" \").trim();\n if (spaced === \"\") {\n return name;\n }\n return spaced.charAt(0).toUpperCase() + spaced.slice(1);\n}\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** What the inline question card asks (the `ask_user` frontend tool's args). */\nexport interface QuestionRequest {\n /** The question shown to the user. */\n question: string;\n /**\n * Preset choices rendered as radios. When empty/omitted the card is a plain\n * free-text prompt.\n */\n options?: readonly string[];\n /**\n * Whether the user may type a custom answer. With `options`, adds an \"other\"\n * radio revealing a text field; without options the card is free-text anyway.\n */\n allowCustom?: boolean;\n}\n\n/** Options for {@link requestQuestion}. */\nexport interface QuestionOptions {\n /**\n * Aborting this signal resolves the card with an empty answer and disabled\n * fields \u2014 how a Stop control dismisses an open question.\n */\n signal?: AbortSignal;\n /** Localized strings; defaults to the English {@link DEFAULT_UI_STRINGS}. */\n strings?: UiStrings;\n}\n\n/**\n * A fully custom renderer for the `ask_user` question, set via\n * `AgUiChat.askUserRenderer`. Receives the parsed {@link QuestionRequest} and an\n * `AbortSignal` that fires when the run is stopped, and resolves with the user's\n * answer; an empty string means no answer. Replaces the built-in\n * {@link requestQuestion} card entirely \u2014 see {@link ApprovalRenderer} for the\n * same seam on approvals.\n */\nexport type QuestionRenderer = (\n request: QuestionRequest,\n options: { signal: AbortSignal },\n) => Promise<string>;\n\n/** A single custom-answer text field. */\nfunction answerInput(placeholder: string): HTMLInputElement {\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.className = \"question-input\";\n input.setAttribute(\"part\", \"question-input\");\n input.placeholder = placeholder;\n return input;\n}\n\n/**\n * Append an inline question card to `host` and resolve with the user's answer \u2014\n * the browser half of the built-in `ask_user` frontend tool.\n *\n * Collects a typed answer rather than the yes/no the confirmation and approval\n * cards return: a radio pick from `options`, or free text when `allowCustom` is\n * set or no `options` are given. Stays in the transcript as a resolved record,\n * controls disabled and `data-resolved` set; a Stop while it is open resolves\n * it with an empty string.\n */\nexport function requestQuestion(\n host: Node & ParentNode,\n request: QuestionRequest,\n options: QuestionOptions = {},\n): Promise<string> {\n const strings = options.strings ?? DEFAULT_UI_STRINGS;\n const choices = request.options ?? [];\n const hasChoices = choices.length > 0;\n // Free text is offered when there are no preset choices, or when custom\n // answers are explicitly allowed alongside them (via an \"other\" radio).\n const allowsText = !hasChoices || request.allowCustom === true;\n\n return new Promise<string>((resolve) => {\n const card = document.createElement(\"div\");\n card.className = \"question\";\n card.setAttribute(\"part\", \"question\");\n card.setAttribute(\"role\", \"group\");\n card.setAttribute(\"aria-label\", strings.askUserAction);\n\n const body = document.createElement(\"div\");\n body.className = \"question-body\";\n body.setAttribute(\"part\", \"question-body\");\n body.textContent = request.question;\n\n const form = document.createElement(\"div\");\n form.className = \"question-options\";\n form.setAttribute(\"part\", \"question-options\");\n\n // `name` scopes the radio group to this card so multiple open cards don't\n // interfere; a per-card token keeps it unique without module state.\n const group = `q-${choices.length}-${request.question.length}`;\n const radios: HTMLInputElement[] = [];\n for (const choice of choices) {\n const label = document.createElement(\"label\");\n label.className = \"question-choice\";\n label.setAttribute(\"part\", \"question-choice\");\n const radio = document.createElement(\"input\");\n radio.type = \"radio\";\n radio.name = group;\n radio.value = choice;\n radio.setAttribute(\"part\", \"question-radio\");\n const text = document.createElement(\"span\");\n text.setAttribute(\"part\", \"question-choice-text\");\n text.textContent = choice;\n label.append(radio, text);\n form.appendChild(label);\n radios.push(radio);\n }\n\n // The \"other\" radio (only alongside choices) toggles the free-text field.\n let otherRadio: HTMLInputElement | null = null;\n let input: HTMLInputElement | null = null;\n if (allowsText) {\n input = answerInput(strings.answerPlaceholder);\n if (hasChoices) {\n const label = document.createElement(\"label\");\n label.className = \"question-choice\";\n label.setAttribute(\"part\", \"question-choice\");\n otherRadio = document.createElement(\"input\");\n otherRadio.type = \"radio\";\n otherRadio.name = group;\n otherRadio.value = \"\";\n otherRadio.setAttribute(\"part\", \"question-radio\");\n const text = document.createElement(\"span\");\n text.setAttribute(\"part\", \"question-choice-text\");\n text.textContent = strings.otherOption;\n label.append(otherRadio, text);\n form.appendChild(label);\n input.disabled = true;\n }\n form.appendChild(input);\n }\n\n const actions = document.createElement(\"div\");\n actions.className = \"question-actions\";\n actions.setAttribute(\"part\", \"question-actions\");\n const submit = document.createElement(\"button\");\n submit.type = \"button\";\n submit.className = \"question-btn\";\n submit.setAttribute(\"part\", \"question-button\");\n submit.textContent = strings.submit;\n actions.appendChild(submit);\n\n let settled = false;\n const answerFor = (): string | null => {\n const picked = radios.find((r) => r.checked);\n if (picked !== undefined) {\n return picked.value;\n }\n if (input !== null && (otherRadio === null || otherRadio.checked)) {\n const typed = input.value.trim();\n return typed === \"\" ? null : typed;\n }\n return null;\n };\n const refresh = (): void => {\n if (input !== null && otherRadio !== null) {\n input.disabled = !otherRadio.checked;\n }\n submit.disabled = answerFor() === null;\n };\n const close = (answer: string): void => {\n if (settled) {\n return;\n }\n settled = true;\n submit.disabled = true;\n for (const radio of radios) {\n radio.disabled = true;\n }\n if (otherRadio !== null) {\n otherRadio.disabled = true;\n }\n if (input !== null) {\n input.disabled = true;\n }\n card.setAttribute(\"data-resolved\", answer === \"\" ? \"cancelled\" : \"answered\");\n resolve(answer);\n };\n\n for (const radio of [...radios, ...(otherRadio !== null ? [otherRadio] : [])]) {\n radio.addEventListener(\"change\", refresh);\n }\n input?.addEventListener(\"input\", refresh);\n input?.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n const answer = answerFor();\n if (answer !== null) {\n close(answer);\n }\n }\n });\n submit.addEventListener(\"click\", () => {\n const answer = answerFor();\n if (answer !== null) {\n close(answer);\n }\n });\n options.signal?.addEventListener(\"abort\", () => close(\"\"), { once: true });\n\n card.append(body, form, actions);\n host.appendChild(card);\n if (options.signal?.aborted === true) {\n close(\"\");\n return;\n }\n refresh();\n (hasChoices ? radios[0] : input)?.focus();\n });\n}\n", "const {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!freeze) {\n freeze = function <T>(x: T): T {\n return x;\n };\n}\n\nif (!seal) {\n seal = function <T>(x: T): T {\n return x;\n };\n}\n\nif (!apply) {\n apply = function <T>(\n func: (thisArg: any, ...args: any[]) => T,\n thisArg: any,\n ...args: any[]\n ): T {\n return func.apply(thisArg, args);\n };\n}\n\nif (!construct) {\n construct = function <T>(Func: new (...args: any[]) => T, ...args: any[]): T {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\nconst arraySplice = unapply(Array.prototype.splice);\nconst arrayIsArray = Array.isArray;\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst numberToString = unapply(Number.prototype.toString);\nconst booleanToString = unapply(Boolean.prototype.toString);\nconst bigintToString =\n typeof BigInt === 'undefined' ? null : unapply(BigInt.prototype.toString);\nconst symbolToString =\n typeof Symbol === 'undefined' ? null : unapply(Symbol.prototype.toString);\n\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst objectToString = unapply(Object.prototype.toString);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply<T>(\n func: (thisArg: any, ...args: any[]) => T\n): (thisArg: any, ...args: any[]) => T {\n return (thisArg: any, ...args: any[]): T => {\n if (thisArg instanceof RegExp) {\n thisArg.lastIndex = 0;\n }\n\n return apply(func, thisArg, args);\n };\n}\n\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct<T>(\n Func: new (...args: any[]) => T\n): (...args: any[]) => T {\n return (...args: any[]): T => construct(Func, args);\n}\n\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(\n set: Record<string, boolean>,\n array: readonly unknown[],\n transformCaseFunc: ReturnType<typeof unapply<string>> = stringToLowerCase\n): Record<string, boolean> {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n if (!arrayIsArray(array)) {\n return set;\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n (array as unknown[])[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element as string] = true;\n }\n\n return set;\n}\n\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray<T>(array: T[]): Array<T | null> {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n\n return array;\n}\n\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone<T extends Record<string, any>>(object: T): T {\n const newObject = create(null);\n\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n\n if (isPropertyExist) {\n if (arrayIsArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (\n value &&\n typeof value === 'object' &&\n value.constructor === Object\n ) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n\n return newObject;\n}\n\n/**\n * Convert non-node values into strings without depending on direct property access.\n *\n * @param value - The value to stringify.\n * @returns A string representation of the provided value.\n */\nfunction stringifyValue(value: unknown): string {\n switch (typeof value) {\n case 'string': {\n return value;\n }\n\n case 'number': {\n return numberToString(value);\n }\n\n case 'boolean': {\n return booleanToString(value);\n }\n\n case 'bigint': {\n return bigintToString ? bigintToString(value) : '0';\n }\n\n case 'symbol': {\n return symbolToString ? symbolToString(value) : 'Symbol()';\n }\n\n case 'undefined': {\n return objectToString(value);\n }\n\n case 'function':\n case 'object': {\n if (value === null) {\n return objectToString(value);\n }\n\n const valueAsRecord = value as Record<string, any>;\n const valueToString = lookupGetter(valueAsRecord, 'toString');\n\n if (typeof valueToString === 'function') {\n const stringified = valueToString(valueAsRecord);\n\n return typeof stringified === 'string'\n ? stringified\n : objectToString(stringified);\n }\n\n return objectToString(value);\n }\n\n default: {\n return objectToString(value);\n }\n }\n}\n\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter<T extends Record<string, any>>(\n object: T,\n prop: string\n): ReturnType<typeof unapply<any>> | (() => null) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(): null {\n return null;\n }\n\n return fallbackValue;\n}\n\nfunction isRegex(value: unknown): value is RegExp {\n try {\n regExpTest(value as RegExp, '');\n return true;\n } catch {\n return false;\n }\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayIsArray,\n arrayLastIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n arraySplice,\n // Object\n entries,\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n isFrozen,\n setPrototypeOf,\n seal,\n clone,\n create,\n objectHasOwnProperty,\n objectToString,\n // RegExp\n regExpTest,\n isRegex,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringTrim,\n // Other conversion\n stringifyValue,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n addToSet,\n // Reflect\n unapply,\n unconstruct,\n};\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'search',\n 'section',\n 'select',\n 'shadow',\n 'slot',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n] as const);\n\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'enterkeyhint',\n 'exportparts',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'inputmode',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'part',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n] as const);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n] as const);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n] as const);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n 'mprescripts',\n] as const);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n] as const);\n\nexport const text = freeze(['#text'] as const);\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'command',\n 'commandfor',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'exportparts',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inert',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'part',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'popover',\n 'popovertarget',\n 'popovertargetaction',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'slot',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'wrap',\n 'xmlns',\n] as const);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'amplitude',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dominant-baseline',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'exponent',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'intercept',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'mask-type',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'slope',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'tablevalues',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-orientation',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n] as const);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnalign',\n 'columnlines',\n 'columnspacing',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lquote',\n 'lspace',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n] as const);\n", "import { seal } from './utils.js';\n\nexport const MUSTACHE_EXPR = seal(/{{[\\w\\W]*|^[\\w\\W]*}}/g);\nexport const ERB_EXPR = seal(/<%[\\w\\W]*|^[\\w\\W]*%>/g);\nexport const TMPLIT_EXPR = seal(/\\${[\\w\\W]*/g);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nexport const DOCTYPE_NAME = seal(/^html$/i);\nexport const CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\n// Markup-significant character probes used by _sanitizeElements.\n// Shared module-level instances are safe despite the sticky /g flags:\n// unapply() resets lastIndex for RegExp receivers before every call.\nexport const ELEMENT_MARKUP_PROBE = seal(/<[/\\w!]/g);\nexport const COMMENT_MARKUP_PROBE = seal(/<[/\\w]/g);\nexport const FALLBACK_TAG_CLOSE = seal(/<\\/no(script|embed|frames)/i);\nexport const SELF_CLOSING_TAG = seal(/\\/>/i);\n", "import type { Config, UseProfilesConfig } from './config';\nimport type { DOMPurify, HooksMap, HookFunction, WindowLike } from './types';\nimport * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n entries,\n freeze,\n seal,\n arrayForEach,\n arrayIsArray,\n arrayLastIndexOf,\n arrayPop,\n arrayPush,\n arraySplice,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringIndexOf,\n stringTrim,\n regExpTest,\n isRegex,\n typeErrorCreate,\n lookupGetter,\n create,\n objectHasOwnProperty,\n stringifyValue,\n} from './utils.js';\n\nexport type { Config } from './config';\n\nexport type {\n DOMPurify,\n RemovedElement,\n RemovedAttribute,\n HookName,\n NodeHook,\n ElementHook,\n DocumentFragmentHook,\n UponSanitizeElementHook,\n UponSanitizeAttributeHook,\n UponSanitizeElementHookEvent,\n UponSanitizeAttributeHookEvent,\n WindowLike,\n} from './types';\n\ndeclare const VERSION: string;\n\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5, // Deprecated\n entityNode: 6, // Deprecated\n processingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12, // Deprecated\n};\n\nconst getGlobal = function (): WindowLike {\n return typeof window === 'undefined' ? null : window;\n};\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function (\n trustedTypes: TrustedTypePolicyFactory,\n purifyHostElement: HTMLScriptElement\n) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nconst _createHooksMap = function (): HooksMap {\n return {\n afterSanitizeAttributes: [],\n afterSanitizeElements: [],\n afterSanitizeShadowDOM: [],\n beforeSanitizeAttributes: [],\n beforeSanitizeElements: [],\n beforeSanitizeShadowDOM: [],\n uponSanitizeAttribute: [],\n uponSanitizeElement: [],\n uponSanitizeShadowNode: [],\n };\n};\n\n/**\n * Resolve a set-valued configuration option: a fresh set built from\n * cfg[key] when it is an own array property (seeded with a clone of\n * options.base when given, case-normalized via options.transform),\n * the fallback set otherwise.\n *\n * @param cfg the cloned, prototype-free configuration object\n * @param key the configuration property to read\n * @param fallback the set to use when the option is absent or not an array\n * @param options transform and optional base set to merge into\n * @returns the resolved set\n */\nconst _resolveSetOption = function (\n cfg: Config,\n key: keyof Config,\n fallback: Record<string, boolean>,\n options: {\n transform: Parameters<typeof addToSet>[2];\n base?: Record<string, boolean>;\n }\n): Record<string, boolean> {\n return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key])\n ? addToSet(\n options.base ? clone(options.base) : {},\n cfg[key] as readonly unknown[],\n options.transform\n )\n : fallback;\n};\n\nfunction createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {\n const DOMPurify: DOMPurify = (root: WindowLike) => createDOMPurify(root);\n\n DOMPurify.version = VERSION;\n\n DOMPurify.removed = [];\n\n if (\n !window ||\n !window.document ||\n window.document.nodeType !== NODE_TYPE.document ||\n !window.Element\n ) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n let { document } = window;\n\n const originalDocument = document;\n const currentScript: HTMLScriptElement =\n originalDocument.currentScript as HTMLScriptElement;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || (window as any).MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes,\n } = window;\n\n const ElementPrototype = Element.prototype;\n\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n const getShadowRoot = lookupGetter(ElementPrototype, 'shadowRoot');\n const getAttributes = lookupGetter(ElementPrototype, 'attributes');\n const getNodeType =\n Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeType') : null;\n const getNodeName =\n Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeName') : null;\n const getOwnerDocument =\n Node && Node.prototype\n ? lookupGetter(Node.prototype, 'ownerDocument')\n : null;\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n let trustedTypesPolicy;\n let emptyHTML = '';\n\n // The instance's own internal Trusted Types policy. Unlike a caller-supplied\n // `TRUSTED_TYPES_POLICY`, this is created at most once \u2014 Trusted Types throws\n // on duplicate policy names \u2014 and is the only policy allowed to persist\n // across configurations and survive `clearConfig()`.\n let defaultTrustedTypesPolicy;\n let defaultTrustedTypesPolicyResolved = false;\n\n // Tracks whether we are already inside a call to the configured Trusted Types\n // policy (`createHTML` or `createScriptURL`). If a supplied policy callback\n // itself calls `DOMPurify.sanitize` (the cause of #1422), `sanitize` would\n // re-enter the policy and recurse until the stack overflows. We detect that\n // re-entry and throw a clear, actionable error instead. The guard is shared\n // across both callbacks, because either one re-entering `sanitize` triggers\n // the same unbounded recursion.\n let IN_TRUSTED_TYPES_POLICY = 0;\n const _assertNotInTrustedTypesPolicy = function (): void {\n if (IN_TRUSTED_TYPES_POLICY > 0) {\n throw typeErrorCreate(\n 'A configured TRUSTED_TYPES_POLICY callback (createHTML or ' +\n 'createScriptURL) must not call DOMPurify.sanitize, as that causes ' +\n 'infinite recursion. Do not pass a policy whose callbacks wrap ' +\n 'DOMPurify as TRUSTED_TYPES_POLICY; see the \"DOMPurify and Trusted ' +\n 'Types\" section of the README.'\n );\n }\n };\n\n const _createTrustedHTML = function (html: string): string {\n _assertNotInTrustedTypesPolicy();\n\n IN_TRUSTED_TYPES_POLICY++;\n try {\n return trustedTypesPolicy.createHTML(html);\n } finally {\n IN_TRUSTED_TYPES_POLICY--;\n }\n };\n\n const _createTrustedScriptURL = function (scriptUrl: string): string {\n _assertNotInTrustedTypesPolicy();\n\n IN_TRUSTED_TYPES_POLICY++;\n try {\n return trustedTypesPolicy.createScriptURL(scriptUrl);\n } finally {\n IN_TRUSTED_TYPES_POLICY--;\n }\n };\n\n // Lazily resolve (and cache) the instance's internal default policy.\n // Resolution is attempted at most once: a successful `createPolicy` cannot be\n // repeated (Trusted Types throws on duplicate names), and a failed or\n // unsupported attempt must not be retried on every parse.\n const _getDefaultTrustedTypesPolicy = function () {\n if (!defaultTrustedTypesPolicyResolved) {\n defaultTrustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n currentScript\n );\n defaultTrustedTypesPolicyResolved = true;\n }\n\n return defaultTrustedTypesPolicy;\n };\n\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName,\n } = document;\n const { importNode } = originalDocument;\n\n let hooks = _createHooksMap();\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n typeof entries === 'function' &&\n typeof getParentNode === 'function' &&\n implementation &&\n implementation.createHTMLDocument !== undefined;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /*\n * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(\n create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false,\n },\n })\n );\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */\n const EXTRA_ELEMENT_HANDLING = Object.seal(\n create(null, {\n tagCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n })\n );\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Pristine allowlist bindings captured at setConfig() time. On the\n * persistent-config path sanitize() restores the sets from these before\n * the per-walk hook clone-guard, so a hook's in-call widening cannot\n * carry across calls. Null until setConfig() is called; reset by\n * clearConfig(). */\n let SET_CONFIG_ALLOWED_TAGS = null;\n let SET_CONFIG_ALLOWED_ATTR = null;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (\u00A77.3.3)\n * - DOM Tree Accessors (\u00A73.1.5)\n * - Form Element Parent-Child Relations (\u00A74.10.3)\n * - Iframe srcdoc / Nested WindowProxies (\u00A74.8.5)\n * - HTMLCollection (\u00A74.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES: UseProfilesConfig | false = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'noscript',\n 'plaintext',\n 'script',\n // <selectedcontent> mirrors the selected <option>'s subtree, cloned by\n // the UA (customizable <select>) \u2014 including any on* handlers \u2014 and the\n // engine re-mirrors synchronously whenever a removal changes which\n // option/selectedcontent is current, even inside DOMPurify's inert\n // DOMParser document. Hoisting its children on removal re-inserts a fresh\n // mirror target ahead of the walk, which the engine refills, looping\n // forever (DoS) and amplifying output. Dropping its content on removal\n // (rather than hoisting) breaks that cascade; the content is a duplicate\n // of the option, which is sanitized on its own. See campaign-3 F1/F6.\n 'selectedcontent',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'role',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet(\n {},\n [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE],\n stringToString\n );\n\n const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze([\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n ]);\n let MATHML_TEXT_INTEGRATION_POINTS = addToSet(\n {},\n DEFAULT_MATHML_TEXT_INTEGRATION_POINTS\n );\n\n const DEFAULT_HTML_INTEGRATION_POINTS = freeze(['annotation-xml']);\n let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [\n 'title',\n 'style',\n 'font',\n 'a',\n 'script',\n ]);\n\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE: null | DOMParserSupportedType = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc: null | Parameters<typeof addToSet>[2] = null;\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG: Config | null = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function (\n testValue: unknown\n ): testValue is Function | RegExp {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n\n /**\n * _parseConfig\n *\n * @param cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg: Config = {}): void {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1\n ? DEFAULT_PARSER_MEDIA_TYPE\n : cfg.PARSER_MEDIA_TYPE;\n\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc =\n PARSER_MEDIA_TYPE === 'application/xhtml+xml'\n ? stringToString\n : stringToLowerCase;\n\n /* Set configuration parameters */\n ALLOWED_TAGS = _resolveSetOption(\n cfg,\n 'ALLOWED_TAGS',\n DEFAULT_ALLOWED_TAGS,\n { transform: transformCaseFunc }\n );\n ALLOWED_ATTR = _resolveSetOption(\n cfg,\n 'ALLOWED_ATTR',\n DEFAULT_ALLOWED_ATTR,\n { transform: transformCaseFunc }\n );\n ALLOWED_NAMESPACES = _resolveSetOption(\n cfg,\n 'ALLOWED_NAMESPACES',\n DEFAULT_ALLOWED_NAMESPACES,\n { transform: stringToString }\n );\n URI_SAFE_ATTRIBUTES = _resolveSetOption(\n cfg,\n 'ADD_URI_SAFE_ATTR',\n DEFAULT_URI_SAFE_ATTRIBUTES,\n { transform: transformCaseFunc, base: DEFAULT_URI_SAFE_ATTRIBUTES }\n );\n DATA_URI_TAGS = _resolveSetOption(\n cfg,\n 'ADD_DATA_URI_TAGS',\n DEFAULT_DATA_URI_TAGS,\n { transform: transformCaseFunc, base: DEFAULT_DATA_URI_TAGS }\n );\n FORBID_CONTENTS = _resolveSetOption(\n cfg,\n 'FORBID_CONTENTS',\n DEFAULT_FORBID_CONTENTS,\n { transform: transformCaseFunc }\n );\n FORBID_TAGS = _resolveSetOption(cfg, 'FORBID_TAGS', clone({}), {\n transform: transformCaseFunc,\n });\n FORBID_ATTR = _resolveSetOption(cfg, 'FORBID_ATTR', clone({}), {\n transform: transformCaseFunc,\n });\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES')\n ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === 'object'\n ? clone(cfg.USE_PROFILES)\n : cfg.USE_PROFILES\n : false;\n\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = isRegex(cfg.ALLOWED_URI_REGEXP)\n ? cfg.ALLOWED_URI_REGEXP\n : EXPRESSIONS.IS_ALLOWED_URI; // Default regexp\n\n NAMESPACE =\n typeof cfg.NAMESPACE === 'string' ? cfg.NAMESPACE : HTML_NAMESPACE; // Default HTML namespace\n\n MATHML_TEXT_INTEGRATION_POINTS =\n objectHasOwnProperty(cfg, 'MATHML_TEXT_INTEGRATION_POINTS') &&\n cfg.MATHML_TEXT_INTEGRATION_POINTS &&\n typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === 'object'\n ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS)\n : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS); // Default built-in map\n\n HTML_INTEGRATION_POINTS =\n objectHasOwnProperty(cfg, 'HTML_INTEGRATION_POINTS') &&\n cfg.HTML_INTEGRATION_POINTS &&\n typeof cfg.HTML_INTEGRATION_POINTS === 'object'\n ? clone(cfg.HTML_INTEGRATION_POINTS)\n : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS); // Default built-in map\n\n const customElementHandling =\n objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') &&\n cfg.CUSTOM_ELEMENT_HANDLING &&\n typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object'\n ? clone(cfg.CUSTOM_ELEMENT_HANDLING)\n : create(null);\n\n CUSTOM_ELEMENT_HANDLING = create(null);\n\n if (\n objectHasOwnProperty(customElementHandling, 'tagNameCheck') &&\n isRegexOrFunction(customElementHandling.tagNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck; // Default undefined\n }\n\n if (\n objectHasOwnProperty(customElementHandling, 'attributeNameCheck') &&\n isRegexOrFunction(customElementHandling.attributeNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck =\n customElementHandling.attributeNameCheck; // Default undefined\n }\n\n if (\n objectHasOwnProperty(\n customElementHandling,\n 'allowCustomizedBuiltInElements'\n ) &&\n typeof customElementHandling.allowCustomizedBuiltInElements === 'boolean'\n ) {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements =\n customElementHandling.allowCustomizedBuiltInElements; // Default undefined\n }\n\n seal(CUSTOM_ELEMENT_HANDLING);\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, TAGS.text);\n ALLOWED_ATTR = create(null);\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Always reset function-based ADD_TAGS / ADD_ATTR checks to prevent\n * leaking across calls when switching from function to array config */\n EXTRA_ELEMENT_HANDLING.tagCheck = null;\n EXTRA_ELEMENT_HANDLING.attributeCheck = null;\n\n /* Merge configuration parameters */\n if (objectHasOwnProperty(cfg, 'ADD_TAGS')) {\n if (typeof cfg.ADD_TAGS === 'function') {\n EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;\n } else if (arrayIsArray(cfg.ADD_TAGS)) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n }\n\n if (objectHasOwnProperty(cfg, 'ADD_ATTR')) {\n if (typeof cfg.ADD_ATTR === 'function') {\n EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;\n } else if (arrayIsArray(cfg.ADD_ATTR)) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n }\n\n if (\n objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') &&\n arrayIsArray(cfg.ADD_URI_SAFE_ATTR)\n ) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n\n if (\n objectHasOwnProperty(cfg, 'FORBID_CONTENTS') &&\n arrayIsArray(cfg.FORBID_CONTENTS)\n ) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n\n if (\n objectHasOwnProperty(cfg, 'ADD_FORBID_CONTENTS') &&\n arrayIsArray(cfg.ADD_FORBID_CONTENTS)\n ) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n // Re-derive the active Trusted Types policy from this configuration on\n // every parse. The active policy must never be sticky closure state that\n // outlives the config that set it: a caller-supplied policy left in place\n // after `clearConfig()` \u2014 or after a later call that supplied none, or\n // `TRUSTED_TYPES_POLICY: null` \u2014 could sign a subsequent \"default\"\n // `RETURN_TRUSTED_TYPE` result with a foreign, possibly unsafe policy.\n // See GHSA-vxr8-fq34-vvx9.\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.'\n );\n }\n\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.'\n );\n }\n\n // A caller-supplied policy applies to this configuration only.\n const previousTrustedTypesPolicy = trustedTypesPolicy;\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n\n // Sign local variables required by `sanitize`. If the supplied policy's\n // `createHTML` is circular (i.e. it calls `DOMPurify.sanitize`), this\n // throws via the re-entrancy guard. Restore the previous policy first so\n // the instance is not left in a poisoned state. See #1422.\n try {\n emptyHTML = _createTrustedHTML('');\n } catch (error) {\n trustedTypesPolicy = previousTrustedTypesPolicy;\n throw error;\n }\n } else if (cfg.TRUSTED_TYPES_POLICY === null) {\n // Explicit opt-out for this call: perform no Trusted Types signing and\n // create nothing (so a strict `trusted-types` CSP that disallows a\n // `dompurify` policy can still call `sanitize` from inside its own\n // policy \u2014 see #1422). Resetting to `undefined` rather than a sticky\n // `null` also drops any previously retained caller policy, so it cannot\n // resurface on a later call, while still allowing the next config-less\n // call to restore the internal default policy. See GHSA-vxr8-fq34-vvx9.\n trustedTypesPolicy = undefined;\n emptyHTML = '';\n } else {\n // No policy supplied: keep the currently active policy if one is set \u2014 a\n // previously supplied policy is intentionally sticky across config-less\n // calls \u2014 otherwise fall back to the instance's own internal policy,\n // created at most once. (A policy supplied for a *single* call still\n // lingers by design; what must not linger is a policy whose configuration\n // has been torn down via `clearConfig()`, which restores the default.)\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _getDefaultTrustedTypesPolicy();\n }\n\n // Sign internal variables only when a policy is active. A falsy policy\n // (Trusted Types unsupported, creation failed, or an explicit opt-out)\n // leaves `emptyHTML` as a plain string, so we never call `.createHTML` on\n // a non-policy and throw. See #1422.\n if (trustedTypesPolicy && typeof emptyHTML === 'string') {\n emptyHTML = _createTrustedHTML('');\n }\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.svgDisallowed,\n ]);\n const ALL_MATHML_TAGS = addToSet({}, [\n ...TAGS.mathMl,\n ...TAGS.mathMlDisallowed,\n ]);\n\n /**\n * Namespace rules for an element in the SVG namespace.\n *\n * @param tagName the element's lowercase tag name\n * @param parent the (possibly simulated) parent node\n * @param parentTagName the parent's lowercase tag name\n * @returns true if a spec-compliant parser could produce this element\n */\n const _checkSvgNamespace = function (\n tagName: string,\n parent: { namespaceURI?: string },\n parentTagName: string\n ): boolean {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via <svg>\n // if the parent is either <annotation-xml> or a MathML\n // text integration point.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return (\n tagName === 'svg' &&\n (parentTagName === 'annotation-xml' ||\n MATHML_TEXT_INTEGRATION_POINTS[parentTagName])\n );\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n };\n\n /**\n * Namespace rules for an element in the MathML namespace.\n *\n * @param tagName the element's lowercase tag name\n * @param parent the (possibly simulated) parent node\n * @param parentTagName the parent's lowercase tag name\n * @returns true if a spec-compliant parser could produce this element\n */\n const _checkMathMlNamespace = function (\n tagName: string,\n parent: { namespaceURI?: string },\n parentTagName: string\n ): boolean {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n };\n\n /**\n * Namespace rules for an element in the HTML namespace.\n *\n * @param tagName the element's lowercase tag name\n * @param parent the (possibly simulated) parent node\n * @param parentTagName the parent's lowercase tag name\n * @returns true if a spec-compliant parser could produce this element\n */\n const _checkHtmlNamespace = function (\n tagName: string,\n parent: { namespaceURI?: string },\n parentTagName: string\n ): boolean {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (\n parent.namespaceURI === SVG_NAMESPACE &&\n !HTML_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n if (\n parent.namespaceURI === MATHML_NAMESPACE &&\n !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return (\n !ALL_MATHML_TAGS[tagName] &&\n (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName])\n );\n };\n\n /**\n * @param element a DOM element whose namespace is being checked\n * @returns Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function (element: Element): boolean {\n let parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template',\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n return _checkSvgNamespace(tagName, parent, parentTagName);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n return _checkMathMlNamespace(tagName, parent, parentTagName);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n return _checkHtmlNamespace(tagName, parent, parentTagName);\n }\n\n // For XHTML and XML documents that support custom namespaces\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n ALLOWED_NAMESPACES[element.namespaceURI]\n ) {\n return true;\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param node a DOM node\n */\n const _forceRemove = function (node: Node): void {\n arrayPush(DOMPurify.removed, { element: node });\n\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n /* The normal detach failed \u2014 this is reached for a parentless node\n (getParentNode() is null, so .removeChild throws). Element.prototype\n .remove() is itself a spec no-op on a parentless node, so a recorded\n \"removal\" would otherwise hand the caller back an intact,\n payload-bearing node (e.g. a detached IN_PLACE root the mXSS canary or\n the style-with-element-child rule decided to kill). Fail closed by\n throwing \u2014 exactly as a clobbered root does at the IN_PLACE entry \u2014\n rather than trying to \"neutralize\" the node via its own methods.\n Neutralizing would mean calling getAttributeNames()/removeAttribute()\n on the node, both of which a <form> root can clobber via a named child\n (and _isClobbered does not even probe getAttributeNames), so the\n neutralize step could itself be silently defeated, leaving the payload\n intact. A throw touches only the cached, clobber-safe remove() and\n getParentNode(). Generalizes GHSA-r47g-fvhr-h676 (clobbered-form root)\n to every root-kill reason. REPORT-3.\n\n This lives inside the catch, so it never fires for a normally-removed\n in-tree node: those have a parent, removeChild() succeeds, and the\n catch is not entered. Only a kept (parentless) root reaches here. */\n remove(node);\n\n if (!getParentNode(node)) {\n throw typeErrorCreate(\n 'a node selected for removal could not be detached from its tree ' +\n 'and cannot be safely returned; refusing to sanitize in place'\n );\n }\n }\n };\n\n /**\n * _neutralizeRoot\n *\n * Fail-closed teardown of an in-place root after the sanitize walk aborts\n * (campaign-3 F2). An internal throw mid-walk \u2014 e.g. a page-registered\n * custom element's reaction detaches a node so `_forceRemove`'s deliberate\n * parentless guard throws, or any other re-entrant engine mutation \u2014 would\n * otherwise leave the caller's *live* tree half-sanitized, with everything\n * after the abort point still carrying its handlers. There is no safe way\n * to resume the walk (the tree mutated under us), so we strip the root bare:\n * remove every child and every attribute, then let the caller's catch see\n * the original error. Clobber-safe (cached `remove`/`childNodes`/`attributes`\n * getters; the root was already clobber-pre-flighted at the IN_PLACE entry).\n *\n * @param root the in-place root to empty\n */\n const _neutralizeRoot = function (root: Node): void {\n /* Strip every disallowed attribute (on* handlers included) off the whole\n subtree BEFORE detaching anything. Detaching first would hand back\n handler-bearing originals (e.g. an already-loading `<img onerror>`)\n whose queued resource event still fires in page scope after we throw.\n Clobber-safe reads; a doomed clobbered node's own attributes are\n irrelevant while its non-clobbered descendants are reached and scrubbed. */\n _neutralizeSubtree(root);\n\n const childNodes = getChildNodes(root);\n if (childNodes) {\n const snapshot: Node[] = [];\n arrayForEach(childNodes, (child) => {\n arrayPush(snapshot, child);\n });\n arrayForEach(snapshot, (child) => {\n try {\n remove(child);\n } catch (_) {\n /* Best-effort teardown; a still-attached child is handled below */\n }\n });\n }\n\n const attributes = getAttributes(root);\n if (attributes) {\n for (let i = attributes.length - 1; i >= 0; --i) {\n const attribute = attributes[i];\n const name = attribute && attribute.name;\n if (typeof name === 'string') {\n try {\n (root as Element).removeAttribute(name);\n } catch (_) {\n /* Clobbered removeAttribute \u2014 ignore (fail-closed best effort) */\n }\n }\n }\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param name an Attribute name\n * @param element a DOM node\n */\n const _removeAttribute = function (name: string, element: Element): void {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: element.getAttributeNode(name),\n from: element,\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: element,\n });\n }\n\n element.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\" attributes\n if (name === 'is') {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(element);\n } catch (_) {}\n } else {\n try {\n element.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _stripDisallowedAttributes\n *\n * Removes every attribute the active configuration does not allow from a\n * single element, using the same allowlist as the main attribute pass (so\n * `on*` handlers go, but no `/^on/` blocklist is introduced). Used only to\n * neutralise nodes that are being discarded from an in-place tree.\n *\n * @param element the element to strip\n */\n const _stripDisallowedAttributes = function (element: Element): void {\n const attributes = getAttributes(element);\n if (!attributes) {\n return;\n }\n\n for (let i = attributes.length - 1; i >= 0; --i) {\n const attribute = attributes[i];\n const name = attribute && attribute.name;\n if (typeof name !== 'string' || ALLOWED_ATTR[transformCaseFunc(name)]) {\n continue;\n }\n\n try {\n element.removeAttribute(name);\n } catch (_) {\n /* Clobbered removeAttribute on a doomed node \u2014 ignore */\n }\n }\n };\n\n /**\n * _neutralizeSubtree\n *\n * Completes the audit-5 F1 fix across every removal path. The KEEP_CONTENT\n * move-hoist neutralises only disallowed-tag removals; clobber, mXSS-canary,\n * namespace, comment, processing-instruction and KEEP_CONTENT:false removals\n * all drop their subtree wholesale via `_forceRemove`. On the IN_PLACE path\n * those dropped nodes are detached from the caller's LIVE tree but a\n * handler-bearing original among them (an `<img onerror>`/`<video>` that was\n * loading) keeps its queued resource event, which fires in page scope after\n * sanitize returns. This walks a removed subtree and strips every attribute\n * the active configuration does not allow \u2014 so `on*` handlers are cancelled\n * through the SAME allowlist that governs kept nodes, not a separate `/^on/`\n * blocklist. Run synchronously before sanitize returns, i.e. before any\n * queued event can fire. Hook-free by design: these nodes leave the output,\n * so firing attribute hooks for them would be surprising. Clobber-safe reads;\n * a doomed clobbered node may shadow `removeAttribute` (its own attributes are\n * irrelevant \u2014 it is discarded \u2014 while its non-clobbered descendants, e.g.\n * the `<img>`, are reached and scrubbed).\n *\n * @param root the root of a removed subtree to neutralise\n */\n const _neutralizeSubtree = function (root: Node): void {\n const stack: Node[] = [root];\n\n while (stack.length > 0) {\n const node = stack.pop();\n const nodeType = getNodeType ? getNodeType(node) : (node as any).nodeType;\n\n if (nodeType === NODE_TYPE.element) {\n _stripDisallowedAttributes(node as Element);\n }\n\n const childNodes = getChildNodes(node);\n if (childNodes) {\n for (let i = childNodes.length - 1; i >= 0; --i) {\n stack.push(childNodes[i]);\n }\n }\n }\n };\n\n /**\n * _neutralizePatchLinkage\n *\n * IN_PLACE entry pre-pass (declarative-partial-updates / streaming\n * hardening, https://github.com/WICG/declarative-partial-updates).\n *\n * The main walk strips patch linkage (`for`/`patchsrc`) and removes range\n * markers (PIs / markup comments) node-by-node, in document order, AS it\n * reaches each node. On a live in-place root that leaves a window: from the\n * moment the root is connected until the walk arrives at a given node, that\n * node's linkage is live. A patch applied on connection/stream can fire as\n * a microtask during the walk and inject or teleport an unsanitized DOM\n * range into a region the iterator has already passed and will not revisit,\n * so the post-return \"tree is sanitized\" contract is violated. Sweep the\n * whole tree once up front and sever every linkage before the walk begins,\n * closing that window.\n *\n * This CANNOT undo a patch that already fired before sanitize ran \u2014 that is\n * the irreducible \"do not IN_PLACE a live-connected attacker tree\" caveat \u2014\n * but it closes everything from sanitize-start onward. Gated on SAFE_FOR_XML\n * to group with the rest of the declarative-partial-updates handling and\n * stay overridable, consistent with the codebase.\n *\n * Clobber-safe traversal (cached childNodes getter); per-node try/catch so a\n * clobbered root cannot defeat the sweep of its non-clobbered descendants.\n *\n * NOTE (pending real-Chrome confirmation, see test/declarative-patch-probe\n * .html Q1): this mirrors the existing policy of keeping `for` on\n * <label>/<output>. If the shipping feature can drive a patch through a\n * surviving `for`-on-label/output + `id` pair, this pre-pass and the\n * attribute check at _isBasicCustomElement's caller must additionally drop\n * that pair on the IN_PLACE path. Left as-is until the taxonomy is verified.\n *\n * @param root the in-place root to sweep\n */\n const _neutralizePatchLinkage = function (root: Node): void {\n if (!SAFE_FOR_XML) {\n return;\n }\n\n const stack: Node[] = [root];\n while (stack.length > 0) {\n const node = stack.pop();\n const nodeType = getNodeType ? getNodeType(node) : (node as any).nodeType;\n\n /* Remove range markers (the target side of a patch linkage): every\n processing instruction, and any markup-bearing comment. */\n if (\n nodeType === NODE_TYPE.processingInstruction ||\n (nodeType === NODE_TYPE.comment &&\n regExpTest(EXPRESSIONS.COMMENT_MARKUP_PROBE, (node as any).data))\n ) {\n try {\n remove(node);\n } catch (_) {\n /* Best-effort */\n }\n\n continue;\n }\n\n /* Strip patch-source attributes (the source side) off elements. */\n if (nodeType === NODE_TYPE.element) {\n const element = node as Element;\n const lcTag = transformCaseFunc(\n getNodeName ? getNodeName(node) : (node as any).nodeName\n );\n try {\n if (element.hasAttribute && element.hasAttribute('patchsrc')) {\n element.removeAttribute('patchsrc');\n }\n\n if (\n element.hasAttribute &&\n element.hasAttribute('for') &&\n lcTag !== 'label' &&\n lcTag !== 'output'\n ) {\n element.removeAttribute('for');\n }\n } catch (_) {\n /* Clobbered removeAttribute/hasAttribute on a doomed node \u2014 ignore */\n }\n }\n\n const childNodes = getChildNodes(node);\n if (childNodes) {\n for (let i = childNodes.length - 1; i >= 0; --i) {\n stack.push(childNodes[i]);\n }\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param dirty - a string of dirty markup\n * @return a DOM, filled with the dirty markup\n */\n const _initDocument = function (dirty: string): Document {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n NAMESPACE === HTML_NAMESPACE\n ) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty =\n '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' +\n dirty +\n '</body></html>';\n }\n\n const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT\n ? emptyHTML\n : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n const body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(\n document.createTextNode(leadingWhitespace),\n body.childNodes[0] || null\n );\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(\n doc,\n WHOLE_DOCUMENT ? 'html' : 'body'\n )[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param root The root element or node to start traversing on.\n * @return The created NodeIterator\n */\n const _createNodeIterator = function (root: Node): NodeIterator {\n /* Read ownerDocument through the cached Node.prototype getter, never the\n direct property. HTMLFormElement has [LegacyOverrideBuiltIns], so a\n clobbering child (<input name=\"ownerDocument\"> or a form-associated\n external input) shadows the prototype getter and makes a direct read\n return that <input>. createNodeIterator.call(<input>, ...) then throws\n \"Illegal invocation\", and on the IN_PLACE path that throw lands before\n the walk's fail-closed barrier - leaving the caller's live tree, with\n any already-armed handler in it, un-neutralized. The cached getter\n returns the real Document regardless of the clobber. */\n const doc = getOwnerDocument ? getOwnerDocument(root) : root.ownerDocument;\n return createNodeIterator.call(\n doc || root,\n root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT |\n NodeFilter.SHOW_COMMENT |\n NodeFilter.SHOW_TEXT |\n NodeFilter.SHOW_PROCESSING_INSTRUCTION |\n NodeFilter.SHOW_CDATA_SECTION,\n null\n );\n };\n\n /**\n * Replace template expression syntax (mustache, ERB, template\n * literal) with a space; shared by all SAFE_FOR_TEMPLATES scrub\n * sites. Order matters: mustache, then ERB, then template literal.\n *\n * @param value the string to scrub\n * @returns the scrubbed string\n */\n const _stripTemplateExpressions = function (value: string): string {\n value = stringReplace(value, MUSTACHE_EXPR, ' ');\n value = stringReplace(value, ERB_EXPR, ' ');\n value = stringReplace(value, TMPLIT_EXPR, ' ');\n return value;\n };\n\n /**\n * Strip template-engine expressions ({{...}}, ${...}, <%...%>) from the\n * character data of an element subtree. Used as the final safety net for\n * SAFE_FOR_TEMPLATES on every DOM-returning code path so that expressions\n * which only form after text-node normalization (e.g. fragments split across\n * stripped elements) cannot survive into a template-evaluating framework.\n *\n * Walks text/comment/CDATA/processing-instruction nodes and mutates `.data`\n * in place rather than round-tripping through innerHTML. This preserves\n * descendant node references (important for IN_PLACE callers), avoids a\n * serialize/reparse cycle, and reads literal character data \u2014 which means\n * `<%...%>` in text content matches the ERB regex against its real bytes\n * instead of the HTML-entity-escaped form innerHTML would produce.\n *\n * Attribute values are not visited here; SAFE_FOR_TEMPLATES handling for\n * attributes is performed during the per-node `_sanitizeAttributes` pass.\n *\n * @param node The root element whose character data should be scrubbed.\n */\n const _scrubTemplateExpressions = function (node: Element): void {\n node.normalize();\n /* Clobber-safe ownerDocument read, same reasoning as _createNodeIterator:\n under SAFE_FOR_TEMPLATES this runs on the live IN_PLACE root, which may\n carry a form-named-getter override of ownerDocument. */\n const doc = getOwnerDocument ? getOwnerDocument(node) : node.ownerDocument;\n const walker = createNodeIterator.call(\n doc || node,\n node,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_TEXT |\n NodeFilter.SHOW_COMMENT |\n NodeFilter.SHOW_CDATA_SECTION |\n NodeFilter.SHOW_PROCESSING_INSTRUCTION,\n null\n );\n\n let currentNode = walker.nextNode() as CharacterData | null;\n while (currentNode) {\n currentNode.data = _stripTemplateExpressions(currentNode.data);\n currentNode = walker.nextNode() as CharacterData | null;\n }\n\n // NodeIterator does not descend into <template>.content per the DOM spec,\n // so we must explicitly recurse into each template's content fragment,\n // mirroring the approach used by _sanitizeShadowDOM.\n const templates = node.querySelectorAll?.('template');\n if (templates) {\n arrayForEach(templates, (tmpl: HTMLTemplateElement) => {\n if (_isDocumentFragment(tmpl.content)) {\n _scrubTemplateExpressions(tmpl.content as unknown as Element);\n }\n });\n }\n };\n\n /**\n * _isClobbered\n *\n * Detect DOM-clobbering on HTMLFormElement nodes. Form is the only HTML\n * interface with [LegacyOverrideBuiltIns]; a descendant element with a\n * `name` attribute matching a prototype property shadows that property\n * on direct reads. We use this check at the IN_PLACE entry-point and\n * during attribute sanitization to refuse clobbered forms.\n *\n * @param element element to check for clobbering attacks\n * @return true if clobbered, false if safe\n */\n const _isClobbered = function (element: Element): boolean {\n // Realm-independent tag-name probe. If we can't determine the tag\n // name at all, we can't reason about clobbering \u2014 return false\n // (the caller's other defences still apply).\n const realTagName = getNodeName ? getNodeName(element) : null;\n if (typeof realTagName !== 'string') {\n return false;\n }\n\n if (transformCaseFunc(realTagName) !== 'form') {\n return false;\n }\n\n return (\n typeof element.nodeName !== 'string' ||\n typeof element.textContent !== 'string' ||\n typeof element.removeChild !== 'function' ||\n // Realm-safe NamedNodeMap detection: equality against the cached\n // prototype getter. Clobbered .attributes (e.g. <input name=\"attributes\">)\n // makes the direct read diverge from the cached read; a clean form\n // (same-realm OR foreign-realm) has both reads pointing at the same\n // canonical NamedNodeMap.\n element.attributes !== getAttributes(element) ||\n typeof element.removeAttribute !== 'function' ||\n typeof element.setAttribute !== 'function' ||\n typeof element.namespaceURI !== 'string' ||\n typeof element.insertBefore !== 'function' ||\n typeof element.hasChildNodes !== 'function' ||\n // NodeType clobbering probe. Cached Node.prototype.nodeType getter\n // returns the integer 1 for any Element regardless of realm; direct\n // read on a clobbered form (e.g. <input name=\"nodeType\">) returns\n // the named child element. Cheap addition \u2014 nodeType is read from\n // an internal slot, no serialization cost \u2014 and removes a residual\n // clobbering surface used by several mXSS / PI / comment branches\n // in _sanitizeElements that compare currentNode.nodeType directly.\n element.nodeType !== getNodeType(element) ||\n // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named\n // \"childNodes\" shadows the prototype getter. Direct reads of\n // form.childNodes from a clobbered form return the named child\n // instead of the real NodeList, so any walk that reads it directly\n // skips the form's real children. Compare the direct read to the\n // cached Node.prototype getter \u2014 when the form's named-property\n // getter intercepts the read, the two values differ and we flag\n // the form. This catches every clobbering child type (input,\n // select, etc.) regardless of whether the named child happens to\n // carry a numeric .length, which a typeof-based probe would miss\n // (e.g. HTMLSelectElement.length is a defined unsigned-long).\n element.childNodes !== getChildNodes(element)\n );\n };\n\n /**\n * Checks whether the given value is a DocumentFragment from any realm.\n *\n * The realm-independent replacement reads `nodeType` through the cached\n * Node.prototype getter and compares to the DOCUMENT_FRAGMENT_NODE\n * constant (11). nodeType is a numeric value resolved from the node's\n * internal slot, identical across realms for the same kind of node.\n *\n * @param value object to check\n * @return true if value is a DocumentFragment-shaped node from any realm\n */\n const _isDocumentFragment = function (value: unknown): boolean {\n if (!getNodeType || typeof value !== 'object' || value === null) {\n return false;\n }\n\n try {\n return getNodeType(value as Node) === NODE_TYPE.documentFragment;\n } catch (_) {\n return false;\n }\n };\n\n /**\n * Checks whether the given object is a DOM node, including nodes that\n * originate from a different window/realm (e.g. an iframe's\n * contentDocument). The previous `value instanceof Node` check was\n * realm-bound: nodes from a different window failed it, causing\n * sanitize() to silently stringify them and reset IN_PLACE to false,\n * returning the original node unsanitized. See GHSA-4w3q-35jp-p934.\n *\n * @param value object to check whether it's a DOM node\n * @return true if value is a DOM node from any realm\n */\n const _isNode = function (value: unknown): value is Node {\n if (!getNodeType || typeof value !== 'object' || value === null) {\n return false;\n }\n\n try {\n return typeof getNodeType(value) === 'number';\n } catch (_) {\n return false;\n }\n };\n\n function _executeHooks<T extends HookFunction>(\n hooks: HookFunction[],\n currentNode: Parameters<T>[0],\n data: Parameters<T>[1]\n ): void {\n if (hooks.length === 0) {\n return;\n }\n\n arrayForEach(hooks, (hook: T) => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n }\n\n /**\n * Structural-threat checks that condemn a node regardless of the\n * allowlists: mXSS via namespace confusion, risky CSS construction,\n * processing instructions, markup-bearing comments. Pure predicate;\n * the caller removes. Check order is load-bearing.\n *\n * @param currentNode the node to inspect\n * @param tagName the node's transformCaseFunc'd tag name\n * @return true if the node must be removed\n */\n const _isUnsafeNode = function (currentNode: any, tagName: string): boolean {\n /* Detect mXSS attempts abusing namespace confusion */\n if (\n SAFE_FOR_XML &&\n currentNode.hasChildNodes() &&\n !_isNode(currentNode.firstElementChild) &&\n regExpTest(EXPRESSIONS.ELEMENT_MARKUP_PROBE, currentNode.textContent) &&\n regExpTest(EXPRESSIONS.ELEMENT_MARKUP_PROBE, currentNode.innerHTML)\n ) {\n return true;\n }\n\n /* Remove risky CSS construction leading to mXSS */\n if (\n SAFE_FOR_XML &&\n currentNode.namespaceURI === HTML_NAMESPACE &&\n tagName === 'style' &&\n _isNode(currentNode.firstElementChild)\n ) {\n return true;\n }\n\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.processingInstruction) {\n return true;\n }\n\n /* Remove any kind of possibly harmful comments */\n if (\n SAFE_FOR_XML &&\n currentNode.nodeType === NODE_TYPE.comment &&\n regExpTest(EXPRESSIONS.COMMENT_MARKUP_PROBE, currentNode.data)\n ) {\n return true;\n }\n\n return false;\n };\n\n /**\n * Handle a node whose tag is forbidden or not allowlisted: keep\n * allowed custom elements (false return exits _sanitizeElements\n * early - the namespace and fallback-tag removal checks are\n * intentionally skipped for kept custom elements), else hoist\n * content per KEEP_CONTENT and remove.\n *\n * A kept custom element is the ONLY case in which this function\n * returns false, so the caller uses that return value to run the\n * afterSanitizeElements hook on the kept element and keep the\n * element-hook lifecycle consistent with normal allowlisted\n * elements (GHSA-c2j3-45gr-mqc4).\n *\n * @param currentNode the disallowed node\n * @param tagName the node's transformCaseFunc'd tag name\n * @return true if the node was removed, false if kept\n */\n const _sanitizeDisallowedNode = function (\n currentNode: any,\n tagName: string,\n root: Node\n ): boolean {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)\n ) {\n return false;\n }\n\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)\n ) {\n return false;\n }\n }\n\n /* Keep content except for bad-listed elements.\n Use the cached prototype getters exclusively \u2014 the previous code\n had `|| currentNode.parentNode` / `|| currentNode.childNodes`\n fallbacks, but the cached getters always return the canonical\n value (or null for a real parent-less node), so the fallback\n path was dead in safe cases and a clobbering surface in unsafe\n ones. Falsy cached results stay falsy; the `if (childNodes &&\n parentNode)` check already gates correctly. */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode);\n const childNodes = getChildNodes(currentNode);\n\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n\n /* Hoist by moving each child up one level rather than deep-cloning\n it. Moving transfers every descendant exactly once, so a chain of\n nested disallowed elements costs O(n) instead of the O(n^2) that\n re-cloning the shrinking subtree at each level produced; it also\n empties the removed original, so `DOMPurify.removed` no longer\n pins whole subtrees. Moving preserves the in-place guarantee too:\n an original carrying already-queued resource events (`<img\n onerror>`, `<video>`/`<audio>` error, lazy/`onload`, \u2026) is\n relocated and sanitised rather than left detached but still armed.\n\n The sole case that must clone is removing the walk root itself.\n The result is serialised from the root's subtree, so a restrictive\n ALLOWED_TAGS that strips the root (`body` on the string path) must\n leave the content inside it, which only cloning does. In IN_PLACE\n the root is pre-validated as an allowed tag and so is never removed\n here, so that path always takes the move branch.\n\n `childNodes` is live; a tail-to-head walk keeps `childNodes[i]`\n valid whether we move (drops the trailing entry) or clone (leaves\n the list intact). */\n for (let i = childCount - 1; i >= 0; --i) {\n const hoisted =\n currentNode === root\n ? cloneNode(childNodes[i], true)\n : childNodes[i];\n parentNode.insertBefore(hoisted, getNextSibling(currentNode));\n }\n }\n }\n\n _forceRemove(currentNode);\n return true;\n };\n\n /**\n * Fork a hook-mutable allowlist off its shared binding the first time a\n * (possibly lazily-installed) uponSanitize* hook is about to see it, so the\n * hook cannot widen the per-instance default or the setConfig binding by\n * reference and leak past the call. Returns the set unchanged once it is\n * already call-local, so repeated calls across elements are idempotent.\n *\n * @param hookList the uponSanitize* hook array for this event\n * @param set the current ALLOWED_TAGS / ALLOWED_ATTR binding\n * @param defaultSet the per-instance DEFAULT_ALLOWED_* constant\n * @param setConfigSet the captured setConfig() binding, or null\n * @return a call-local clone if a hook is present and set is still shared,\n * else set unchanged\n */\n const _forkSharedAllowlist = function <T extends Record<string, any>>(\n hookList: unknown[],\n set: T,\n defaultSet: T,\n setConfigSet: T | null\n ): T {\n if (hookList.length === 0) {\n return set;\n }\n\n return set === defaultSet || set === setConfigSet ? clone(set) : set;\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n * @param currentNode to check for permission to exist\n * @return true if node was killed, false if left alive\n */\n // eslint-disable-next-line complexity\n const _sanitizeElements = function (currentNode: any, root: Node): boolean {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n\n /* A hook may have detached the node - treat it as removed (see the\n detached-node comment after the uponSanitizeElement hook below). On\n the IN_PLACE path, neutralize the detached subtree first so a queued\n resource handler on it cannot fire in page scope after we return. */\n if (currentNode !== root && getParentNode(currentNode) === null) {\n if (IN_PLACE) {\n _neutralizeSubtree(currentNode);\n }\n\n return true;\n }\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(\n getNodeName ? getNodeName(currentNode) : currentNode.nodeName\n );\n\n /* Close the pre-walk clone-guard's timing gap: an uponSanitizeElement\n hook may have been installed after that guard sampled the hook arrays\n (e.g. lazily from beforeSanitizeElements), leaving ALLOWED_TAGS still\n aliasing a shared binding that a widening hook would mutate by\n reference. Fork it before exposing it to the hook. */\n ALLOWED_TAGS = _forkSharedAllowlist(\n hooks.uponSanitizeElement,\n ALLOWED_TAGS,\n DEFAULT_ALLOWED_TAGS,\n SET_CONFIG_ALLOWED_TAGS\n );\n\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeElement, currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS,\n });\n\n /* A hook may have detached the node from the tree \u2014 a long-standing\n user pattern (issue #469; draw.io-style foreignObject filtering).\n Per the cached, unclobberable parentNode getter the node is\n genuinely out of the tree, so it can reach neither the serialized\n output nor an IN_PLACE live tree; treat it as removed and stop\n processing it. Without this guard, the unsafe-node / namespace\n checks below would call _forceRemove on a parentless node and hit\n the REPORT-3 fail-closed throw \u2014 which exists for nodes DOMPurify\n wants gone but *cannot* detach (clobbered / parentless roots), the\n opposite of a node that is already safely gone. The walk root is\n exempt: a detached IN_PLACE root is legitimate input and must still\n be fully sanitized, and a kill-decision on it must keep hitting the\n REPORT-3 throw. Nodes detached by hooks stay the hook's\n responsibility for placement: they are not recorded in\n DOMPurify.removed, so the post-walk IN_PLACE pass (which iterates\n DOMPurify.removed) does not reach them. But a hook-detached subtree\n can still hold a queued resource-event handler - e.g. an <img onload>\n that began loading when the caller built the live tree - which fires\n in page scope after sanitize returns even though the handler never\n reached the returned tree. That is the audit-5 F1 hazard, and the\n documented node.remove() hook pattern walks straight into it. So on\n the IN_PLACE path we neutralize the detached subtree inline here,\n stripping its non-allow-listed attributes before returning, exactly\n as the post-walk pass does for _forceRemove'd subtrees. */\n if (currentNode !== root && getParentNode(currentNode) === null) {\n if (IN_PLACE) {\n _neutralizeSubtree(currentNode);\n }\n\n return true;\n }\n\n /* Remove mXSS vectors, processing instructions and risky comments */\n if (_isUnsafeNode(currentNode, tagName)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove element if anything forbids its presence */\n if (\n FORBID_TAGS[tagName] ||\n (!(\n EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function &&\n EXTRA_ELEMENT_HANDLING.tagCheck(tagName)\n ) &&\n !ALLOWED_TAGS[tagName])\n ) {\n const removed = _sanitizeDisallowedNode(currentNode, tagName, root);\n\n /* A false return means the node is a custom element kept via\n CUSTOM_ELEMENT_HANDLING - the only keep path through\n _sanitizeDisallowedNode. Run afterSanitizeElements on it so the\n element-hook lifecycle matches normal allowlisted elements: a\n security policy applied in this hook (e.g. stripping an attribute\n from every surviving element) must not silently skip kept custom\n elements (GHSA-c2j3-45gr-mqc4). This mirrors the normal-element\n tail below - the hook runs, then the walker's subsequent\n _sanitizeAttributes pass sanitizes the element's attributes. The\n deliberately skipped namespace and fallback-tag removal checks stay\n skipped; they are removal decisions, not the hook contract. */\n if (removed === false) {\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n }\n\n return removed;\n }\n\n /* Check whether element has a valid namespace.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): use the cached Node.prototype\n nodeType getter rather than `instanceof Element`, which is realm-\n bound and short-circuits to false for any node minted in a different\n realm \u2014 letting a foreign-realm element with a forbidden namespace\n slip past the namespace check entirely. */\n const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;\n if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if (\n (tagName === 'noscript' ||\n tagName === 'noembed' ||\n tagName === 'noframes') &&\n regExpTest(EXPRESSIONS.FALLBACK_TAG_CLOSE, currentNode.innerHTML)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n const content = _stripTemplateExpressions(currentNode.textContent);\n\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param lcTag Lowercase tag name of containing element.\n * @param lcName Lowercase attribute name.\n * @param value Attribute value.\n * @return Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function (\n lcTag: string,\n lcName: string,\n value: string\n ): boolean {\n /* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */\n if (FORBID_ATTR[lcName]) {\n return false;\n }\n\n /* Reject declarative-partial-updates patch-linkage attributes\n (https://github.com/WICG/declarative-partial-updates).\n\n Empirical note (Chrome 150, verified \u2014 see\n test/declarative-patch-probe-v3.html): expansion is NOT applied after\n sanitization. For the string path it fires during sanitize()'s own\n parse, so the walk sees and sanitizes the fully materialized expanded\n tree \u2014 teleports into MathML/SVG integration points included; a\n weaponized `<template for>`->`<img onerror>` comes back with the handler\n stripped. For the IN_PLACE path it fires on connection, before the walk.\n Either way DOMPurify is NOT blind to the patch.\n\n This removal is therefore defense-in-depth rather than the sole barrier:\n it prevents live linkage from surviving into the OUTPUT and re-expanding\n in the caller's context, and keeps behaviour deterministic if a future\n engine defers expansion. `for` is legitimate only on <label>/<output>;\n anywhere else (notably <template for>) it links the element to a patch\n target and teleports or removes an arbitrary DOM range by id/marker name.\n `patchsrc` fetches remote markup and is treated as a script-loading\n mechanism (CSP). Gated on SAFE_FOR_XML so the removal groups with the\n other structural-threat checks and stays overridable, consistent with\n the rest of the codebase. PI range markers are already removed by\n _isUnsafeNode. */\n if (SAFE_FOR_XML && lcName === 'patchsrc') {\n return false;\n }\n\n if (\n SAFE_FOR_XML &&\n lcName === 'for' &&\n lcTag !== 'label' &&\n lcTag !== 'output'\n ) {\n return false;\n }\n\n /* Make sure attribute cannot clobber */\n if (\n SANITIZE_DOM &&\n (lcName === 'id' || lcName === 'name') &&\n (value in document || value in formElement)\n ) {\n return false;\n }\n\n const nameIsPermitted =\n ALLOWED_ATTR[lcName] ||\n (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function &&\n EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag));\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR, lcName)) {\n // This attribute is safe\n } else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) {\n // This attribute is safe\n /* Otherwise, check the name is permitted */\n } else if (!nameIsPermitted) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n (_isBasicCustomElement(lcTag) &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag))) &&\n ((CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName)) ||\n (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)))) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n (lcName === 'is' &&\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))))\n ) {\n // If user has supplied a regexp or function in CUSTOM_ELEMENT_HANDLING.tagNameCheck, we need to also allow derived custom elements using the same tagName test.\n // Additionally, we need to allow attributes passing the CUSTOM_ELEMENT_HANDLING.attributeNameCheck user has configured, as custom elements can define these at their own discretion.\n } else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) {\n // This attribute is safe\n /* Check no script, data or unknown possibly unsafe URI\n unless we know URI values are safe for that attribute */\n } else if (\n regExpTest(IS_ALLOWED_URI, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Keep image data URIs alive if src/xlink:href is allowed */\n /* Further prevent gadget XSS for dynamically built script tags */\n } else if (\n (lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') &&\n lcTag !== 'script' &&\n stringIndexOf(value, 'data:') === 0 &&\n DATA_URI_TAGS[lcTag]\n ) {\n // This attribute is safe\n /* Allow unknown protocols: This provides support for links that\n are handled by protocol handlers which may be unknown ahead of\n time, e.g. fb:, spotify: */\n } else if (\n ALLOW_UNKNOWN_PROTOCOLS &&\n !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Check for binary attributes */\n } else if (value) {\n return false;\n } else {\n // Binary attributes are safe at this point\n /* Anything else, presume unsafe, do not add it back */\n }\n\n return true;\n };\n\n /* Names the HTML spec reserves from valid-custom-element-name; these must\n * never be treated as basic custom elements even when a permissive\n * CUSTOM_ELEMENT_HANDLING.tagNameCheck is configured. */\n const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, [\n 'annotation-xml',\n 'color-profile',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'missing-glyph',\n ]);\n\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param tagName name of the tag of the node to sanitize\n * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function (tagName: string): boolean {\n return (\n !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] &&\n regExpTest(CUSTOM_ELEMENT, tagName)\n );\n };\n\n /**\n * Wrap an attribute value in the matching Trusted Types object when\n * the active policy requires it. Namespaced attributes pass through\n * unchanged (no TT support yet, see\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1305293).\n *\n * @param lcTag lowercase tag name of the containing element\n * @param lcName lowercase attribute name\n * @param namespaceURI the attribute's namespace, if any\n * @param value the attribute value to wrap\n * @return the value, wrapped when Trusted Types demand it\n */\n const _applyTrustedTypesToAttribute = function (\n lcTag: string,\n lcName: string,\n namespaceURI: string | null,\n value: string\n ): string {\n if (\n trustedTypesPolicy &&\n typeof trustedTypes === 'object' &&\n typeof trustedTypes.getAttributeType === 'function' &&\n !namespaceURI\n ) {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML': {\n return _createTrustedHTML(value);\n }\n\n case 'TrustedScriptURL': {\n return _createTrustedScriptURL(value);\n }\n\n default: {\n break;\n }\n }\n }\n\n return value;\n };\n\n /**\n * Write a modified attribute value back onto the element. On\n * success, re-probe for clobbering introduced by the new value and\n * remove the element when found; otherwise pop the removal entry\n * recorded by the earlier _removeAttribute (long-standing pairing\n * with the SANITIZE_NAMED_PROPS path - do not \"fix\" casually). On\n * failure, remove the attribute instead.\n *\n * @param currentNode the element carrying the attribute\n * @param name the attribute name as present on the element\n * @param namespaceURI the attribute's namespace, if any\n * @param value the new attribute value\n */\n const _setAttributeValue = function (\n currentNode: Element,\n name: string,\n namespaceURI: string | null,\n value: string\n ): void {\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {\n _removeAttribute(name, currentNode);\n }\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param currentNode to sanitize\n */\n const _sanitizeAttributes = function (currentNode: Element): void {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n\n const { attributes } = currentNode;\n\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes || _isClobbered(currentNode)) {\n return;\n }\n\n /* Same lazy-install guard as uponSanitizeElement (see there): fork the\n attribute allowlist off its shared binding before a hook can see it. */\n ALLOWED_ATTR = _forkSharedAllowlist(\n hooks.uponSanitizeAttribute,\n ALLOWED_ATTR,\n DEFAULT_ALLOWED_ATTR,\n SET_CONFIG_ALLOWED_ATTR\n );\n\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n forceKeepAttr: undefined,\n };\n let l = attributes.length;\n const lcTag = transformCaseFunc(currentNode.nodeName);\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const { name, namespaceURI, value: attrValue } = attr;\n const lcName = transformCaseFunc(name);\n\n const initValue = attrValue;\n let value = name === 'value' ? initValue : stringTrim(initValue);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n value = hookEvent.attrValue;\n\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (\n SANITIZE_NAMED_PROPS &&\n (lcName === 'id' || lcName === 'name') &&\n stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0\n ) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n // Else: already prefixed, leave the attribute alone \u2014 the prefix is\n // itself the clobbering protection, and re-applying it is incorrect.\n\n /* Work around a security issue with comments inside attributes */\n if (\n SAFE_FOR_XML &&\n regExpTest(\n /((--!?|])>)|<\\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,\n value\n )\n ) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Make sure we cannot easily use animated hrefs, even if animations are allowed */\n if (lcName === 'attributename' && stringMatch(value, 'href')) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Did the hooks force-keep the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (\n !ALLOW_SELF_CLOSE_IN_ATTR &&\n regExpTest(EXPRESSIONS.SELF_CLOSING_TAG, value)\n ) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n value = _stripTemplateExpressions(value);\n }\n\n /* Is `value` valid for this attribute? */\n if (!_isValidAttribute(lcTag, lcName, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Handle attributes that require Trusted Types */\n value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);\n\n /* Handle invalid data-* attribute set by try-catching it */\n if (value !== initValue) {\n _setAttributeValue(currentNode, name, namespaceURI, value);\n }\n }\n\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function (fragment: DocumentFragment): void {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n\n while ((shadowNode = shadowIterator.nextNode())) {\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n\n /* Sanitize tags and elements */\n _sanitizeElements(shadowNode, fragment);\n\n /* Check attributes next */\n _sanitizeAttributes(shadowNode);\n\n /* Deep shadow DOM detected.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): use nodeType against the\n DOCUMENT_FRAGMENT_NODE constant rather than instanceof, so we\n recurse into <template>.content from foreign realms too. */\n if (_isDocumentFragment(shadowNode.content)) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* An element iterated here may itself host an attached\n shadow root. The default NodeIterator does not enter shadow\n trees, so a shadow root nested inside template.content was\n previously reached by no walk at all (the pre-pass at\n _sanitizeAttachedShadowRoots descends via childNodes, which\n doesn't enter template.content; the template-content recursion\n above iterates the content but never inspected shadowRoot).\n Walk it explicitly. The nodeType guard avoids reading\n shadowRoot off text / comment / CDATA / PI nodes that the\n iterator also surfaces. */\n const shadowNodeType = getNodeType\n ? getNodeType(shadowNode)\n : shadowNode.nodeType;\n if (shadowNodeType === NODE_TYPE.element) {\n const innerSr = getShadowRoot(shadowNode);\n if (_isDocumentFragment(innerSr)) {\n _sanitizeAttachedShadowRoots(innerSr);\n _sanitizeShadowDOM(innerSr);\n }\n }\n }\n\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n };\n\n /**\n * _sanitizeAttachedShadowRoots\n *\n * Walks `root` and feeds every attached shadow root we encounter into\n * the existing _sanitizeShadowDOM pipeline. The default node iterator\n * does not descend into shadow trees, so nodes inside an attached\n * shadow root would otherwise be skipped entirely.\n *\n * Two real input paths put attached shadow roots in front of us:\n * 1. IN_PLACE on a DOM node that already has shadow roots attached.\n * 2. DOM-node input where importNode(dirty, true) deep-clones the\n * shadow root because it was created with `clonable: true`.\n *\n * This pass runs once, up front, so the main iteration loop (and the\n * existing _sanitizeShadowDOM template-content recursion) stay\n * untouched \u2014 string-input paths are not affected.\n *\n * @param root the subtree root to walk for attached shadow roots\n */\n const _sanitizeAttachedShadowRoots = function (root: Node): void {\n /* Iterative (explicit stack) rather than per-child recursion. DOM APIs\n impose no depth cap, so an attacker-shaped tree (JSON/CRDT/editor data\n built straight into the DOM \u2014 the IN_PLACE surface) deeper than the JS\n call-stack budget would otherwise overflow native recursion here and\n throw at the IN_PLACE entry pre-pass, before a single node is\n sanitized, leaving the caller's live tree untouched (fail-open). See\n campaign-3 F4. A heap stack keeps depth off the call stack.\n\n Each work item is either a node to descend into, or a deferred\n `_sanitizeShadowDOM` for an already-walked shadow root. The deferred\n form preserves the original post-order discipline: a shadow root's\n nested shadow roots are discovered before the outer shadow is\n sanitized (which may remove hosts). Pushes are in reverse of the\n desired processing order (LIFO): template content, then children, then\n the shadow-sanitize, then the shadow walk \u2014 so the order matches the\n previous recursion exactly. */\n const stack: Array<{ node: Node | null; shadow: DocumentFragment | null }> =\n [{ node: root, shadow: null }];\n\n while (stack.length > 0) {\n const item = stack.pop();\n\n /* Deferred shadow-DOM sanitisation: runs after its subtree was walked. */\n if (item.shadow) {\n _sanitizeShadowDOM(item.shadow);\n continue;\n }\n\n const node = item.node;\n const nodeType = getNodeType ? getNodeType(node) : (node as any).nodeType;\n const isElement = nodeType === NODE_TYPE.element;\n\n /* (pushed last \u2192 processed first) Children, snapshotted in reverse so\n the first child is processed first. Snapshotting matters because a\n hook may detach siblings mid-walk. */\n const childNodes = getChildNodes(node);\n if (childNodes) {\n for (let i = childNodes.length - 1; i >= 0; --i) {\n stack.push({ node: childNodes[i], shadow: null });\n }\n }\n\n /* (pushed before children \u2192 processed after them, matching the old\n \"template content last\" order) When the node is a <template>,\n descend into its content. */\n if (isElement) {\n const rootName = getNodeName ? getNodeName(node) : null;\n if (\n typeof rootName === 'string' &&\n transformCaseFunc(rootName) === 'template'\n ) {\n const content = (node as HTMLTemplateElement).content;\n if (_isDocumentFragment(content)) {\n stack.push({ node: content, shadow: null });\n }\n }\n }\n\n /* Shadow root (processed first): walk its subtree, then sanitise it.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): nodeType-based detection\n rather than `instanceof DocumentFragment`, which is realm-bound and\n silently skipped foreign-realm shadow roots (e.g.\n iframe.contentDocument attachShadow). */\n if (isElement) {\n const sr = getShadowRoot(node);\n if (_isDocumentFragment(sr)) {\n /* Push the deferred sanitise first so it pops after the shadow\n walk we push next, i.e. nested shadow roots are discovered\n before this one is sanitised. */\n stack.push({ node: null, shadow: sr }, { node: sr, shadow: null });\n }\n }\n }\n };\n\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg = {}) {\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n dirty = stringifyValue(dirty);\n\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n }\n\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n\n /* Assign config vars */\n if (SET_CONFIG) {\n /* Persistent setConfig() path: _parseConfig is skipped, so the sets are\n * not re-derived per call. Restore them from the pristine bindings\n * captured at setConfig() time so a previous call's hook clone (mutated\n * below) does not carry over. */\n ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;\n ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;\n } else {\n _parseConfig(cfg);\n }\n\n /* Clone the hook-mutable allowlists before the walk whenever an\n * uponSanitize* hook is registered. The hook event exposes ALLOWED_TAGS\n * and ALLOWED_ATTR by reference (as allowedTags / allowedAttributes), so\n * a hook that widens them would otherwise mutate the shared set\n * permanently: across later calls and across every element. Cloning per\n * walk keeps documented in-call widening working while scoping it to the\n * call. A single guard for both config paths - the per-call path rebinds\n * the sets in _parseConfig each call, the persistent path restores them\n * from the captured bindings just above - so the two cannot diverge. */\n if (\n hooks.uponSanitizeElement.length > 0 ||\n hooks.uponSanitizeAttribute.length > 0\n ) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n if (hooks.uponSanitizeAttribute.length > 0) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Resolve IN_PLACE for this call without mutating persistent config.\n Writing the IN_PLACE closure variable here leaks under setConfig(),\n where _parseConfig is skipped on later calls: a single string call would\n disable in-place mode for every subsequent node call, returning a\n sanitized copy while leaving the caller's node \u2014 which in-place callers\n keep using and whose return value they ignore \u2014 unsanitized. REPORT-2. */\n const inPlace = IN_PLACE && typeof dirty !== 'string' && _isNode(dirty);\n\n if (inPlace) {\n /* Declarative-partial-updates / streaming pre-pass: sever every patch\n linkage across the live tree BEFORE the walk, so no patch can fire\n mid-walk and inject into an already-processed region. Runs first, so\n it also covers the forbidden/clobbered roots that throw below. */\n _neutralizePatchLinkage(dirty as Node);\n\n /* Do some early pre-sanitization to avoid unsafe root nodes.\n Read nodeName through the cached prototype getter \u2014 a clobbering\n child named \"nodeName\" on the form root would otherwise shadow\n the property and let this check skip the root-allowlist\n validation entirely. */\n const nn = getNodeName\n ? getNodeName(dirty as Node)\n : (dirty as Node).nodeName;\n if (typeof nn === 'string') {\n const tagName = transformCaseFunc(nn);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Fail closed on a live root: neutralize handlers/children before\n throwing, exactly as the mid-walk abort path does. */\n _neutralizeRoot(dirty as Node);\n\n throw typeErrorCreate(\n 'root node is forbidden and cannot be sanitized in-place'\n );\n }\n }\n\n /* Pre-flight the root through _isClobbered. The iterator-driven\n removal path can not detach a parent-less root: _forceRemove\n falls through to Element.prototype.remove(), which per spec\n is a no-op on a node with no parent. A clobbered root would\n then survive the main loop with its attributes uninspected,\n because _sanitizeAttributes early-returns on _isClobbered. The\n result would be an attacker-controlled form, complete with any\n event-handler attributes the caller passed in, handed back to\n the application unsanitized. Refuse to sanitize such a root\n the same way we refuse a forbidden tag. GHSA-r47g-fvhr-h676. */\n if (_isClobbered(dirty as Element)) {\n /* Fail closed on a live clobbered root before throwing.\n _neutralizeRoot's reads are clobber-safe (cached getters); the\n form's non-clobbered descendants, e.g. an armed <img>, are scrubbed. */\n _neutralizeRoot(dirty as Node);\n\n throw typeErrorCreate(\n 'root node is clobbered and cannot be sanitized in-place'\n );\n }\n\n /* Sanitize attached shadow roots before the main iterator runs.\n The iterator does not descend into shadow trees. Same fail-closed\n barrier as the main walk (campaign-3 F2): a custom-element reaction\n inside a shadow root could abort this pre-pass before the walk runs,\n which would otherwise leave the entire live tree unsanitized. */\n try {\n _sanitizeAttachedShadowRoots(dirty as Node);\n } catch (error) {\n _neutralizeRoot(dirty as Node);\n\n throw error;\n }\n } else if (_isNode(dirty)) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (\n importedNode.nodeType === NODE_TYPE.element &&\n importedNode.nodeName === 'BODY'\n ) {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n\n /* Clonable shadow roots are deep-cloned by importNode(); sanitize\n them before the main iterator runs, since the iterator does not\n descend into shadow trees. The walk routes every read through a\n cached prototype getter so clobbering descendants on a form root\n cannot hide a shadow host from this pass. */\n _sanitizeAttachedShadowRoots(importedNode);\n } else {\n /* Exit directly if we have nothing to do */\n if (\n !RETURN_DOM &&\n !SAFE_FOR_TEMPLATES &&\n !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1\n ) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? _createTrustedHTML(dirty)\n : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n const walkRoot: Node = inPlace ? (dirty as Node) : body;\n\n /* Now start iterating over the created document.\n The walk runs inside an exception barrier (campaign-3 F2): a re-entrant\n engine/custom-element mutation can detach a node mid-walk so\n `_forceRemove`'s parentless guard throws, aborting the loop. Without the\n barrier the caller's in-place tree would be left half-sanitized with the\n unvisited tail still armed. _createNodeIterator itself is inside the\n barrier too: constructing the iterator dereferences the root's document,\n and any failure there (e.g. an exotic/clobbered root) must still fail\n closed rather than skip the neutralize. On any throw we fail closed -\n strip the in-place root bare - then rethrow so the existing throw\n contract is preserved. (String/DOM-copy paths never return the partial\n body, so the propagating throw is already fail-closed there.) */\n try {\n const nodeIterator = _createNodeIterator(walkRoot);\n while ((currentNode = nodeIterator.nextNode())) {\n /* Sanitize tags and elements */\n _sanitizeElements(currentNode, walkRoot);\n\n /* Check attributes next */\n _sanitizeAttributes(currentNode);\n\n /* Shadow DOM detected, sanitize it.\n Realm-safe check (GHSA-hpcv-96wg-7vj8): nodeType-based detection\n instead of instanceof, so foreign-realm <template>.content is\n walked correctly. */\n if (_isDocumentFragment(currentNode.content)) {\n _sanitizeShadowDOM(currentNode.content);\n }\n }\n } catch (error) {\n if (inPlace) {\n _neutralizeRoot(dirty as Node);\n /* Nodes _forceRemove'd earlier in the aborted walk are already\n detached from the root, so _neutralizeRoot's subtree pass does not\n reach them. Defuse them too, mirroring the success-path loop below. */\n arrayForEach(DOMPurify.removed, (entry) => {\n if (entry.element) {\n _neutralizeSubtree(entry.element as Node);\n }\n });\n }\n\n throw error;\n }\n\n /* If we sanitized `dirty` in-place, return it. */\n if (inPlace) {\n /* Fail-closed completion of the audit-5 F1 fix: every node removed from\n the caller's live tree is detached but may still hold a queued\n resource-event handler that fires in page scope after we return. The\n move-hoist covers only disallowed-tag KEEP_CONTENT removals; strip the\n non-allow-listed attributes off every other removed subtree (clobber,\n mXSS, namespace, comments, KEEP_CONTENT:false, \u2026) so those handlers are\n cancelled before any event can fire. Runs synchronously, pre-return. */\n arrayForEach(DOMPurify.removed, (entry) => {\n if (entry.element) {\n _neutralizeSubtree(entry.element as Node);\n }\n });\n\n if (SAFE_FOR_TEMPLATES) {\n _scrubTemplateExpressions(dirty as Element);\n }\n\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (SAFE_FOR_TEMPLATES) {\n _scrubTemplateExpressions(body);\n }\n\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Serialize doctype if allowed */\n if (\n WHOLE_DOCUMENT &&\n ALLOWED_TAGS['!doctype'] &&\n body.ownerDocument &&\n body.ownerDocument.doctype &&\n body.ownerDocument.doctype.name &&\n regExpTest(EXPRESSIONS.DOCTYPE_NAME, body.ownerDocument.doctype.name)\n ) {\n serializedHTML =\n '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n serializedHTML = _stripTemplateExpressions(serializedHTML);\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? _createTrustedHTML(serializedHTML)\n : serializedHTML;\n };\n\n DOMPurify.setConfig = function (cfg = {}) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;\n SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;\n };\n\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n SET_CONFIG_ALLOWED_TAGS = null;\n SET_CONFIG_ALLOWED_ATTR = null;\n\n // Drop any caller-supplied Trusted Types policy so it cannot poison later\n // `RETURN_TRUSTED_TYPE` output. The internal default policy (cached, and\n // never recreated \u2014 Trusted Types throws on duplicate names) is restored by\n // the next `_parseConfig`. See GHSA-vxr8-fq34-vvx9.\n trustedTypesPolicy = defaultTrustedTypesPolicy;\n emptyHTML = '';\n };\n\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n DOMPurify.addHook = function (\n entryPoint: keyof HooksMap,\n hookFunction: HookFunction\n ) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n /* Reject unknown entry points. Without this, a non-hook key (e.g.\n * '__proto__') indexes off the prototype chain rather than a real\n * hook array, and arrayPush then writes to Object.prototype. Guard\n * with an own-property check against the known hook names. */\n if (!objectHasOwnProperty(hooks, entryPoint)) {\n return;\n }\n\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n DOMPurify.removeHook = function (\n entryPoint: keyof HooksMap,\n hookFunction: HookFunction\n ) {\n if (!objectHasOwnProperty(hooks, entryPoint)) {\n return undefined;\n }\n\n if (hookFunction !== undefined) {\n const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);\n\n return index === -1\n ? undefined\n : arraySplice(hooks[entryPoint], index, 1)[0];\n }\n\n return arrayPop(hooks[entryPoint]);\n };\n\n DOMPurify.removeHooks = function (entryPoint: keyof HooksMap) {\n if (!objectHasOwnProperty(hooks, entryPoint)) {\n return;\n }\n\n hooks[entryPoint] = [];\n };\n\n DOMPurify.removeAllHooks = function () {\n hooks = _createHooksMap();\n };\n\n return DOMPurify;\n}\n\nexport default createDOMPurify();\n", "import type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Gets the original marked default options.\n */\nexport function _getDefaults<ParserOutput = string, RendererOutput = string>(): MarkedOptions<ParserOutput, RendererOutput> {\n return {\n async: false,\n breaks: false,\n extensions: null,\n gfm: true,\n hooks: null,\n pedantic: false,\n renderer: null,\n silent: false,\n tokenizer: null,\n walkTokens: null,\n };\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport let _defaults: MarkedOptions<any, any> = _getDefaults();\n\nexport function changeDefaults<ParserOutput = string, RendererOutput = string>(newDefaults: MarkedOptions<ParserOutput, RendererOutput>) {\n _defaults = newDefaults;\n}\n", "const noopTest = { exec: () => null } as unknown as RegExp;\n\nfunction cachedIndentRegex(createRegex: (indent: number) => RegExp) {\n const cache: RegExp[] = [];\n return (indent: number) => {\n const cacheIndex = Math.max(0, Math.min(3, indent - 1));\n let regex = cache[cacheIndex];\n if (!regex) {\n regex = createRegex(cacheIndex);\n cache[cacheIndex] = regex;\n }\n return regex;\n };\n}\n\nfunction edit(regex: string | RegExp, opt = '') {\n let source = typeof regex === 'string' ? regex : regex.source;\n const obj = {\n replace: (name: string | RegExp, val: string | RegExp) => {\n let valSource = typeof val === 'string' ? val : val.source;\n valSource = valSource.replace(other.caret, '$1');\n source = source.replace(name, valSource);\n return obj;\n },\n getRegex: () => {\n return new RegExp(source, opt);\n },\n };\n return obj;\n}\n\n// use a default variable to ensure the regex is evaluated on client an not removed by minifiers\nconst supportsLookbehind = ((a = '') => {\ntry {\n return !!new RegExp('(?<=1)(?<!1)' + a);\n} catch {\n // See browser support here:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookbehind_assertion\n return false;\n}\n})();\n\nexport const other = {\n codeRemoveIndent: /^(?: {1,4}| {0,3}\\t)/gm,\n outputLinkReplace: /\\\\([\\[\\]])/g,\n indentCodeCompensation: /^(\\s+)(?:```)/,\n beginningSpace: /^\\s+/,\n endingHash: /#$/,\n startingSpaceChar: /^ /,\n endingSpaceChar: / $/,\n nonSpaceChar: /[^ ]/,\n newLineCharGlobal: /\\n/g,\n tabCharGlobal: /\\t/g,\n multipleSpaceGlobal: /\\s+/g,\n blankLine: /^[ \\t]*$/,\n doubleBlankLine: /\\n[ \\t]*\\n[ \\t]*$/,\n blockquoteStart: /^ {0,3}>/,\n blockquoteSetextReplace: /\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,\n blockquoteSetextReplace2: /^ {0,3}>[ \\t]?/gm,\n listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g,\n listIsTask: /^\\[[ xX]\\] +\\S/,\n listReplaceTask: /^\\[[ xX]\\] +/,\n listTaskCheckbox: /\\[[ xX]\\]/,\n anyLine: /\\n.*\\n/,\n hrefBrackets: /^<(.*)>$/,\n tableDelimiter: /[:|]/,\n tableAlignChars: /^\\||\\| *$/g,\n tableRowBlankLine: /\\n[ \\t]*$/,\n tableAlignRight: /^ *-+: *$/,\n tableAlignCenter: /^ *:-+: *$/,\n tableAlignLeft: /^ *:-+ *$/,\n startATag: /^<a /i,\n endATag: /^<\\/a>/i,\n startPreScriptTag: /^<(pre|code|kbd|script)(\\s|>)/i,\n endPreScriptTag: /^<\\/(pre|code|kbd|script)(\\s|>)/i,\n startAngleBracket: /^</,\n endAngleBracket: />$/,\n pedanticHrefTitle: /^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/,\n unicodeAlphaNumeric: /[\\p{L}\\p{N}]/u,\n escapeTest: /[&<>\"']/,\n escapeReplace: /[&<>\"']/g,\n escapeTestNoEncode: /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,\n escapeReplaceNoEncode: /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,\n caret: /(^|[^\\[])\\^/g,\n percentDecode: /%25/g,\n findPipe: /\\|/g,\n splitPipe: / \\|/,\n slashPipe: /\\\\\\|/g,\n carriageReturn: /\\r\\n|\\r/g,\n spaceLine: /^ +$/gm,\n notSpaceStart: /^\\S*/,\n endingNewline: /\\n$/,\n listItemRegex: (bull: string) => new RegExp(`^( {0,3}${bull})((?:[\\t ][^\\\\n]*)?(?:\\\\n|$))`),\n nextBulletRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \\t][^\\\\n]*)?(?:\\\\n|$))`)),\n hrRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),\n fencesBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:\\`\\`\\`|~~~)`)),\n headingBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}#`)),\n htmlBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}<(?:[a-z].*>|!--)`, 'i')),\n blockquoteBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}>`)),\n};\n\n/**\n * Block-Level Grammar\n */\n\nconst newline = /^(?:[ \\t]*(?:\\n|$))+/;\nconst blockCode = /^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/;\nconst fences = /^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/;\nconst hr = /^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/;\nconst heading = /^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/;\nconst bullet = / {0,3}(?:[*+-]|\\d{1,9}[.)])/;\nconst lheadingCore = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/;\nconst lheading = edit(lheadingCore)\n .replace(/bull/g, bullet) // lists can interrupt\n .replace(/blockCode/g, /(?: {4}| {0,3}\\t)/) // indented code blocks can interrupt\n .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt\n .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt\n .replace(/heading/g, / {0,3}#{1,6}(?:\\s|$)/) // ATX heading can interrupt\n .replace(/html/g, / {0,3}<[^\\n>]+>\\n/) // block html can interrupt\n .replace(/\\|table/g, '') // table not in commonmark\n .getRegex();\nconst lheadingGfm = edit(lheadingCore)\n .replace(/bull/g, bullet) // lists can interrupt\n .replace(/blockCode/g, /(?: {4}| {0,3}\\t)/) // indented code blocks can interrupt\n .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt\n .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt\n .replace(/heading/g, / {0,3}#{1,6}(?:\\s|$)/) // ATX heading can interrupt\n .replace(/html/g, / {0,3}<[^\\n>]+>\\n/) // block html can interrupt\n .replace(/table/g, / {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/) // table can interrupt\n .getRegex();\nconst _paragraph = /^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/;\nconst blockText = /^[^\\n]+/;\nconst _blockLabel = /(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/;\nconst def = edit(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/)\n .replace('label', _blockLabel)\n .replace('title', /(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/)\n .getRegex();\n\nconst list = edit(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/)\n .replace(/bull/g, bullet)\n .getRegex();\n\nconst _tag = 'address|article|aside|base|basefont|blockquote|body|caption'\n + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'\n + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'\n + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'\n + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title'\n + '|tr|track|ul';\nconst _comment = /<!--(?:-?>|[\\s\\S]*?(?:-->|$))/;\nconst html = edit(\n '^ {0,3}(?:' // optional indentation\n+ '<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n*|$)' // (1)\n+ '|comment[^\\\\n]*(\\\\n+|$)' // (2)\n+ '|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>[^\\\\n]*\\\\n*|$)' // (3)\n+ '|<![A-Z][\\\\s\\\\S]*?(?:>[^\\\\n]*\\\\n*|$)' // (4)\n+ '|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>[^\\\\n]*\\\\n*|$)' // (5)\n+ '|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (6)\n+ '|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) open tag\n+ '|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) closing tag\n+ ')', 'i')\n .replace('comment', _comment)\n .replace('tag', _tag)\n .replace('attribute', / +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/)\n .getRegex();\n\nconst createParagraph = (listInterrupt: RegExp) => edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n .replace('|table', '')\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n')\n .replace('list', listInterrupt)\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n .getRegex();\n\n// only non-empty lists starting from 1 can interrupt paragraphs\nconst paragraph = createParagraph(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/);\n// inside a blockquote a bare list marker (any number) starts a sibling list,\n// so it must not be lazily continued as paragraph text (unlike a top level\n// paragraph, where an empty list cannot interrupt)\nconst blockquoteParagraph = createParagraph(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/);\n\nconst blockquote = edit(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/)\n .replace('paragraph', blockquoteParagraph)\n .getRegex();\n\n/**\n * Normal Block Grammar\n */\n\nconst blockNormal = {\n blockquote,\n code: blockCode,\n def,\n fences,\n heading,\n hr,\n html,\n lheading,\n list,\n newline,\n paragraph,\n table: noopTest,\n text: blockText,\n};\n\ntype BlockKeys = keyof typeof blockNormal;\n\n/**\n * GFM Block Grammar\n */\n\nconst gfmTable = edit(\n '^ *([^\\\\n ].*)\\\\n' // Header\n+ ' {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)' // Align\n+ '(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)') // Cells\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('blockquote', ' {0,3}>')\n .replace('code', '(?: {4}| {0,3}\\t)[^\\\\n]')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)])[ \\\\t]') // any bullet ends the table rows\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // tables can be interrupted by type (6) html blocks\n .getRegex();\n\nconst blockGfm: Record<BlockKeys, RegExp> = {\n ...blockNormal,\n lheading: lheadingGfm,\n table: gfmTable,\n paragraph: edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n .replace('table', gfmTable) // interrupt paragraphs with table\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)])[ \\\\t]+[^ \\\\t\\\\n]') // only non-empty lists starting from 1 can interrupt\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n .getRegex(),\n};\n\n/**\n * Pedantic grammar (original John Gruber's loose markdown specification)\n */\n\nconst blockPedantic: Record<BlockKeys, RegExp> = {\n ...blockNormal,\n html: edit(\n '^ *(?:comment *(?:\\\\n|\\\\s*$)'\n + '|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)' // closed tag\n + '|<tag(?:\"[^\"]*\"|\\'[^\\']*\\'|\\\\s[^\\'\"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))')\n .replace('comment', _comment)\n .replace(/tag/g, '(?!(?:'\n + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'\n + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'\n + '\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b')\n .getRegex(),\n def: /^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,\n heading: /^(#{1,6})(.*)(?:\\n+|$)/,\n fences: noopTest, // fences not supported\n lheading: /^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,\n paragraph: edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' *#{1,6} *[^\\n]')\n .replace('lheading', lheading)\n .replace('|table', '')\n .replace('blockquote', ' {0,3}>')\n .replace('|fences', '')\n .replace('|list', '')\n .replace('|html', '')\n .replace('|tag', '')\n .getRegex(),\n};\n\n/**\n * Inline-Level Grammar\n */\n\nconst escape = /^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/;\nconst inlineCode = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst br = /^( {2,}|\\\\)\\n(?!\\s*$)/;\nconst inlineText = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/;\n\n// list of unicode punctuation marks, plus any missing characters from CommonMark spec\nconst _punctuation = /[\\p{P}\\p{S}]/u;\nconst _punctuationOrSpace = /[\\s\\p{P}\\p{S}]/u;\nconst _notPunctuationOrSpace = /[^\\s\\p{P}\\p{S}]/u;\nconst punctuation = edit(/^((?![*_])punctSpace)/, 'u')\n .replace(/punctSpace/g, _punctuationOrSpace).getRegex();\n\n/**\n * Opening punct/quotes excluded from pedantic LDelim nextChar so\n * `aa**\"A\"**bb` / `aa**(A)**bb` can start strong (Pi + Ps + ASCII straight quotes).\n */\nconst _openQuote = /[\\p{Pi}\\p{Ps}\"']/u;\n\n// GFM allows ~ inside strong and em for strikethrough\nconst _punctuationGfmStrongEm = /(?!~)[\\p{P}\\p{S}]/u;\nconst _punctuationOrSpaceGfmStrongEm = /(?!~)[\\s\\p{P}\\p{S}]/u;\nconst _notPunctuationOrSpaceGfmStrongEm = /(?:[^\\s\\p{P}\\p{S}]|~)/u;\n\n// sequences em should skip over [title](link), `code`, <html>\nconst blockSkip = edit(/link|precode-code|html/, 'g')\n .replace('link', /\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/)\n .replace('precode-', supportsLookbehind ? '(?<!`)()' : '(^^|[^`])')\n .replace('code', /(?<b>`+)[^`]+\\k<b>(?!`)/)\n .replace('html', /<(?! )[^<>]*?>/)\n .getRegex();\n\nconst emStrongLDelimCore = /^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/;\n\nconst emStrongLDelim = edit(emStrongLDelimCore, 'u')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongLDelimGfm = edit(emStrongLDelimCore, 'u')\n .replace(/punct/g, _punctuationGfmStrongEm)\n .getRegex();\n\n// Pedantic: do not treat opening punct/quotes as left-delim punct (e.g. **( / **\").\nconst emStrongLDelimPedanticCore = /^(?:\\*+(?:((?!\\*)(?!openQuote)punct)|([^\\s*]))?)|^_+(?:((?!_)(?!openQuote)punct)|([^\\s_]))?/;\n\nconst emStrongLDelimPedantic = edit(emStrongLDelimPedanticCore, 'u')\n .replace(/openQuote/g, _openQuote)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongRDelimAstCore =\n '^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)' // Skip orphan inside strong\n+ '|[^*]+(?=[^*])' // Consume to delim\n+ '|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)' // (1) #*** can only be a Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter\n+ '|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)' // (3) #***a, ***a can only be Left Delimiter\n+ '|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)' // (4) ***# can only be Left Delimiter\n+ '|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?=notPunctSpace)'; // (6) a***a can be either Left or Right Delimiter\n\nconst emStrongRDelimAst = edit(emStrongRDelimAstCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongRDelimAstGfm = edit(emStrongRDelimAstCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmStrongEm)\n .replace(/punctSpace/g, _punctuationOrSpaceGfmStrongEm)\n .replace(/punct/g, _punctuationGfmStrongEm)\n .getRegex();\n\n// Pedantic: rule 3 requires whitespace before left delim; rule 6 allows punct before close (e.g. `:**bar`).\nconst emStrongRDelimAstPedanticCore =\n '^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)' // Skip orphan inside strong\n+ '|[^*]+(?=[^*])' // Consume to delim\n+ '|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)' // (1) #*** can only be a Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter\n+ '|(?!\\\\*)[\\\\s](\\\\*+)(?=notPunctSpace)' // (3) ***a can only be Left Delimiter (whitespace required; not #***a)\n+ '|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)' // (4) ***# can only be Left Delimiter\n+ '|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter\n+ '|(?:(?!\\\\*)punct|notPunctSpace)(\\\\*+)(?!\\\\*)(?=notPunctSpace)'; // (6) a***a, #***a, and :** (e.g. **foo:**bar)\n\nconst emStrongRDelimAstPedantic = edit(emStrongRDelimAstPedanticCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Normal: no rule 6 for _ (a___a cannot close as emphasis).\nconst emStrongRDelimUnd = edit(\n '^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)' // Skip orphan inside strong\n+ '|[^_]+(?=[^_])' // Consume to delim\n+ '|(?!_)punct(_+)(?=[\\\\s]|$)' // (1) #___ can only be a Right Delimiter\n+ '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter\n+ '|(?!_)punctSpace(_+)(?=notPunctSpace)' // (3) #___a, ___a can only be Left Delimiter\n+ '|[\\\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter\n+ '|(?!_)punct(_+)(?!_)(?=punct)', 'gu') // (5) #___# can be either Left or Right Delimiter\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Pedantic: same rule 3/6 adjustments as emStrongRDelimAstPedantic (e.g. `_foo:_bar`).\nconst emStrongRDelimUndPedanticCore =\n '^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)' // Skip orphan inside strong\n+ '|[^_]+(?=[^_])' // Consume to delim\n+ '|(?!_)punct(_+)(?=[\\\\s]|$)' // (1) #___ can only be a Right Delimiter\n+ '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter\n+ '|(?!_)[\\\\s](_+)(?=notPunctSpace)' // (3) ___a can only be Left Delimiter (whitespace required; not #___a)\n+ '|[\\\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter\n+ '|(?!_)punct(_+)(?!_)(?=punct)' // (5) #___# can be either Left or Right Delimiter\n+ '|(?:(?!_)punct|notPunctSpace)(_+)(?!_)(?=notPunctSpace)'; // (6) a___a, #___a, and :__ (e.g. _foo:_bar)\n\nconst emStrongRDelimUndPedantic = edit(emStrongRDelimUndPedanticCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Tilde left delimiter for strikethrough (similar to emStrongLDelim for asterisk)\nconst delLDelim = edit(/^~~?(?:((?!~)punct)|[^\\s~])/, 'u')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Tilde delimiter patterns for strikethrough (similar to asterisk)\nconst delRDelimCore =\n '^[^~]+(?=[^~])' // Consume to delim\n+ '|(?!~)punct(~~?)(?=[\\\\s]|$)' // (1) #~~ can only be a Right Delimiter\n+ '|notPunctSpace(~~?)(?!~)(?=punctSpace|$)' // (2) a~~#, a~~ can only be a Right Delimiter\n+ '|(?!~)punctSpace(~~?)(?=notPunctSpace)' // (3) #~~a, ~~a can only be Left Delimiter\n+ '|[\\\\s](~~?)(?!~)(?=punct)' // (4) ~~# can only be Left Delimiter\n+ '|(?!~)punct(~~?)(?!~)(?=punct)' // (5) #~~# can be either Left or Right Delimiter\n+ '|notPunctSpace(~~?)(?=notPunctSpace)'; // (6) a~~a can be either Left or Right Delimiter\n\nconst delRDelim = edit(delRDelimCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst anyPunctuation = edit(/\\\\(punct)/, 'gu')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst autolink = edit(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/)\n .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)\n .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/)\n .getRegex();\n\nconst _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();\nconst tag = edit(\n '^comment'\n + '|^</[a-zA-Z][\\\\w:-]*\\\\s*>' // self-closing tag\n + '|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>' // open tag\n + '|^<\\\\?[\\\\s\\\\S]*?\\\\?>' // processing instruction, e.g. <?php ?>\n + '|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>' // declaration, e.g. <!DOCTYPE html>\n + '|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>') // CDATA section\n .replace('comment', _inlineComment)\n .replace('attribute', /\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/)\n .getRegex();\n\nconst _inlineLabel = /(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/;\n\nconst link = edit(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/)\n .replace('label', _inlineLabel)\n .replace('href', /<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/)\n .replace('title', /\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/)\n .getRegex();\n\nconst reflink = edit(/^!?\\[(label)\\]\\[(ref)\\]/)\n .replace('label', _inlineLabel)\n .replace('ref', _blockLabel)\n .getRegex();\n\nconst nolink = edit(/^!?\\[(ref)\\](?:\\[\\])?/)\n .replace('ref', _blockLabel)\n .getRegex();\n\nconst reflinkSearch = edit('reflink|nolink(?!\\\\()', 'g')\n .replace('reflink', reflink)\n .replace('nolink', nolink)\n .getRegex();\n\nconst _caseInsensitiveProtocol = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;\n\n/**\n * Normal Inline Grammar\n */\n\nconst inlineNormal = {\n _backpedal: noopTest, // only used for GFM url\n anyPunctuation,\n autolink,\n blockSkip,\n br,\n code: inlineCode,\n del: noopTest,\n delLDelim: noopTest,\n delRDelim: noopTest,\n emStrongLDelim,\n emStrongRDelimAst,\n emStrongRDelimUnd,\n escape,\n link,\n nolink,\n punctuation,\n reflink,\n reflinkSearch,\n tag,\n text: inlineText,\n url: noopTest,\n};\n\ntype InlineKeys = keyof typeof inlineNormal;\n\n/**\n * Pedantic Inline Grammar\n */\n\nconst inlinePedantic: Record<InlineKeys, RegExp> = {\n ...inlineNormal,\n emStrongLDelim: emStrongLDelimPedantic,\n emStrongRDelimAst: emStrongRDelimAstPedantic,\n emStrongRDelimUnd: emStrongRDelimUndPedantic,\n link: edit(/^!?\\[(label)\\]\\((.*?)\\)/)\n .replace('label', _inlineLabel)\n .getRegex(),\n reflink: edit(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/)\n .replace('label', _inlineLabel)\n .getRegex(),\n};\n\n/**\n * GFM Inline Grammar\n */\n\nconst inlineGfm: Record<InlineKeys, RegExp> = {\n ...inlineNormal,\n emStrongRDelimAst: emStrongRDelimAstGfm,\n emStrongLDelim: emStrongLDelimGfm,\n delLDelim,\n delRDelim,\n url: edit(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/)\n .replace('protocol', _caseInsensitiveProtocol)\n .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)\n .getRegex(),\n _backpedal: /(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,\n del: /^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,\n text: edit(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|protocol:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)))/)\n .replace('protocol', _caseInsensitiveProtocol)\n .getRegex(),\n};\n\n/**\n * GFM + Line Breaks Inline Grammar\n */\n\nconst inlineBreaks: Record<InlineKeys, RegExp> = {\n ...inlineGfm,\n br: edit(br).replace('{2,}', '*').getRegex(),\n text: edit(inlineGfm.text)\n .replace('\\\\b_', '\\\\b_| {2,}\\\\n')\n .replace(/\\{2,\\}/g, '*')\n .getRegex(),\n};\n\n/**\n * exports\n */\n\nexport const block = {\n normal: blockNormal,\n gfm: blockGfm,\n pedantic: blockPedantic,\n};\n\nexport const inline = {\n normal: inlineNormal,\n gfm: inlineGfm,\n breaks: inlineBreaks,\n pedantic: inlinePedantic,\n};\n\nexport interface Rules {\n other: typeof other\n block: Record<BlockKeys, RegExp>\n inline: Record<InlineKeys, RegExp>\n}\n", "import { other } from './rules.ts';\n\n/**\n * Helpers\n */\nconst escapeReplacements: { [index: string]: string } = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\nconst getEscapeReplacement = (ch: string) => escapeReplacements[ch];\n\nexport function escapeHtmlEntities(html: string, encode?: boolean) {\n if (encode) {\n if (other.escapeTest.test(html)) {\n return html.replace(other.escapeReplace, getEscapeReplacement);\n }\n } else {\n if (other.escapeTestNoEncode.test(html)) {\n return html.replace(other.escapeReplaceNoEncode, getEscapeReplacement);\n }\n }\n\n return html;\n}\n\nexport function cleanUrl(href: string) {\n try {\n href = encodeURI(href).replace(other.percentDecode, '%');\n } catch {\n return null;\n }\n return href;\n}\n\nexport function splitCells(tableRow: string, count?: number) {\n // ensure that every cell-delimiting pipe has a space\n // before it to distinguish it from an escaped pipe\n const row = tableRow.replace(other.findPipe, (match, offset, str) => {\n let escaped = false;\n let curr = offset;\n while (--curr >= 0 && str[curr] === '\\\\') escaped = !escaped;\n if (escaped) {\n // odd number of slashes means | is escaped\n // so we leave it alone\n return '|';\n } else {\n // add space before unescaped |\n return ' |';\n }\n }),\n cells = row.split(other.splitPipe);\n let i = 0;\n\n // First/last cell in a row cannot be empty if it has no leading/trailing pipe\n if (!cells[0].trim()) {\n cells.shift();\n }\n if (cells.length > 0 && !cells.at(-1)?.trim()) {\n cells.pop();\n }\n\n if (count) {\n if (cells.length > count) {\n cells.splice(count);\n } else {\n while (cells.length < count) cells.push('');\n }\n }\n\n for (; i < cells.length; i++) {\n // leading or trailing whitespace is ignored per the gfm spec\n cells[i] = cells[i].trim().replace(other.slashPipe, '|');\n }\n return cells;\n}\n\n/**\n * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').\n * /c*$/ is vulnerable to REDOS.\n *\n * @param str\n * @param c\n * @param invert Remove suffix of non-c chars instead. Default falsey.\n */\nexport function rtrim(str: string, c: string, invert?: boolean) {\n const l = str.length;\n if (l === 0) {\n return '';\n }\n\n // Length of suffix matching the invert condition.\n let suffLen = 0;\n\n // Step left until we fail to match the invert condition.\n while (suffLen < l) {\n const currChar = str.charAt(l - suffLen - 1);\n if (currChar === c && !invert) {\n suffLen++;\n } else if (currChar !== c && invert) {\n suffLen++;\n } else {\n break;\n }\n }\n\n return str.slice(0, l - suffLen);\n}\n\nexport function trimTrailingBlankLines(str: string) {\n const lines = str.split('\\n');\n let end = lines.length - 1;\n while (end >= 0 && other.blankLine.test(lines[end])) {\n end--;\n }\n if (lines.length - end <= 2) {\n // we want to keep single trailing blank lines\n return str;\n }\n\n return lines.slice(0, end + 1).join('\\n');\n}\n\nexport function findClosingBracket(str: string, b: string) {\n if (str.indexOf(b[1]) === -1) {\n return -1;\n }\n\n let level = 0;\n for (let i = 0; i < str.length; i++) {\n if (str[i] === '\\\\') {\n i++;\n } else if (str[i] === b[0]) {\n level++;\n } else if (str[i] === b[1]) {\n level--;\n if (level < 0) {\n return i;\n }\n }\n }\n if (level > 0) {\n return -2;\n }\n\n return -1;\n}\n\nexport function expandTabs(line: string, indent = 0) {\n let col = indent;\n let expanded = '';\n for (const char of line) {\n if (char === '\\t') {\n const added = 4 - (col % 4);\n expanded += ' '.repeat(added);\n col += added;\n } else {\n expanded += char;\n col++;\n }\n }\n\n return expanded;\n}\n", "import { _defaults } from './defaults.ts';\nimport {\n rtrim,\n splitCells,\n findClosingBracket,\n expandTabs,\n trimTrailingBlankLines,\n} from './helpers.ts';\nimport type { Rules } from './rules.ts';\nimport type { _Lexer } from './Lexer.ts';\nimport type { Links, Tokens, Token } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\nfunction outputLink(cap: string[], link: Pick<Tokens.Link, 'href' | 'title'>, raw: string, lexer: _Lexer, rules: Rules): Tokens.Link | Tokens.Image {\n const href = link.href;\n const title = link.title || null;\n const text = cap[1].replace(rules.other.outputLinkReplace, '$1');\n\n lexer.state.inLink = true;\n const token: Tokens.Link | Tokens.Image = {\n type: cap[0].charAt(0) === '!' ? 'image' : 'link',\n raw,\n href,\n title,\n text,\n tokens: lexer.inlineTokens(text),\n };\n lexer.state.inLink = false;\n return token;\n}\n\nfunction indentCodeCompensation(raw: string, text: string, rules: Rules) {\n const matchIndentToCode = raw.match(rules.other.indentCodeCompensation);\n\n if (matchIndentToCode === null) {\n return text;\n }\n\n const indentToCode = matchIndentToCode[1];\n\n return text\n .split('\\n')\n .map(node => {\n const matchIndentInNode = node.match(rules.other.beginningSpace);\n if (matchIndentInNode === null) {\n return node;\n }\n\n const [indentInNode] = matchIndentInNode;\n\n if (indentInNode.length >= indentToCode.length) {\n return node.slice(indentToCode.length);\n }\n\n return node;\n })\n .join('\\n');\n}\n\n/**\n * Tokenizer\n */\nexport class _Tokenizer<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n rules!: Rules; // set by the lexer\n lexer!: _Lexer<ParserOutput, RendererOutput>; // set by the lexer\n\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n }\n\n space(src: string): Tokens.Space | undefined {\n const cap = this.rules.block.newline.exec(src);\n if (cap && cap[0].length > 0) {\n return {\n type: 'space',\n raw: cap[0],\n };\n }\n }\n\n code(src: string): Tokens.Code | undefined {\n const cap = this.rules.block.code.exec(src);\n if (cap) {\n const raw = this.options.pedantic\n ? cap[0]\n : trimTrailingBlankLines(cap[0]);\n const text = raw.replace(this.rules.other.codeRemoveIndent, '');\n return {\n type: 'code',\n raw,\n codeBlockStyle: 'indented',\n text,\n };\n }\n }\n\n fences(src: string): Tokens.Code | undefined {\n const cap = this.rules.block.fences.exec(src);\n if (cap) {\n const raw = cap[0];\n const text = indentCodeCompensation(raw, cap[3] || '', this.rules);\n\n return {\n type: 'code',\n raw,\n lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],\n text,\n };\n }\n }\n\n heading(src: string): Tokens.Heading | undefined {\n const cap = this.rules.block.heading.exec(src);\n if (cap) {\n let text = cap[2].trim();\n\n // remove trailing #s\n if (this.rules.other.endingHash.test(text)) {\n const trimmed = rtrim(text, '#');\n if (this.options.pedantic) {\n text = trimmed.trim();\n } else if (!trimmed || this.rules.other.endingSpaceChar.test(trimmed)) {\n // CommonMark requires space before trailing #s\n text = trimmed.trim();\n }\n }\n\n return {\n type: 'heading',\n raw: rtrim(cap[0], '\\n'),\n depth: cap[1].length,\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n hr(src: string): Tokens.Hr | undefined {\n const cap = this.rules.block.hr.exec(src);\n if (cap) {\n return {\n type: 'hr',\n raw: rtrim(cap[0], '\\n'),\n };\n }\n }\n\n blockquote(src: string): Tokens.Blockquote | undefined {\n const cap = this.rules.block.blockquote.exec(src);\n if (cap) {\n let lines = rtrim(cap[0], '\\n').split('\\n');\n let raw = '';\n let text = '';\n const tokens: Token[] = [];\n\n while (lines.length > 0) {\n let inBlockquote = false;\n const currentLines = [];\n\n let i;\n for (i = 0; i < lines.length; i++) {\n // get lines up to a continuation\n if (this.rules.other.blockquoteStart.test(lines[i])) {\n currentLines.push(lines[i]);\n inBlockquote = true;\n } else if (!inBlockquote) {\n currentLines.push(lines[i]);\n } else {\n break;\n }\n }\n lines = lines.slice(i);\n\n const currentRaw = currentLines.join('\\n');\n const currentText = currentRaw\n // precede setext continuation with 4 spaces so it isn't a setext\n .replace(this.rules.other.blockquoteSetextReplace, '\\n $1')\n .replace(this.rules.other.blockquoteSetextReplace2, '');\n raw = raw ? `${raw}\\n${currentRaw}` : currentRaw;\n text = text ? `${text}\\n${currentText}` : currentText;\n\n // parse blockquote lines as top level tokens\n // merge paragraphs if this is a continuation\n const top = this.lexer.state.top;\n this.lexer.state.top = true;\n this.lexer.blockTokens(currentText, tokens, true);\n this.lexer.state.top = top;\n\n // if there is no continuation then we are done\n if (lines.length === 0) {\n break;\n }\n\n const lastToken = tokens.at(-1);\n\n if (lastToken?.type === 'code') {\n // blockquote continuation cannot be preceded by a code block\n break;\n } else if (lastToken?.type === 'blockquote') {\n // include continuation in nested blockquote\n const oldToken = lastToken as Tokens.Blockquote;\n // The continuation lines belong to the same nesting frame as the\n // nested blockquote, which already had one '>' marker stripped, so\n // strip one marker from them too. Otherwise a restated marker after a\n // lazy line is re-parsed as a spurious deeper blockquote.\n const continuation = lines.join('\\n');\n const newText = oldToken.raw + '\\n' + continuation.replace(this.rules.other.blockquoteSetextReplace2, '');\n const newToken = this.blockquote(newText)!;\n tokens[tokens.length - 1] = newToken;\n\n raw = `${raw}\\n${continuation}`;\n text = text.substring(0, text.length - oldToken.text.length) + newToken.text;\n break;\n } else if (lastToken?.type === 'list') {\n // include continuation in nested list\n const oldToken = lastToken as Tokens.List;\n const newText = oldToken.raw + '\\n' + lines.join('\\n');\n const newToken = this.list(newText)!;\n tokens[tokens.length - 1] = newToken;\n\n raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;\n text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;\n lines = newText.substring(tokens.at(-1)!.raw.length).split('\\n');\n continue;\n }\n }\n\n return {\n type: 'blockquote',\n raw,\n tokens,\n text,\n };\n }\n }\n\n list(src: string): Tokens.List | undefined {\n let cap = this.rules.block.list.exec(src);\n if (cap) {\n let bull = cap[1].trim();\n const isordered = bull.length > 1;\n\n const list: Tokens.List = {\n type: 'list',\n raw: '',\n ordered: isordered,\n start: isordered ? +bull.slice(0, -1) : '',\n loose: false,\n items: [],\n };\n\n bull = isordered ? `\\\\d{1,9}\\\\${bull.slice(-1)}` : `\\\\${bull}`;\n\n if (this.options.pedantic) {\n bull = isordered ? bull : '[*+-]';\n }\n\n // Get next list item\n const itemRegex = this.rules.other.listItemRegex(bull);\n let endsWithBlankLine = false;\n // Check if current bullet point can start a new List Item\n while (src) {\n let endEarly = false;\n let raw = '';\n let itemContents = '';\n if (!(cap = itemRegex.exec(src))) {\n break;\n }\n\n if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)\n break;\n }\n\n raw = cap[0];\n src = src.substring(raw.length);\n\n let line = expandTabs(cap[2].split('\\n', 1)[0], cap[1].length);\n let nextLine = src.split('\\n', 1)[0];\n let blankLine = !line.trim();\n\n let indent = 0;\n if (this.options.pedantic) {\n indent = 2;\n itemContents = line.trimStart();\n } else if (blankLine) {\n indent = cap[1].length + 1;\n } else {\n indent = line.search(this.rules.other.nonSpaceChar); // Find first non-space char\n indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent\n itemContents = line.slice(indent);\n indent += cap[1].length;\n }\n\n if (blankLine && this.rules.other.blankLine.test(nextLine)) { // Items begin with at most one blank line\n raw += nextLine + '\\n';\n src = src.substring(nextLine.length + 1);\n endEarly = true;\n }\n\n if (!endEarly) {\n const nextBulletRegex = this.rules.other.nextBulletRegex(indent);\n const hrRegex = this.rules.other.hrRegex(indent);\n const fencesBeginRegex = this.rules.other.fencesBeginRegex(indent);\n const headingBeginRegex = this.rules.other.headingBeginRegex(indent);\n const htmlBeginRegex = this.rules.other.htmlBeginRegex(indent);\n const blockquoteBeginRegex = this.rules.other.blockquoteBeginRegex(indent);\n\n // Check if following lines should be included in List Item\n while (src) {\n const rawLine = src.split('\\n', 1)[0];\n let nextLineWithoutTabs;\n nextLine = rawLine;\n\n // Re-align to follow commonmark nesting rules\n if (this.options.pedantic) {\n nextLine = nextLine.replace(this.rules.other.listReplaceNesting, ' ');\n nextLineWithoutTabs = nextLine;\n } else {\n nextLineWithoutTabs = nextLine.replace(this.rules.other.tabCharGlobal, ' ');\n }\n\n // End list item if found code fences\n if (fencesBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of new heading\n if (headingBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of html block\n if (htmlBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of blockquote\n if (blockquoteBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of new bullet\n if (nextBulletRegex.test(nextLine)) {\n break;\n }\n\n // Horizontal rule found\n if (hrRegex.test(nextLine)) {\n break;\n }\n\n if (nextLineWithoutTabs.search(this.rules.other.nonSpaceChar) >= indent || !nextLine.trim()) { // Dedent if possible\n itemContents += '\\n' + nextLineWithoutTabs.slice(indent);\n } else {\n // not enough indentation\n if (blankLine) {\n break;\n }\n\n // paragraph continuation unless last line was a different block level element\n if (line.replace(this.rules.other.tabCharGlobal, ' ').search(this.rules.other.nonSpaceChar) >= 4) { // indented code block\n break;\n }\n if (fencesBeginRegex.test(line)) {\n break;\n }\n if (headingBeginRegex.test(line)) {\n break;\n }\n if (hrRegex.test(line)) {\n break;\n }\n\n itemContents += '\\n' + nextLine;\n }\n\n blankLine = !nextLine.trim();\n\n raw += rawLine + '\\n';\n src = src.substring(rawLine.length + 1);\n line = nextLineWithoutTabs.slice(indent);\n }\n }\n\n if (!list.loose) {\n // If the previous item ended with a blank line, the list is loose\n if (endsWithBlankLine) {\n list.loose = true;\n } else if (this.rules.other.doubleBlankLine.test(raw)) {\n endsWithBlankLine = true;\n }\n }\n\n list.items.push({\n type: 'list_item',\n raw,\n task: !!this.options.gfm && this.rules.other.listIsTask.test(itemContents),\n loose: false,\n text: itemContents,\n tokens: [],\n });\n\n list.raw += raw;\n }\n\n // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic\n const lastItem = list.items.at(-1);\n if (lastItem) {\n lastItem.raw = lastItem.raw.trimEnd();\n lastItem.text = lastItem.text.trimEnd();\n } else {\n // not a list since there were no items\n return;\n }\n list.raw = list.raw.trimEnd();\n\n // Item child tokens handled here at end because we needed to have the final item to trim it first\n for (const item of list.items) {\n this.lexer.state.top = false;\n item.tokens = this.lexer.blockTokens(item.text, []);\n const itemToken = item.tokens[0];\n if (item.task && (itemToken?.type === 'text' || itemToken?.type === 'paragraph')) {\n // Remove checkbox markdown from item tokens\n item.text = item.text.replace(this.rules.other.listReplaceTask, '');\n itemToken.raw = itemToken.raw.replace(this.rules.other.listReplaceTask, '');\n itemToken.text = itemToken.text.replace(this.rules.other.listReplaceTask, '');\n for (let i = this.lexer.inlineQueue.length - 1; i >= 0; i--) {\n if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[i].src)) {\n this.lexer.inlineQueue[i].src = this.lexer.inlineQueue[i].src.replace(this.rules.other.listReplaceTask, '');\n break;\n }\n }\n\n const taskRaw = this.rules.other.listTaskCheckbox.exec(item.raw);\n if (taskRaw) {\n const checkboxToken: Tokens.Checkbox = {\n type: 'checkbox',\n raw: taskRaw[0] + ' ',\n checked: taskRaw[0] !== '[ ]',\n };\n item.checked = checkboxToken.checked;\n if (list.loose) {\n if (item.tokens[0] && ['paragraph', 'text'].includes(item.tokens[0].type) && 'tokens' in item.tokens[0] && item.tokens[0].tokens) {\n item.tokens[0].raw = checkboxToken.raw + item.tokens[0].raw;\n item.tokens[0].text = checkboxToken.raw + item.tokens[0].text;\n item.tokens[0].tokens.unshift(checkboxToken);\n } else {\n item.tokens.unshift({\n type: 'paragraph',\n raw: checkboxToken.raw,\n text: checkboxToken.raw,\n tokens: [checkboxToken],\n });\n }\n } else {\n item.tokens.unshift(checkboxToken);\n }\n }\n } else if (item.task) {\n item.task = false;\n }\n\n if (!list.loose) {\n // Check if list should be loose\n const spacers = item.tokens.filter(t => t.type === 'space');\n const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => this.rules.other.anyLine.test(t.raw));\n\n list.loose = hasMultipleLineBreaks;\n }\n }\n\n // Set all items to loose if list is loose\n if (list.loose) {\n for (const item of list.items) {\n item.loose = true;\n for (const token of item.tokens) {\n if (token.type === 'text') {\n token.type = 'paragraph';\n }\n }\n }\n }\n\n return list;\n }\n }\n\n html(src: string): Tokens.HTML | undefined {\n const cap = this.rules.block.html.exec(src);\n if (cap) {\n const raw = trimTrailingBlankLines(cap[0]);\n const token: Tokens.HTML = {\n type: 'html',\n block: true,\n raw,\n pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',\n text: raw,\n };\n return token;\n }\n }\n\n def(src: string): Tokens.Def | undefined {\n const cap = this.rules.block.def.exec(src);\n if (cap) {\n const tag = cap[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, ' ');\n const href = cap[2] ? cap[2].replace(this.rules.other.hrefBrackets, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';\n const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];\n return {\n type: 'def',\n tag,\n raw: rtrim(cap[0], '\\n'),\n href,\n title,\n };\n }\n }\n\n table(src: string): Tokens.Table | undefined {\n const cap = this.rules.block.table.exec(src);\n if (!cap) {\n return;\n }\n\n if (!this.rules.other.tableDelimiter.test(cap[2])) {\n // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading\n return;\n }\n\n const headers = splitCells(cap[1]);\n const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');\n const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\\n') : [];\n\n const item: Tokens.Table = {\n type: 'table',\n raw: rtrim(cap[0], '\\n'),\n header: [],\n align: [],\n rows: [],\n };\n\n if (headers.length !== aligns.length) {\n // header and align columns must be equal, rows can be different.\n return;\n }\n\n for (const align of aligns) {\n if (this.rules.other.tableAlignRight.test(align)) {\n item.align.push('right');\n } else if (this.rules.other.tableAlignCenter.test(align)) {\n item.align.push('center');\n } else if (this.rules.other.tableAlignLeft.test(align)) {\n item.align.push('left');\n } else {\n item.align.push(null);\n }\n }\n\n for (let i = 0; i < headers.length; i++) {\n item.header.push({\n text: headers[i],\n tokens: this.lexer.inline(headers[i]),\n header: true,\n align: item.align[i],\n });\n }\n\n for (const row of rows) {\n item.rows.push(splitCells(row, item.header.length).map((cell, i) => {\n return {\n text: cell,\n tokens: this.lexer.inline(cell),\n header: false,\n align: item.align[i],\n };\n }));\n }\n\n return item;\n }\n\n lheading(src: string): Tokens.Heading | undefined {\n const cap = this.rules.block.lheading.exec(src);\n if (cap) {\n const text = cap[1].trim();\n return {\n type: 'heading',\n raw: rtrim(cap[0], '\\n'),\n depth: cap[2].charAt(0) === '=' ? 1 : 2,\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n paragraph(src: string): Tokens.Paragraph | undefined {\n const cap = this.rules.block.paragraph.exec(src);\n if (cap) {\n const text = cap[1].charAt(cap[1].length - 1) === '\\n'\n ? cap[1].slice(0, -1)\n : cap[1];\n return {\n type: 'paragraph',\n raw: cap[0],\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n text(src: string): Tokens.Text | undefined {\n const cap = this.rules.block.text.exec(src);\n if (cap) {\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n tokens: this.lexer.inline(cap[0]),\n };\n }\n }\n\n escape(src: string): Tokens.Escape | undefined {\n const cap = this.rules.inline.escape.exec(src);\n if (cap) {\n return {\n type: 'escape',\n raw: cap[0],\n text: cap[1],\n };\n }\n }\n\n tag(src: string): Tokens.Tag | undefined {\n const cap = this.rules.inline.tag.exec(src);\n if (cap) {\n if (!this.lexer.state.inLink && this.rules.other.startATag.test(cap[0])) {\n this.lexer.state.inLink = true;\n } else if (this.lexer.state.inLink && this.rules.other.endATag.test(cap[0])) {\n this.lexer.state.inLink = false;\n }\n if (!this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(cap[0])) {\n this.lexer.state.inRawBlock = true;\n } else if (this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(cap[0])) {\n this.lexer.state.inRawBlock = false;\n }\n\n return {\n type: 'html',\n raw: cap[0],\n inLink: this.lexer.state.inLink,\n inRawBlock: this.lexer.state.inRawBlock,\n block: false,\n text: cap[0],\n };\n }\n }\n\n link(src: string): Tokens.Link | Tokens.Image | undefined {\n const cap = this.rules.inline.link.exec(src);\n if (cap) {\n const trimmedUrl = cap[2].trim();\n if (!this.options.pedantic && this.rules.other.startAngleBracket.test(trimmedUrl)) {\n // commonmark requires matching angle brackets\n if (!(this.rules.other.endAngleBracket.test(trimmedUrl))) {\n return;\n }\n\n // ending angle bracket cannot be escaped\n const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\\\');\n if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {\n return;\n }\n } else {\n // find closing parenthesis\n const lastParenIndex = findClosingBracket(cap[2], '()');\n if (lastParenIndex === -2) {\n // more open parens than closed\n return;\n }\n\n if (lastParenIndex > -1) {\n const start = cap[0].indexOf('!') === 0 ? 5 : 4;\n const linkLen = start + cap[1].length + lastParenIndex;\n cap[2] = cap[2].substring(0, lastParenIndex);\n cap[0] = cap[0].substring(0, linkLen).trim();\n cap[3] = '';\n }\n }\n let href = cap[2];\n let title = '';\n if (this.options.pedantic) {\n // split pedantic href and title\n const link = this.rules.other.pedanticHrefTitle.exec(href);\n\n if (link) {\n href = link[1];\n title = link[3];\n }\n } else {\n title = cap[3] ? cap[3].slice(1, -1) : '';\n }\n\n href = href.trim();\n if (this.rules.other.startAngleBracket.test(href)) {\n if (this.options.pedantic && !(this.rules.other.endAngleBracket.test(trimmedUrl))) {\n // pedantic allows starting angle bracket without ending angle bracket\n href = href.slice(1);\n } else {\n href = href.slice(1, -1);\n }\n }\n return outputLink(cap, {\n href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,\n title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title,\n }, cap[0], this.lexer, this.rules);\n }\n }\n\n reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined {\n let cap;\n if ((cap = this.rules.inline.reflink.exec(src))\n || (cap = this.rules.inline.nolink.exec(src))) {\n const linkString = (cap[2] || cap[1]).replace(this.rules.other.multipleSpaceGlobal, ' ');\n const link = links[linkString.toLowerCase()];\n if (!link) {\n const text = cap[0].charAt(0);\n return {\n type: 'text',\n raw: text,\n text,\n };\n }\n return outputLink(cap, link, cap[0], this.lexer, this.rules);\n }\n }\n\n emStrong(src: string, maskedSrc: string, prevChar = ''): Tokens.Em | Tokens.Strong | undefined {\n let match = this.rules.inline.emStrongLDelim.exec(src);\n if (!match) return;\n if (!match[1] && !match[2] && !match[3] && !match[4]) return;\n\n // _ can't be between two alphanumerics. \\p{L}\\p{N} includes non-english alphabet/numbers as well\n if (match[4] && prevChar.match(this.rules.other.unicodeAlphaNumeric)) return;\n\n const nextChar = match[1] || match[3] || '';\n\n if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)\n const lLength = [...match[0]].length - 1;\n let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;\n\n const delimChar = match[0][0];\n // A mid-run opener (for example the second star of an unmatched `**`) must\n // only pair with a delimiter that can only close, otherwise it steals the\n // opener of a later span (`**a*b*c` must be `**a<em>b</em>c`).\n const midRun = prevChar === delimChar;\n const endReg = delimChar === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;\n endReg.lastIndex = 0;\n\n // Clip maskedSrc to same section of string as src (move to lexer?)\n maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n\n while ((match = endReg.exec(maskedSrc)) !== null) {\n rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n\n if (!rDelim) continue; // skip single * in __abc*abc__\n\n rLength = [...rDelim].length;\n\n if (match[3] || match[4]) { // found another Left Delim\n delimTotal += rLength;\n continue;\n } else if (match[5] || match[6]) { // either Left or Right Delim\n if (lLength % 3 && !((lLength + rLength) % 3)) {\n midDelimTotal += rLength;\n continue; // CommonMark Emphasis Rules 9-10\n }\n if (midRun) {\n // A mid-run opener cannot close against an ambiguous delimiter that\n // can also open; that delimiter opens its own emphasis span instead.\n break;\n }\n }\n\n delimTotal -= rLength;\n\n if (delimTotal > 0) continue; // Haven't found enough closing delimiters\n\n // Remove extra characters. *a*** -> *a*\n rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);\n // char length can be >1 for unicode characters;\n const lastCharLength = [...match[0]][0].length;\n const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n\n // Create `em` if smallest delimiter has odd char count. *a***\n if (Math.min(lLength, rLength) % 2) {\n const text = raw.slice(1, -1);\n return {\n type: 'em',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n\n // Create 'strong' if smallest delimiter has even char count. **a***\n const text = raw.slice(2, -2);\n return {\n type: 'strong',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n }\n }\n\n codespan(src: string): Tokens.Codespan | undefined {\n const cap = this.rules.inline.code.exec(src);\n if (cap) {\n let text = cap[2].replace(this.rules.other.newLineCharGlobal, ' ');\n const hasNonSpaceChars = this.rules.other.nonSpaceChar.test(text);\n const hasSpaceCharsOnBothEnds = this.rules.other.startingSpaceChar.test(text) && this.rules.other.endingSpaceChar.test(text);\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n return {\n type: 'codespan',\n raw: cap[0],\n text,\n };\n }\n }\n\n br(src: string): Tokens.Br | undefined {\n const cap = this.rules.inline.br.exec(src);\n if (cap) {\n return {\n type: 'br',\n raw: cap[0],\n };\n }\n }\n\n del(src: string, maskedSrc: string, prevChar = ''): Tokens.Del | undefined {\n let match = this.rules.inline.delLDelim.exec(src);\n if (!match) return;\n\n const nextChar = match[1] || '';\n\n if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n // unicode Regex counts emoji as 1 char; spread into array for proper count\n const lLength = [...match[0]].length - 1;\n let rDelim, rLength, delimTotal = lLength;\n\n const endReg = this.rules.inline.delRDelim;\n endReg.lastIndex = 0;\n\n // Clip maskedSrc to same section of string as src\n maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n\n while ((match = endReg.exec(maskedSrc)) !== null) {\n rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n\n if (!rDelim) continue;\n\n rLength = [...rDelim].length;\n\n if (rLength !== lLength) continue;\n\n if (match[3] || match[4]) { // found another Left Delim\n delimTotal += rLength;\n continue;\n }\n\n delimTotal -= rLength;\n\n if (delimTotal > 0) continue; // Haven't found enough closing delimiters\n\n // Remove extra characters\n rLength = Math.min(rLength, rLength + delimTotal);\n // char length can be >1 for unicode characters\n const lastCharLength = [...match[0]][0].length;\n const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n\n // Create del token - only single ~ or double ~~ supported\n const text = raw.slice(lLength, -lLength);\n return {\n type: 'del',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n }\n }\n\n autolink(src: string): Tokens.Link | undefined {\n const cap = this.rules.inline.autolink.exec(src);\n if (cap) {\n let text, href;\n if (cap[2] === '@') {\n text = cap[1];\n href = 'mailto:' + text;\n } else {\n text = cap[1];\n href = text;\n }\n\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text,\n },\n ],\n };\n }\n }\n\n url(src: string): Tokens.Link | undefined {\n let cap;\n if (cap = this.rules.inline.url.exec(src)) {\n let text, href;\n if (cap[2] === '@') {\n text = cap[0];\n href = 'mailto:' + text;\n } else {\n // do extended autolink path validation\n let prevCapZero;\n do {\n prevCapZero = cap[0];\n cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';\n } while (prevCapZero !== cap[0]);\n text = cap[0];\n if (cap[1] === 'www.') {\n href = 'http://' + cap[0];\n } else {\n href = cap[0];\n }\n }\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text,\n },\n ],\n };\n }\n }\n\n inlineText(src: string): Tokens.Text | undefined {\n const cap = this.rules.inline.text.exec(src);\n if (cap) {\n const escaped = this.lexer.state.inRawBlock;\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n escaped,\n };\n }\n }\n}\n", "import { _Tokenizer } from './Tokenizer.ts';\nimport { _defaults } from './defaults.ts';\nimport { other, block, inline } from './rules.ts';\nimport type { Token, TokensList, Tokens } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Block Lexer\n */\nexport class _Lexer<ParserOutput = string, RendererOutput = string> {\n tokens: TokensList;\n options: MarkedOptions<ParserOutput, RendererOutput>;\n state: {\n inLink: boolean;\n inRawBlock: boolean;\n top: boolean;\n };\n\n public inlineQueue: { src: string, tokens: Token[] }[];\n\n private tokenizer: _Tokenizer<ParserOutput, RendererOutput>;\n\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n // TokenList cannot be created in one go\n this.tokens = [] as unknown as TokensList;\n this.tokens.links = Object.create(null);\n this.options = options || _defaults;\n this.options.tokenizer = this.options.tokenizer || new _Tokenizer<ParserOutput, RendererOutput>();\n this.tokenizer = this.options.tokenizer;\n this.tokenizer.options = this.options;\n this.tokenizer.lexer = this;\n this.inlineQueue = [];\n this.state = {\n inLink: false,\n inRawBlock: false,\n top: true,\n };\n\n const rules = {\n other,\n block: block.normal,\n inline: inline.normal,\n };\n\n if (this.options.pedantic) {\n rules.block = block.pedantic;\n rules.inline = inline.pedantic;\n } else if (this.options.gfm) {\n rules.block = block.gfm;\n if (this.options.breaks) {\n rules.inline = inline.breaks;\n } else {\n rules.inline = inline.gfm;\n }\n }\n this.tokenizer.rules = rules;\n }\n\n /**\n * Expose Rules\n */\n static get rules() {\n return {\n block,\n inline,\n };\n }\n\n /**\n * Static Lex Method\n */\n static lex<ParserOutput = string, RendererOutput = string>(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const lexer = new _Lexer<ParserOutput, RendererOutput>(options);\n return lexer.lex(src);\n }\n\n /**\n * Static Lex Inline Method\n */\n static lexInline<ParserOutput = string, RendererOutput = string>(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const lexer = new _Lexer<ParserOutput, RendererOutput>(options);\n return lexer.inlineTokens(src);\n }\n\n /**\n * Preprocessing\n */\n lex(src: string) {\n src = src.replace(other.carriageReturn, '\\n');\n\n this.blockTokens(src, this.tokens);\n\n for (let i = 0; i < this.inlineQueue.length; i++) {\n const next = this.inlineQueue[i];\n this.inlineTokens(next.src, next.tokens);\n }\n this.inlineQueue = [];\n\n return this.tokens;\n }\n\n /**\n * Lexing\n */\n blockTokens(src: string, tokens?: Token[], lastParagraphClipped?: boolean): Token[];\n blockTokens(src: string, tokens?: TokensList, lastParagraphClipped?: boolean): TokensList;\n blockTokens(src: string, tokens: Token[] = [], lastParagraphClipped = false) {\n this.tokenizer.lexer = this;\n if (this.options.pedantic) {\n src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');\n }\n\n let srcLength = Infinity;\n while (src) {\n if (src.length < srcLength) {\n srcLength = src.length;\n } else {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n\n let token: Tokens.Generic | undefined;\n\n if (this.options.extensions?.block?.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n\n // newline\n if (token = this.tokenizer.space(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (token.raw.length === 1 && lastToken !== undefined) {\n // if there's a single \\n as a spacer, it's terminating the last line,\n // so move it there so that we don't get unnecessary paragraph tags\n lastToken.raw += '\\n';\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // code\n if (token = this.tokenizer.code(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n // An indented code block cannot interrupt a paragraph.\n if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // fences\n if (token = this.tokenizer.fences(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // heading\n if (token = this.tokenizer.heading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // hr\n if (token = this.tokenizer.hr(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // blockquote\n if (token = this.tokenizer.blockquote(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // list\n if (token = this.tokenizer.list(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // html\n if (token = this.tokenizer.html(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // def\n if (token = this.tokenizer.def(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.raw;\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else if (!this.tokens.links[token.tag]) {\n this.tokens.links[token.tag] = {\n href: token.href,\n title: token.title,\n };\n tokens.push(token);\n }\n continue;\n }\n\n // table (gfm)\n if (token = this.tokenizer.table(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // lheading\n if (token = this.tokenizer.lheading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // top-level paragraph\n // prevent paragraph consuming extensions by clipping 'src' to extension start\n let cutSrc = src;\n if (this.options.extensions?.startBlock) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startBlock.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {\n const lastToken = tokens.at(-1);\n if (lastParagraphClipped && lastToken?.type === 'paragraph') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n lastParagraphClipped = cutSrc.length !== src.length;\n src = src.substring(token.raw.length);\n continue;\n }\n\n // text\n if (token = this.tokenizer.text(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n if (src) {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n }\n\n this.state.top = true;\n return tokens;\n }\n\n inline(src: string, tokens: Token[] = []) {\n this.inlineQueue.push({ src, tokens });\n return tokens;\n }\n\n /**\n * Lexing/Compiling\n */\n inlineTokens(src: string, tokens: Token[] = []): Token[] {\n this.tokenizer.lexer = this;\n // String with links masked to avoid interference with em and strong\n let maskedSrc = src;\n\n // Mask out reflinks\n if (this.tokens.links) {\n const links = Object.keys(this.tokens.links);\n if (links.length > 0) {\n maskedSrc = maskedSrc.replace(this.tokenizer.rules.inline.reflinkSearch, match0 =>\n links.includes(match0.slice(match0.lastIndexOf('[') + 1, -1))\n ? '[' + 'a'.repeat(match0.length - 2) + ']'\n : match0);\n }\n }\n\n // Mask out escaped characters\n maskedSrc = maskedSrc.replace(this.tokenizer.rules.inline.anyPunctuation, '++');\n\n // Mask out other blocks\n maskedSrc = maskedSrc.replace(this.tokenizer.rules.inline.blockSkip, (match0, _link, context) => {\n const offset = context ? context.length : 0;\n return match0.slice(0, offset) + '[' + 'a'.repeat(match0.length - offset - 2) + ']';\n });\n\n // Mask out blocks from extensions\n maskedSrc = this.options.hooks?.emStrongMask?.call({ lexer: this }, maskedSrc) ?? maskedSrc;\n\n let keepPrevChar = false;\n let prevChar = '';\n let srcLength = Infinity;\n while (src) {\n if (src.length < srcLength) {\n srcLength = src.length;\n } else {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n\n if (!keepPrevChar) {\n prevChar = '';\n }\n keepPrevChar = false;\n\n let token: Tokens.Generic | undefined;\n\n // extensions\n if (this.options.extensions?.inline?.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n\n // escape\n if (token = this.tokenizer.escape(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // tag\n if (token = this.tokenizer.tag(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // link\n if (token = this.tokenizer.link(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // reflink, nolink\n if (token = this.tokenizer.reflink(src, this.tokens.links)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (token.type === 'text' && lastToken?.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // em & strong\n if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // code\n if (token = this.tokenizer.codespan(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // br\n if (token = this.tokenizer.br(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // del (gfm)\n if (token = this.tokenizer.del(src, maskedSrc, prevChar)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // autolink\n if (token = this.tokenizer.autolink(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // url (gfm)\n if (!this.state.inLink && (token = this.tokenizer.url(src))) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // text\n // prevent inlineText consuming extensions by clipping 'src' to extension start\n let cutSrc = src;\n if (this.options.extensions?.startInline) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startInline.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (token = this.tokenizer.inlineText(cutSrc)) {\n src = src.substring(token.raw.length);\n if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started\n prevChar = token.raw.slice(-1);\n }\n keepPrevChar = true;\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n if (src) {\n this.infiniteLoopError(src.charCodeAt(0));\n break;\n }\n }\n\n return tokens;\n }\n\n private infiniteLoopError(byte: number) {\n const errMsg = 'Infinite loop on byte: ' + byte;\n if (this.options.silent) {\n console.error(errMsg);\n } else {\n throw new Error(errMsg);\n }\n }\n}\n", "import { _defaults } from './defaults.ts';\nimport {\n cleanUrl,\n escapeHtmlEntities,\n} from './helpers.ts';\nimport { other } from './rules.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\nimport type { Tokens } from './Tokens.ts';\nimport type { _Parser } from './Parser.ts';\n\n/**\n * Renderer\n */\nexport class _Renderer<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n parser!: _Parser<ParserOutput, RendererOutput>; // set by the parser\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n }\n\n space(token: Tokens.Space): RendererOutput {\n return '' as RendererOutput;\n }\n\n code({ text, lang, escaped }: Tokens.Code): RendererOutput {\n const langString = (lang || '').match(other.notSpaceStart)?.[0];\n\n const code = text.replace(other.endingNewline, '') + '\\n';\n\n if (!langString) {\n return '<pre><code>'\n + (escaped ? code : escapeHtmlEntities(code, true))\n + '</code></pre>\\n' as RendererOutput;\n }\n\n return '<pre><code class=\"language-'\n + escapeHtmlEntities(langString)\n + '\">'\n + (escaped ? code : escapeHtmlEntities(code, true))\n + '</code></pre>\\n' as RendererOutput;\n }\n\n blockquote({ tokens }: Tokens.Blockquote): RendererOutput {\n const body = this.parser.parse(tokens);\n return `<blockquote>\\n${body}</blockquote>\\n` as RendererOutput;\n }\n\n html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n def(token: Tokens.Def): RendererOutput {\n return '' as RendererOutput;\n }\n\n heading({ tokens, depth }: Tokens.Heading): RendererOutput {\n return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\\n` as RendererOutput;\n }\n\n hr(token: Tokens.Hr): RendererOutput {\n return '<hr>\\n' as RendererOutput;\n }\n\n list(token: Tokens.List): RendererOutput {\n const ordered = token.ordered;\n const start = token.start;\n\n let body = '';\n for (let j = 0; j < token.items.length; j++) {\n const item = token.items[j];\n body += this.listitem(item);\n }\n\n const type = ordered ? 'ol' : 'ul';\n const startAttr = (ordered && start !== 1) ? (' start=\"' + start + '\"') : '';\n return '<' + type + startAttr + '>\\n' + body + '</' + type + '>\\n' as RendererOutput;\n }\n\n listitem(item: Tokens.ListItem): RendererOutput {\n return `<li>${this.parser.parse(item.tokens)}</li>\\n` as RendererOutput;\n }\n\n checkbox({ checked }: Tokens.Checkbox): RendererOutput {\n return '<input '\n + (checked ? 'checked=\"\" ' : '')\n + 'disabled=\"\" type=\"checkbox\"> ' as RendererOutput;\n }\n\n paragraph({ tokens }: Tokens.Paragraph): RendererOutput {\n return `<p>${this.parser.parseInline(tokens)}</p>\\n` as RendererOutput;\n }\n\n table(token: Tokens.Table): RendererOutput {\n let header = '';\n\n // header\n let cell = '';\n for (let j = 0; j < token.header.length; j++) {\n cell += this.tablecell(token.header[j]);\n }\n header += this.tablerow({ text: cell as ParserOutput });\n\n let body = '';\n for (let j = 0; j < token.rows.length; j++) {\n const row = token.rows[j];\n\n cell = '';\n for (let k = 0; k < row.length; k++) {\n cell += this.tablecell(row[k]);\n }\n\n body += this.tablerow({ text: cell as ParserOutput });\n }\n if (body) body = `<tbody>${body}</tbody>`;\n\n return '<table>\\n'\n + '<thead>\\n'\n + header\n + '</thead>\\n'\n + body\n + '</table>\\n' as RendererOutput;\n }\n\n tablerow({ text }: Tokens.TableRow<ParserOutput>): RendererOutput {\n return `<tr>\\n${text}</tr>\\n` as RendererOutput;\n }\n\n tablecell(token: Tokens.TableCell): RendererOutput {\n const content = this.parser.parseInline(token.tokens);\n const type = token.header ? 'th' : 'td';\n const tag = token.align\n ? `<${type} align=\"${token.align}\">`\n : `<${type}>`;\n return tag + content + `</${type}>\\n` as RendererOutput;\n }\n\n /**\n * span level renderer\n */\n strong({ tokens }: Tokens.Strong): RendererOutput {\n return `<strong>${this.parser.parseInline(tokens)}</strong>` as RendererOutput;\n }\n\n em({ tokens }: Tokens.Em): RendererOutput {\n return `<em>${this.parser.parseInline(tokens)}</em>` as RendererOutput;\n }\n\n codespan({ text }: Tokens.Codespan): RendererOutput {\n return `<code>${escapeHtmlEntities(text, true)}</code>` as RendererOutput;\n }\n\n br(token: Tokens.Br): RendererOutput {\n return '<br>' as RendererOutput;\n }\n\n del({ tokens }: Tokens.Del): RendererOutput {\n return `<del>${this.parser.parseInline(tokens)}</del>` as RendererOutput;\n }\n\n link({ href, title, tokens }: Tokens.Link): RendererOutput {\n const text = this.parser.parseInline(tokens) as string;\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return text as RendererOutput;\n }\n href = cleanHref;\n let out = '<a href=\"' + href + '\"';\n if (title) {\n out += ' title=\"' + (escapeHtmlEntities(title)) + '\"';\n }\n out += '>' + text + '</a>';\n return out as RendererOutput;\n }\n\n image({ href, title, text, tokens }: Tokens.Image): RendererOutput {\n if (tokens) {\n text = this.parser.parseInline(tokens, this.parser.textRenderer) as string;\n }\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return escapeHtmlEntities(text) as RendererOutput;\n }\n href = cleanHref;\n\n let out = `<img src=\"${href}\" alt=\"${escapeHtmlEntities(text)}\"`;\n if (title) {\n out += ` title=\"${escapeHtmlEntities(title)}\"`;\n }\n out += '>';\n return out as RendererOutput;\n }\n\n text(token: Tokens.Text | Tokens.Escape): RendererOutput {\n return 'tokens' in token && token.tokens\n ? this.parser.parseInline(token.tokens) as unknown as RendererOutput\n : ('escaped' in token && token.escaped ? token.text as RendererOutput : escapeHtmlEntities(token.text) as RendererOutput);\n }\n}\n", "import type { Tokens } from './Tokens.ts';\n\n/**\n * TextRenderer\n * returns only the textual part of the token\n */\nexport class _TextRenderer<RendererOutput = string> {\n // no need for block level renderers\n strong({ text }: Tokens.Strong): RendererOutput {\n return text as RendererOutput;\n }\n\n em({ text }: Tokens.Em): RendererOutput {\n return text as RendererOutput;\n }\n\n codespan({ text }: Tokens.Codespan): RendererOutput {\n return text as RendererOutput;\n }\n\n del({ text }: Tokens.Del): RendererOutput {\n return text as RendererOutput;\n }\n\n html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n link({ text }: Tokens.Link): RendererOutput {\n return '' + text as RendererOutput;\n }\n\n image({ text }: Tokens.Image): RendererOutput {\n return '' + text as RendererOutput;\n }\n\n br(): RendererOutput {\n return '' as RendererOutput;\n }\n\n checkbox({ raw }: Tokens.Checkbox): RendererOutput {\n return raw as RendererOutput;\n }\n}\n", "import { _Renderer } from './Renderer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { _defaults } from './defaults.ts';\nimport type { MarkedToken, Token, Tokens } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Parsing & Compiling\n */\nexport class _Parser<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n renderer: _Renderer<ParserOutput, RendererOutput>;\n textRenderer: _TextRenderer<RendererOutput>;\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n this.options.renderer = this.options.renderer || new _Renderer<ParserOutput, RendererOutput>();\n this.renderer = this.options.renderer;\n this.renderer.options = this.options;\n this.renderer.parser = this;\n this.textRenderer = new _TextRenderer<RendererOutput>();\n }\n\n /**\n * Static Parse Method\n */\n static parse<ParserOutput = string, RendererOutput = string>(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const parser = new _Parser<ParserOutput, RendererOutput>(options);\n return parser.parse(tokens);\n }\n\n /**\n * Static Parse Inline Method\n */\n static parseInline<ParserOutput = string, RendererOutput = string>(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>) {\n const parser = new _Parser<ParserOutput, RendererOutput>(options);\n return parser.parseInline(tokens);\n }\n\n /**\n * Parse Loop\n */\n parse(tokens: Token[]): ParserOutput {\n this.renderer.parser = this;\n let out = '';\n\n for (let i = 0; i < tokens.length; i++) {\n const anyToken = tokens[i];\n\n // Run any renderer extensions\n if (this.options.extensions?.renderers?.[anyToken.type]) {\n const genericToken = anyToken as Tokens.Generic;\n const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);\n if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'checkbox', 'html', 'def', 'paragraph', 'text'].includes(genericToken.type)) {\n out += ret || '';\n continue;\n }\n }\n\n const token = anyToken as MarkedToken;\n\n switch (token.type) {\n case 'space': {\n out += this.renderer.space(token);\n break;\n }\n case 'hr': {\n out += this.renderer.hr(token);\n break;\n }\n case 'heading': {\n out += this.renderer.heading(token);\n break;\n }\n case 'code': {\n out += this.renderer.code(token);\n break;\n }\n case 'table': {\n out += this.renderer.table(token);\n break;\n }\n case 'blockquote': {\n out += this.renderer.blockquote(token);\n break;\n }\n case 'list': {\n out += this.renderer.list(token);\n break;\n }\n case 'checkbox': {\n out += this.renderer.checkbox(token);\n break;\n }\n case 'html': {\n out += this.renderer.html(token);\n break;\n }\n case 'def': {\n out += this.renderer.def(token);\n break;\n }\n case 'paragraph': {\n out += this.renderer.paragraph(token);\n break;\n }\n case 'text': {\n out += this.renderer.text(token);\n break;\n }\n\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '' as ParserOutput;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n }\n\n return out as ParserOutput;\n }\n\n /**\n * Parse Inline Tokens\n */\n parseInline(tokens: Token[], renderer: _Renderer<ParserOutput, RendererOutput> | _TextRenderer<RendererOutput> = this.renderer): ParserOutput {\n this.renderer.parser = this;\n let out = '';\n\n for (let i = 0; i < tokens.length; i++) {\n const anyToken = tokens[i];\n\n // Run any renderer extensions\n if (this.options.extensions?.renderers?.[anyToken.type]) {\n const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);\n if (ret !== false || !['escape', 'html', 'link', 'image', 'checkbox', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {\n out += ret || '';\n continue;\n }\n }\n\n const token = anyToken as MarkedToken;\n\n switch (token.type) {\n case 'escape': {\n out += renderer.text(token);\n break;\n }\n case 'html': {\n out += renderer.html(token);\n break;\n }\n case 'link': {\n out += renderer.link(token);\n break;\n }\n case 'image': {\n out += renderer.image(token);\n break;\n }\n case 'checkbox': {\n out += renderer.checkbox(token);\n break;\n }\n case 'strong': {\n out += renderer.strong(token);\n break;\n }\n case 'em': {\n out += renderer.em(token);\n break;\n }\n case 'codespan': {\n out += renderer.codespan(token);\n break;\n }\n case 'br': {\n out += renderer.br(token);\n break;\n }\n case 'del': {\n out += renderer.del(token);\n break;\n }\n case 'text': {\n out += renderer.text(token);\n break;\n }\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '' as ParserOutput;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n }\n return out as ParserOutput;\n }\n}\n", "import { _defaults } from './defaults.ts';\nimport { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, TokensList } from './Tokens.ts';\n\nexport class _Hooks<ParserOutput = string, RendererOutput = string> {\n options: MarkedOptions<ParserOutput, RendererOutput>;\n block?: boolean;\n\n constructor(options?: MarkedOptions<ParserOutput, RendererOutput>) {\n this.options = options || _defaults;\n }\n\n static passThroughHooks = new Set([\n 'preprocess',\n 'postprocess',\n 'processAllTokens',\n 'emStrongMask',\n ]);\n\n static passThroughHooksRespectAsync = new Set([\n 'preprocess',\n 'postprocess',\n 'processAllTokens',\n ]);\n\n /**\n * Process markdown before marked\n */\n preprocess(markdown: string) {\n return markdown;\n }\n\n /**\n * Process HTML after marked is finished\n */\n postprocess(html: ParserOutput) {\n return html;\n }\n\n /**\n * Process all tokens before walk tokens\n */\n processAllTokens(tokens: Token[] | TokensList) {\n return tokens;\n }\n\n /**\n * Mask contents that should not be interpreted as em/strong delimiters\n */\n emStrongMask(src: string) {\n return src;\n }\n\n /**\n * Provide function to tokenize markdown\n */\n provideLexer(block = this.block) {\n return block ? _Lexer.lex : _Lexer.lexInline;\n }\n\n /**\n * Provide function to parse tokens\n */\n provideParser(block = this.block) {\n return block ? _Parser.parse<ParserOutput, RendererOutput> : _Parser.parseInline<ParserOutput, RendererOutput>;\n }\n}\n", "import { _getDefaults } from './defaults.ts';\nimport { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport { _Hooks } from './Hooks.ts';\nimport { _Renderer } from './Renderer.ts';\nimport { _Tokenizer } from './Tokenizer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { escapeHtmlEntities } from './helpers.ts';\nimport type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, Tokens, TokensList } from './Tokens.ts';\n\nexport type MaybePromise = void | Promise<void>;\n\ntype UnknownFunction = (...args: unknown[]) => unknown;\ntype GenericRendererFunction = (...args: unknown[]) => string | false;\n\nexport class Marked<ParserOutput = string, RendererOutput = string> {\n defaults = _getDefaults<ParserOutput, RendererOutput>();\n options = this.setOptions;\n\n /**\n * Compiles markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a separate `Marked`\n * instance and use `Marked#use` instead of passing them on each call.\n */\n parse = this.parseMarkdown(true);\n\n /**\n * Compiles inline markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a separate `Marked`\n * instance and use `Marked#use` instead of passing them on each call.\n */\n parseInline = this.parseMarkdown(false);\n\n Parser = _Parser<ParserOutput, RendererOutput>;\n Renderer = _Renderer<ParserOutput, RendererOutput>;\n TextRenderer = _TextRenderer<RendererOutput>;\n Lexer = _Lexer;\n Tokenizer = _Tokenizer<ParserOutput, RendererOutput>;\n Hooks = _Hooks<ParserOutput, RendererOutput>;\n\n constructor(...args: MarkedExtension<ParserOutput, RendererOutput>[]) {\n this.use(...args);\n }\n\n /**\n * Run callback for every token\n */\n walkTokens(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) {\n let values: MaybePromise[] = [];\n for (const token of tokens) {\n values = values.concat(callback.call(this, token));\n switch (token.type) {\n case 'table': {\n const tableToken = token as Tokens.Table;\n for (const cell of tableToken.header) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n for (const row of tableToken.rows) {\n for (const cell of row) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n }\n break;\n }\n case 'list': {\n const listToken = token as Tokens.List;\n values = values.concat(this.walkTokens(listToken.items, callback));\n break;\n }\n default: {\n const genericToken = token as Tokens.Generic;\n if (this.defaults.extensions?.childTokens?.[genericToken.type]) {\n this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {\n const tokens = genericToken[childTokens].flat(Infinity) as Token[] | TokensList;\n values = values.concat(this.walkTokens(tokens, callback));\n });\n } else if (genericToken.tokens) {\n values = values.concat(this.walkTokens(genericToken.tokens, callback));\n }\n }\n }\n }\n return values;\n }\n\n /**\n * Registers extensions with this Marked instance.\n *\n * The `renderer`, `tokenizer`, and `hooks` objects may each contain only the\n * methods that should be overridden. Their methods are merged with built-in\n * behavior and extensions registered by earlier calls.\n *\n * Use this method when supplying only some hook methods.\n */\n use(...args: MarkedExtension<ParserOutput, RendererOutput>[]) {\n const extensions: MarkedOptions<ParserOutput, RendererOutput>['extensions'] = this.defaults.extensions || { renderers: {}, childTokens: {} };\n\n args.forEach((pack) => {\n // copy options to new object\n const opts = { ...pack } as MarkedOptions<ParserOutput, RendererOutput>;\n\n // set async to true if it was set to true before\n opts.async = this.defaults.async || opts.async || false;\n\n // ==-- Parse \"addon\" extensions --== //\n if (pack.extensions) {\n pack.extensions.forEach((ext) => {\n if (!ext.name) {\n throw new Error('extension name required');\n }\n if ('renderer' in ext) { // Renderer extensions\n const prevRenderer = extensions.renderers[ext.name];\n if (prevRenderer) {\n // Replace extension with func to run new extension but fall back if false\n extensions.renderers[ext.name] = function(...args) {\n let ret = ext.renderer.apply(this, args);\n if (ret === false) {\n ret = prevRenderer.apply(this, args);\n }\n return ret;\n };\n } else {\n extensions.renderers[ext.name] = ext.renderer;\n }\n }\n if ('tokenizer' in ext) { // Tokenizer Extensions\n if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {\n throw new Error(\"extension level must be 'block' or 'inline'\");\n }\n const extLevel = extensions[ext.level];\n if (extLevel) {\n extLevel.unshift(ext.tokenizer);\n } else {\n extensions[ext.level] = [ext.tokenizer];\n }\n if (ext.start) { // Function to check for start of token\n if (ext.level === 'block') {\n if (extensions.startBlock) {\n extensions.startBlock.push(ext.start);\n } else {\n extensions.startBlock = [ext.start];\n }\n } else if (ext.level === 'inline') {\n if (extensions.startInline) {\n extensions.startInline.push(ext.start);\n } else {\n extensions.startInline = [ext.start];\n }\n }\n }\n }\n if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens\n extensions.childTokens[ext.name] = ext.childTokens;\n }\n });\n opts.extensions = extensions;\n }\n\n // ==-- Parse \"overwrite\" extensions --== //\n if (pack.renderer) {\n const renderer = this.defaults.renderer || new _Renderer<ParserOutput, RendererOutput>(this.defaults);\n for (const prop in pack.renderer) {\n if (!(prop in renderer)) {\n throw new Error(`renderer '${prop}' does not exist`);\n }\n if (['options', 'parser'].includes(prop)) {\n // ignore options property\n continue;\n }\n const rendererProp = prop as Exclude<keyof _Renderer<ParserOutput, RendererOutput>, 'options' | 'parser'>;\n const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction;\n const prevRenderer = renderer[rendererProp] as GenericRendererFunction;\n // Replace renderer with func to run extension, but fall back if false\n renderer[rendererProp] = (...args: unknown[]) => {\n let ret = rendererFunc.apply(renderer, args);\n if (ret === false) {\n ret = prevRenderer.apply(renderer, args);\n }\n return (ret || '') as RendererOutput;\n };\n }\n opts.renderer = renderer;\n }\n if (pack.tokenizer) {\n const tokenizer = this.defaults.tokenizer || new _Tokenizer<ParserOutput, RendererOutput>(this.defaults);\n for (const prop in pack.tokenizer) {\n if (!(prop in tokenizer)) {\n throw new Error(`tokenizer '${prop}' does not exist`);\n }\n if (['options', 'rules', 'lexer'].includes(prop)) {\n // ignore options, rules, and lexer properties\n continue;\n }\n const tokenizerProp = prop as Exclude<keyof _Tokenizer<ParserOutput, RendererOutput>, 'options' | 'rules' | 'lexer'>;\n const tokenizerFunc = pack.tokenizer[tokenizerProp] as UnknownFunction;\n const prevTokenizer = tokenizer[tokenizerProp] as UnknownFunction;\n // Replace tokenizer with func to run extension, but fall back if false\n // @ts-expect-error cannot type tokenizer function dynamically\n tokenizer[tokenizerProp] = (...args: unknown[]) => {\n let ret = tokenizerFunc.apply(tokenizer, args);\n if (ret === false) {\n ret = prevTokenizer.apply(tokenizer, args);\n }\n return ret;\n };\n }\n opts.tokenizer = tokenizer;\n }\n\n // ==-- Parse Hooks extensions --== //\n if (pack.hooks) {\n const hooks = this.defaults.hooks || new _Hooks<ParserOutput, RendererOutput>();\n for (const prop in pack.hooks) {\n if (!(prop in hooks)) {\n throw new Error(`hook '${prop}' does not exist`);\n }\n if (['options', 'block'].includes(prop)) {\n // ignore options and block properties\n continue;\n }\n const hooksProp = prop as Exclude<keyof _Hooks<ParserOutput, RendererOutput>, 'options' | 'block'>;\n const hooksFunc = pack.hooks[hooksProp] as UnknownFunction;\n const prevHook = hooks[hooksProp] as UnknownFunction;\n if (_Hooks.passThroughHooks.has(prop)) {\n // @ts-expect-error cannot type hook function dynamically\n hooks[hooksProp] = (arg: unknown) => {\n if (this.defaults.async && _Hooks.passThroughHooksRespectAsync.has(prop)) {\n return (async() => {\n const ret = await hooksFunc.call(hooks, arg);\n return prevHook.call(hooks, ret);\n })();\n }\n\n const ret = hooksFunc.call(hooks, arg);\n return prevHook.call(hooks, ret);\n };\n } else {\n // @ts-expect-error cannot type hook function dynamically\n hooks[hooksProp] = (...args: unknown[]) => {\n if (this.defaults.async) {\n return (async() => {\n let ret = await hooksFunc.apply(hooks, args);\n if (ret === false) {\n ret = await prevHook.apply(hooks, args);\n }\n return ret;\n })();\n }\n\n let ret = hooksFunc.apply(hooks, args);\n if (ret === false) {\n ret = prevHook.apply(hooks, args);\n }\n return ret;\n };\n }\n }\n opts.hooks = hooks;\n }\n\n // ==-- Parse WalkTokens extensions --== //\n if (pack.walkTokens) {\n const walkTokens = this.defaults.walkTokens;\n const packWalktokens = pack.walkTokens;\n opts.walkTokens = function(token) {\n let values: MaybePromise[] = [];\n values.push(packWalktokens.call(this, token));\n if (walkTokens) {\n values = values.concat(walkTokens.call(this, token));\n }\n return values;\n };\n }\n\n this.defaults = { ...this.defaults, ...opts };\n });\n\n return this;\n }\n\n setOptions(opt: MarkedOptions<ParserOutput, RendererOutput>) {\n this.defaults = { ...this.defaults, ...opt };\n return this;\n }\n\n lexer(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>) {\n return _Lexer.lex(src, options ?? this.defaults);\n }\n\n parser(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>) {\n return _Parser.parse<ParserOutput, RendererOutput>(tokens, options ?? this.defaults);\n }\n\n private parseMarkdown(blockType: boolean) {\n type overloadedParse = {\n (src: string, options: MarkedOptions<ParserOutput, RendererOutput> & { async: true }): Promise<ParserOutput>;\n (src: string, options: MarkedOptions<ParserOutput, RendererOutput> & { async: false }): ParserOutput;\n (src: string, options?: MarkedOptions<ParserOutput, RendererOutput> | null): ParserOutput | Promise<ParserOutput>;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const parse: overloadedParse = (src: string, options?: MarkedOptions<ParserOutput, RendererOutput> | null): any => {\n const origOpt = { ...options };\n const opt = { ...this.defaults, ...origOpt };\n\n const throwError = this.onError(!!opt.silent, !!opt.async);\n\n // throw error if an extension set async to true but parse was called with async: false\n if (this.defaults.async === true && origOpt.async === false) {\n return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));\n }\n\n // throw error in case of non string input\n if (typeof src === 'undefined' || src === null) {\n return throwError(new Error('marked(): input parameter is undefined or null'));\n }\n if (typeof src !== 'string') {\n return throwError(new Error('marked(): input parameter is of type '\n + Object.prototype.toString.call(src) + ', string expected'));\n }\n\n if (opt.hooks) {\n opt.hooks.options = opt;\n opt.hooks.block = blockType;\n }\n\n if (opt.async) {\n return (async() => {\n const processedSrc = opt.hooks ? await opt.hooks.preprocess(src) : src;\n const lexer = opt.hooks ? await opt.hooks.provideLexer(blockType) : (blockType ? _Lexer.lex : _Lexer.lexInline);\n const tokens = await lexer(processedSrc, opt);\n const processedTokens = opt.hooks ? await opt.hooks.processAllTokens(tokens) : tokens;\n if (opt.walkTokens) {\n await Promise.all(this.walkTokens(processedTokens, opt.walkTokens));\n }\n const parser = opt.hooks ? await opt.hooks.provideParser(blockType) : (blockType ? _Parser.parse : _Parser.parseInline);\n const html = await parser(processedTokens, opt);\n return opt.hooks ? await opt.hooks.postprocess(html) : html;\n })().catch(throwError);\n }\n\n try {\n if (opt.hooks) {\n src = opt.hooks.preprocess(src) as string;\n }\n const lexer = opt.hooks ? opt.hooks.provideLexer(blockType) : (blockType ? _Lexer.lex : _Lexer.lexInline);\n let tokens = lexer(src, opt);\n if (opt.hooks) {\n tokens = opt.hooks.processAllTokens(tokens);\n }\n if (opt.walkTokens) {\n this.walkTokens(tokens, opt.walkTokens);\n }\n const parser = opt.hooks ? opt.hooks.provideParser(blockType) : (blockType ? _Parser.parse : _Parser.parseInline);\n let html = parser(tokens, opt);\n if (opt.hooks) {\n html = opt.hooks.postprocess(html);\n }\n return html;\n } catch(e) {\n return throwError(e as Error);\n }\n };\n\n return parse;\n }\n\n private onError(silent: boolean, async: boolean) {\n return (e: Error): string | Promise<string> => {\n e.message += '\\nPlease report this to https://github.com/markedjs/marked.';\n\n if (silent) {\n const msg = '<p>An error occurred:</p><pre>'\n + escapeHtmlEntities(e.message + '', true)\n + '</pre>';\n if (async) {\n return Promise.resolve(msg);\n }\n return msg;\n }\n\n if (async) {\n return Promise.reject(e);\n }\n throw e;\n };\n }\n}\n", "import { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport { _Tokenizer } from './Tokenizer.ts';\nimport { _Renderer } from './Renderer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { _Hooks } from './Hooks.ts';\nimport { Marked } from './Instance.ts';\nimport {\n _getDefaults,\n changeDefaults,\n _defaults,\n} from './defaults.ts';\nimport type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, TokensList } from './Tokens.ts';\nimport type { MaybePromise } from './Instance.ts';\n\nconst markedInstance = new Marked();\n\n/**\n * Compiles markdown to HTML asynchronously.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options, having async: true\n * @return Promise of string of compiled HTML\n */\nexport function marked(src: string, options: MarkedOptions & { async: true }): Promise<string>;\n\n/**\n * Compiles markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n *\n * @param src String of markdown source to be compiled\n * @param options Optional hash of options\n * @return String of compiled HTML. Will be a Promise of string if async is set to true by any extensions.\n */\nexport function marked(src: string, options: MarkedOptions & { async: false }): string;\nexport function marked(src: string, options: MarkedOptions & { async: true }): Promise<string>;\nexport function marked(src: string, options?: MarkedOptions | null): string | Promise<string>;\nexport function marked(src: string, opt?: MarkedOptions | null): string | Promise<string> {\n return markedInstance.parse(src, opt);\n}\n\nexport declare namespace marked {\n /**\n * Compiles inline markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n */\n let parseInline: typeof markedInstance.parseInline;\n\n /**\n * Registers extensions with the default Marked instance.\n *\n * The `renderer`, `tokenizer`, and `hooks` objects may each contain only the\n * methods that should be overridden. Their methods are merged with built-in\n * behavior and extensions registered by earlier calls.\n *\n * Use this function when supplying only some hook methods.\n */\n let use: (...args: MarkedExtension[]) => typeof marked;\n}\n\n/**\n * Sets the default options.\n *\n * @param options Hash of options\n */\nmarked.options =\n marked.setOptions = function(options: MarkedOptions) {\n markedInstance.setOptions(options);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n };\n\n/**\n * Gets the original marked default options.\n */\nmarked.getDefaults = _getDefaults;\n\nmarked.defaults = _defaults;\n\n/**\n * Registers extensions with the default Marked instance.\n *\n * The `renderer`, `tokenizer`, and `hooks` objects may each contain only the\n * methods that should be overridden. Their methods are merged with built-in\n * behavior and extensions registered by earlier calls.\n *\n * Use this function when supplying only some hook methods.\n *\n * @param args Extensions to register\n * @return The `marked` function\n */\nfunction useExtension(...args: MarkedExtension[]) {\n markedInstance.use(...args);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n}\n\nmarked.use = useExtension;\n\n/**\n * Run callback for every token\n */\n\nmarked.walkTokens = function(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) {\n return markedInstance.walkTokens(tokens, callback);\n};\n\n/**\n * Compiles markdown to HTML without enclosing `p` tag.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options\n * @return String of compiled HTML\n */\nmarked.parseInline = markedInstance.parseInline;\n\n/**\n * Expose\n */\nmarked.Parser = _Parser;\nmarked.parser = _Parser.parse;\nmarked.Renderer = _Renderer;\nmarked.TextRenderer = _TextRenderer;\nmarked.Lexer = _Lexer;\nmarked.lexer = _Lexer.lex;\nmarked.Tokenizer = _Tokenizer;\nmarked.Hooks = _Hooks;\nmarked.parse = marked;\n\nexport const options = marked.options;\nexport const setOptions = marked.setOptions;\nexport const walkTokens = marked.walkTokens;\n/**\n * Compiles inline markdown to HTML.\n *\n * To configure hooks, a renderer, or a tokenizer, create a `Marked` instance\n * and use `Marked#use` instead of passing them as options on each call.\n */\nexport const parseInline = marked.parseInline;\nexport const parse = marked;\nexport const parser = _Parser.parse;\nexport const lexer = _Lexer.lex;\nexport { _defaults as defaults, _getDefaults as getDefaults } from './defaults.ts';\nexport { _Lexer as Lexer } from './Lexer.ts';\nexport { _Parser as Parser } from './Parser.ts';\nexport { _Tokenizer as Tokenizer } from './Tokenizer.ts';\nexport { _Renderer as Renderer } from './Renderer.ts';\nexport { _TextRenderer as TextRenderer } from './TextRenderer.ts';\nexport { _Hooks as Hooks } from './Hooks.ts';\nexport { Marked } from './Instance.ts';\nexport { useExtension as use };\nexport type * from './MarkedOptions.ts';\nexport type * from './Tokens.ts';\n", "// This module's sanitisation is verified only by the `chromium` project in\n// vitest.config.ts, and must stay there. DOMPurify 3.4.8+ silently sanitises\n// nothing under happy-dom (every element resolves to an empty tag name), so a\n// happy-dom-only suite goes green while this module strips nothing at all.\n// Moving those assertions back under happy-dom for speed removes the only check\n// that this module does anything. CLAUDE.md records the upstream root cause.\nimport DOMPurify from \"dompurify\";\nimport { Marked } from \"marked\";\n\n// A local parser instance, so configuration never leaks into the shared\n// `marked` singleton a host app's deduped copy would share. Built once at module\n// scope and never mutated; per-call construction would re-pay setup on every\n// streaming re-render.\nconst parser = new Marked({ gfm: true, breaks: true });\n\n// Conservative allowlist for assistant chat content. Rendering untrusted\n// model/tool output as HTML is an XSS surface and this sanitiser is the only\n// thing standing in front of it, so `iframe`, `style` and all scripting stay\n// out.\n//\n// `img` is excluded by default: a model-controlled image URL is fetched with no\n// user interaction, turning prompt-injected page data into a zero-click\n// exfiltration channel. Hosts that trust their content opt in via `allowImages`.\nconst ALLOWED_TAGS = [\n \"a\",\n \"p\",\n \"br\",\n \"strong\",\n \"em\",\n \"b\",\n \"i\",\n \"u\",\n \"s\",\n \"del\",\n \"code\",\n \"pre\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"hr\",\n \"span\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n];\n\nconst ALLOWED_ATTR = [\"href\", \"title\", \"class\"];\n\n// The image-permitting variants used when the host opts in.\nconst ALLOWED_TAGS_WITH_IMAGES = [...ALLOWED_TAGS, \"img\"];\nconst ALLOWED_ATTR_WITH_IMAGES = [...ALLOWED_ATTR, \"src\", \"alt\", \"width\", \"height\"];\n\n/** Options for {@link renderMarkdown}. */\nexport interface RenderMarkdownOptions {\n /**\n * Permit `<img>` tags (and their `src`/`alt`/`width`/`height` attributes) in\n * the sanitised output. Off by default; see the exfiltration note on the\n * allowlist above. Only enable for trusted content sources.\n */\n readonly allowImages?: boolean;\n}\n\n/**\n * Render markdown (and any embedded raw HTML) to a sanitised HTML string.\n *\n * Markdown syntax and literal HTML share one path: `marked` emits HTML, then\n * DOMPurify strips everything outside {@link ALLOWED_TAGS} /\n * {@link ALLOWED_ATTR} \u2014 scripts, event handlers, `javascript:` URLs. Links are\n * hardened with `target=\"_blank\"` and `rel=\"noopener noreferrer\"`.\n *\n * The result is trimmed so a single-paragraph message round-trips to clean\n * `textContent`, without the wrapping paragraph's trailing newline.\n */\nexport function renderMarkdown(text: string, options?: RenderMarkdownOptions): string {\n const allowImages = options?.allowImages === true;\n const rendered = parser.parse(text, { async: false });\n const clean = DOMPurify.sanitize(rendered, {\n ALLOWED_TAGS: allowImages ? ALLOWED_TAGS_WITH_IMAGES : ALLOWED_TAGS,\n ALLOWED_ATTR: allowImages ? ALLOWED_ATTR_WITH_IMAGES : ALLOWED_ATTR,\n });\n const template = document.createElement(\"template\");\n template.innerHTML = clean;\n for (const anchor of template.content.querySelectorAll(\"a[href]\")) {\n anchor.setAttribute(\"target\", \"_blank\");\n anchor.setAttribute(\"rel\", \"noopener noreferrer\");\n }\n return template.innerHTML.trim();\n}\n", "/** Which edges the layout holds still while the panel changes size. */\nexport interface ResizeAnchor {\n /** The horizontal edge that does not move. */\n readonly x: \"left\" | \"right\";\n /** The vertical edge that does not move. */\n readonly y: \"top\" | \"bottom\";\n}\n\n/**\n * What the current placement allows: both axes, width only, or nothing. Which\n * corner the grip sits on is separate, and is measured rather than assumed.\n */\nexport type ResizeAxis = \"none\" | \"width\" | \"both\";\n\n/** Persisted size, in CSS pixels. Either axis may be absent. */\nexport interface ResizeSize {\n readonly width?: number;\n readonly height?: number;\n}\n\n/** The panel's position on screen at the moment a drag starts. */\nexport interface PanelRect {\n readonly left: number;\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n}\n\n/** What the handle needs from its host to do its job. */\nexport interface ResizeOptions {\n /**\n * Which axes the current placement allows, read per interaction. A getter\n * because `placement` is a live attribute, and a value read at construction\n * would survive the host switching to a docked or full-bleed layout.\n */\n readonly axis: () => ResizeAxis;\n /**\n * Which edges the layout is holding still, measured at the moment of the drag\n * rather than derived from `placement`: a floating panel is pinned\n * bottom-right, while an embedded one goes wherever the host's CSS puts it,\n * so `placement` alone cannot answer the question.\n */\n readonly anchor: () => ResizeAnchor;\n /** The panel's current bounding box. */\n readonly rect: () => PanelRect;\n /** Apply a size (the host writes the custom properties). */\n readonly apply: (size: ResizeSize) => void;\n /** Called once per completed drag, for persistence. */\n readonly commit: (size: ResizeSize) => void;\n /** Accessible label. */\n readonly label: string;\n}\n\n/** Smallest usable panel; below this the composer and header collide. */\nconst MIN_WIDTH = 280;\nconst MIN_HEIGHT = 240;\n\n/**\n * A drag handle that resizes the chat panel.\n *\n * Two rules keep it correct, and both are easy to break invisibly:\n *\n * - The new size is measured from the edge that is *not* moving, never from a\n * delta, and that edge is measured rather than assumed. Getting it wrong is\n * very visible: the panel shrinks when dragged outward and travels by its\n * opposite corner.\n * - It writes the `--ag-ui-width` / `--ag-ui-height` custom properties, not\n * inline `width` / `height`. The placement rules set those same properties,\n * so an inline dimension would outrank and fight them \u2014 a sidebar would keep\n * its dragged width after switching to fullscreen. Writing the property\n * leaves placement the final say.\n *\n * Axes and anchor are both read per interaction, so a runtime `placement`\n * change takes effect at once.\n */\nexport function createResizeHandle(options: ResizeOptions): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className = \"resize-handle\";\n handle.setAttribute(\"part\", \"resize-handle\");\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-label\", options.label);\n handle.tabIndex = 0;\n\n /** The size implied by a pointer at (x, y), given which edges are pinned. */\n const sizeAt = (\n axis: ResizeAxis,\n anchor: ResizeAnchor,\n rect: PanelRect,\n x: number,\n y: number,\n ): ResizeSize => {\n const width = anchor.x === \"right\" ? rect.right - x : x - rect.left;\n const clamped: ResizeSize = { width: Math.max(MIN_WIDTH, width) };\n if (axis !== \"both\") {\n return clamped;\n }\n const height = anchor.y === \"bottom\" ? rect.bottom - y : y - rect.top;\n return { ...clamped, height: Math.max(MIN_HEIGHT, height) };\n };\n\n handle.addEventListener(\"pointerdown\", (event: PointerEvent) => {\n const axis = options.axis();\n if (axis === \"none\") {\n return;\n }\n // Captured once: the pinned edges cannot move during the drag, and reading\n // them live would chase the panel as it resizes.\n const anchor = options.anchor();\n const rect = options.rect();\n\n const onMove = (move: PointerEvent): void => {\n options.apply(sizeAt(axis, anchor, rect, move.clientX, move.clientY));\n };\n\n const onUp = (up: PointerEvent): void => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n handle.removeAttribute(\"data-dragging\");\n options.commit(sizeAt(axis, anchor, rect, up.clientX, up.clientY));\n };\n\n handle.setAttribute(\"data-dragging\", \"true\");\n // Listeners on `window`, not the handle: a fast drag outruns the pointer\n // and would otherwise strand the panel mid-resize with no pointerup.\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n event.preventDefault();\n });\n\n // Keyboard parity: a pointer-only resize is unreachable without a mouse, and\n // this control has no equivalent elsewhere in the UI.\n handle.addEventListener(\"keydown\", (event: KeyboardEvent) => {\n const axis = options.axis();\n if (axis === \"none\") {\n return;\n }\n const anchor = options.anchor();\n const rect = options.rect();\n const step = event.shiftKey ? 64 : 16;\n // An arrow moves the grip, so whether it grows or shrinks depends on which\n // side the grip is on \u2014 the asymmetry the pointer path also handles.\n const outward = anchor.x === \"right\" ? -1 : 1;\n const width = rect.right - rect.left;\n const height = rect.bottom - rect.top;\n let next: ResizeSize | null = null;\n if (event.key === \"ArrowLeft\") {\n next = { width: Math.max(MIN_WIDTH, width - step * outward) };\n } else if (event.key === \"ArrowRight\") {\n next = { width: Math.max(MIN_WIDTH, width + step * outward) };\n } else if (axis === \"both\" && (event.key === \"ArrowUp\" || event.key === \"ArrowDown\")) {\n const grow = event.key === (anchor.y === \"bottom\" ? \"ArrowUp\" : \"ArrowDown\");\n next = { height: Math.max(MIN_HEIGHT, height + (grow ? step : -step)) };\n }\n if (next === null) {\n return;\n }\n event.preventDefault();\n options.apply(next);\n options.commit(next);\n });\n\n return handle;\n}\n", "/** Collect the text nodes under ``root`` with their parents (depth-first). */\nfunction collectTextNodes(root: Node, out: { node: Text; parent: Node }[]): void {\n for (const child of Array.from(root.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) {\n out.push({ node: child as Text, parent: root });\n } else {\n collectTextNodes(child, out);\n }\n }\n}\n\n/**\n * Wrap each word under ``root`` in `<span class=\"word\" style=\"--ag-ui-word-index: N\">`\n * so CSS can reveal them one-by-one (staggered by the index). Whitespace is\n * preserved as plain text. Used for the `word` text-animation mode on a\n * completed assistant message; pure DOM, idempotent enough to re-run.\n */\nexport function wrapWords(root: HTMLElement): void {\n const texts: { node: Text; parent: Node }[] = [];\n collectTextNodes(root, texts);\n let index = 0;\n for (const { node, parent } of texts) {\n const fragment = document.createDocumentFragment();\n for (const part of node.data.split(/(\\s+)/)) {\n if (part === \"\") {\n continue;\n }\n if (/\\s/.test(part)) {\n fragment.appendChild(document.createTextNode(part));\n continue;\n }\n const span = document.createElement(\"span\");\n span.className = \"word\";\n span.style.setProperty(\"--ag-ui-word-index\", String(index));\n span.textContent = part;\n fragment.appendChild(span);\n index += 1;\n }\n parent.replaceChild(fragment, node);\n }\n}\n", "/**\n * A muted one-line notice about something the run did (history condensed, a\n * skill loaded), rendered inline between turns.\n *\n * Distinct from a tool card, which reports work the agent asked for and\n * settles, and from an error, which is a failure. A notice never settles, takes\n * no action, and carries no controls.\n */\nexport function renderRunNotice(icon: string, text: string, kind: string): HTMLDivElement {\n const notice = document.createElement(\"div\");\n notice.className = `run-notice run-notice--${kind}`;\n notice.setAttribute(\"part\", `run-notice run-notice-${kind}`);\n // status, not alert: informational, so it must not interrupt a screen reader\n // mid-sentence. Polite announcements land after the current utterance.\n notice.setAttribute(\"role\", \"status\");\n\n const glyph = document.createElement(\"span\");\n glyph.className = \"run-notice-icon\";\n glyph.setAttribute(\"part\", \"run-notice-icon\");\n glyph.textContent = icon;\n // Decorative: the adjacent text already says what happened, so announcing the\n // glyph's name would only add noise.\n glyph.setAttribute(\"aria-hidden\", \"true\");\n\n const label = document.createElement(\"span\");\n label.className = \"run-notice-text\";\n label.setAttribute(\"part\", \"run-notice-text\");\n label.textContent = text;\n\n notice.append(glyph, label);\n return notice;\n}\n", "import type { Skill } from \"../skills/skill.js\";\n\n/**\n * The two skill surfaces over a single catalog: a chips row (the `chip: true`\n * subset) and a slash-command palette (all skills, filtered). Both opt-in.\n * Pure DOM; the host appends {@link chips} and {@link palette}, feeds input via\n * {@link onInput} / {@link onKeydown}, and acts on {@link onPick}.\n */\nexport class SkillsMenu {\n /** Chips row \u2014 append above the input. Hidden unless chips are enabled and present. */\n readonly chips: HTMLDivElement;\n /** The `/`-command dropdown \u2014 append in the input area. Hidden until opened. */\n readonly palette: HTMLDivElement;\n\n readonly #onPick: (skill: Skill) => void;\n #skills: readonly Skill[] = [];\n #chipsEnabled = false;\n #slashEnabled = false;\n #filtered: Skill[] = [];\n #activeIndex = 0;\n\n constructor(onPick: (skill: Skill) => void) {\n this.#onPick = onPick;\n this.chips = document.createElement(\"div\");\n this.chips.className = \"skill-chips\";\n this.chips.setAttribute(\"part\", \"skill-chips\");\n this.chips.hidden = true;\n this.palette = document.createElement(\"div\");\n this.palette.className = \"skill-palette\";\n this.palette.setAttribute(\"part\", \"skill-palette\");\n this.palette.setAttribute(\"role\", \"listbox\");\n this.palette.hidden = true;\n }\n\n /** Replace the catalog (both surfaces re-derive from it). */\n setSkills(skills: readonly Skill[]): void {\n this.#skills = skills;\n this.#renderChips();\n }\n\n enableChips(enabled: boolean): void {\n this.#chipsEnabled = enabled;\n this.#renderChips();\n }\n\n enableSlash(enabled: boolean): void {\n this.#slashEnabled = enabled;\n }\n\n /** Whether the palette is currently open. */\n isOpen(): boolean {\n return !this.palette.hidden;\n }\n\n /**\n * React to an input value change: open + filter the palette when slash mode\n * is on and the value starts with `/`, otherwise close it.\n */\n onInput(value: string): void {\n if (this.#slashEnabled && value.startsWith(\"/\")) {\n this.#open(value.slice(1));\n } else {\n this.close();\n }\n }\n\n /**\n * Handle a keydown while the palette is open. Returns ``true`` when consumed\n * (the host should `preventDefault` and skip its own handling).\n */\n onKeydown(event: KeyboardEvent): boolean {\n if (!this.isOpen()) {\n return false;\n }\n if (event.key === \"ArrowDown\") {\n this.#move(1);\n return true;\n }\n if (event.key === \"ArrowUp\") {\n this.#move(-1);\n return true;\n }\n if (event.key === \"Escape\") {\n this.close();\n return true;\n }\n if (event.key === \"Enter\") {\n // `slice(i, i+1)` yields a 0-or-1 element array; forEach gives a\n // definite Skill (no indexed-access `| undefined`).\n this.#filtered.slice(this.#activeIndex, this.#activeIndex + 1).forEach((skill) => {\n this.#pick(skill);\n });\n return true;\n }\n return false;\n }\n\n /** Close the palette. */\n close(): void {\n this.palette.hidden = true;\n this.palette.replaceChildren();\n }\n\n #open(query: string): void {\n const needle = query.trim().toLowerCase();\n const matches = this.#skills.filter(\n (skill) =>\n skill.name.toLowerCase().includes(needle) || skill.title.toLowerCase().includes(needle),\n );\n if (matches.length === 0) {\n this.close();\n return;\n }\n this.#filtered = matches;\n this.#activeIndex = 0;\n this.#renderPalette();\n this.palette.hidden = false;\n }\n\n #move(delta: number): void {\n const count = this.#filtered.length;\n this.#activeIndex = (this.#activeIndex + delta + count) % count;\n this.#renderPalette();\n }\n\n #pick(skill: Skill): void {\n this.close();\n this.#onPick(skill);\n }\n\n #renderChips(): void {\n this.chips.replaceChildren();\n const chipSkills = this.#chipsEnabled\n ? this.#skills.filter((skill) => skill.chip === true)\n : [];\n this.chips.hidden = chipSkills.length === 0;\n for (const skill of chipSkills) {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = \"skill-chip\";\n button.setAttribute(\"part\", \"skill-chip\");\n button.textContent = skill.title;\n // The chip stays a label \u2014 it is a one-click affordance, not something to\n // memorise \u2014 but naming the command it stands for makes the two\n // discoverable as the same thing.\n button.title = `/${skill.name}`;\n button.addEventListener(\"click\", () => this.#pick(skill));\n this.chips.appendChild(button);\n }\n }\n\n #renderPalette(): void {\n this.palette.replaceChildren();\n this.#filtered.forEach((skill, index) => {\n const item = document.createElement(\"button\");\n item.type = \"button\";\n item.className = \"skill-item\";\n item.setAttribute(\"part\", \"skill-item\");\n item.setAttribute(\"role\", \"option\");\n item.setAttribute(\"aria-selected\", index === this.#activeIndex ? \"true\" : \"false\");\n\n const title = document.createElement(\"span\");\n title.className = \"skill-item-title\";\n title.setAttribute(\"part\", \"skill-item-title\");\n\n // The token leads, because it is the thing the user has to type. A row\n // showing only the label taught the label and not the command, so the\n // palette could not be used to learn its own vocabulary.\n const token = document.createElement(\"code\");\n token.className = \"skill-item-token\";\n token.setAttribute(\"part\", \"skill-item-token\");\n token.textContent = `/${skill.name}`;\n title.append(token, document.createTextNode(` ${skill.title}`));\n item.appendChild(title);\n\n if (skill.description !== undefined) {\n const desc = document.createElement(\"span\");\n desc.className = \"skill-item-desc\";\n desc.setAttribute(\"part\", \"skill-item-desc\");\n desc.textContent = skill.description;\n item.appendChild(desc);\n }\n\n item.addEventListener(\"click\", () => this.#pick(skill));\n this.palette.appendChild(item);\n });\n }\n}\n", "// Shadow-DOM-scoped styles for the chat shell. Kept as a string constant so\n// the Custom Element can inject it into its shadow root without a build-time\n// CSS pipeline. Scoped by the shadow boundary, so class names stay terse.\n\nexport const STYLES = `\n/* \u2500\u2500 Token defaults \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Every public --ag-ui-* token is read here into a private --_* alias, and\n only the alias is used by the rules below.\n\n The indirection is what makes ancestor theming work. Declaring the public\n name on :host would set it on the host element, and a value on an element\n always beats one inherited from an ancestor, so tokens put on a wrapper\n would have no effect. Reading the public name with the default as a var()\n fallback leaves it undeclared on the element, so an ancestor's value\n inherits normally while one aimed at the element still wins.\n\n Two invariants hold this together:\n 1. No rule outside this file's :host blocks may reference a public name\n directly. A public name read outside these blocks resolves to nothing and\n silently drops its declaration rather than erroring, so the miss shows up\n as a missing colour, not a failure.\n 2. Every --_* alias in use is declared here. Aliases inherit like any custom\n property, so an undeclared one would pick up a same-named property from\n the host page; declaring it on :host shields the shadow tree from that. */\n:host {\n /* Colors */\n --_bg: var(--ag-ui-bg, #ffffff);\n --_fg: var(--ag-ui-fg, #1a1a2e);\n --_accent: var(--ag-ui-accent, #4f46e5);\n --_user-bg: var(--ag-ui-user-bg, #4f46e5);\n --_user-fg: var(--ag-ui-user-fg, #ffffff);\n --_assistant-bg: var(--ag-ui-assistant-bg, #f1f1f6);\n --_hover: var(--ag-ui-hover, #e7e7ee);\n --_input-bg: var(--ag-ui-input-bg, var(--_bg));\n --_tool-bg: var(--ag-ui-tool-bg, var(--_assistant-bg));\n --_tool-fg: var(--ag-ui-tool-fg, var(--_accent));\n --_header-bg: var(--ag-ui-header-bg, var(--_accent));\n --_header-fg: var(--ag-ui-header-fg, #ffffff);\n --_border: var(--ag-ui-border, #e2e2ec);\n --_radius: var(--ag-ui-radius, 12px);\n\n /* Body text and raised chrome, read only by the code-block copy button.\n The defaults restate what it inherits, so a host that sets neither sees\n no repaint \u2014 see the note on .code-copy. */\n --_text: var(--ag-ui-text, var(--_fg));\n --_surface: var(--ag-ui-surface, transparent);\n\n /* Status accents for tool-call cards. */\n --_success: var(--ag-ui-success, #15803d);\n --_danger: var(--ag-ui-danger, #b91c1c);\n --_muted: var(--ag-ui-muted, #6b7280);\n\n /* Tool-call status icon glyphs (override to re-theme) + spinner speed.\n The pending state is the animated ring; the settled states use these. */\n --_tool-icon-done: var(--ag-ui-tool-icon-done, \"\u2713\");\n --_tool-icon-error: var(--ag-ui-tool-icon-error, \"\u2715\");\n --_tool-icon-declined: var(--ag-ui-tool-icon-declined, \"\u2298\");\n --_tool-spin-duration: var(--ag-ui-tool-spin-duration, 0.7s);\n\n /* Answer well (opt-in via data-answer-well) \u2014 boxes a whole assistant turn. */\n --_well-bg: var(--ag-ui-well-bg, transparent);\n --_well-border: var(--ag-ui-well-border, var(--_border));\n\n /* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(20, 20, 50, 0.18));\n --_font: var(--ag-ui-font, inherit);\n --_font-size: var(--ag-ui-font-size, 14px);\n --_code-font: var(--ag-ui-code-font, ui-monospace, \"SF Mono\", Menlo, monospace);\n\n /* Header / launcher icon box. */\n --_icon-size: var(--ag-ui-icon-size, 22px);\n --_icon-radius: var(--ag-ui-icon-radius, 4px);\n\n /* Composer \u2014 one bordered surface holding the field and its tool row. */\n --_composer-radius: var(--ag-ui-composer-radius, 14px);\n --_composer-max-height: var(--ag-ui-composer-max-height, 40vh);\n --_tool-btn-size: var(--ag-ui-tool-btn-size, 30px);\n --_send-size: var(--ag-ui-send-size, 30px);\n --_glyph-size: var(--ag-ui-glyph-size, 18px);\n --_glyph-stroke: var(--ag-ui-glyph-stroke, 1.75);\n\n /* Unread badge on the launcher. */\n --_badge-bg: var(--ag-ui-badge-bg, var(--_danger));\n --_badge-fg: var(--ag-ui-badge-fg, #ffffff);\n --_badge-size: var(--ag-ui-badge-size, 18px);\n --_badge-font-size: var(--ag-ui-badge-font-size, 11px);\n\n /* The floating launcher a collapsed widget shrinks to. */\n --_launcher-size: var(--ag-ui-launcher-size, 56px);\n --_launcher-bg: var(--ag-ui-launcher-bg, var(--_header-bg));\n --_launcher-fg: var(--ag-ui-launcher-fg, var(--_header-fg));\n --_launcher-radius: var(--ag-ui-launcher-radius, 50%);\n --_launcher-icon-size: var(--ag-ui-launcher-icon-size, 26px);\n --_launcher-inset: var(--ag-ui-launcher-inset, auto 0 0 auto);\n\n /* Motion. One duration and two curves drive every collapse, expand and\n slide-over, so the widget accelerates and settles as one thing. The\n default curve decelerates into place; the pop curve overshoots slightly,\n for something arriving. */\n --_motion: var(--ag-ui-motion, 0.28s);\n --_ease: var(--ag-ui-ease, cubic-bezier(0.32, 0.72, 0, 1));\n --_ease-pop: var(--ag-ui-ease-pop, cubic-bezier(0.34, 1.36, 0.64, 1));\n\n /* Spacing \u2014 the density preset overrides these. */\n --_space: var(--ag-ui-space, 10px);\n --_pad: var(--ag-ui-pad, 16px);\n --_msg-pad: var(--ag-ui-msg-pad, 8px 12px);\n --_msg-radius: var(--ag-ui-msg-radius, 14px);\n\n /* Layout \u2014 override from outside to dock the widget anywhere.\n Set --ag-ui-position: static (and place this element in your own\n grid/flex layout) to embed it in the page flow instead of floating. */\n --_position: var(--ag-ui-position, fixed);\n --_z-index: var(--ag-ui-z-index, 2147483000);\n --_width: var(--ag-ui-width, 380px);\n --_height: var(--ag-ui-height, 560px);\n --_inset: var(--ag-ui-inset, auto 24px 24px auto);\n --_max-width: var(--ag-ui-max-width, calc(100vw - 48px));\n --_max-height: var(--ag-ui-max-height, calc(100vh - 48px));\n /* Reading-column width for placement=\"page\" (full-bleed, centred content). */\n --_content-max-width: var(--ag-ui-content-max-width, 820px);\n /* Slim rail the sidebar placement collapses to. Only that placement reads\n it, but it is declared here so every alias has a default in one place. */\n --_rail-width: var(--ag-ui-rail-width, 52px);\n\n position: var(--_position);\n inset: var(--_inset);\n z-index: var(--_z-index);\n width: var(--_width);\n max-width: var(--_max-width);\n height: var(--_height);\n max-height: var(--_max-height);\n display: flex;\n font-family: var(--_font);\n font-size: var(--_font-size);\n color: var(--_fg);\n}\n\n/* \u2500\u2500 Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Themes only re-set the colour variables; layout/spacing are unaffected.\n theme=\"auto\" follows the OS via prefers-color-scheme. */\n:host([theme=\"dark\"]) {\n --_bg: var(--ag-ui-bg, #15151f);\n --_fg: var(--ag-ui-fg, #e8e8f2);\n --_assistant-bg: var(--ag-ui-assistant-bg, #25253a);\n --_hover: var(--ag-ui-hover, #303049);\n --_header-bg: var(--ag-ui-header-bg, #1f1f30);\n --_header-fg: var(--ag-ui-header-fg, #e8e8f2);\n --_border: var(--ag-ui-border, #33334a);\n --_muted: var(--ag-ui-muted, #9aa0b4);\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.5));\n}\n\n@media (prefers-color-scheme: dark) {\n :host([theme=\"auto\"]) {\n --_bg: var(--ag-ui-bg, #15151f);\n --_fg: var(--ag-ui-fg, #e8e8f2);\n --_assistant-bg: var(--ag-ui-assistant-bg, #25253a);\n --_hover: var(--ag-ui-hover, #303049);\n --_header-bg: var(--ag-ui-header-bg, #1f1f30);\n --_header-fg: var(--ag-ui-header-fg, #e8e8f2);\n --_border: var(--ag-ui-border, #33334a);\n --_muted: var(--ag-ui-muted, #9aa0b4);\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.5));\n }\n}\n\n/* A terminal-flavoured \"code\" theme: dark, monospace, green accent. */\n:host([theme=\"code\"]) {\n --_bg: var(--ag-ui-bg, #0d1117);\n --_fg: var(--ag-ui-fg, #c9d1d9);\n --_accent: var(--ag-ui-accent, #3fb950);\n --_user-bg: var(--ag-ui-user-bg, #238636);\n --_assistant-bg: var(--ag-ui-assistant-bg, #161b22);\n --_hover: var(--ag-ui-hover, #21262d);\n --_header-bg: var(--ag-ui-header-bg, #010409);\n --_header-fg: var(--ag-ui-header-fg, #c9d1d9);\n --_border: var(--ag-ui-border, #30363d);\n --_muted: var(--ag-ui-muted, #8b949e);\n --_font: var(--ag-ui-font, var(--_code-font));\n --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.6));\n}\n\n/* \u2500\u2500 Density \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([density=\"compact\"]) {\n --_font-size: var(--ag-ui-font-size, 13px);\n --_space: var(--ag-ui-space, 6px);\n --_pad: var(--ag-ui-pad, 10px);\n --_msg-pad: var(--ag-ui-msg-pad, 5px 9px);\n --_msg-radius: var(--ag-ui-msg-radius, 10px);\n}\n\n/* \u2500\u2500 Placement presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([placement=\"bottom-left\"]) {\n --_inset: var(--ag-ui-inset, auto auto 24px 24px);\n}\n\n:host([placement=\"side\"]) {\n --_inset: var(--ag-ui-inset, 0 0 0 auto);\n --_width: var(--ag-ui-width, 420px);\n --_height: var(--ag-ui-height, 100vh);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n}\n\n:host([placement=\"full\"]) {\n --_inset: var(--ag-ui-inset, 0);\n --_width: var(--ag-ui-width, 100vw);\n --_height: var(--ag-ui-height, 100vh);\n --_max-width: var(--ag-ui-max-width, 100vw);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n}\n\n/* Page: full-bleed background with a centred reading column capped at\n --ag-ui-content-max-width, where \"full\" is edge-to-edge and left-aligned.\n The column comes from symmetric auto padding on the scroll area and\n composer rather than a per-row wrapper, so user pills still right-align and\n the assistant well spans the column. */\n:host([placement=\"page\"]) {\n --_inset: var(--ag-ui-inset, 0);\n --_width: var(--ag-ui-width, 100vw);\n --_height: var(--ag-ui-height, 100vh);\n --_max-width: var(--ag-ui-max-width, 100vw);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n}\n\n:host([placement=\"page\"]) .messages {\n padding-inline: max(var(--_pad), calc((100% - var(--_content-max-width)) / 2));\n}\n\n:host([placement=\"page\"]) .input-row {\n padding-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));\n}\n\n/* The rows between the message list and the composer line up with the column\n too. Chips and tray are padding-based while palette and hint are\n margin-based, so each gets its own inline axis nudged by the same gutter. */\n:host([placement=\"page\"]) .skill-chips,\n:host([placement=\"page\"]) .attachment-tray {\n padding-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));\n}\n\n:host([placement=\"page\"]) .skill-palette,\n:host([placement=\"page\"]) .skill-hint {\n margin-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));\n}\n\n/* In the reading column the assistant well uses the full width; the user\n message stays a right-aligned pill (its default align-self + max-width). */\n:host([placement=\"page\"]) .message--assistant {\n max-width: 100%;\n}\n\n/* Sidebar: a full-height docked panel that slides open/closed and\n collapses to a slim icon rail (not the floating launcher). Docked right by\n default; data-side=\"left\" docks it left. Overlay by default \u2014 set\n --ag-ui-position: static (and place this element in your own layout) for a\n host-managed push instead. */\n:host([placement=\"sidebar\"]) {\n --_inset: var(--ag-ui-inset, 0 0 0 auto);\n --_width: var(--ag-ui-width, 420px);\n --_height: var(--ag-ui-height, 100vh);\n --_max-height: var(--ag-ui-max-height, 100vh);\n --_radius: var(--ag-ui-radius, 0);\n transition: width var(--_motion) var(--_ease);\n}\n\n:host([placement=\"sidebar\"][data-side=\"left\"]) {\n --_inset: var(--ag-ui-inset, 0 auto 0 0);\n}\n\n/* The docked panel is pinned to the edge it docks against rather than filling\n the host as a flex child. Collapsing shrinks the host to the rail width, and\n a flex child would be squashed to 52px on the way out instead of sliding out\n at full width. */\n:host([placement=\"sidebar\"]) .chat {\n position: absolute;\n inset: 0 0 0 auto;\n width: var(--_width);\n transform-origin: right center;\n}\n\n:host([placement=\"sidebar\"][data-side=\"left\"]) .chat {\n inset: 0 auto 0 0;\n transform-origin: left center;\n}\n\n/* Collapsed sidebar: shrink the host to the rail width and slide the panel out\n through the edge it docks against. Higher specificity than the generic\n collapse rules, so it wins regardless of source order. */\n:host([placement=\"sidebar\"][collapsed]) {\n width: var(--_rail-width);\n height: 100vh;\n max-height: 100vh;\n bottom: 0;\n pointer-events: auto;\n}\n\n:host([placement=\"sidebar\"][collapsed]) .chat {\n transform: translateX(100%);\n}\n\n:host([placement=\"sidebar\"][data-side=\"left\"][collapsed]) .chat {\n transform: translateX(-100%);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([placement=\"sidebar\"]),\n :host([placement=\"sidebar\"]) .chat {\n transition: none;\n }\n}\n\n/* \u2500\u2500 Launcher \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n What a collapsed widget shrinks to: a round floating button by default, the\n sidebar's slim edge rail under that placement. A sibling of the panel, so it\n survives the panel being hidden, and the only part of a collapsed widget\n that takes pointer events. */\n.launcher {\n display: flex;\n position: absolute;\n inset: var(--_launcher-inset);\n align-items: center;\n justify-content: center;\n width: var(--_launcher-size);\n height: var(--_launcher-size);\n padding: 0;\n border: none;\n border-radius: var(--_launcher-radius);\n background: var(--_launcher-bg);\n color: var(--_launcher-fg);\n box-shadow: var(--_shadow);\n font: inherit;\n cursor: pointer;\n pointer-events: auto;\n opacity: 0;\n transform: scale(0.4);\n visibility: hidden;\n transition:\n opacity var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease-pop),\n visibility var(--_motion) var(--_ease);\n}\n\n/* The launcher grows out of the corner the panel shrank into. It stays laid\n out at rest rather than display:none, which is what lets it animate both in\n and out: an unrendered element has no before-change style to transition\n from, and one flipping display to none cannot transition at all. visibility\n keeps it unpaintable, untabbable and unclickable in between, so the expanded\n panel's own controls underneath stay reachable. */\n:host([collapsed]) .launcher {\n opacity: 1;\n transform: none;\n visibility: visible;\n}\n\n:host([collapsed]) .launcher:hover {\n transform: scale(1.06);\n}\n\n:host([collapsed]) .launcher:active {\n transform: scale(0.94);\n}\n\n.launcher .icon-holder {\n width: var(--_launcher-icon-size);\n height: var(--_launcher-icon-size);\n}\n\n/* The unread badge rides the launcher's top-right corner. The ring in the\n widget's own background is what separates it from the launcher underneath,\n whatever colour the host themes either one. */\n.launcher-badge {\n position: absolute;\n top: -2px;\n right: -2px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-width: var(--_badge-size);\n height: var(--_badge-size);\n padding: 0 5px;\n border-radius: 999px;\n background: var(--_badge-bg);\n color: var(--_badge-fg);\n font-size: var(--_badge-font-size);\n font-weight: 600;\n line-height: 1;\n box-shadow: 0 0 0 2px var(--_bg);\n}\n\n.launcher-badge[hidden] {\n display: none;\n}\n\n/* The sidebar collapses to an edge rail instead: full height, square, flush\n against the dock. It slides in with the panel rather than popping. */\n:host([placement=\"sidebar\"][collapsed]) .launcher {\n inset: 0;\n width: auto;\n height: auto;\n align-items: flex-start;\n padding-top: 16px;\n border: 1px solid var(--_border);\n border-radius: 0;\n background: var(--_header-bg);\n color: var(--_header-fg);\n box-shadow: none;\n transform: none;\n}\n\n/* Every transition in this file is timed by --_motion, so collapsing it to a\n frame is the whole reduced-motion story: states still change (and display\n still flips at the end of its discrete transition), nothing travels. */\n@media (prefers-reduced-motion: reduce) {\n :host {\n --_motion: var(--ag-ui-motion, 0.001s);\n }\n}\n\n/* Embedded: drop the floating chrome and the high z-index stacking context so\n the widget lives in the host's own layout (fixes overlay/z-index clashes). */\n:host([placement=\"embedded\"]) {\n --_position: var(--ag-ui-position, static);\n --_width: var(--ag-ui-width, 100%);\n --_height: var(--ag-ui-height, 100%);\n --_max-width: var(--ag-ui-max-width, 100%);\n --_max-height: var(--ag-ui-max-height, 100%);\n --_shadow: var(--ag-ui-shadow, none);\n --_z-index: var(--ag-ui-z-index, auto);\n}\n\n.chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n box-shadow: var(--_shadow);\n overflow: hidden;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--_border);\n background: var(--_header-bg);\n color: var(--_header-fg);\n}\n\n.header-title {\n flex: 1;\n min-width: 0;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header / launcher icon holder: a slot, with a data-icon-url <img>\n fallback, sized via --ag-ui-icon-size. */\n.icon-holder {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: var(--_icon-size);\n height: var(--_icon-size);\n line-height: 1;\n}\n\n.icon-img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n border-radius: var(--_icon-radius);\n}\n\n.header-controls {\n display: flex;\n gap: 2px;\n flex: none;\n}\n\n.header-btn {\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n padding: 4px 7px;\n border-radius: 6px;\n cursor: pointer;\n opacity: 0.85;\n}\n\n.header-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.18);\n}\n\n/* \u2500\u2500 Collapse \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Collapsing shrinks the widget to the round floating launcher: the panel\n scales toward the launcher's corner and fades, the launcher pops in from the\n same point. Both halves are transform and opacity only, so the morph runs on\n the compositor and never reflows the host page.\n\n The host box keeps its expanded size, since animating it would animate\n layout and a dragged --ag-ui-width would fight the launcher's own size.\n Nothing paints there once the panel is gone, so the box only has to stop\n swallowing clicks: pointer events go to none and the launcher takes them.\n\n Two placements collapse differently: \"sidebar\" slides to its rail (below),\n while \"embedded\" and \"page\" keep the header bar, having no corner for a\n floating circle that would escape the host's layout. */\n:host([collapsed]) {\n pointer-events: none;\n}\n\n:host([collapsed]) .chat {\n opacity: 0;\n transform: scale(0.94);\n visibility: hidden;\n}\n\n/* visibility keeps the panel out of the tab order and the a11y tree at rest\n without display:none killing the transition. It interpolates so any progress\n below 1 still counts as visible: the panel stays on screen for the whole\n collapse, flips hidden exactly at the end, and on expand is visible from the\n first frame. */\n.chat {\n transform-origin: bottom right;\n transition:\n opacity var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease),\n visibility var(--_motion) var(--_ease);\n}\n\n:host([placement=\"bottom-left\"]) .chat {\n transform-origin: bottom left;\n}\n\n/* The two in-flow placements keep the original collapse: hide the body, let\n the host shrink to the header bar. */\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) {\n height: auto;\n max-height: none;\n pointer-events: auto;\n}\n\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .chat {\n opacity: 1;\n transform: none;\n visibility: visible;\n}\n\n/* These two keep the header bar, so the launcher must stay out of the way: an\n embedded host is position: static, which would let an absolutely-positioned\n circle escape the layout and land against whatever the page positions. */\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .launcher {\n visibility: hidden;\n opacity: 0;\n}\n\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .messages,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .input-row,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .skill-chips,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .skill-palette,\n:host([collapsed]:is([placement=\"embedded\"], [placement=\"page\"])) .skill-hint {\n display: none;\n}\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: var(--_pad);\n display: flex;\n flex-direction: column;\n gap: var(--_space);\n}\n\n/* Empty-state region (slot): centred while it's the only thing in the\n list, hidden as soon as a message, card, or pending indicator renders. */\n.empty {\n margin: auto;\n text-align: center;\n color: var(--_muted);\n}\n\n.empty[hidden] {\n display: none;\n}\n\n/* \u2500\u2500 Answer group / well \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n One .answer per assistant turn wraps the streamed text, its tool cards,\n and the pending indicator so a whole answer reads (and can be boxed) as one\n unit. A flex column on the message-list gap, stretched to the list width so\n its children keep their own left/right alignment. data-answer-well opts into\n the bordered \"well\"; without it the turn renders as a flat stack. */\n.answer {\n display: flex;\n flex-direction: column;\n gap: var(--_space);\n align-self: stretch;\n min-width: 0;\n}\n\n:host([data-answer-well]) .answer {\n padding: var(--_pad);\n background: var(--_well-bg);\n border: 1px solid var(--_well-border);\n border-radius: var(--_radius);\n}\n\n.message {\n max-width: 80%;\n padding: var(--_msg-pad);\n border-radius: var(--_msg-radius);\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* \u2500\u2500 Incoming-text animations (data-text-animation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* .message--restored (rehydrated history) is excluded: entrance animations are\n for freshly-arriving messages, not the whole transcript replaying on reload.\n Word mode is excluded implicitly \u2014 restored bubbles aren't wrapped. */\n:host([data-text-animation=\"fade\"]) .message--assistant:not(.message--restored) {\n animation: ag-ui-msg-fade 0.25s ease both;\n}\n\n@keyframes ag-ui-msg-fade {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n}\n\n.message--assistant .word {\n animation: ag-ui-word-in 0.3s ease both;\n animation-delay: calc(var(--ag-ui-word-index, 0) * 35ms);\n}\n\n@keyframes ag-ui-word-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([data-text-animation=\"fade\"]) .message--assistant,\n .message--assistant .word {\n animation: none;\n }\n}\n\n.message--user {\n align-self: flex-end;\n background: var(--_user-bg);\n color: var(--_user-fg);\n border-bottom-right-radius: 4px;\n}\n\n.message--assistant {\n align-self: flex-start;\n background: var(--_assistant-bg);\n border-bottom-left-radius: 4px;\n /* Assistant bubbles hold rendered markdown/HTML, so collapse the source\n whitespace the renderer leaves between block tags. */\n white-space: normal;\n}\n\n/* Rendered-markdown elements inside an assistant bubble. */\n.message--assistant > :first-child {\n margin-top: 0;\n}\n\n.message--assistant > :last-child {\n margin-bottom: 0;\n}\n\n.message--assistant p,\n.message--assistant ul,\n.message--assistant ol,\n.message--assistant blockquote,\n.message--assistant pre {\n margin: 0.5em 0;\n}\n\n.message--assistant ul,\n.message--assistant ol {\n padding-left: 1.3em;\n}\n\n.message--assistant a {\n color: var(--_accent);\n text-decoration: underline;\n}\n\n.message--assistant code {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n font-size: 0.92em;\n background: rgba(127, 127, 127, 0.16);\n padding: 1px 4px;\n border-radius: 4px;\n}\n\n.message--assistant pre {\n padding: 8px 10px;\n overflow: auto;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 6px;\n}\n\n.message--assistant pre code {\n background: none;\n padding: 0;\n}\n\n/* The copy button sits inside the block, so it scrolls with wide code rather\n than floating over the bubble. Positioning is on the pre; the button only\n appears once one has been attached. */\n.message--assistant pre.has-copy {\n position: relative;\n}\n\n/* The only reader of --ag-ui-surface and --ag-ui-text. Their defaults are\n transparent and the body foreground, which is what this button rendered as\n before either token existed; changing them repaints only this control. */\n.code-copy {\n position: absolute;\n top: 4px;\n right: 4px;\n padding: 2px 8px;\n font: inherit;\n font-size: 0.75em;\n line-height: 1.6;\n color: var(--_muted);\n background: var(--_surface);\n border: 1px solid var(--_border);\n border-radius: 4px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.12s ease;\n}\n\n/* Revealed on hover or keyboard focus. Focus matters as much as hover here:\n hidden-until-hover is invisible to a keyboard user otherwise. */\n.message--assistant pre.has-copy:hover .code-copy,\n.code-copy:focus-visible {\n opacity: 1;\n}\n\n.code-copy:hover {\n color: var(--_text);\n background: var(--_hover);\n}\n\n.code-copy[data-state=\"copied\"] {\n opacity: 1;\n color: var(--_text);\n}\n\n.code-copy[data-state=\"failed\"] {\n opacity: 1;\n color: var(--_danger, var(--_text));\n}\n\n.message--assistant blockquote {\n padding-left: 10px;\n border-left: 3px solid var(--_border);\n color: var(--_muted);\n}\n\n/* Markdown tables. table/thead/tbody/tr/th/td are all in the sanitizer's\n ALLOWED_TAGS, so an agent can emit one. A wide table must scroll inside its\n own box rather than stretch the message: the bubble is width-constrained, so\n without this the columns either crush or push the layout sideways. */\n.message--assistant table {\n display: block;\n width: fit-content;\n max-width: 100%;\n overflow-x: auto;\n border-collapse: collapse;\n font-size: 0.95em;\n}\n\n.message--assistant th,\n.message--assistant td {\n padding: 6px 10px;\n border: 1px solid var(--_border);\n text-align: left;\n vertical-align: top;\n}\n\n.message--assistant th {\n background: var(--_hover);\n font-weight: 600;\n}\n\n.pending {\n align-self: flex-start;\n display: inline-flex;\n gap: 4px;\n align-items: center;\n padding: 12px 14px;\n background: var(--_assistant-bg);\n border-radius: 14px;\n border-bottom-left-radius: 4px;\n}\n\n.pending-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--_muted);\n animation: ag-ui-pending 1.2s infinite ease-in-out both;\n}\n\n.pending-dot:nth-child(2) {\n animation-delay: 0.16s;\n}\n\n.pending-dot:nth-child(3) {\n animation-delay: 0.32s;\n}\n\n@keyframes ag-ui-pending {\n 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pending-dot {\n animation: none;\n opacity: 0.6;\n }\n}\n\n/* \u2500\u2500 Thoughts region \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n A muted, collapsible chain-of-thought at the top of the answer group: open\n while the model reasons, folded once the answer text starts. */\n.thoughts {\n align-self: stretch;\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 12px;\n color: var(--_muted);\n}\n\n.thoughts-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-size: 12px;\n font-weight: 600;\n color: var(--_muted);\n cursor: pointer;\n}\n\n.thoughts-toggle::before {\n content: \"\u25BE \";\n}\n\n.thoughts-toggle[aria-expanded=\"false\"]::before {\n content: \"\u25B8 \";\n}\n\n/* A gentle pulse on the label while reasoning is still streaming. */\n.thoughts[data-streaming] .thoughts-label {\n animation: ag-ui-thoughts-pulse 1.4s ease-in-out infinite;\n}\n\n@keyframes ag-ui-thoughts-pulse {\n 0%, 100% { opacity: 0.55; }\n 50% { opacity: 1; }\n}\n\n.thoughts-body {\n margin: 0;\n padding: 4px 0 4px 10px;\n border-left: 2px solid var(--_border);\n max-height: 220px;\n overflow: auto;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: inherit;\n}\n\n.thoughts-body[hidden] {\n display: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .thoughts[data-streaming] .thoughts-label {\n animation: none;\n }\n}\n\n.tool-call {\n align-self: flex-start;\n max-width: 80%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--_tool-bg);\n border: 1px solid var(--_border);\n color: var(--_tool-fg);\n}\n\n/* Wraps, because the name is the only flexible child and every badge the row\n gains is taken out of it. An approved call adds a third fixed badge, which in\n a sidebar-width panel left the name 37px and broke it mid-word. Badges drop to\n their own row instead. */\n.tool-call-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.tool-call-name {\n /* An auto basis, and a min-width floor rather than zero: the name may shrink,\n but not below something readable, so wrapping moves a badge instead of\n shredding a word. Breaking anywhere still applies to a name that cannot fit\n on a line of its own, which is what keeps a long unbroken tool name inside\n the card. */\n flex: 1 1 auto;\n min-width: 6ch;\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n\n/* Leading status icon. Empty in the DOM \u2014 the glyph/spinner is drawn\n here from the card's data-status, so it stays themeable. */\n.tool-call-icon {\n flex: none;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n font-size: 12px;\n line-height: 1;\n}\n\n/* Pending: a real spinning ring. Speed is tunable; reduced motion stops it. */\n.tool-call[data-status=\"pending\"] .tool-call-icon {\n border: 2px solid var(--_muted);\n border-top-color: transparent;\n border-radius: 50%;\n animation: ag-ui-tool-spin var(--_tool-spin-duration) linear infinite;\n}\n\n@keyframes ag-ui-tool-spin {\n to { transform: rotate(360deg); }\n}\n\n/* Deferred: no spinner, because nothing is spinning. A steady accent dot, since\n the state is waiting-on-you rather than an outcome. */\n.tool-call[data-status=\"deferred\"] .tool-call-icon {\n border-radius: 50%;\n background: var(--_accent);\n}\n\n/* Settled: a themeable glyph coloured by outcome. */\n.tool-call[data-status=\"done\"] .tool-call-icon::before {\n content: var(--_tool-icon-done);\n color: var(--_success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-icon::before {\n content: var(--_tool-icon-error);\n color: var(--_danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-icon::before {\n content: var(--_tool-icon-declined);\n color: var(--_muted);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .tool-call[data-status=\"pending\"] .tool-call-icon {\n animation: none;\n }\n}\n\n/* Inline display mode: the lightest card. Drop the box chrome so the status row\n reads as one line of the answer; the result toggle still expands below it. */\n:host([data-tool-display=\"inline\"]) .tool-call {\n max-width: 100%;\n background: transparent;\n border: none;\n padding: 2px 0;\n gap: 2px;\n}\n\n.tool-call-status {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: rgba(127, 127, 127, 0.16);\n color: var(--_muted);\n}\n\n.tool-call[data-status=\"deferred\"] .tool-call-status {\n color: var(--_accent);\n}\n\n.tool-call[data-status=\"done\"] .tool-call-status {\n color: var(--_success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-status {\n color: var(--_danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-status {\n color: var(--_muted);\n}\n\n.tool-call-body {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.tool-call-section {\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n/* The heading that tells the two payloads apart. Without it the arguments and\n the result were one run of text and a reader had to guess the boundary. */\n.tool-call-section-label {\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--_muted);\n}\n\n.skill-item-token {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n font-size: 0.92em;\n color: var(--_accent);\n margin-right: 6px;\n}\n\n/* The lasting record of a human decision on a gated call \u2014 without it an\n approved call looks exactly like one that was never gated. */\n.tool-call-decision {\n flex: none;\n font-size: 11px;\n font-style: italic;\n color: var(--_muted);\n}\n\n.tool-call-args,\n.tool-call-result {\n margin: 0;\n padding: 6px 8px;\n max-height: 160px;\n overflow: auto;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--_fg);\n}\n\n/* Display modes are pure visibility over one DOM shape, selected from the host\n attribute rather than a value stamped on the card at build time, so flipping\n data-tool-display re-styles cards already on screen. See ToolCallCard.\n\n Default (no attribute) is the full mode: arguments always visible, result\n behind the toggle. */\n.tool-call[data-expanded=\"false\"] .tool-call-section--result {\n display: none;\n}\n\n/* Compact: one toggle over both regions, so a settled card is a single line\n until asked. */\n:host([data-tool-display=\"compact\"]) .tool-call[data-expanded=\"false\"] .tool-call-section {\n display: none;\n}\n\n/* Inline: the result only; the call's arguments are noise at this density. */\n:host([data-tool-display=\"inline\"]) .tool-call .tool-call-section--args {\n display: none;\n}\n\n/* Minimal: the status row and nothing else, so there is no toggle to press. */\n:host([data-tool-display=\"minimal\"]) .tool-call .tool-call-toggle,\n:host([data-tool-display=\"minimal\"]) .tool-call .tool-call-body {\n display: none;\n}\n\n/* A pending card has no result yet, and in the modes where the arguments are\n hidden too there is nothing behind the toggle. Hide the control rather than\n offer one that expands onto nothing. A deferred card is the same, and its\n arguments are shown unconditionally by the rules below. */\n.tool-call[data-status=\"pending\"] .tool-call-toggle,\n.tool-call[data-status=\"deferred\"] .tool-call-toggle,\n:host([data-tool-display=\"inline\"]) .tool-call[data-status=\"pending\"] .tool-call-toggle {\n display: none;\n}\n\n/* The approval prompt for a gated call, rendered inside that call's own card.\n Empty on every card nobody is being asked about, so it collapses instead of\n adding a gap to each one. */\n.tool-call-approval:empty {\n display: none;\n}\n\n.tool-call-approval {\n margin-top: 8px;\n}\n\n/* A card that is asking a question shows what it is asking about, in every\n display mode. Three gated calls of one tool ask the same words, so the\n arguments are the only thing telling them apart, and a density setting must\n not be able to hide the answer to \"which one is this\". */\n:host([data-tool-display=\"minimal\"]) .tool-call[data-status=\"deferred\"] .tool-call-body {\n display: flex;\n}\n\n/* The arguments region only, never every section: the result region carries the\n hidden attribute until a result exists, and a display value here overrides it,\n framing an empty RESULT heading under the question. */\n:host([data-tool-display=\"compact\"]) .tool-call[data-status=\"deferred\"] .tool-call-section--args,\n:host([data-tool-display=\"inline\"]) .tool-call[data-status=\"deferred\"] .tool-call-section--args {\n display: flex;\n}\n\n.tool-call-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-weight: 600;\n color: var(--_accent);\n cursor: pointer;\n}\n\n.tool-call-toggle::before {\n content: \"\u25B8 \";\n}\n\n.tool-call-toggle[aria-expanded=\"true\"]::before {\n content: \"\u25BE \";\n}\n\n/* Resize handle: a corner grip on a floating panel, an edge grip on a docked\n one. Absent entirely where the placement is full-bleed, since there is\n nothing to drag. */\n.resize-handle {\n position: absolute;\n z-index: 2;\n background: transparent;\n touch-action: none;\n}\n\n.resize-handle:focus-visible {\n outline: 2px solid var(--_accent);\n outline-offset: -2px;\n}\n\n/* The grip sits on the corner opposite the panel's anchor, because a resize\n measures from whichever edge is not moving.\n\n Default is floating: pinned bottom-right, so the grip is top-left. */\n.resize-handle {\n top: 0;\n left: 0;\n width: 14px;\n height: 14px;\n cursor: nwse-resize;\n}\n\n/* Placement is only the opening guess, and these two rules are all it is good\n for. Embedded sits in normal flow, pinned top-left, so it grows bottom-right;\n bottom-left is pinned there, so its free corner is top-right. */\n:host([placement=\"embedded\"]) .resize-handle {\n top: auto;\n left: auto;\n right: 0;\n bottom: 0;\n cursor: nwse-resize;\n}\n\n:host([placement=\"bottom-left\"]) .resize-handle {\n left: auto;\n right: 0;\n cursor: nesw-resize;\n}\n\n/* Then the measurement corrects it. Which edges are held still belongs to the\n host's layout, not to placement -- a floating panel a host right-aligns is\n anchored bottom-left -- so the element measures them and stamps a single\n hyphenated \"<y>-<x>\" token here. Equal specificity to the rules above, so\n source order is what lets the measured value win.\n\n Two traps, both of which silently draw the grip on the corner that moves:\n\n Never write these as [data-resize-anchor~=\"left\"]. The stamped value is one\n hyphenated token and ~= matches whitespace-separated words, so it can never\n match.\n\n Each rule must set both sides of its axis, not only the side it moves, or it\n cannot undo a placement guess that flipped the other way. */\n:host([data-resize-anchor$=\"-left\"]) .resize-handle {\n left: auto;\n right: 0;\n}\n\n:host([data-resize-anchor$=\"-right\"]) .resize-handle {\n left: 0;\n right: auto;\n}\n\n:host([data-resize-anchor^=\"top-\"]) .resize-handle {\n top: auto;\n bottom: 0;\n}\n\n:host([data-resize-anchor^=\"bottom-\"]) .resize-handle {\n top: 0;\n bottom: auto;\n}\n\n/* One axis flipped means the drag runs along the other diagonal. */\n:host([data-resize-anchor=\"top-left\"]) .resize-handle,\n:host([data-resize-anchor=\"bottom-right\"]) .resize-handle {\n cursor: nwse-resize;\n}\n\n:host([data-resize-anchor=\"top-right\"]) .resize-handle,\n:host([data-resize-anchor=\"bottom-left\"]) .resize-handle {\n cursor: nesw-resize;\n}\n\n/* Docked: the placement owns the height, so only the inner edge is the user's --\n an edge, not a corner, so this outranks the measured anchor by coming after. */\n:host([placement=\"sidebar\"]) .resize-handle,\n:host([placement=\"side\"]) .resize-handle {\n top: 0;\n bottom: auto;\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n}\n\n/* Docked to the left, so the inner edge is the right-hand one. */\n:host([placement=\"sidebar\"][data-side=\"left\"]) .resize-handle {\n left: auto;\n right: 0;\n}\n\n/* Full-bleed: nothing to drag. */\n:host([placement=\"full\"]) .resize-handle,\n:host([placement=\"page\"]) .resize-handle {\n display: none;\n}\n\n.resize-handle[data-dragging] {\n background: var(--_accent);\n opacity: 0.35;\n}\n\n/* \u2500\u2500 Composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n One surface owns the border, the background and the focus ring; the field\n and its tool row sit inside it, rather than being siblings stretched to the\n textarea's height. */\n.input-row {\n display: flex;\n padding: 12px;\n border-top: 1px solid var(--_border);\n}\n\n.composer {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 6px 6px 6px 10px;\n background: var(--_input-bg);\n border: 1px solid var(--_border);\n border-radius: var(--_composer-radius);\n transition: border-color var(--_motion) var(--_ease);\n}\n\n.composer:focus-within {\n border-color: var(--_accent);\n}\n\n/* The field grows with its content (sized by #autoGrow) up to the ceiling,\n then scrolls. border-box keeps that measurement stable: with content-box the\n padding would be added to every scrollHeight read and the field would creep\n taller on each keystroke. */\n.input {\n box-sizing: border-box;\n resize: none;\n max-height: var(--_composer-max-height);\n overflow-y: auto;\n padding: 6px 4px 2px;\n background: transparent;\n border: none;\n font: inherit;\n color: inherit;\n outline: none;\n}\n\n.composer-tools {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n/* Icon buttons: quiet at rest, so the field is what the eye lands on. */\n.attach-btn,\n.voice-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--_tool-btn-size);\n height: var(--_tool-btn-size);\n padding: 0;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--_muted);\n font: inherit;\n line-height: 1;\n cursor: pointer;\n transition:\n background-color var(--_motion) var(--_ease),\n color var(--_motion) var(--_ease);\n}\n\n.attach-btn:hover,\n.voice-btn:hover {\n background: var(--_hover);\n color: var(--_fg);\n}\n\n.attach-btn:disabled,\n.voice-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n/* The same trap the attachment tray carries a note about, two rules along: an\n author display beats the UA stylesheet's rule for the hidden property, so a\n button the element has explicitly hidden keeps laying out and painting. The\n clip is hidden until a host supplies an upload handler or an attachments URL,\n and without this it is a visible control that cannot do anything.\n\n The mic needs no such rule, and the asymmetry is worth knowing before adding\n one: it is not hidden when unconfigured, it is never built. The voice wiring\n returns before constructing the button, leaving only an empty voice slot that\n is display: contents. A hidden-state rule for the mic would match nothing. */\n.attach-btn[hidden] {\n display: none;\n}\n\n/* Send closes the row on the right: a circle, the only filled control in the\n composer, so \"the thing that acts\" reads at a glance. */\n.send {\n margin-left: auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: var(--_send-size);\n height: var(--_send-size);\n padding: 0;\n border: none;\n border-radius: 50%;\n background: var(--_accent);\n color: #ffffff;\n font: inherit;\n line-height: 1;\n cursor: pointer;\n transition:\n background-color var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease-pop);\n}\n\n.send:hover {\n transform: scale(1.08);\n}\n\n.send:active {\n transform: scale(0.92);\n}\n\n.send:disabled {\n opacity: 0.5;\n cursor: default;\n transform: none;\n}\n\n/* The composer button doubles as the Stop control while a run is in flight \u2014\n same circle, different glyph, so nothing moves when a run starts. */\n.send[data-state=\"running\"] {\n background: var(--_muted);\n}\n\n.send[data-state=\"idle\"] .send-stop,\n.send[data-state=\"running\"] .send-send {\n display: none;\n}\n\n/* Glyphs \u2014 one class, painted from the button's own colour so every state\n (hover, recording, running) carries the icon with it. */\n.glyph {\n width: var(--_glyph-size);\n height: var(--_glyph-size);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--_glyph-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n.glyph--solid {\n fill: currentColor;\n stroke: none;\n}\n\n/* In an icon holder (header brand, launcher) the glyph takes the holder's size\n rather than the composer's. */\n.icon-holder .glyph {\n width: 100%;\n height: 100%;\n}\n\n/* \u2500\u2500 File attachments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* The picker button sits in the composer's tool row; hidden until\n data-attachments-url. */\n.attach-input {\n display: none;\n}\n\n/* The mic button's mount point; filled only once #wireVoice mounts the\n control. */\n.voice-slot {\n display: contents;\n}\n\n/* Recording: a red tint + a gentle pulse so it's clearly \"live\". */\n.voice-btn[data-state=\"recording\"] {\n background: var(--_danger);\n color: #ffffff;\n animation: ag-ui-voice-pulse 1.2s ease-in-out infinite;\n}\n\n.voice-btn[data-state=\"recording\"]:hover {\n background: var(--_danger);\n color: #ffffff;\n}\n\n@keyframes ag-ui-voice-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .voice-btn[data-state=\"recording\"] {\n animation: none;\n }\n}\n\n/* Pending-attachments tray, above the input row; collapses (hidden) when empty. */\n.attachment-slot {\n display: contents;\n}\n\n/* The padding is the only separation the tray gets: its slot is display:\n contents, so the tray is a direct child of the .chat column, and that column\n sets no gap. The bottom value keeps a chip off the composer's top edge.\n The inline value here is only the default: the page placement overrides\n padding-inline further down to compute its reading-column gutter, and wins\n on specificity whichever way this declaration is written. Read the two\n together before changing either. */\n.attachment-tray {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 12px;\n}\n\n/* The tray sets the hidden property while empty, and an author display beats\n the UA stylesheet's rule for it, so without this the empty tray keeps\n laying out and its padding is permanent dead space above the composer. */\n.attachment-tray[hidden] {\n display: none;\n}\n\n.attachment-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n/* Charts.\n *\n * The SVG scales to the column and carries no colours of its own beyond the\n * series palette, so a host restyles it the same way it restyles everything\n * else. Series colours are custom properties with fallbacks rather than fixed\n * values, and the axis furniture inherits currentColor at low opacity so it\n * reads correctly in either theme without a second palette.\n */\n.chart-block {\n align-self: stretch;\n max-width: 100%;\n margin: 6px 0;\n color: var(--_fg);\n}\n\n.chart-title {\n margin-bottom: 2px;\n font-size: 0.85em;\n font-weight: 600;\n opacity: 0.85;\n}\n\n.chart-legend {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 12px;\n margin-top: 4px;\n font-size: 0.78em;\n opacity: 0.75;\n}\n\n.chart-legend-item {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n}\n\n.chart-legend-swatch {\n width: 9px;\n height: 9px;\n border-radius: 2px;\n flex: 0 0 auto;\n}\n\n.run-notice {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n align-self: flex-start;\n max-width: 100%;\n margin: 2px 0;\n padding: 3px 10px;\n border: 1px dashed var(--_border);\n border-radius: 999px;\n background: transparent;\n color: var(--_muted);\n font-size: 0.8em;\n line-height: 1.4;\n}\n\n.run-notice-icon {\n flex: none;\n opacity: 0.75;\n}\n\n.run-notice-text {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* A chip carries its own text colour because it carries its own background.\n The same chip renders in two places with opposite inherited colours: the\n composer tray gives it the panel's, a sent user bubble gives it the user\n foreground, which is white on the stock light theme and near-invisible\n against the chip. Pairing the colour with the background it belongs to makes\n both placements read alike. Overridden below for an errored chip, which\n keeps its red. */\n.attachment-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n /* Without this the 100% below caps the content box, so the chip still\n overflows its container by its own padding and border. Invisible while a\n character cap kept names short; routine once the container is what bounds\n the name. */\n box-sizing: border-box;\n max-width: 100%;\n padding: 4px 8px;\n border: 1px solid var(--_border);\n border-radius: 999px;\n background: var(--_assistant-bg);\n color: var(--_text);\n font-size: 0.85em;\n position: relative;\n}\n\n.attachment-chip--error {\n border-color: var(--_danger);\n color: var(--_danger);\n}\n\n/* The type mark. Painted from currentColor, so it carries the chip's state\n with it and turns red along with an errored one; muted by opacity rather\n than a colour, which is what keeps that true. Sized from the chip's own text\n rather than --ag-ui-glyph-size, the way an icon holder's glyph takes the\n holder's size: the composer's 18px buttons would make a chip button-height. */\n.attachment-chip-icon {\n display: inline-flex;\n flex: none;\n opacity: 0.75;\n}\n\n.attachment-chip-icon .glyph {\n width: 1.25em;\n height: 1.25em;\n}\n\n/* No character cap: the chip is already max-width 100%, so its container is\n what bounds the name, and a fixed cap only truncated names the chip had room\n for. min-width: 0 is what lets the flex item shrink past its content, so the\n ellipsis appears at the container edge instead of the chip overflowing. */\n.attachment-chip-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.attachment-chip-size {\n color: var(--_muted);\n white-space: nowrap;\n}\n\n.attachment-chip--error .attachment-chip-size {\n color: var(--_danger);\n}\n\n/* The progress bar fills as the file uploads. */\n.attachment-chip-bar {\n flex-basis: 100%;\n height: 3px;\n border-radius: 2px;\n background: var(--_border);\n overflow: hidden;\n}\n\n.attachment-chip-bar-fill {\n height: 100%;\n background: var(--_accent);\n transition: width 0.15s ease;\n}\n\n.attachment-chip-remove,\n.attachment-chip-retry {\n border: none;\n background: none;\n color: inherit;\n cursor: pointer;\n padding: 0;\n line-height: 1;\n opacity: 0.7;\n}\n\n.attachment-chip-remove:hover,\n.attachment-chip-retry:hover {\n opacity: 1;\n}\n\n/* A subtle outline while a file is dragged over the shell. */\n.chat--dragover {\n outline: 2px dashed var(--_accent);\n outline-offset: -4px;\n}\n\n/* Muted \"\u23F9 Stopped\" line after a cancelled run \u2014 a note, not an error bubble. */\n.stopped-note {\n align-self: flex-start;\n color: var(--_muted);\n font-size: 12px;\n padding: 2px 4px;\n}\n\n/* Inline confirmation card \u2014 lives in the transcript, no focus-stealing overlay. */\n.confirm {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--_bg);\n border: 1px solid var(--_accent);\n border-radius: 10px;\n}\n\n.confirm[data-resolved] {\n opacity: 0.7;\n border-color: var(--_border);\n}\n\n.confirm-body {\n font-weight: 600;\n}\n\n.confirm-args {\n margin: 0;\n padding: 8px 10px;\n max-height: 140px;\n overflow: auto;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n background: var(--_assistant-bg);\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.confirm-btn {\n border: 1px solid var(--_border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--_bg);\n color: var(--_fg);\n}\n\n.confirm-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.confirm-btn--confirm {\n border-color: var(--_accent);\n background: var(--_accent);\n color: #ffffff;\n}\n\n/* Approval card \u2014 the server-side-tool gate (approve/deny an interrupt). */\n.approval {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--_bg);\n border: 1px solid var(--_accent);\n border-radius: 10px;\n}\n\n.approval[data-resolved] {\n opacity: 0.7;\n border-color: var(--_border);\n}\n\n.approval-body {\n font-weight: 600;\n}\n\n.approval-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.approval-btn {\n border: 1px solid var(--_border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--_bg);\n color: var(--_fg);\n}\n\n.approval-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.approval-btn--approve {\n border-color: var(--_accent);\n background: var(--_accent);\n color: #ffffff;\n}\n\n/* Question card \u2014 the built-in ask_user prompt (radios and/or free text). */\n.question {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--_bg);\n border: 1px solid var(--_accent);\n border-radius: 10px;\n}\n\n.question[data-resolved] {\n opacity: 0.7;\n border-color: var(--_border);\n}\n\n.question-body {\n font-weight: 600;\n}\n\n.question-options {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.question-choice {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n\n.question-input {\n box-sizing: border-box;\n width: 100%;\n padding: 8px 10px;\n font: inherit;\n color: var(--_fg);\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 8px;\n}\n\n.question-input:disabled {\n opacity: 0.6;\n}\n\n.question-actions {\n display: flex;\n justify-content: flex-end;\n}\n\n.question-btn {\n border: 1px solid var(--_accent);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--_accent);\n color: #ffffff;\n}\n\n.question-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n/* Skills \u2014 chips row + the /-command palette, above the input. */\n.skill-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 10px 12px;\n}\n\n.skill-chip {\n border: 1px solid var(--_border);\n border-radius: 999px;\n padding: 4px 12px;\n font: inherit;\n font-size: 0.9em;\n cursor: pointer;\n background: var(--_assistant-bg);\n color: var(--_fg);\n}\n\n.skill-chip:hover {\n border-color: var(--_accent);\n}\n\n.skill-palette {\n margin: 8px 12px 0;\n display: flex;\n flex-direction: column;\n max-height: 220px;\n overflow: auto;\n background: var(--_bg);\n border: 1px solid var(--_border);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);\n}\n\n.skill-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n align-items: flex-start;\n padding: 8px 12px;\n border: none;\n background: none;\n font: inherit;\n text-align: left;\n cursor: pointer;\n color: var(--_fg);\n}\n\n.skill-item[aria-selected=\"true\"] {\n background: var(--_assistant-bg);\n}\n\n.skill-item-title {\n font-weight: 600;\n}\n\n.skill-item-desc {\n font-size: 0.85em;\n color: var(--_muted);\n}\n\n/* The hint sits directly above the composer's top border, so a zero bottom\n margin left the text touching the divider. */\n.skill-hint {\n margin: 8px 12px;\n font-size: 0.85em;\n line-height: 1.4;\n color: var(--_danger);\n}\n\n/* Chat-history drawer \u2014 a slide-over within the chat panel.\n The hidden attribute stays the single source of truth for open/closed (no\n JS-driven animation state): display is transitioned discretely, so on close\n the drawer stays displayed for the whole exit and is removed only at the end,\n which is what lets the backdrop fade and the panel slide out. */\n.drawer {\n position: absolute;\n inset: 0;\n z-index: 5;\n display: flex;\n transition: visibility var(--_motion) var(--_ease);\n}\n\n/* Closed. The overlay keeps its box (display, not none) so the backdrop and\n panel inside it stay rendered and can transition both ways; visibility is\n what takes the whole subtree out of the tab order, the a11y tree and hit\n testing at rest, and it holds off until the slide has finished. */\n.drawer[hidden] {\n display: flex;\n visibility: hidden;\n pointer-events: none;\n}\n\n.drawer[hidden] .drawer-backdrop {\n opacity: 0;\n}\n\n.drawer[hidden] .drawer-panel {\n transform: translateX(-100%);\n}\n\n.checkpoints {\n position: absolute;\n inset-block-start: 3rem;\n inset-inline: 0.75rem;\n z-index: 6;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n border: 1px solid var(--_border);\n border-radius: 0.5rem;\n background: var(--_assistant-bg);\n box-shadow: 0 6px 24px rgb(0 0 0 / 12%);\n max-height: 60%;\n overflow-y: auto;\n transform-origin: top center;\n transition:\n opacity var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease),\n visibility var(--_motion) var(--_ease);\n}\n\n/* Same idiom as the drawer: laid out at rest, hidden by visibility, so the\n popover can animate open and closed. */\n.checkpoints[hidden] {\n display: flex;\n visibility: hidden;\n pointer-events: none;\n opacity: 0;\n transform: scale(0.96) translateY(-6px);\n}\n\n.checkpoints-title {\n font-size: 0.75rem;\n font-weight: 600;\n opacity: 0.7;\n}\n\n.checkpoints-empty {\n padding: 0.5rem 0.25rem;\n font-size: 0.8125rem;\n opacity: 0.7;\n}\n\n/* A row is a label and two buttons, and nothing about the row itself is\n pressable. It used to light up on hover, which is the affordance of something\n clickable and made the buttons look like decoration on a clickable strip. The\n resting surface groups the row instead, so hover can mean what it says: only\n the buttons respond to it.\n\n It wraps for the same reason the tool-call head does. Every child but the label\n is fixed-width, so in a narrow panel the label is the only thing that can give\n -- and a flex-basis of zero lets it give everything. Adding the run id was\n enough to crush \"just now\" to zero pixels: present, correct, and invisible.\n Wrapping puts the buttons on their own line instead. */\n.checkpoint-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5rem;\n padding: 0.3125rem 0.4375rem;\n border-radius: 0.375rem;\n background: var(--_hover);\n}\n\n/* Grows into spare room, and refuses to shrink past the shortest thing it ever\n says. A time is short and bounded, so there is no case for eliding it. */\n.checkpoint-label {\n flex: 1 1 auto;\n min-width: 7ch;\n font-size: 0.8125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* When the label holds the run's first message, the time moves here: still worth\n showing, no longer what identifies the row. Muted and unshrinkable, so it does\n not compete with the words beside it. */\n.checkpoint-time {\n flex: 0 0 auto;\n font-size: 0.6875rem;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n/* Enough of the run id to tell two runs apart when both say \"just now\". Muted\n and monospaced: it is a reference, not a name. */\n.checkpoint-id {\n flex: 0 0 auto;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.6875rem;\n opacity: 0.55;\n}\n\n/* On the panel's own surface, not the row's: the row now paints the hover token\n itself, and a badge the same colour as what it sits on is not a badge. */\n.checkpoint-branch {\n font-size: 0.6875rem;\n padding: 0 0.375rem;\n border-radius: 999px;\n background: var(--_assistant-bg);\n opacity: 0.8;\n}\n\n/* The two things in the row that actually do something, so they are the two\n things that look like it: a filled surface at rest rather than a transparent\n outline, which on top of the old row highlight was nearly invisible. */\n.checkpoint-action {\n font: inherit;\n font-size: 0.75rem;\n line-height: 1.4;\n cursor: pointer;\n padding: 0.1875rem 0.5625rem;\n border: 1px solid var(--_border);\n border-radius: 0.375rem;\n background: var(--_bg);\n color: inherit;\n transition:\n background var(--_motion) var(--_ease),\n border-color var(--_motion) var(--_ease),\n transform var(--_motion) var(--_ease);\n}\n\n/* Resume is what a reader wants nine times in ten; fork is the deliberate choice\n beside it. Filled and outlined, the same pair the confirmation and approval\n cards already use for their primary and secondary action. */\n.checkpoint-resume {\n font-weight: 600;\n border-color: var(--_accent);\n background: var(--_accent);\n color: #ffffff;\n}\n\n.checkpoint-fork:hover {\n background: var(--_hover);\n border-color: var(--_accent);\n}\n\n/* The filled one cannot go lighter on hover without losing its contrast with the\n white label, so it dims instead. */\n.checkpoint-resume:hover {\n opacity: 0.88;\n}\n\n/* Pressed: a pixel down, so the click is felt as well as seen. */\n.checkpoint-action:active {\n transform: translateY(1px);\n}\n\n/* Keyboard focus was invisible here, in a panel that traps focus and is reached\n by Tab -- so the one navigation path guaranteed to land on these buttons was\n the one with nothing to show for it. */\n.checkpoint-action:focus-visible {\n outline: 2px solid var(--_accent);\n outline-offset: 2px;\n}\n\n.drawer-backdrop {\n position: absolute;\n inset: 0;\n background: rgba(20, 20, 50, 0.32);\n opacity: 1;\n transition: opacity var(--_motion) var(--_ease);\n}\n\n.drawer-panel {\n position: relative;\n display: flex;\n flex-direction: column;\n width: min(300px, 85%);\n height: 100%;\n background: var(--_bg);\n border-right: 1px solid var(--_border);\n box-shadow: var(--_shadow);\n overflow: hidden;\n transform: none;\n transition: transform var(--_motion) var(--_ease);\n}\n\n.drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--_space);\n padding: var(--_pad);\n border-bottom: 1px solid var(--_border);\n}\n\n.drawer-title {\n font-weight: 600;\n}\n\n.drawer-new {\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_bg);\n color: var(--_accent);\n padding: 4px 10px;\n font: inherit;\n font-size: 0.85em;\n cursor: pointer;\n}\n\n.drawer-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n\n.drawer-empty {\n padding: var(--_pad);\n font-size: 0.9em;\n color: var(--_muted);\n}\n\n.drawer-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--_border);\n}\n\n.drawer-row--active {\n background: var(--_assistant-bg);\n}\n\n.drawer-row-select {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 12px;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.drawer-row-title {\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-time {\n font-size: 0.72em;\n color: var(--_muted);\n}\n\n.drawer-row-preview {\n font-size: 0.8em;\n color: var(--_muted);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.drawer-row-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 6px;\n}\n\n.drawer-row-rename,\n.drawer-row-delete {\n border: none;\n background: none;\n color: var(--_muted);\n font-size: 0.9em;\n padding: 4px;\n cursor: pointer;\n}\n\n.drawer-rename-input {\n flex: 1;\n min-width: 0;\n margin: 6px 10px;\n padding: 4px 8px;\n border: 1px solid var(--_accent);\n border-radius: 6px;\n background: var(--_input-bg);\n color: var(--_fg);\n font: inherit;\n}\n\n.drawer-confirm {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n font-size: 0.85em;\n}\n\n.drawer-confirm-label {\n color: var(--_danger);\n}\n\n.drawer-confirm-yes {\n border: none;\n border-radius: 6px;\n background: var(--_danger);\n color: #ffffff;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n.drawer-confirm-no {\n border: 1px solid var(--_border);\n border-radius: 6px;\n background: none;\n color: inherit;\n padding: 3px 10px;\n font: inherit;\n cursor: pointer;\n}\n\n/* Embedded placement: an inline, flush side panel rather than a dimmed,\n floating slide-over. */\n:host([placement=\"embedded\"]) .drawer-backdrop {\n background: none;\n}\n\n:host([placement=\"embedded\"]) .drawer-panel {\n width: 100%;\n border-right: none;\n box-shadow: none;\n}\n`;\n", "import { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/**\n * A muted, collapsible \"thinking\" region for a reasoning model's streamed\n * chain-of-thought.\n *\n * Sits at the top of the current answer group. It opens expanded while the\n * model reasons, {@link stream} replacing its body with the running buffer, and\n * {@link collapse} folds it away once the answer's first text token arrives.\n * The header toggle reopens it.\n *\n * Pure DOM. The host inserts {@link element}; all visible chrome text comes\n * from {@link UiStrings}.\n */\nexport class ThoughtsBlock {\n /** The block's root element; insert this at the top of the answer group. */\n readonly element: HTMLDivElement;\n\n readonly #label: HTMLSpanElement;\n readonly #body: HTMLPreElement;\n readonly #toggle: HTMLButtonElement;\n readonly #strings: UiStrings;\n #collapsed = false;\n\n constructor(strings: UiStrings = DEFAULT_UI_STRINGS) {\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"thoughts\";\n this.element.setAttribute(\"part\", \"thoughts\");\n // Lets CSS animate the header while the model is still reasoning; dropped\n // on collapse.\n this.element.setAttribute(\"data-streaming\", \"\");\n\n this.#toggle = document.createElement(\"button\");\n this.#toggle.type = \"button\";\n this.#toggle.className = \"thoughts-toggle\";\n this.#toggle.setAttribute(\"part\", \"thoughts-toggle\");\n this.#toggle.setAttribute(\"aria-expanded\", \"true\");\n\n this.#label = document.createElement(\"span\");\n this.#label.className = \"thoughts-label\";\n this.#label.setAttribute(\"part\", \"thoughts-label\");\n this.#label.textContent = strings.thinking;\n this.#toggle.append(this.#label);\n\n this.#body = document.createElement(\"pre\");\n this.#body.className = \"thoughts-body\";\n this.#body.setAttribute(\"part\", \"thoughts-body\");\n\n this.#toggle.addEventListener(\"click\", () => {\n this.#setCollapsed(!this.#collapsed);\n });\n\n this.element.append(this.#toggle, this.#body);\n }\n\n /** Replace the reasoning body with the running buffer (the full text so far). */\n stream(buffer: string): void {\n this.#body.textContent = buffer;\n }\n\n /**\n * Fold the region away when the answer's first text token arrives, flipping\n * the header label to its settled form. Idempotent, since the per-token text\n * handler calls it repeatedly.\n */\n collapse(): void {\n if (this.#collapsed) {\n return;\n }\n this.element.removeAttribute(\"data-streaming\");\n this.#label.textContent = this.#strings.thoughts;\n this.#setCollapsed(true);\n }\n\n #setCollapsed(collapsed: boolean): void {\n this.#collapsed = collapsed;\n this.#body.hidden = collapsed;\n this.#toggle.setAttribute(\"aria-expanded\", String(!collapsed));\n }\n}\n", "import type { ThreadMeta } from \"../core/conversation_store.js\";\nimport { relativeTime } from \"./relative_time.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Actions the host ({@link AgUiChat}) wires to the drawer's rows. */\nexport interface ThreadDrawerCallbacks {\n /** A row was picked \u2014 load that thread and make it active. */\n readonly onSelect: (threadId: string) => void;\n /** The \"New chat\" action \u2014 start a fresh thread. */\n readonly onNew: () => void;\n /** A row was renamed to `title`. */\n readonly onRename: (threadId: string, title: string) => void;\n /** A row was deleted (after the inline confirm). */\n readonly onDelete: (threadId: string) => void;\n}\n\n/**\n * The chat-history drawer: a slide-over listing the user's threads (title,\n * relative time, preview), with select / new / rename / delete actions and an\n * empty state. Pure DOM, like {@link SkillsMenu}: the host appends\n * {@link element}, toggles it, feeds rows via {@link setThreads}, and acts on\n * the callbacks.\n *\n * A view only \u2014 it never mutates the store. After a callback the host updates\n * the store and calls {@link setThreads} to refresh. All visible text comes\n * from {@link UiStrings}; {@link setStrings} re-localizes a drawer built before\n * its strings resolved.\n */\nexport class ThreadDrawer {\n /** The drawer root (backdrop + panel). Append to the chat shell; hidden until opened. */\n readonly element: HTMLDivElement;\n\n readonly #callbacks: ThreadDrawerCallbacks;\n readonly #panel: HTMLDivElement;\n readonly #heading: HTMLSpanElement;\n readonly #newButton: HTMLButtonElement;\n readonly #list: HTMLDivElement;\n #strings: UiStrings;\n #threads: readonly ThreadMeta[] = [];\n #activeId = \"\";\n /** The element focused before the drawer opened, restored on close. */\n #lastFocused: HTMLElement | null = null;\n\n constructor(callbacks: ThreadDrawerCallbacks, strings: UiStrings = DEFAULT_UI_STRINGS) {\n this.#callbacks = callbacks;\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"drawer\";\n this.element.setAttribute(\"part\", \"drawer\");\n this.element.hidden = true;\n\n const backdrop = document.createElement(\"div\");\n backdrop.className = \"drawer-backdrop\";\n backdrop.setAttribute(\"part\", \"drawer-backdrop\");\n backdrop.addEventListener(\"click\", () => this.close());\n\n this.#panel = document.createElement(\"div\");\n this.#panel.className = \"drawer-panel\";\n this.#panel.setAttribute(\"part\", \"drawer-panel\");\n this.#panel.setAttribute(\"role\", \"dialog\");\n this.#panel.setAttribute(\"aria-modal\", \"true\");\n this.#panel.setAttribute(\"aria-label\", strings.chatHistory);\n // Escape closes the drawer; Tab is trapped within the panel while it's open.\n this.#panel.addEventListener(\"keydown\", (event) => this.#onPanelKeydown(event));\n\n const header = document.createElement(\"div\");\n header.className = \"drawer-header\";\n header.setAttribute(\"part\", \"drawer-header\");\n this.#heading = document.createElement(\"span\");\n this.#heading.className = \"drawer-title\";\n this.#heading.setAttribute(\"part\", \"drawer-title\");\n this.#heading.textContent = strings.chats;\n this.#newButton = document.createElement(\"button\");\n this.#newButton.type = \"button\";\n this.#newButton.className = \"drawer-new\";\n this.#newButton.setAttribute(\"part\", \"drawer-new\");\n this.#newButton.textContent = strings.newChat;\n this.#newButton.addEventListener(\"click\", () => {\n this.close();\n this.#callbacks.onNew();\n });\n header.append(this.#heading, this.#newButton);\n\n this.#list = document.createElement(\"div\");\n this.#list.className = \"drawer-list\";\n this.#list.setAttribute(\"part\", \"drawer-list\");\n\n this.#panel.append(header, this.#list);\n this.element.append(backdrop, this.#panel);\n }\n\n /** Re-localize the drawer's chrome and rows (the host calls this on connect). */\n setStrings(strings: UiStrings): void {\n this.#strings = strings;\n this.#panel.setAttribute(\"aria-label\", strings.chatHistory);\n this.#heading.textContent = strings.chats;\n this.#newButton.textContent = strings.newChat;\n this.#renderList();\n }\n\n isOpen(): boolean {\n return !this.element.hidden;\n }\n\n open(): void {\n if (this.isOpen()) {\n return;\n }\n // Remember what had focus so it's restored on close, then move focus into\n // the panel (its first control) so keyboard users land inside the dialog.\n this.#lastFocused = this.#activeElement() as HTMLElement | null;\n this.element.hidden = false;\n this.#newButton.focus();\n }\n\n close(): void {\n if (!this.isOpen()) {\n return;\n }\n this.element.hidden = true;\n this.#lastFocused?.focus();\n this.#lastFocused = null;\n }\n\n toggle(): void {\n if (this.isOpen()) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /** The currently-focused element within the drawer's root (shadow-aware). */\n #activeElement(): Element | null {\n return (this.element.getRootNode() as Document | ShadowRoot).activeElement;\n }\n\n /** Escape-to-close and a Tab focus trap while the dialog is open. */\n #onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n event.preventDefault();\n this.close();\n return;\n }\n if (event.key !== \"Tab\") {\n return;\n }\n const focusables = Array.from(\n this.#panel.querySelectorAll<HTMLElement>(\"button, input, [tabindex]\"),\n ).filter((el) => !el.hidden);\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = this.#activeElement();\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first?.focus();\n }\n }\n\n /** Render the rows (or the empty state), highlighting the active thread. */\n setThreads(threads: readonly ThreadMeta[], activeId: string): void {\n this.#threads = threads;\n this.#activeId = activeId;\n this.#renderList();\n }\n\n #renderList(): void {\n this.#list.replaceChildren();\n if (this.#threads.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"drawer-empty\";\n empty.setAttribute(\"part\", \"drawer-empty\");\n empty.textContent = this.#strings.noConversations;\n this.#list.appendChild(empty);\n return;\n }\n for (const meta of this.#threads) {\n this.#list.appendChild(this.#renderRow(meta));\n }\n }\n\n #renderRow(meta: ThreadMeta): HTMLDivElement {\n const row = document.createElement(\"div\");\n row.className = \"drawer-row\";\n row.setAttribute(\"part\", \"drawer-row\");\n if (meta.threadId === this.#activeId) {\n row.classList.add(\"drawer-row--active\");\n }\n\n const select = document.createElement(\"button\");\n select.type = \"button\";\n select.className = \"drawer-row-select\";\n select.setAttribute(\"part\", \"drawer-row-select\");\n const title = document.createElement(\"span\");\n title.className = \"drawer-row-title\";\n title.setAttribute(\"part\", \"drawer-row-title\");\n title.textContent = meta.title;\n const time = document.createElement(\"span\");\n time.className = \"drawer-row-time\";\n time.setAttribute(\"part\", \"drawer-row-time\");\n time.textContent = relativeTime(meta.updatedAt, undefined, this.#strings);\n const preview = document.createElement(\"span\");\n preview.className = \"drawer-row-preview\";\n preview.setAttribute(\"part\", \"drawer-row-preview\");\n preview.textContent = meta.preview;\n select.append(title, time, preview);\n select.addEventListener(\"click\", () => {\n this.close();\n this.#callbacks.onSelect(meta.threadId);\n });\n\n const rename = document.createElement(\"button\");\n rename.type = \"button\";\n rename.className = \"drawer-row-rename\";\n rename.setAttribute(\"part\", \"drawer-row-rename\");\n rename.title = this.#strings.rename;\n rename.setAttribute(\"aria-label\", this.#strings.renameConversation);\n rename.textContent = \"\u270E\";\n rename.addEventListener(\"click\", () => this.#startRename(row, meta));\n\n const remove = document.createElement(\"button\");\n remove.type = \"button\";\n remove.className = \"drawer-row-delete\";\n remove.setAttribute(\"part\", \"drawer-row-delete\");\n remove.title = this.#strings.delete;\n remove.setAttribute(\"aria-label\", this.#strings.deleteConversation);\n remove.textContent = \"\uD83D\uDDD1\";\n remove.addEventListener(\"click\", () => this.#confirmDelete(row, meta));\n\n const actions = document.createElement(\"div\");\n actions.className = \"drawer-row-actions\";\n actions.setAttribute(\"part\", \"drawer-row-actions\");\n actions.append(rename, remove);\n\n row.append(select, actions);\n return row;\n }\n\n /** Swap a row for an inline rename input; Enter/blur commits, Escape cancels. */\n #startRename(row: HTMLDivElement, meta: ThreadMeta): void {\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.className = \"drawer-rename-input\";\n input.setAttribute(\"part\", \"drawer-rename-input\");\n input.value = meta.title;\n // One-shot: Enter, Escape, and blur can all fire for a single edit (Enter\n // commits and re-renders, which blurs the detached input); the flag makes\n // the later events no-ops so a rename isn't submitted twice.\n let done = false;\n const commit = (): void => {\n if (done) {\n return;\n }\n done = true;\n const value = input.value.trim();\n if (value === \"\" || value === meta.title) {\n this.#renderList();\n } else {\n this.#callbacks.onRename(meta.threadId, value);\n }\n };\n const cancel = (): void => {\n if (done) {\n return;\n }\n done = true;\n this.#renderList();\n };\n input.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n commit();\n } else if (event.key === \"Escape\") {\n // Stop the panel's Escape handler from also closing the drawer.\n event.preventDefault();\n event.stopPropagation();\n cancel();\n }\n });\n input.addEventListener(\"blur\", () => commit());\n row.replaceChildren(input);\n input.focus();\n input.select();\n }\n\n /** Swap a row for an inline \"Delete? [Delete] [Cancel]\" confirm. */\n #confirmDelete(row: HTMLDivElement, meta: ThreadMeta): void {\n const confirm = document.createElement(\"div\");\n confirm.className = \"drawer-confirm\";\n confirm.setAttribute(\"part\", \"drawer-confirm\");\n const label = document.createElement(\"span\");\n label.className = \"drawer-confirm-label\";\n label.setAttribute(\"part\", \"drawer-confirm-label\");\n label.textContent = this.#strings.deletePrompt;\n const yes = document.createElement(\"button\");\n yes.type = \"button\";\n yes.className = \"drawer-confirm-yes\";\n yes.setAttribute(\"part\", \"drawer-confirm-yes\");\n yes.textContent = this.#strings.delete;\n yes.addEventListener(\"click\", () => this.#callbacks.onDelete(meta.threadId));\n const no = document.createElement(\"button\");\n no.type = \"button\";\n no.className = \"drawer-confirm-no\";\n no.setAttribute(\"part\", \"drawer-confirm-no\");\n no.textContent = this.#strings.cancel;\n no.addEventListener(\"click\", () => this.#renderList());\n confirm.append(label, yes, no);\n row.replaceChildren(confirm);\n }\n}\n", "import { TOOL_CALL_STATUS, type TOOL_DISPLAY } from \"../constants.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Any state a tool-call card can be in. */\nexport type ToolCallStatus = (typeof TOOL_CALL_STATUS)[keyof typeof TOOL_CALL_STATUS];\n\n/** How much detail a card renders. */\nexport type ToolDisplayMode = (typeof TOOL_DISPLAY)[keyof typeof TOOL_DISPLAY];\n\n/** The two states a card can sit in before an outcome exists. */\nexport type UnsettledStatus = typeof TOOL_CALL_STATUS.PENDING | typeof TOOL_CALL_STATUS.DEFERRED;\n\n/** The terminal states a card settles into (everything unsettled excluded). */\nexport type SettledStatus = Exclude<ToolCallStatus, UnsettledStatus>;\n\n/** Short pill text shown for each status, drawn from the string table. */\nfunction statusLabels(strings: UiStrings): Record<ToolCallStatus, string> {\n return {\n [TOOL_CALL_STATUS.PENDING]: strings.toolRunning,\n [TOOL_CALL_STATUS.DEFERRED]: strings.toolDeferred,\n [TOOL_CALL_STATUS.DONE]: strings.toolDone,\n [TOOL_CALL_STATUS.ERROR]: strings.toolError,\n [TOOL_CALL_STATUS.DECLINED]: strings.toolDeclined,\n };\n}\n\n/** Section-heading text for each settled outcome's result region. */\nfunction resultLabels(strings: UiStrings): Record<SettledStatus, string> {\n return {\n [TOOL_CALL_STATUS.DONE]: strings.resultLabel,\n [TOOL_CALL_STATUS.ERROR]: strings.errorLabel,\n [TOOL_CALL_STATUS.DECLINED]: strings.declinedLabel,\n };\n}\n\n/** Pretty-print a JSON payload; fall back to the raw text if it isn't JSON. */\nfunction formatPayload(text: string): string {\n try {\n return JSON.stringify(JSON.parse(text), null, 2);\n } catch {\n return text;\n }\n}\n\n/**\n * A live tool-call card for the chat transcript.\n *\n * Construction renders a status icon, the tool name, a status pill, and a body\n * of two separately-headed regions \u2014 arguments and result \u2014 each with its own\n * `part`. {@link settle} fills in the result and flips the pill. Both payloads\n * are pretty-printed and never concatenated into one block.\n *\n * The card renders one DOM shape in every display mode and lets CSS decide what\n * shows, selecting visibility from the host attribute rather than a value\n * copied onto the card at construction. That is what lets `data-tool-display`\n * be flipped on the host and re-read by every card already on screen; building\n * a different structure per mode would leave existing cards stale.\n *\n * The leading icon carries no text: the shadow CSS draws its glyph or spinner\n * from the card's `data-status`, so a host themes it through the\n * `--ag-ui-tool-icon-*` custom properties or the `tool-card-icon` part without\n * the card reaching into the host stylesheet.\n *\n * Pure DOM. The host appends {@link element} into its shadow root; all visible\n * text comes from {@link UiStrings}.\n */\nexport class ToolCallCard {\n /** The card's root element; append this into the message list. */\n readonly element: HTMLDivElement;\n\n /**\n * Where a question about *this* call renders \u2014 the approval prompt for a\n * server-side tool the run deferred.\n *\n * It belongs to the card rather than to the transcript because a run can defer\n * several calls at once, and a prompt written per *tool* (\"Add this event to\n * the board?\") is identical for every one of them. Rendered into the answer\n * group they were three anonymous copies of one question, below the three\n * cards they gated; rendered here, position identifies them and the arguments\n * are already on screen above the question.\n *\n * Empty until used, and hidden while empty by the shadow CSS.\n */\n readonly approvalSlot: HTMLDivElement;\n\n readonly #status: HTMLSpanElement;\n readonly #decision: HTMLSpanElement;\n readonly #toggle: HTMLButtonElement;\n readonly #resultSection: HTMLDivElement;\n readonly #resultLabel: HTMLSpanElement;\n readonly #resultBody: HTMLPreElement;\n readonly #strings: UiStrings;\n #settled = false;\n\n constructor(\n name: string,\n args: Record<string, unknown>,\n summary?: string,\n strings: UiStrings = DEFAULT_UI_STRINGS,\n ) {\n this.#strings = strings;\n\n this.element = document.createElement(\"div\");\n this.element.className = \"tool-call\";\n this.element.setAttribute(\"part\", \"tool-card\");\n this.element.setAttribute(\"data-tool-name\", name);\n this.element.setAttribute(\"data-status\", TOOL_CALL_STATUS.PENDING);\n this.element.setAttribute(\"data-expanded\", \"false\");\n\n const head = document.createElement(\"div\");\n head.className = \"tool-call-head\";\n head.setAttribute(\"part\", \"tool-card-head\");\n\n // Left empty in the DOM on purpose: the shadow CSS draws the spinner or\n // settled mark from `data-status`, keeping the glyphs themeable.\n const icon = document.createElement(\"span\");\n icon.className = \"tool-call-icon\";\n icon.setAttribute(\"part\", \"tool-card-icon\");\n icon.setAttribute(\"aria-hidden\", \"true\");\n\n const label = document.createElement(\"span\");\n label.className = \"tool-call-name\";\n label.setAttribute(\"part\", \"tool-card-name\");\n // A server-provided `x-summary` label reads better than the raw tool name.\n label.textContent = summary ?? name;\n\n this.#status = document.createElement(\"span\");\n this.#status.className = \"tool-call-status\";\n this.#status.setAttribute(\"part\", \"tool-card-status\");\n this.#status.textContent = statusLabels(strings)[TOOL_CALL_STATUS.PENDING];\n\n this.#decision = document.createElement(\"span\");\n this.#decision.className = \"tool-call-decision\";\n this.#decision.setAttribute(\"part\", \"tool-card-decision\");\n this.#decision.hidden = true;\n\n head.append(icon, label, this.#status, this.#decision);\n\n const argsSection = this.#section(\"args\", strings.argumentsLabel);\n argsSection.body.textContent = JSON.stringify(args, null, 2);\n // Drop the region rather than frame an empty object.\n argsSection.root.hidden = Object.keys(args).length === 0;\n\n const resultSection = this.#section(\"result\", strings.resultLabel);\n this.#resultSection = resultSection.root;\n this.#resultLabel = resultSection.label;\n this.#resultBody = resultSection.body;\n // Nothing to show until `settle` supplies it, or a pending card expands\n // onto an empty region.\n resultSection.root.hidden = true;\n\n this.#toggle = document.createElement(\"button\");\n this.#toggle.type = \"button\";\n this.#toggle.className = \"tool-call-toggle\";\n this.#toggle.setAttribute(\"part\", \"tool-card-toggle\");\n this.#toggle.setAttribute(\"aria-expanded\", \"false\");\n this.#toggle.textContent = strings.details;\n this.#toggle.addEventListener(\"click\", () => this.#setExpanded(!this.#expanded()));\n\n const body = document.createElement(\"div\");\n body.className = \"tool-call-body\";\n body.setAttribute(\"part\", \"tool-card-body\");\n body.append(argsSection.root, resultSection.root);\n\n this.approvalSlot = document.createElement(\"div\");\n this.approvalSlot.className = \"tool-call-approval\";\n this.approvalSlot.setAttribute(\"part\", \"tool-card-approval\");\n\n this.element.append(head, this.#toggle, body, this.approvalSlot);\n }\n\n /**\n * Move between the two states that are not an outcome \u2014 `pending` (running)\n * and `deferred` (gated, waiting on a person).\n *\n * Ignored once {@link settle} has run: a card that was declined must not be\n * talked back into looking live by a late event.\n */\n mark(status: UnsettledStatus): void {\n if (this.#settled) {\n return;\n }\n this.element.setAttribute(\"data-status\", status);\n this.#status.textContent = statusLabels(this.#strings)[status];\n }\n\n /**\n * Record that a human approved or declined this call, as a line in the card.\n * The prompt disappears once answered, so this is the only lasting trace that\n * the call was gated at all.\n */\n recordDecision(kind: \"approved\" | \"declined\"): void {\n this.element.setAttribute(\"data-decision\", kind);\n this.#decision.textContent =\n kind === \"approved\" ? this.#strings.decisionApproved : this.#strings.decisionDeclined;\n this.#decision.hidden = false;\n }\n\n /** Whether {@link settle} has already run (so a terminal sweep can skip it). */\n get settled(): boolean {\n return this.#settled;\n }\n\n /**\n * Flip the status pill to `status` and fill in the result region, whose\n * heading names the outcome (result / error / declined).\n */\n settle(status: SettledStatus, text: string): void {\n // Idempotent: a duplicate `TOOL_CALL_RESULT`, or a replayed tool message\n // for an already-settled card, must not overwrite the first outcome.\n if (this.#settled) {\n return;\n }\n this.#settled = true;\n this.element.setAttribute(\"data-status\", status);\n this.#status.textContent = statusLabels(this.#strings)[status];\n this.#resultLabel.textContent = resultLabels(this.#strings)[status];\n this.#resultBody.textContent = formatPayload(text);\n this.#resultSection.hidden = false;\n }\n\n /** Build one labelled region of the body: a heading plus a payload block. */\n #section(\n kind: string,\n labelText: string,\n ): {\n root: HTMLDivElement;\n label: HTMLSpanElement;\n body: HTMLPreElement;\n } {\n const root = document.createElement(\"div\");\n root.className = `tool-call-section tool-call-section--${kind}`;\n root.setAttribute(\"part\", `tool-card-section tool-card-${kind}-section`);\n\n const label = document.createElement(\"span\");\n label.className = \"tool-call-section-label\";\n label.setAttribute(\"part\", `tool-card-section-label tool-card-${kind}-label`);\n label.textContent = labelText;\n\n const body = document.createElement(\"pre\");\n body.className = `tool-call-${kind}`;\n body.setAttribute(\"part\", `tool-card-${kind}`);\n\n root.append(label, body);\n return { root, label, body };\n }\n\n #expanded(): boolean {\n return this.element.getAttribute(\"data-expanded\") === \"true\";\n }\n\n #setExpanded(expand: boolean): void {\n this.element.setAttribute(\"data-expanded\", String(expand));\n this.#toggle.setAttribute(\"aria-expanded\", String(expand));\n }\n}\n", "import { ICON_VOICE } from \"../constants.js\";\nimport type { TranscribeHandler } from \"../core/transcribe_audio.js\";\nimport { DEFAULT_UI_STRINGS, type UiStrings } from \"./ui_strings.js\";\n\n/** Lifecycle of the mic button, reflected on its `data-state` for CSS. */\ntype VoiceState = \"idle\" | \"recording\" | \"transcribing\";\n\n/** Construction options for {@link VoiceInput}. */\nexport interface VoiceInputOptions {\n /** Turns a recorded clip into text (the built-in or a custom transport). */\n readonly transcribe: TranscribeHandler;\n /** Called with the transcript when a recording transcribes successfully. */\n readonly onText: (text: string) => void;\n /** UI string table (labels/tooltips). */\n readonly strings?: UiStrings;\n}\n\n/**\n * The composer's voice-input control: a mic button that records via\n * `MediaRecorder`, then POSTs the clip through a {@link TranscribeHandler} and\n * hands the transcript back via `onText`.\n *\n * Click to start recording, which prompts for mic permission, and again to stop\n * and transcribe. The button reflects its `idle` / `recording` / `transcribing`\n * state on `data-state` for theming and is exposed as `part=\"voice-button\"`; a\n * capture or transcription failure returns it to idle and surfaces the message\n * on its tooltip.\n *\n * Pure DOM. The host mounts {@link element} in the input row.\n */\nexport class VoiceInput {\n /** The mic button; mount this in the composer. */\n readonly element: HTMLButtonElement;\n\n readonly #transcribe: TranscribeHandler;\n readonly #onText: (text: string) => void;\n readonly #strings: UiStrings;\n #state: VoiceState = \"idle\";\n #recorder: MediaRecorder | null = null;\n #stream: MediaStream | null = null;\n #chunks: Blob[] = [];\n #disposed = false;\n\n constructor(options: VoiceInputOptions) {\n this.#transcribe = options.transcribe;\n this.#onText = options.onText;\n this.#strings = options.strings ?? DEFAULT_UI_STRINGS;\n\n this.element = document.createElement(\"button\");\n this.element.type = \"button\";\n this.element.className = \"voice-btn\";\n this.element.setAttribute(\"part\", \"voice-button\");\n // The mic glyph, in a slot so a host can project its own mark. Author-written\n // constant markup, never user or server data.\n const glyph = document.createElement(\"slot\");\n glyph.name = \"icon-voice\";\n glyph.innerHTML = ICON_VOICE;\n this.element.append(glyph);\n this.#setState(\"idle\");\n this.element.addEventListener(\"click\", () => {\n void this.toggle();\n });\n }\n\n /** Start recording when idle, stop (and transcribe) when recording. */\n async toggle(): Promise<void> {\n if (this.#state === \"recording\") {\n this.#stop();\n return;\n }\n if (this.#state === \"transcribing\") {\n return;\n }\n await this.#start();\n }\n\n async #start(): Promise<void> {\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch {\n this.#fail(this.#strings.transcriptionFailed);\n return;\n }\n this.#stream = stream;\n this.#chunks = [];\n const recorder = new MediaRecorder(stream);\n recorder.addEventListener(\"dataavailable\", (event) => {\n this.#chunks.push(event.data);\n });\n recorder.addEventListener(\"stop\", () => {\n void this.#finish(recorder.mimeType);\n });\n this.#recorder = recorder;\n recorder.start();\n this.#setState(\"recording\");\n }\n\n #stop(): void {\n // ``stop`` flushes a final ``dataavailable`` then fires ``stop`` \u2192 #finish.\n this.#recorder?.stop();\n }\n\n /**\n * Tear the control down, for a host element removed mid-recording. Stops any\n * live `MediaRecorder`, releases the mic tracks so the browser's recording\n * indicator clears, and suppresses the pending transcription \u2014 a\n * disconnected control must not fire `onText` into a detached element.\n */\n dispose(): void {\n this.#disposed = true;\n if (this.#recorder !== null && this.#recorder.state !== \"inactive\") {\n this.#recorder.stop();\n }\n this.#recorder = null;\n this.#releaseStream();\n }\n\n async #finish(mimeType: string): Promise<void> {\n if (this.#disposed) {\n return;\n }\n this.#releaseStream();\n this.#setState(\"transcribing\");\n const audio = new Blob(this.#chunks, { type: mimeType || \"audio/webm\" });\n try {\n const text = await this.#transcribe(audio);\n this.#setState(\"idle\");\n if (text !== \"\") {\n this.#onText(text);\n }\n } catch (error) {\n this.#fail(error instanceof Error ? error.message : this.#strings.transcriptionFailed);\n } finally {\n this.#recorder = null;\n }\n }\n\n /** Stop the mic tracks so the browser's recording indicator clears. */\n #releaseStream(): void {\n for (const track of this.#stream?.getTracks() ?? []) {\n track.stop();\n }\n this.#stream = null;\n }\n\n #fail(message: string): void {\n this.#releaseStream();\n this.#recorder = null;\n this.#setState(\"idle\");\n this.element.title = message;\n }\n\n #setState(state: VoiceState): void {\n this.#state = state;\n this.element.dataset[\"state\"] = state;\n const label = this.#labelFor(state);\n this.element.title = label;\n this.element.setAttribute(\"aria-label\", label);\n this.element.setAttribute(\"aria-pressed\", String(state === \"recording\"));\n // The control is inert while a clip transcribes (no second recording yet).\n this.element.disabled = state === \"transcribing\";\n }\n\n #labelFor(state: VoiceState): string {\n if (state === \"recording\") {\n return this.#strings.stopRecording;\n }\n if (state === \"transcribing\") {\n return this.#strings.transcribing;\n }\n return this.#strings.recordVoice;\n }\n}\n", "import {\n type AbstractAgent,\n type AgentSubscriber,\n buildResumeArray,\n type RunAgentParameters,\n randomUUID,\n} from \"@ag-ui/client\";\nimport type { Context, Interrupt, Message, ResumeEntry, Tool } from \"@ag-ui/core\";\nimport { MAX_TOOL_ROUNDS } from \"../constants.js\";\nimport type { AttachmentRef } from \"./attachment.js\";\n\n/** A tool call surfaced to the host by {@link AgUiClient}. */\nexport interface AgUiToolCall {\n readonly id: string;\n readonly name: string;\n readonly args: Record<string, unknown>;\n}\n\n/** The result of executing a frontend tool, destined for a tool-result message. */\nexport interface ToolExecution {\n /** String content for the AG-UI tool-result message. */\n content: string;\n /** Present when the handler failed; surfaced for logging. */\n error?: string;\n /**\n * When `true`, a navigating tool triggered a page reload. The loop stops\n * without appending a result \u2014 the result is supplied after the next mount\n * (see the resume path). Mutually exclusive with a usable `content`.\n */\n halt?: boolean;\n}\n\n/**\n * Executes a frontend tool call.\n *\n * Returns the {@link ToolExecution} to post back to the agent, or `null` when\n * the call is not a frontend tool the host owns \u2014 a server-side tool the server\n * already executed, which the client must not re-run.\n */\nexport type ExecuteTool = (call: AgUiToolCall) => Promise<ToolExecution | null>;\n\n/**\n * One user decision for a server-side-tool approval interrupt. Structurally\n * matches `@ag-ui/client`'s (non-exported) `ResumeResponse`, the payload\n * {@link buildResumeArray} turns into a `ResumeEntry`: `resolved` approves (with\n * an optional `payload`, e.g. `{ approved: true }`), `cancelled` denies.\n */\nexport type InterruptResponse = { status: \"resolved\"; payload?: unknown } | { status: \"cancelled\" };\n\n/**\n * Resolves the approval interrupts a run finished on, keyed by interrupt id.\n *\n * A gated server-side tool defers instead of executing, so the run finishes on\n * an interrupt outcome; the host collects one decision per interrupt and the\n * loop resumes with the answers. Omit for agents that never gate server-side\n * tools \u2014 an unresolved interrupt then ends the loop.\n */\nexport type ResolveInterrupts = (\n interrupts: readonly Interrupt[],\n) => Promise<Record<string, InterruptResponse>>;\n\n/**\n * Callbacks the {@link AgUiClient} invokes as a run progresses. The host\n * (the `<ag-ui-chat>` element) implements these to render streaming text and\n * tool activity into the chat.\n */\nexport interface AgUiClientHandlers {\n onRunStart(): void;\n /** Fired on every streamed token; `buffer` is the full text so far. */\n onTextDelta(buffer: string): void;\n /** Fired when the assistant message completes; `buffer` is the final text. */\n onTextEnd(buffer: string): void;\n /** Fired when the agent finishes calling a tool (server- or frontend-side). */\n onToolCall(call: AgUiToolCall): void;\n /**\n * Fired when a server-side tool's result streams back (AG-UI's\n * `TOOL_CALL_RESULT`). Frontend tools don't emit this \u2014 the client supplies\n * their result itself \u2014 so this is the channel for server-executed output.\n */\n onToolResult(toolCallId: string, content: string): void;\n /**\n * Fired for AG-UI activity events \u2014 ambient notices about what the *run* did,\n * as opposed to work the agent asked for. `django-ag-ui` emits one with\n * `activityType: \"compaction\"` when it condensed the history.\n */\n onActivity(activityType: string, content: unknown, messageId: string): void;\n /**\n * An activity's content changed in place \u2014 a snapshot re-sent under the same\n * `messageId` with `replace`, or an `ACTIVITY_DELTA` whose JSON patch\n * `@ag-ui/client` has already applied.\n *\n * Reported after the client has updated its own message, so `content` is the\n * result rather than the instruction. That is the whole reason this is a\n * separate callback: the raw delta event fires *before* the patch lands, and\n * a subscriber acting on it would redraw from stale content.\n */\n onActivityChanged(messageId: string, activityType: string, content: unknown): void;\n /** Fired when a reasoning model starts emitting its chain-of-thought. */\n onReasoningStart(): void;\n /** Fired on every reasoning token; ``buffer`` is the full reasoning text so far. */\n onReasoningDelta(buffer: string): void;\n /** Fired when the reasoning block ends (before the answer text streams). */\n onReasoningEnd(): void;\n onRunEnd(): void;\n onError(message: string): void;\n /**\n * Fired when the user cancelled the run ({@link AgUiClient.cancel}) \u2014 the\n * deliberate-stop sibling of `onError`. Partial assistant text already\n * streamed stays valid, so the host keeps the bubble and shows a stopped\n * affordance rather than an error. `onSettled` still follows.\n */\n onCancelled(): void;\n /**\n * Fired exactly once when the interaction settles, however the run loop ended\n * \u2014 server-only round, rounds exhausted, cancellation, or error. The terminal\n * guarantee that the UI returns to rest.\n */\n onSettled(): void;\n}\n\n/**\n * Provider of the per-run frontend tool catalog and context. Both are read\n * fresh on every {@link AgUiClient.send} so the catalog reflects the current\n * page state.\n */\nexport interface AgUiRunInputs {\n getTools?: () => Tool[];\n getContext?: () => Context[];\n}\n\nexport interface AgUiClientConfig extends AgUiRunInputs {\n /** The AG-UI agent to drive. Injected so it can be faked in tests. */\n agent: AbstractAgent;\n handlers: AgUiClientHandlers;\n /** Executes frontend tool calls. Omit for server-only tool sets. */\n executeTool?: ExecuteTool;\n /**\n * Resolves server-side-tool approval interrupts. Omit when no server-side\n * tool is gated for approval \u2014 an interrupt then ends the loop unanswered.\n */\n resolveInterrupts?: ResolveInterrupts;\n /**\n * Invoked with the latest history whenever it changes, so the host can\n * persist it for durability across page reloads. Omit to keep the\n * conversation in-memory only.\n */\n onPersist?: (messages: readonly Message[]) => void;\n /**\n * Called whenever AG-UI shared state changes \u2014 a streamed `STATE_SNAPSHOT` /\n * `STATE_DELTA`, or {@link AgUiClient.setState}. `@ag-ui/client` owns applying\n * those events; this only forwards the result.\n */\n onStateChanged?: (state: Readonly<Record<string, unknown>>) => void;\n /**\n * Error text for {@link AgUiClientHandlers.onError} when a run's stream closes\n * without a terminal AG-UI event. Defaults to `\"Connection lost\"`; the host\n * passes its localized string.\n */\n connectionLostMessage?: string;\n}\n\n/**\n * Raised when a run's stream closes cleanly at the transport level but never\n * emits a terminal AG-UI event, so the run neither finished nor errored. Routed\n * to {@link AgUiClientHandlers.onError} (it is not an abort), turning a silent\n * \"stuck pending\" into a visible \"connection lost\".\n */\nexport class ConnectionLostError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConnectionLostError\";\n }\n}\n\n/**\n * Thin orchestration layer over an AG-UI {@link AbstractAgent}.\n *\n * Translates AG-UI's subscriber callbacks into the host's\n * {@link AgUiClientHandlers}, and appends the user message + current frontend\n * tool catalog + context to each run.\n */\nexport class AgUiClient {\n readonly #agent: AbstractAgent;\n readonly #handlers: AgUiClientHandlers;\n readonly #getTools: () => Tool[];\n readonly #getContext: () => Context[];\n readonly #executeTool: ExecuteTool | null;\n readonly #resolveInterrupts: ResolveInterrupts | null;\n readonly #onPersist: (messages: readonly Message[]) => void;\n /**\n * Message ids the server has already closed, so a reuse can be reported. Per\n * client rather than per run \u2014 the merge happens across runs, which a per-run\n * set would miss entirely.\n */\n readonly #closedMessageIds = new Set<string>();\n readonly #connectionLostMessage: string;\n // Set by cancel(); reset at the top of each #run(). Checked by the loop so\n // a cancel between frontend-tool rounds doesn't start another round.\n #cancelled = false;\n\n constructor(config: AgUiClientConfig) {\n this.#agent = config.agent;\n this.#handlers = config.handlers;\n this.#getTools = config.getTools ?? (() => []);\n this.#getContext = config.getContext ?? (() => []);\n this.#executeTool = config.executeTool ?? null;\n this.#resolveInterrupts = config.resolveInterrupts ?? null;\n this.#onPersist = config.onPersist ?? (() => {});\n this.#connectionLostMessage = config.connectionLostMessage ?? \"Connection lost\";\n const onStateChanged = config.onStateChanged;\n if (onStateChanged !== undefined) {\n // The agent applies STATE_SNAPSHOT / STATE_DELTA itself; subscribing is\n // how the result is learned rather than re-derived from the event stream.\n // Lives for the agent's lifetime, which is this client's.\n this.#agent.subscribe({\n onStateChanged: ({ state }) => {\n onStateChanged(state as Record<string, unknown>);\n },\n });\n }\n }\n\n /** The current AG-UI shared state, as the agent last applied it. */\n get state(): Readonly<Record<string, unknown>> {\n return this.#agent.state as Record<string, unknown>;\n }\n\n /** Replace the shared state; the next run sends it as `RunAgentInput.state`. */\n setState(state: Readonly<Record<string, unknown>>): void {\n this.#agent.setState({ ...state });\n }\n\n /** Whether a run is currently in flight. */\n get running(): boolean {\n return this.#agent.isRunning;\n }\n\n /** The current conversation history (for persistence / rehydration). */\n get messages(): readonly Message[] {\n return this.#agent.messages;\n }\n\n /**\n * Append a user message and run the agent to completion.\n *\n * When the agent calls frontend tools, this executes them and re-runs the\n * agent with the results, looping until the agent stops calling frontend\n * tools (bounded by {@link MAX_TOOL_ROUNDS}).\n *\n * `attachments` ride on the user message as a non-standard field so the\n * default store round-trips them for history replay; see\n * {@link messageAttachments}.\n */\n async send(content: string, attachments: readonly AttachmentRef[] = []): Promise<void> {\n // Cast at the AG-UI boundary: `attachments` is a web-component augmentation\n // the strict `Message` union doesn't declare, but `addMessage` /\n // `structuredClone` preserve it verbatim.\n const message = { id: randomUUID(), role: \"user\", content } as Message;\n if (attachments.length > 0) {\n (message as { attachments?: readonly AttachmentRef[] }).attachments = attachments;\n }\n this.#agent.addMessage(message);\n this.#onPersist(this.#agent.messages);\n await this.#run();\n }\n\n /**\n * Resume the run loop after a navigating tool's result was supplied\n * post-reload (via {@link addToolResult}). Unlike {@link send}, adds no user\n * message; it continues the conversation already in history.\n */\n async resume(): Promise<void> {\n await this.#run();\n }\n\n /** Append a frontend tool result to history (used by the resume path). */\n addToolResult(toolCallId: string, content: string): void {\n this.#agent.addMessage({ id: randomUUID(), role: \"tool\", content, toolCallId });\n this.#onPersist(this.#agent.messages);\n }\n\n /**\n * Cancel the in-flight run (AG-UI has no server cancel route \u2014 aborting the\n * streaming request is the protocol's cancel; the server observes the\n * disconnect). Safe to call with no run in flight. Partial text already\n * streamed stays in history; {@link AgUiClientHandlers.onCancelled} fires\n * instead of `onError`, and `onSettled` still follows.\n */\n cancel(): void {\n this.#cancelled = true;\n this.#agent.abortRun();\n }\n\n async #run(): Promise<void> {\n this.#cancelled = false;\n try {\n await this.#runLoop();\n // `@ag-ui/client` filters abort errors inside `runAgent` (it resolves\n // rather than rejects on a cancelled fetch), so a cancelled run usually\n // ends here, not in the catch.\n if (this.#cancelled) {\n this.#onCancelled();\n }\n } catch (error) {\n if (this.#cancelled || isAbortError(error)) {\n this.#onCancelled();\n } else {\n this.#handlers.onError(error instanceof Error ? error.message : String(error));\n }\n } finally {\n this.#handlers.onSettled();\n }\n }\n\n #onCancelled(): void {\n // Persist so the truncated exchange, partial assistant text included,\n // survives a reload.\n this.#onPersist(this.#agent.messages);\n this.#handlers.onCancelled();\n }\n\n async #runLoop(): Promise<void> {\n // Carries resolved approval answers into the next run when a round finished\n // on a server-side-tool interrupt. Distinct from the public resume(), which\n // continues an unfinished frontend-tool round after a page load; this stays\n // inside one #run().\n let resume: ResumeEntry[] | undefined;\n for (let round = 0; round < MAX_TOOL_ROUNDS; round += 1) {\n // A cancel during the previous round's tool execution lands here: the\n // running handler completed, but no further round starts.\n if (this.#cancelled) {\n return;\n }\n const pending: AgUiToolCall[] = [];\n const runState: RunState = { terminal: false, errored: false, interrupts: [] };\n const params: RunAgentParameters = {\n tools: this.#getTools(),\n context: this.#getContext(),\n };\n if (resume !== undefined) {\n params.resume = resume;\n }\n await this.#agent.runAgent(params, this.#buildSubscriber(pending, runState));\n resume = undefined;\n this.#onPersist(this.#agent.messages);\n // Cancelled mid-stream: don't execute the tool calls collected before the\n // abort.\n if (this.#cancelled) {\n return;\n }\n // The stream resolved without RUN_FINISHED / RUN_ERROR, so the transport\n // dropped mid-run. Surface it as an error (via #run) rather than resting\n // silently with a stuck pending indicator.\n if (!runState.terminal) {\n throw new ConnectionLostError(this.#connectionLostMessage);\n }\n // RUN_ERROR is terminal and the agent already reported it via onError.\n // Executing the calls collected before it, or starting another round,\n // would run into a broken context and raise a confusing second error.\n // Pending tool cards are swept at onSettled.\n if (runState.errored) {\n return;\n }\n // A gated server-side tool deferred, so the run finished on an interrupt\n // outcome: resolve each interrupt, then re-enter carrying the answers so\n // the follow-up run executes or denies the tool. Must precede the\n // frontend-tool sweep below \u2014 a server-side tool isn't ours to run.\n if (runState.interrupts.length > 0) {\n if (this.#resolveInterrupts === null) {\n return;\n }\n const responses = await this.#resolveInterrupts(runState.interrupts);\n if (this.#cancelled) {\n return;\n }\n resume = buildResumeArray(runState.interrupts, responses);\n continue;\n }\n if (this.#executeTool === null || pending.length === 0) {\n return;\n }\n let executed = false;\n for (const call of pending) {\n const result = await this.#executeTool(call);\n if (result === null) {\n continue;\n }\n if (result.halt === true) {\n // A navigating tool reloaded the page; the result arrives on the\n // next mount. Stop here rather than re-running into a dead context.\n return;\n }\n this.#agent.addMessage({\n id: randomUUID(),\n role: \"tool\",\n content: result.content,\n toolCallId: call.id,\n });\n this.#onPersist(this.#agent.messages);\n executed = true;\n }\n if (!executed) {\n return;\n }\n }\n }\n\n #buildSubscriber(pending: AgUiToolCall[], runState: RunState): AgentSubscriber {\n const h = this.#handlers;\n const closed = this.#closedMessageIds;\n // Charts whose patch has been dispatched but not yet applied. Scoped to the\n // subscriber, so it cannot outlive the run that created it.\n const pendingDeltas = new Set<string>();\n return {\n onRunInitialized() {\n h.onRunStart();\n },\n onTextMessageStartEvent({ event }) {\n // A reused message id merges two answers into one persisted transcript\n // entry. The protocol has no rule to enforce and refusing the event\n // would be worse than the merge, so warn and continue \u2014 but do not stay\n // silent, since the corruption outlives the session.\n if (closed.has(event.messageId)) {\n console.warn(\n `<ag-ui-chat>: the server reused message id \"${event.messageId}\", which was ` +\n \"already closed. Its content will be appended to that earlier message rather \" +\n \"than starting a new one, and the merged result is what gets persisted. \" +\n \"Issue a fresh id per message.\",\n );\n }\n },\n onTextMessageContentEvent({ textMessageBuffer }) {\n h.onTextDelta(textMessageBuffer);\n },\n onTextMessageEndEvent({ event, textMessageBuffer }) {\n closed.add(event.messageId);\n h.onTextEnd(textMessageBuffer);\n },\n onToolCallEndEvent({ event, toolCallName, toolCallArgs }) {\n const call: AgUiToolCall = {\n id: event.toolCallId,\n name: toolCallName,\n args: toolCallArgs,\n };\n pending.push(call);\n h.onToolCall(call);\n },\n onToolCallResultEvent({ event }) {\n h.onToolResult(event.toolCallId, event.content);\n },\n onActivitySnapshotEvent({ event, messages }) {\n // A snapshot for an id already in the list is a replacement, not a new\n // activity: the client has swapped its content in place, and a second\n // append would leave the superseded one on screen.\n const known = messages.some(\n (message) => message.id === event.messageId && message.role === \"activity\",\n );\n if (known) {\n h.onActivityChanged(event.messageId, event.activityType, event.content);\n return;\n }\n h.onActivity(event.activityType, event.content, event.messageId);\n },\n // Deliberately does *not* read the message here. `@ag-ui/client`\n // dispatches this subscriber **before** applying the patch, so the\n // message still holds its previous content: redrawing from it would leave\n // the chart one revision behind for the life of the run, and disagreeing\n // with what a reload shows. Note which chart moved and read the result on\n // the change that follows.\n onActivityDeltaEvent({ event }) {\n pendingDeltas.add(event.messageId);\n },\n // Emitted after the client has written the patched messages, which is the\n // first moment the result exists. Only the ids marked above are looked at,\n // so an ordinary text delta does not walk the transcript.\n onMessagesChanged({ messages }) {\n if (pendingDeltas.size === 0) {\n return;\n }\n for (const id of pendingDeltas) {\n const message = messages.find((entry) => entry.id === id);\n if (message !== undefined && message.role === \"activity\") {\n h.onActivityChanged(id, message.activityType, message.content);\n }\n }\n pendingDeltas.clear();\n },\n // `@ag-ui/client` maps the deprecated THINKING_* events onto these\n // REASONING_* callbacks, so the reasoning family alone covers both\n // protocol versions.\n onReasoningStartEvent() {\n h.onReasoningStart();\n },\n onReasoningMessageContentEvent({ reasoningMessageBuffer }) {\n h.onReasoningDelta(reasoningMessageBuffer);\n },\n onReasoningEndEvent() {\n h.onReasoningEnd();\n },\n onRunFinishedEvent(params) {\n // RUN_FINISHED is terminal for both a normal finish and an interrupt.\n // Capture the interrupts here rather than reading the agent's\n // `pendingInterrupts` afterwards, to stay independent of that field's\n // cross-run clearing semantics.\n runState.terminal = true;\n if (params.outcome === \"interrupt\") {\n runState.interrupts = params.interrupts;\n }\n },\n onRunErrorEvent({ event }) {\n runState.terminal = true;\n runState.errored = true;\n h.onError(event.message);\n },\n onRunFinalized() {\n runState.terminal = true;\n h.onRunEnd();\n },\n };\n }\n}\n\n/** Per-run mutable flags the subscriber writes and {@link AgUiClient} reads. */\ninterface RunState {\n terminal: boolean;\n errored: boolean;\n /** Approval interrupts a run finished on (empty for a normal finish). */\n interrupts: Interrupt[];\n}\n\n/**\n * Whether a rejection came from aborting the run's fetch. Belt-and-suspenders\n * with the `#cancelled` flag: some `@ag-ui/client` versions re-throw the\n * `AbortError` instead of filtering it.\n */\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === \"AbortError\";\n}\n", "import type { Message } from \"@ag-ui/core\";\n\n/**\n * A durable, lightweight reference to one uploaded file \u2014 what an upload\n * returns and what rides on a sent message, never the bytes.\n *\n * Mirrors django-ag-ui's `AttachmentRef`: the file uploads out-of-band to the\n * attachments endpoint, the server hands back this ref, and the agent reads the\n * content server-side via the `read_attachment` tool.\n */\nexport interface AttachmentRef {\n /** Opaque, owner-scoped handle the server resolves back to bytes. */\n readonly id: string;\n /** Original filename, for display on the chip. */\n readonly name: string;\n /** Declared content type (a hint \u2014 the server is authoritative). */\n readonly mime: string;\n /** Size in bytes. */\n readonly size: number;\n /** Optional direct fetch URL (the owner-checked download endpoint). */\n readonly url?: string;\n}\n\n/**\n * The attachment refs a user message carries.\n *\n * Refs ride on the message as a non-standard `attachments` field, which the\n * default store round-trips and `@ag-ui/client` preserves through `addMessage`\n * / `structuredClone`, so a restored conversation re-renders its chips. The\n * server's strict `RunAgentInput` validation ignores the unknown field.\n *\n * Storage is untrusted \u2014 hand-edited, truncated, or corrupted \u2014 so malformed\n * entries are dropped here; a shapeless one would throw in `iconFor` and abort\n * the whole history replay.\n */\nexport function messageAttachments(message: Message): readonly AttachmentRef[] {\n const refs = (message as { attachments?: unknown }).attachments;\n return Array.isArray(refs) ? refs.filter(isAttachmentRef) : [];\n}\n\n/** Whether an unknown value is a structurally valid {@link AttachmentRef}. */\nfunction isAttachmentRef(value: unknown): value is AttachmentRef {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const ref = value as Record<string, unknown>;\n return (\n typeof ref[\"id\"] === \"string\" &&\n typeof ref[\"name\"] === \"string\" &&\n typeof ref[\"mime\"] === \"string\" &&\n typeof ref[\"size\"] === \"number\" &&\n (ref[\"url\"] === undefined || typeof ref[\"url\"] === \"string\")\n );\n}\n", "import { randomUUID } from \"@ag-ui/client\";\nimport type { Message } from \"@ag-ui/core\";\n\n/**\n * A checkpoint recorded just before a navigating tool reloads the page.\n *\n * The reload destroys the in-memory run loop, so the element persists this\n * marker first; on the next mount it supplies the tool's result and resumes.\n */\nexport interface NavigationCheckpoint {\n /** The tool-call id whose result must be supplied after the reload. */\n readonly toolCallId: string;\n}\n\n/**\n * Lightweight metadata for one conversation \u2014 the thread-drawer row shape, so\n * the drawer renders without loading message bodies. `title` defaults to a\n * truncation of the first user message until an explicit rename, `preview` is a\n * one-line excerpt of the latest message, and `updatedAt` is epoch ms of the\n * last change, which orders the list.\n */\nexport interface ThreadMeta {\n readonly threadId: string;\n readonly title: string;\n readonly updatedAt: number;\n readonly preview: string;\n}\n\n/**\n * Client-side persistence seam for the conversation and a pending-navigation\n * checkpoint, keyed by `thread_id`.\n *\n * The default {@link SessionStorageStore} keeps everything per-tab. A host may\n * inject a server-backed store instead, which is why `loadMessages` and\n * `listThreads` are async. The checkpoint methods stay synchronous: the marker\n * is a small local hint a server store can derive from history and no-op.\n *\n * Thread enumeration backs the chat-history drawer; deleting a thread reuses\n * {@link clear} and \"new chat\" reuses {@link threadId} after clearing the\n * active thread.\n */\nexport interface ClientConversationStore {\n /** The active conversation id, generated and persisted on first read. */\n threadId(): string;\n /** Load the persisted message history, or `null` when none exists. */\n loadMessages(threadId: string): Promise<readonly Message[] | null>;\n /** Persist the message history (and refresh the thread's drawer metadata). */\n saveMessages(threadId: string, messages: readonly Message[]): void;\n /** Load the pending-navigation checkpoint, or `null` when none is set. */\n loadCheckpoint(threadId: string): NavigationCheckpoint | null;\n /** Set the pending-navigation checkpoint, or clear it when given `null`. */\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void;\n /** Forget the conversation and checkpoint (a \"delete thread\" / \"new chat\"). */\n clear(threadId: string): void;\n /** The user's threads as drawer metadata (no message bodies), newest first. */\n listThreads(): Promise<readonly ThreadMeta[]>;\n /** Make `threadId` the active conversation (the drawer selecting a row). */\n setActiveThread(threadId: string): void;\n /** Set a thread's display title (the drawer renaming a row). */\n renameThread(threadId: string, title: string): void;\n /**\n * Whether `threadId` was minted here and has never been saved \u2014 a thread in\n * which nothing has been sent yet.\n *\n * Exists so a server-backed store can skip asking a server for history that\n * cannot be there: the element mints an id on first mount and immediately tries\n * to restore it, which answers `404` and logs one in the console on every first\n * visit. Nothing is wrong, and it looks exactly like something being wrong.\n *\n * Optional, and deliberately narrow. A store that cannot tell omits it and the\n * fetch happens as before, which is also the right answer for a store that\n * holds nothing locally: \"I have no messages for this id\" is not the same claim\n * as \"this id is new\", and only the store that minted the id can make the\n * second one. A thread picked from the drawer was never minted here, so it is\n * still fetched.\n */\n isUnsent?(threadId: string): boolean;\n}\n\nconst KEY_ROOT = \"ag-ui-chat\";\nconst THREAD_SUFFIX = \"thread\";\nconst THREADS_SUFFIX = \"threads\";\nconst MESSAGES_SUFFIX = \"messages:\";\nconst CHECKPOINT_SUFFIX = \"checkpoint:\";\n// Marks an id this store minted and nothing has been sent in yet. Dropped on\n// the first save, so it never outlives the one question it answers.\nconst MINTED_SUFFIX = \"minted:\";\n\nconst TITLE_LIMIT = 60;\nconst PREVIEW_LIMIT = 100;\nconst DEFAULT_TITLE = \"New conversation\";\n\n/** The drawer-index entry; `titleCustom` (private) freezes a renamed title. */\ninterface StoredThread {\n threadId: string;\n title: string;\n titleCustom: boolean;\n preview: string;\n updatedAt: number;\n}\n\n/**\n * Default {@link ClientConversationStore}: per-tab `sessionStorage`.\n *\n * Survives full page reloads and same-tab navigation, clears on tab close.\n * Tracks multiple threads per tab: the active id under one key, message history\n * and checkpoint namespaced by id, and a small index feeding the drawer with no\n * server involved.\n *\n * An optional `namespace` scopes every key to one element, so two\n * `<ag-ui-chat>` instances on the same origin keep separate active-thread\n * pointers and drawer indexes instead of clobbering each other. The default\n * empty namespace keeps the origin-global keys; see {@link #migrateLegacyKeys}.\n */\nexport class SessionStorageStore implements ClientConversationStore {\n readonly #root: string;\n\n constructor(namespace = \"\") {\n this.#root = namespace === \"\" ? KEY_ROOT : `${KEY_ROOT}@${namespace}`;\n if (namespace !== \"\") {\n this.#migrateLegacyKeys();\n }\n }\n\n threadId(): string {\n const key = this.#key(THREAD_SUFFIX);\n const existing = sessionStorage.getItem(key);\n if (existing !== null) {\n return existing;\n }\n const id = randomUUID();\n sessionStorage.setItem(key, id);\n sessionStorage.setItem(this.#key(MINTED_SUFFIX + id), \"1\");\n return id;\n }\n\n isUnsent(threadId: string): boolean {\n return (\n sessionStorage.getItem(this.#key(MINTED_SUFFIX + threadId)) !== null &&\n sessionStorage.getItem(this.#key(MESSAGES_SUFFIX + threadId)) === null\n );\n }\n\n loadMessages(threadId: string): Promise<readonly Message[] | null> {\n return Promise.resolve(this.#readJson<Message[]>(this.#key(MESSAGES_SUFFIX + threadId)));\n }\n\n saveMessages(threadId: string, messages: readonly Message[]): void {\n sessionStorage.setItem(this.#key(MESSAGES_SUFFIX + threadId), JSON.stringify(messages));\n sessionStorage.removeItem(this.#key(MINTED_SUFFIX + threadId));\n this.#touchThread(threadId, messages);\n }\n\n loadCheckpoint(threadId: string): NavigationCheckpoint | null {\n return this.#readJson<NavigationCheckpoint>(this.#key(CHECKPOINT_SUFFIX + threadId));\n }\n\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void {\n const key = this.#key(CHECKPOINT_SUFFIX + threadId);\n if (checkpoint === null) {\n sessionStorage.removeItem(key);\n return;\n }\n sessionStorage.setItem(key, JSON.stringify(checkpoint));\n }\n\n clear(threadId: string): void {\n sessionStorage.removeItem(this.#key(MESSAGES_SUFFIX + threadId));\n sessionStorage.removeItem(this.#key(CHECKPOINT_SUFFIX + threadId));\n sessionStorage.removeItem(this.#key(MINTED_SUFFIX + threadId));\n this.#writeThreads(this.#readThreads().filter((thread) => thread.threadId !== threadId));\n // Only drop the active pointer when the active thread itself is cleared, so\n // the next `threadId()` mints a fresh one. Deleting another thread from the\n // drawer must not disturb the conversation on screen.\n if (sessionStorage.getItem(this.#key(THREAD_SUFFIX)) === threadId) {\n sessionStorage.removeItem(this.#key(THREAD_SUFFIX));\n }\n }\n\n listThreads(): Promise<readonly ThreadMeta[]> {\n const metas = this.#readThreads()\n .sort((a, b) => b.updatedAt - a.updatedAt)\n .map(({ threadId, title, updatedAt, preview }) => ({ threadId, title, updatedAt, preview }));\n return Promise.resolve(metas);\n }\n\n setActiveThread(threadId: string): void {\n sessionStorage.setItem(this.#key(THREAD_SUFFIX), threadId);\n }\n\n renameThread(threadId: string, title: string): void {\n const threads = this.#readThreads();\n const entry = threads.find((thread) => thread.threadId === threadId);\n if (entry === undefined) {\n return;\n }\n entry.title = title;\n entry.titleCustom = true;\n this.#writeThreads(threads);\n }\n\n /** Add or refresh a thread's drawer metadata from its latest messages. */\n #touchThread(threadId: string, messages: readonly Message[]): void {\n const threads = this.#readThreads();\n const entry = threads.find((thread) => thread.threadId === threadId);\n const preview = derivePreview(messages);\n const updatedAt = Date.now();\n if (entry === undefined) {\n threads.push({\n threadId,\n title: deriveTitle(messages),\n titleCustom: false,\n preview,\n updatedAt,\n });\n } else {\n entry.preview = preview;\n entry.updatedAt = updatedAt;\n if (!entry.titleCustom) {\n entry.title = deriveTitle(messages);\n }\n }\n this.#writeThreads(threads);\n }\n\n #readThreads(): StoredThread[] {\n return this.#readJson<StoredThread[]>(this.#key(THREADS_SUFFIX)) ?? [];\n }\n\n #writeThreads(threads: readonly StoredThread[]): void {\n const key = this.#key(THREADS_SUFFIX);\n if (threads.length === 0) {\n sessionStorage.removeItem(key);\n return;\n }\n sessionStorage.setItem(key, JSON.stringify(threads));\n }\n\n /** This store's fully-qualified key for a suffix (namespaced when set). */\n #key(suffix: string): string {\n return `${this.#root}:${suffix}`;\n }\n\n /**\n * One-time move of un-namespaced `ag-ui-chat:*` keys into this instance's\n * namespace, so an existing conversation isn't orphaned. Only this store's own\n * keys move \u2014 the element's `collapsed` / `theme` keys are left alone. The\n * first namespaced instance to mount adopts the data; a second namespace\n * finds it gone and starts fresh.\n */\n #migrateLegacyKeys(): void {\n const legacyRoot = `${KEY_ROOT}:`;\n const moves: Array<readonly [string, string]> = [];\n for (let i = 0; i < sessionStorage.length; i += 1) {\n const key = sessionStorage.key(i);\n if (key === null || !key.startsWith(legacyRoot)) {\n continue;\n }\n const suffix = key.slice(legacyRoot.length);\n if (isOwnedSuffix(suffix)) {\n moves.push([key, this.#key(suffix)]);\n }\n }\n // Collected first, mutated second \u2014 writing while iterating by index skips\n // entries as the key list shifts.\n for (const [from, to] of moves) {\n const value = sessionStorage.getItem(from);\n if (value !== null && sessionStorage.getItem(to) === null) {\n sessionStorage.setItem(to, value);\n }\n sessionStorage.removeItem(from);\n }\n }\n\n /** Parse a stored JSON value, returning `null` when absent or corrupt. */\n #readJson<T>(key: string): T | null {\n const raw = sessionStorage.getItem(key);\n if (raw === null) {\n return null;\n }\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n }\n}\n\n/** Whether a legacy key suffix belongs to the store (vs the element's own keys). */\nfunction isOwnedSuffix(suffix: string): boolean {\n return (\n suffix === THREAD_SUFFIX ||\n suffix === THREADS_SUFFIX ||\n suffix.startsWith(MESSAGES_SUFFIX) ||\n suffix.startsWith(CHECKPOINT_SUFFIX)\n );\n}\n\n/** The thread title: the first user message, collapsed + truncated. */\nfunction deriveTitle(messages: readonly Message[]): string {\n for (const message of messages) {\n if (message.role === \"user\") {\n const text = cleanText(message.content);\n if (text !== \"\") {\n return truncate(text, TITLE_LIMIT);\n }\n }\n }\n return DEFAULT_TITLE;\n}\n\n/** A one-line preview: the latest message with text, collapsed + truncated. */\nfunction derivePreview(messages: readonly Message[]): string {\n for (const message of [...messages].reverse()) {\n const text = cleanText(message.content);\n if (text !== \"\") {\n return truncate(text, PREVIEW_LIMIT);\n }\n }\n return \"\";\n}\n\n/** Whitespace-collapsed message text, or `\"\"` for non-string content. */\nfunction cleanText(content: unknown): string {\n return typeof content === \"string\" ? content.replace(/\\s+/g, \" \").trim() : \"\";\n}\n\nfunction truncate(text: string, limit: number): string {\n return text.length <= limit ? text : `${text.slice(0, limit - 1).trimEnd()}\u2026`;\n}\n", "import { type AbstractAgent, HttpAgent } from \"@ag-ui/client\";\nimport type { Message } from \"@ag-ui/core\";\nimport { withCredentials } from \"./utils.js\";\n\n/** Config for {@link createHttpAgent}. */\nexport interface HttpAgentOptions {\n endpoint: string;\n headers?: Record<string, string>;\n /**\n * Cookie policy for the run request, as `fetch`'s own `credentials` mode.\n * Unset leaves the browser default (`same-origin`), which sends no cookies\n * to an agent endpoint on a different origin or subdomain. A\n * cookie-authenticated cross-origin deployment needs `\"include\"` here plus a\n * server answering with `Access-Control-Allow-Credentials: true` and a\n * concrete origin.\n */\n credentials?: RequestCredentials;\n /**\n * Live header source, re-read on every request, overlaid on `headers`.\n * `HttpAgent` bakes static `headers` in at construction and the element\n * caches the agent for the whole conversation, so rotating credentials (CSRF,\n * short-lived JWT) must come through here.\n */\n getHeaders?: () => Record<string, string>;\n /** Stable conversation id, so the agent's runs share a thread. */\n threadId?: string;\n /** Rehydrated history to seed the agent with (durable conversation). */\n initialMessages?: readonly Message[];\n /**\n * AG-UI shared state to seed the agent with. `@ag-ui/client` sends it as\n * `RunAgentInput.state` on every run and replaces it in place when the\n * server streams `STATE_SNAPSHOT` / `STATE_DELTA`.\n */\n initialState?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Build an AG-UI {@link HttpAgent} pointed at `endpoint`.\n *\n * The default agent factory for `<ag-ui-chat>`; tests and advanced hosts\n * override the element's `agentFactory` to inject a different\n * {@link AbstractAgent}.\n */\nexport function createHttpAgent(options: HttpAgentOptions): AbstractAgent {\n return new HttpAgent({\n url: options.endpoint,\n headers: options.headers ?? {},\n initialState: { ...(options.initialState ?? {}) },\n // HttpAgent invokes its configured fetch as a method (`this.fetch(...)`),\n // rebinding the global `fetch` to the agent instance \u2014 \"Illegal invocation\"\n // in browsers. The wrapper keeps `fetch` a free call, and is also where the\n // per-request `getHeaders()` overlay and the cookie policy go, the agent's\n // own config having no seam for either.\n fetch: (url, init) => {\n const fresh = options.getHeaders?.();\n if (fresh === undefined) {\n return fetch(url, withCredentials(init, options.credentials));\n }\n const headers = new Headers(init?.headers);\n for (const [name, value] of Object.entries(fresh)) {\n headers.set(name, value);\n }\n return fetch(url, withCredentials({ ...init, headers }, options.credentials));\n },\n // Spread conditionally: under `exactOptionalPropertyTypes` an explicit\n // `undefined` is not assignable to an optional field.\n ...(options.threadId !== undefined ? { threadId: options.threadId } : {}),\n ...(options.initialMessages !== undefined\n ? { initialMessages: [...options.initialMessages] }\n : {}),\n });\n}\n\n/** Signature of the agent factory the element calls to build its agent. */\nexport type AgentFactory = (options: HttpAgentOptions) => AbstractAgent;\n", "// Non-exported-from-index helpers shared by the core transport modules.\n\n/**\n * Overlay a `credentials` mode onto a fetch `init`, or hand the `init` back\n * untouched when none is configured.\n *\n * Absent and `undefined` differ: `exactOptionalPropertyTypes` rejects an\n * explicit `credentials: undefined`, and writing one anyway would state a mode\n * where the point is to leave the browser's own default in place.\n */\nexport function withCredentials(\n init: RequestInit | undefined,\n credentials: RequestCredentials | undefined,\n): RequestInit | undefined {\n return credentials === undefined ? init : { ...init, credentials };\n}\n", "import type { Message } from \"@ag-ui/core\";\nimport {\n type ClientConversationStore,\n type NavigationCheckpoint,\n SessionStorageStore,\n type ThreadMeta,\n} from \"./conversation_store.js\";\nimport { withCredentials } from \"./utils.js\";\n\n/** One row of the server thread index (django-ag-ui's `ThreadsView` wire shape). */\ninterface ServerThreadRow {\n readonly thread_id: string;\n readonly title: string;\n readonly updated_at: string | null;\n readonly preview: string;\n}\n\n/** Live header source, read per request so rotated tokens / CSRF reach the server. */\ntype HeadersProvider = () => Record<string, string>;\n\n/**\n * Live cookie policy, read per request. A provider rather than a value: the\n * store is built once on connect, but a host may configure the element after\n * inserting it, and a captured value would pin that first frame's setting.\n */\ntype CredentialsProvider = () => RequestCredentials | undefined;\n\n/**\n * A {@link ClientConversationStore} backed by a server thread-index endpoint \u2014\n * django-ag-ui's owner-scoped `ThreadsView`, the URL passed to `<ag-ui-chat>`\n * as `data-threads-url`:\n *\n * - `GET <url>` \u2192 list the user's threads (metadata only);\n * - `GET <url><id>/` \u2192 that thread's messages;\n * - `PATCH <url><id>/` \u2192 rename (`{ \"title\": \u2026 }`);\n * - `DELETE <url><id>/` \u2192 delete.\n *\n * Wraps a local store (default {@link SessionStorageStore}) for the client-only\n * concerns \u2014 active thread id, navigation checkpoint, message cache \u2014 and as\n * the fallback when a request fails. Rename and delete apply optimistically via\n * a local overlay, so the drawer reflects them before the fire-and-forget\n * round-trip lands.\n */\nexport class RemoteConversationStore implements ClientConversationStore {\n readonly #url: string;\n readonly #headers: HeadersProvider;\n readonly #local: ClientConversationStore;\n readonly #credentials: CredentialsProvider;\n readonly #dropped = new Set<string>();\n readonly #renamed = new Map<string, string>();\n\n constructor(\n url: string,\n headers: HeadersProvider = () => ({}),\n local: ClientConversationStore = new SessionStorageStore(),\n credentials: CredentialsProvider = () => undefined,\n ) {\n this.#url = url.endsWith(\"/\") ? url : `${url}/`;\n this.#headers = headers;\n this.#local = local;\n this.#credentials = credentials;\n }\n\n threadId(): string {\n return this.#local.threadId();\n }\n\n setActiveThread(threadId: string): void {\n this.#local.setActiveThread(threadId);\n }\n\n /** Delegated, so wrapping a store does not lose what it knows about its own ids. */\n isUnsent(threadId: string): boolean {\n return this.#local.isUnsent?.(threadId) === true;\n }\n\n saveMessages(threadId: string, messages: readonly Message[]): void {\n // The agent run persists server-side; keep a local cache for offline replay.\n this.#local.saveMessages(threadId, messages);\n }\n\n loadCheckpoint(threadId: string): NavigationCheckpoint | null {\n return this.#local.loadCheckpoint(threadId);\n }\n\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void {\n this.#local.saveCheckpoint(threadId, checkpoint);\n }\n\n renameThread(threadId: string, title: string): void {\n this.#local.renameThread(threadId, title);\n this.#renamed.set(threadId, title);\n void this.#mutate(threadId, \"PATCH\", { title });\n }\n\n clear(threadId: string): void {\n this.#local.clear(threadId);\n this.#dropped.add(threadId);\n void this.#mutate(threadId, \"DELETE\");\n }\n\n async listThreads(): Promise<readonly ThreadMeta[]> {\n const rows = await this.#fetchThreads();\n if (rows === null) {\n return this.#local.listThreads();\n }\n return rows.filter((row) => !this.#dropped.has(row.thread_id)).map((row) => this.#toMeta(row));\n }\n\n async loadMessages(threadId: string): Promise<readonly Message[] | null> {\n // Don't ask the server for a thread it cannot have. The element mints an id\n // on first mount and immediately tries to restore it, so every first visit\n // spent a request to be told `404` \u2014 and logged one in the console, on a page\n // where nothing had gone wrong. Only the store that minted the id can say\n // that; a thread chosen from the drawer, or one created on another device, is\n // still fetched. See `ClientConversationStore.isUnsent`.\n if (this.#local.isUnsent?.(threadId) === true) {\n return null;\n }\n const response = await this.#get(`${this.#url}${encodeURIComponent(threadId)}/`);\n if (response === null || !response.ok) {\n return this.#local.loadMessages(threadId);\n }\n // A 200 whose body isn't JSON (a proxy's HTML error page, a truncated\n // stream) must not throw an unhandled rejection that the caller's\n // `void #rehydrate()` swallows; fall back to the local cache.\n const body = await this.#readJson<{ messages?: readonly Message[] }>(response);\n if (body === null) {\n return this.#local.loadMessages(threadId);\n }\n return body.messages ?? null;\n }\n\n async #fetchThreads(): Promise<readonly ServerThreadRow[] | null> {\n const response = await this.#get(this.#url);\n if (response === null || !response.ok) {\n return null;\n }\n const body = await this.#readJson<{ threads?: readonly ServerThreadRow[] }>(response);\n if (body === null) {\n return null;\n }\n return body.threads ?? [];\n }\n\n /** Parse a `Response` body as JSON, or `null` when it isn't valid JSON. */\n async #readJson<T>(response: Response): Promise<T | null> {\n try {\n return (await response.json()) as T;\n } catch {\n return null;\n }\n }\n\n #toMeta(row: ServerThreadRow): ThreadMeta {\n return {\n threadId: row.thread_id,\n title: this.#renamed.get(row.thread_id) ?? row.title,\n // `null` and an unparseable date both become NaN, Date.parse's own\n // signal, which `relativeTime` renders as a neutral label rather than an\n // epoch-0 or NaN duration.\n updatedAt: row.updated_at === null ? Number.NaN : Date.parse(row.updated_at),\n preview: row.preview,\n };\n }\n\n /** GET that resolves to the `Response`, or `null` on a network error. */\n async #get(url: string): Promise<Response | null> {\n try {\n return await fetch(url, withCredentials({ headers: this.#headers() }, this.#credentials()));\n } catch {\n return null;\n }\n }\n\n /** Fire a best-effort write to the thread endpoint; failures are tolerated. */\n async #mutate(\n threadId: string,\n method: \"PATCH\" | \"DELETE\",\n body?: { title: string },\n ): Promise<void> {\n const headers = this.#headers();\n try {\n await fetch(\n `${this.#url}${encodeURIComponent(threadId)}/`,\n withCredentials(\n {\n method,\n headers:\n body === undefined ? headers : { ...headers, \"content-type\": \"application/json\" },\n body: body === undefined ? null : JSON.stringify(body),\n },\n this.#credentials(),\n ),\n );\n } catch {\n // Best-effort; the optimistic overlay keeps the drawer consistent.\n }\n }\n}\n", "import { withCredentials } from \"./utils.js\";\n\n/** One row of the server run index (django-ag-ui's `RunsView` wire shape). */\nexport interface RunRow {\n readonly run_id: string;\n readonly thread_id: string | null;\n readonly parent_run_id: string | null;\n readonly started_at: string | null;\n /** Whether the run has a snapshot to seed from \u2014 see {@link RunIndex}. */\n readonly continuable: boolean;\n /**\n * The run's first user message, one line, already truncated by the server \u2014\n * the only field in a row a person recognises a conversation by.\n *\n * Optional because a server predating the field does not send it, and\n * `null` where the run holds no words to show (seeded from history alone, or\n * opened with an image and no caption). A row without one falls back to the\n * time plus a short id, which is what every row used to be.\n */\n readonly preview?: string | null;\n}\n\n/** Live header source, read per request so rotated tokens / CSRF reach the server. */\ntype HeadersProvider = () => Record<string, string>;\n\n/** Live cookie policy, read per request; see `RemoteConversationStore`'s note. */\ntype CredentialsProvider = () => RequestCredentials | undefined;\n\n/**\n * Reads the server's run index and derives the resume / fork URLs beside it.\n *\n * Backed by django-ag-ui's owner-scoped `RunsView` \u2014 the URL passed to\n * `<ag-ui-chat>` as `data-runs-url`:\n *\n * - `GET <url>` \u2192 the user's runs, newest first.\n *\n * Only `continuable` rows can be resumed: the server reports whether a run has\n * a saved snapshot to seed from, and a run that never reached a provider-valid\n * boundary has none. Offer the action only for those rows ({@link continuable}\n * filters them) and treat the rest as informational.\n *\n * Resume and fork are siblings of the index rather than separate configuration\n * \u2014 django-ag-ui mounts `runs/`, `resume/<id>/` and `fork/<id>/` under one\n * prefix \u2014 so this one URL locates all three.\n */\nexport class RunIndex {\n readonly #url: string;\n readonly #headers: HeadersProvider;\n readonly #credentials: CredentialsProvider;\n\n constructor(\n url: string,\n headers: HeadersProvider = () => ({}),\n credentials: CredentialsProvider = () => undefined,\n ) {\n this.#url = url.endsWith(\"/\") ? url : `${url}/`;\n this.#headers = headers;\n this.#credentials = credentials;\n }\n\n /**\n * The user's runs, or `[]` when the endpoint is unreachable or errors \u2014 the\n * caller renders its empty state rather than a transport fault the user can\n * do nothing about.\n */\n async list(): Promise<readonly RunRow[]> {\n try {\n const response = await fetch(\n this.#url,\n withCredentials(\n {\n method: \"GET\",\n headers: { Accept: \"application/json\", ...this.#headers() },\n },\n this.#credentials(),\n ),\n );\n if (!response.ok) {\n return [];\n }\n const body = (await response.json()) as { runs?: readonly RunRow[] };\n return body.runs ?? [];\n } catch {\n return [];\n }\n }\n\n /** The rows a client may actually continue. */\n async continuable(): Promise<readonly RunRow[]> {\n return (await this.list()).filter((run) => run.continuable);\n }\n\n /** The endpoint that continues `runId` as a new run. */\n resumeUrl(runId: string): string {\n return this.#sibling(\"resume\", runId);\n }\n\n /** The endpoint that branches `runId` into a new run, leaving the source untouched. */\n forkUrl(runId: string): string {\n return this.#sibling(\"fork\", runId);\n }\n\n /**\n * `<mount>/<verb>/<runId>/`, derived from the index URL's own prefix.\n *\n * String surgery on the trailing `runs/` rather than `new URL`, because the\n * configured value may be root-relative (`/agent/runs/`), the common case in\n * a Django template, and `new URL` needs an absolute base.\n */\n #sibling(verb: string, runId: string): string {\n const prefix = this.#url.slice(0, -\"runs/\".length);\n return `${prefix}${verb}/${encodeURIComponent(runId)}/`;\n }\n}\n", "import { withCredentials } from \"./utils.js\";\n\n/**\n * The composer's voice-transcription contract: take a recorded audio `Blob` and\n * resolve to the transcript text. The built-in handler is\n * {@link transcribeAudio}; a host swaps in its own (a Web Speech adapter, a\n * direct-to-provider call) via `AgUiChat.transcribeHandler` without touching\n * the mic button.\n */\nexport type TranscribeHandler = (audio: Blob) => Promise<string>;\n\n/** Options for {@link transcribeAudio}. */\nexport interface TranscribeOptions {\n /** The transcription endpoint (`data-transcribe-url`). */\n readonly url: string;\n /** Extra HTTP headers (CSRF / auth), read fresh per request. */\n readonly headers?: Record<string, string>;\n /**\n * Cookie policy, as `fetch`'s own `credentials` mode. Unset leaves the\n * browser default (`same-origin`), which sends no cookies to an endpoint on\n * another origin; a cookie-authenticated cross-origin deployment needs\n * `\"include\"`.\n */\n readonly credentials?: RequestCredentials;\n}\n\n/**\n * POST a recorded clip to the transcription endpoint and resolve to its text.\n *\n * The clip goes as multipart under the `audio` field with the element's\n * `headers`, mirroring {@link uploadAttachment}, and the server replies\n * `{ \"text\": \"<transcript>\" }`. A non-2xx response or a network error rejects\n * so the mic button can surface the failure.\n */\nexport async function transcribeAudio(audio: Blob, options: TranscribeOptions): Promise<string> {\n const form = new FormData();\n // The extension is cosmetic: the server reads the blob's content type.\n form.append(\"audio\", audio, \"recording.webm\");\n\n const response = await fetch(\n options.url,\n withCredentials(\n {\n method: \"POST\",\n headers: { ...(options.headers ?? {}) },\n body: form,\n },\n options.credentials,\n ),\n );\n if (!response.ok) {\n throw new Error(await errorMessage(response));\n }\n const body: unknown = await response.json();\n if (\n typeof body === \"object\" &&\n body !== null &&\n typeof (body as { text?: unknown }).text === \"string\"\n ) {\n return (body as { text: string }).text;\n }\n throw new Error(\"transcription returned an unreadable response\");\n}\n\n/** A human-readable message from a non-2xx transcription response. */\nasync function errorMessage(response: Response): Promise<string> {\n try {\n const body = (await response.json()) as { error?: unknown };\n if (typeof body.error === \"string\") {\n return body.error;\n }\n } catch {\n // Non-JSON error body \u2014 fall through to the status code.\n }\n return `transcription failed (${response.status})`;\n}\n", "import type { AttachmentRef } from \"./attachment.js\";\n\n/**\n * The composer's upload contract: take a `File`, report `0..1` progress, and\n * resolve to a durable {@link AttachmentRef}. The built-in handler is\n * {@link uploadAttachment}; a host swaps in its own (a `tus-js-client` or\n * direct-to-S3 adapter) via `AgUiChat.uploadHandler` without touching the tray,\n * the chips, or the AG-UI wire, refs being transport-agnostic.\n *\n * The optional `signal` fires when the tray removes a chip or the element is\n * torn down; a handler that honours it should abort its own transport, so a\n * cancelled upload doesn't orphan a server-side file.\n */\nexport type UploadHandler = (\n file: File,\n onProgress: (fraction: number) => void,\n signal?: AbortSignal,\n) => Promise<AttachmentRef>;\n\n/** Options for {@link uploadAttachment}. */\nexport interface UploadOptions {\n /** The attachments endpoint (`data-attachments-url`). */\n readonly url: string;\n /** Extra HTTP headers (CSRF / auth), read fresh per upload. */\n readonly headers?: Record<string, string>;\n /**\n * Cookie policy, spelled as `fetch`'s `credentials` mode for consistency with\n * the other endpoints, but carried by `XMLHttpRequest`'s two-state\n * `withCredentials`: `\"include\"` sets it and every other value leaves it off,\n * matching `\"same-origin\"`. `\"omit\"` therefore cannot be honoured for a\n * same-origin upload, XHR always sending cookies there; use a custom\n * {@link UploadHandler} if that matters.\n */\n readonly credentials?: RequestCredentials;\n /** Progress callback, `0..1`, fired as the body uploads. */\n readonly onProgress?: (fraction: number) => void;\n /** Abort signal to cancel the in-flight upload. */\n readonly signal?: AbortSignal | undefined;\n}\n\n/**\n * Upload one file to the attachments endpoint and resolve to its durable\n * {@link AttachmentRef}.\n *\n * Uses `XMLHttpRequest` rather than `fetch` for real upload-progress events.\n * The file goes as multipart under the `file` field with the element's\n * `headers`, so CSRF / auth ride along; a non-2xx response or a network/abort\n * error rejects, letting the tray show an error chip.\n */\nexport function uploadAttachment(file: File, options: UploadOptions): Promise<AttachmentRef> {\n return new Promise<AttachmentRef>((resolve, reject) => {\n const form = new FormData();\n form.append(\"file\", file);\n\n const xhr = new XMLHttpRequest();\n xhr.open(\"POST\", options.url);\n // Cross-origin cookies ride only when asked for, as at the fetch sites.\n // Without this an upload to another subdomain goes anonymous and 401s while\n // the run itself succeeds.\n xhr.withCredentials = options.credentials === \"include\";\n for (const [key, value] of Object.entries(options.headers ?? {})) {\n xhr.setRequestHeader(key, value);\n }\n\n const onProgress = options.onProgress;\n if (onProgress !== undefined) {\n xhr.upload.addEventListener(\"progress\", (event) => {\n if (event.lengthComputable) {\n onProgress(event.total === 0 ? 0 : event.loaded / event.total);\n }\n });\n }\n\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(parseRef(JSON.parse(xhr.responseText)));\n } catch {\n reject(new Error(\"upload returned an unreadable response\"));\n }\n } else {\n reject(new Error(errorMessage(xhr)));\n }\n });\n xhr.addEventListener(\"error\", () => reject(new Error(\"upload failed\")));\n xhr.addEventListener(\"abort\", () => reject(new Error(\"upload cancelled\")));\n\n const signal = options.signal;\n if (signal !== undefined) {\n signal.addEventListener(\"abort\", () => xhr.abort());\n }\n\n xhr.send(form);\n });\n}\n\n/** Validate + narrow the server's `201` body into an {@link AttachmentRef}. */\nfunction parseRef(body: unknown): AttachmentRef {\n if (typeof body !== \"object\" || body === null) {\n throw new Error(\"not an object\");\n }\n const o = body as Record<string, unknown>;\n const id = o[\"id\"];\n const name = o[\"name\"];\n const mime = o[\"mime\"];\n const size = o[\"size\"];\n const url = o[\"url\"];\n if (\n typeof id !== \"string\" ||\n typeof name !== \"string\" ||\n typeof mime !== \"string\" ||\n typeof size !== \"number\"\n ) {\n throw new Error(\"missing fields\");\n }\n return typeof url === \"string\" ? { id, name, mime, size, url } : { id, name, mime, size };\n}\n\n/** A human-readable message from a non-2xx upload response. */\nfunction errorMessage(xhr: XMLHttpRequest): string {\n try {\n const body = JSON.parse(xhr.responseText) as { error?: unknown };\n if (typeof body.error === \"string\") {\n return body.error;\n }\n } catch {\n // Non-JSON error body \u2014 fall through to the status text.\n }\n return `upload failed (${xhr.status})`;\n}\n", "import type { Context, Interrupt, Message, Tool } from \"@ag-ui/core\";\nimport {\n ATTACHMENT_EVENT,\n CHART_ACTIVITY_TYPE,\n COMPACTION_ACTIVITY_TYPE,\n DEFAULT_ATTACHMENT_MAX_BYTES,\n ICON_ATTACH,\n ICON_LAUNCHER,\n ICON_SEND,\n ICON_STOP,\n LOAD_CAPABILITY_TOOL,\n MESSAGE_ROLE,\n READ_PAGE_TOOL,\n RUN_FINISHED_EVENT,\n STATE_EVENT,\n SUBMIT_EVENT,\n TOGGLE_EVENT,\n TOOL_CALL_STATUS,\n TOOL_DISPLAY,\n UNREAD_EVENT,\n X_CONFIRM_KEY,\n X_SUMMARY_KEY,\n} from \"../constants.js\";\nimport { fillTemplate } from \"../skills/fill_template.js\";\nimport { parseSkills } from \"../skills/parse_skills.js\";\nimport type { Skill } from \"../skills/skill.js\";\nimport { type ClientTool, ClientToolRegistry } from \"../tools/client_tool_registry.js\";\nimport { isDestructive } from \"../tools/is_destructive.js\";\nimport { isNavigates } from \"../tools/is_navigates.js\";\nimport { createPageActionTools, type ResolvePageTarget } from \"../tools/page_action_tools.js\";\nimport { createPageMapContext, type PageMap } from \"../tools/page_map.js\";\nimport { createPageStateTools, type PageState } from \"../tools/page_state.js\";\nimport { parseToolCatalog } from \"../tools/parse_tool_catalog.js\";\nimport { createRouteTools, type RouteMap } from \"../tools/route_map.js\";\nimport {\n type ApprovalRenderer,\n type ApprovalRequest,\n requestApproval,\n} from \"../ui/approval_card.js\";\nimport { attachCopyButtons } from \"../ui/attach_copy_buttons.js\";\nimport { renderAttachmentChips } from \"../ui/attachment_chips.js\";\nimport { AttachmentTray } from \"../ui/attachment_tray.js\";\nimport { renderChart } from \"../ui/chart_block.js\";\nimport { chartSpecFrom } from \"../ui/chart_spec_from.js\";\nimport { createChartTool } from \"../ui/chart_tool.js\";\nimport { CheckpointMenu, type CheckpointVerb } from \"../ui/checkpoint_menu.js\";\nimport { type ConfirmationRequest, requestConfirmation } from \"../ui/confirmation_card.js\";\nimport { prettifyToolName } from \"../ui/prettify_tool_name.js\";\nimport {\n type QuestionRenderer,\n type QuestionRequest,\n requestQuestion,\n} from \"../ui/question_card.js\";\nimport { renderMarkdown } from \"../ui/render_markdown.js\";\nimport {\n createResizeHandle,\n type ResizeAnchor,\n type ResizeAxis,\n type ResizeSize,\n} from \"../ui/resize_handle.js\";\nimport { wrapWords } from \"../ui/reveal_words.js\";\nimport { renderRunNotice } from \"../ui/run_notice.js\";\nimport { SkillsMenu } from \"../ui/skills_menu.js\";\nimport { STYLES } from \"../ui/styles.js\";\nimport { ThoughtsBlock } from \"../ui/thoughts_block.js\";\nimport { ThreadDrawer } from \"../ui/thread_drawer.js\";\nimport { ToolCallCard, type ToolDisplayMode } from \"../ui/tool_call_card.js\";\nimport { DEFAULT_UI_STRINGS, mergeUiStrings, type UiStrings } from \"../ui/ui_strings.js\";\nimport { VoiceInput } from \"../ui/voice_input.js\";\nimport {\n AgUiClient,\n type AgUiClientHandlers,\n type AgUiToolCall,\n type InterruptResponse,\n type ToolExecution,\n} from \"./agui_client.js\";\nimport { type AttachmentRef, messageAttachments } from \"./attachment.js\";\nimport {\n type ClientConversationStore,\n type NavigationCheckpoint,\n SessionStorageStore,\n} from \"./conversation_store.js\";\nimport { type AgentFactory, createHttpAgent } from \"./create_http_agent.js\";\nimport { RemoteConversationStore } from \"./remote_conversation_store.js\";\nimport { RunIndex } from \"./run_index.js\";\nimport { type TranscribeHandler, transcribeAudio } from \"./transcribe_audio.js\";\nimport { type UploadHandler, uploadAttachment } from \"./upload_attachment.js\";\nimport { withCredentials } from \"./utils.js\";\n\n/** The role a rendered chat message takes. */\nexport type MessageRole = (typeof MESSAGE_ROLE)[keyof typeof MESSAGE_ROLE];\n\n/** `detail` shape of the {@link SUBMIT_EVENT} CustomEvent. */\nexport interface SubmitDetail {\n readonly content: string;\n /** Durable refs for the files attached to this message (empty when none). */\n readonly attachments: readonly AttachmentRef[];\n}\n\n/** `detail` shape of the {@link ATTACHMENT_EVENT} CustomEvent. */\nexport interface AttachmentsDetail {\n /** Durable refs for every file that has finished uploading. */\n readonly attachments: readonly AttachmentRef[];\n /** How many files are still uploading; a send now would leave these behind. */\n readonly pending: number;\n}\n\n/** `detail` shape of the {@link STATE_EVENT} CustomEvent. */\nexport interface StateDetail {\n readonly state: Readonly<Record<string, unknown>>;\n}\n\n/** One tool that ran during an interaction, as {@link RunFinishedDetail} lists it. */\nexport interface ToolRun {\n readonly name: string;\n /**\n * Where it executed. `\"server\"` is the one a data-rendering host cares about:\n * a `\"client\"` tool ran in the host's own handler, so the host already knows\n * whatever it did.\n */\n readonly side: \"server\" | \"client\";\n}\n\n/** `detail` shape of the {@link RUN_FINISHED_EVENT} CustomEvent. */\nexport interface RunFinishedDetail {\n /** In settle order. Empty when the interaction called no tools. */\n readonly tools: readonly ToolRun[];\n}\n\n/** `detail` shape of the {@link TOGGLE_EVENT} CustomEvent. */\nexport interface ToggleDetail {\n readonly collapsed: boolean;\n}\n\n/** `detail` shape of the {@link UNREAD_EVENT} CustomEvent. */\nexport interface UnreadDetail {\n readonly unread: number;\n}\n\n/**\n * Attributes read once while connecting, to decide what chrome exists at all.\n *\n * Changing one afterwards is silently ignored: the tray, the mic, the skills\n * menu and the header icon are built during connect and no later read revisits\n * the decision. Observed only so `attributeChangedCallback` can warn.\n *\n * Excludes the attributes that are re-read per use, where a late change works\n * and a warning would be wrong: `data-runs-url`, `data-page-actions`,\n * `data-text-animation`, `data-tool-display`, `endpoint`, and the CSS-reactive\n * `theme` / `collapsed`.\n */\nconst CONNECT_TIME_ATTRIBUTES = [\n \"data-attachments-url\",\n \"data-attachment-accept\",\n \"data-attachment-max-bytes\",\n \"data-transcribe-url\",\n \"data-threads-url\",\n \"data-tools-url\",\n \"data-skills-url\",\n \"data-skills\",\n \"data-prompt-chips\",\n \"data-slash-commands\",\n \"data-theme-toggle\",\n \"data-strings\",\n \"data-icon-url\",\n] as const;\n\n/**\n * The cookie policies `fetch` accepts. Anything else is a configuration\n * mistake, and one that would otherwise surface as an unexplained 401 from a\n * request the browser silently sent anonymously.\n */\nconst CREDENTIALS_MODES: readonly string[] = [\"omit\", \"same-origin\", \"include\"];\n\n/** Whether `value` is one of the three modes `fetch` understands. */\nfunction isCredentialsMode(value: string): value is RequestCredentials {\n return CREDENTIALS_MODES.includes(value);\n}\n\n/** Per-tab persistence key for the collapsed state (survives MPA reloads). */\nconst COLLAPSED_KEY = \"ag-ui-chat:collapsed\";\n\n/** Per-tab persistence key for a dragged panel size. */\nconst SIZE_KEY = \"ag-ui-chat:size\";\n\n/** Per-tab persistence key for the built-in theme toggle. */\nconst THEME_KEY = \"ag-ui-chat:theme\";\n\n/**\n * `<ag-ui-chat>` \u2014 a framework-free chat sidebar Web Component over AG-UI.\n *\n * Owns the Shadow DOM shell (header, scrolling message list, input row),\n * builds an {@link AgUiClient} on first send via the overridable\n * {@link agentFactory}, and renders streaming assistant text plus tool-call\n * activity. Emits a {@link SUBMIT_EVENT} for host visibility.\n *\n * The per-run frontend tool catalog and context come from {@link getTools} and\n * {@link getContext}.\n */\nexport class AgUiChat extends HTMLElement {\n /** Agent factory; override to inject a custom or fake agent (tests). */\n agentFactory: AgentFactory = createHttpAgent;\n\n /**\n * Static extra HTTP headers, sent with every request this element makes: the\n * agent run, the thread index and its messages, the tool and skill catalogs,\n * the run index, uploads and transcription.\n *\n * For values fixed for the element's lifetime. A rotating credential belongs\n * in {@link getHeaders} instead \u2014 only a re-assignment updates this, so a\n * token captured here is pinned until the host assigns again.\n */\n headers: Record<string, string> = {};\n\n /**\n * Live header source, called afresh immediately before every request \u2014 the\n * way to supply rotating credentials, with nothing to re-assign or keep in\n * sync.\n *\n * Composes with {@link headers} rather than replacing it: merged per key with\n * `getHeaders()` winning, so a static `X-Client` and a rotating\n * `Authorization` are configured independently and neither drops the other.\n */\n getHeaders: (() => Record<string, string>) | null = null;\n\n /**\n * Permit `<img>` in rendered assistant markdown. **Off by default**: a\n * model-controlled image URL is fetched with no user interaction, which\n * makes it a zero-click exfiltration channel for prompt-injected page\n * data. Enable only when the content source is trusted.\n */\n allowImages = false;\n\n /** When true, destructive tools execute without a confirmation modal. */\n autoConfirm = false;\n\n /**\n * When true, the built-in `ask_user` frontend tool is offered to the agent:\n * calling it renders an inline question card and returns the user's answer.\n * Off by default, like the other built-in tool groups, so the advertised\n * catalog does not change until a host asks for it.\n */\n askUser = false;\n\n /**\n * Optional full replacement for the `ask_user` question UI, resolving with\n * the answer; the same seam as {@link approvalRenderer}, styled via `strings`\n * and the `question*` `::part()`s when left unset. Requires {@link askUser}.\n */\n askUserRenderer: QuestionRenderer | null = null;\n\n /**\n * Optional full replacement for the server-side-tool approval UI: an approval\n * interrupt invokes this instead of the built-in {@link requestApproval}\n * card, resolving `true` to approve or `false` to deny. Style the built-in\n * card via `strings` and the `approval*` `::part()`s instead. The gate itself\n * is enabled server-side; this only changes how the decision is collected.\n */\n approvalRenderer: ApprovalRenderer | null = null;\n\n /**\n * Optional per-call confirmation predicate. When set it is authoritative,\n * deciding from the tool name and args whether this particular call needs\n * confirmation \u2014 so one tool can be instant for some args and confirmed for\n * others, which a static `x-destructive` flag cannot express. When unset the\n * `x-destructive` flag decides. `autoConfirm` short-circuits both.\n */\n confirmPredicate:\n | ((toolName: string, args: Record<string, unknown>) => boolean | Promise<boolean>)\n | null = null;\n\n /**\n * Per-run frontend tool catalog provider. Defaults to the built-in\n * `route.*` tools (when a {@link routeMap} is set) plus the tools registered\n * via {@link registerTool} / {@link registerPageState}; override to supply a\n * fully custom catalog.\n */\n getTools: () => Tool[] = () => [\n ...this.#builtinTools().map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n ...this.#toolRegistry.tools(),\n ];\n\n /**\n * Per-run context provider. Defaults to the compact page map, when a\n * {@link getPageMap} provider is set and {@link autoInjectPageMap} is on.\n *\n * Attachments are deliberately not restated here: the server derives its own\n * manifest from the refs riding the messages.\n */\n getContext: () => Context[] = () => [\n ...createPageMapContext(this.getPageMap, this.autoInjectPageMap),\n ];\n\n /**\n * Navigable routes the agent can jump to via the built-in `route.*` tools.\n * A compact summary also rides in each run's context.\n */\n routeMap: RouteMap = [];\n\n /**\n * Optional client-side router. When set (an SPA), `navigate_to_route` routes\n * in-page and the run loop continues; when unset (an MPA like the admin), it\n * falls back to `window.location` and the resumable-loop machinery applies.\n */\n navigate: ((path: string) => void) | null = null;\n\n /** Provider for the per-run page map; see {@link getContext}. */\n getPageMap: (() => PageMap) | null = null;\n\n /** Whether to auto-inject the page map into context each run. */\n autoInjectPageMap = true;\n\n /**\n * Persistence for the conversation + navigation checkpoint. Defaults to\n * per-tab `sessionStorage` so the chat survives full page reloads; inject a\n * server-backed store for cross-tab/device durability.\n */\n conversationStore: ClientConversationStore = new SessionStorageStore();\n\n /**\n * How attached files are uploaded. `null` (default) uses the built-in\n * multipart `POST` to `data-attachments-url`; a custom {@link UploadHandler}\n * swaps the transport without changing the tray, the chips, or the AG-UI\n * wire. When set, the \uD83D\uDCCE affordance appears even with no\n * `data-attachments-url`, and the handler owns its own endpoint and headers.\n */\n uploadHandler: UploadHandler | null = null;\n\n /**\n * How recorded voice clips are transcribed. `null` (default) POSTs the clip\n * to `data-transcribe-url`; a custom {@link TranscribeHandler} swaps the\n * transport without touching the mic button. When set, the \uD83C\uDFA4 affordance\n * appears even with no `data-transcribe-url`.\n */\n transcribeHandler: TranscribeHandler | null = null;\n\n /**\n * Builds the tool result a navigating tool resumes with after the page\n * reloads. Defaults to the landed URL; a host (e.g. the admin package) can\n * override to include a page snapshot or post-reload validation errors.\n */\n navigationResult: (checkpoint: NavigationCheckpoint) => unknown = () => ({\n navigated: true,\n url: window.location.href,\n });\n\n /**\n * Named values used to fill a skill prompt's `{placeholder}`s before send\n * (e.g. `{ model: \"Order\", selected_ids: \"1,2\" }`). A host (the admin) sets\n * this from the current page; a missing placeholder blocks the send.\n */\n skillContext: () => Record<string, unknown> = () => ({});\n\n /**\n * Friendly display labels for tool-call cards, keyed by tool name. The\n * fallback when a tool has no `x-summary` in its own schema, which chiefly\n * means server-side tools: AG-UI streams only the tool-call name, so their\n * schema never reaches the browser. Client tools should prefer `x-summary`.\n */\n toolSummaries: Record<string, string> = {};\n\n /**\n * Localizable UI strings \u2014 a partial override merged over the English\n * {@link DEFAULT_UI_STRINGS}. Resolved once on connect (so set it before the\n * element is appended); the `data-strings` JSON attribute is the markup\n * equivalent, and this property wins key-by-key over it.\n */\n strings: Partial<UiStrings> = {};\n\n /**\n * Resolve a `scroll_to` / `drag_and_drop` target string to a host-page\n * element (or `null`). Defaults to a CSS-selector lookup; override to map\n * page-map element ids. The page-action tools are opt-in via the\n * `data-page-actions` attribute (`\"scroll\"` / `\"drag\"`).\n */\n resolvePageTarget: ResolvePageTarget = (target) => document.querySelector<HTMLElement>(target);\n\n /**\n * Card labels fetched from a server tool catalog (`data-tools-url`), keyed by\n * tool name. The base layer behind {@link toolSummaries}: an explicit entry in\n * `toolSummaries` wins, this fills the rest. Populated once on connect.\n */\n #toolCatalog: Record<string, string> = {};\n /** The resolved string table (defaults \u2190 `data-strings` \u2190 `strings`). */\n #strings: UiStrings = DEFAULT_UI_STRINGS;\n\n readonly #toolRegistry = new ClientToolRegistry();\n /** Tool-call cards awaiting execution, keyed by call id. */\n readonly #toolCards = new Map<string, ToolCallCard>();\n /**\n * Call ids whose card was already settled from a streamed server-side result\n * (`TOOL_CALL_RESULT`), so the post-run executeTool sweep doesn't overwrite\n * the real output with the generic \"executed on the server\" fallback.\n */\n /** Whether a server-pushed chart activity is drawn. Off unless asked for. */\n #chartActivity = false;\n\n /** Card elements by call id, so a rendering handler can find its own card. */\n readonly #cardElements = new Map<string, HTMLElement>();\n\n /** Chart blocks by activity message id, so an update redraws in place. */\n readonly #activityBlocks = new Map<string, HTMLElement>();\n\n readonly #serverSettled = new Set<string>();\n /**\n * Tool calls made during the current interaction, in the order they started,\n * so {@link RUN_FINISHED_EVENT} can report them once the whole thing settles.\n * Spans tool rounds and an approval interrupt; cleared when the event fires.\n */\n #runTools: { readonly id: string; readonly name: string }[] = [];\n readonly #root: ShadowRoot;\n readonly #chat: HTMLDivElement;\n readonly #messages: HTMLDivElement;\n readonly #input: HTMLTextAreaElement;\n readonly #send: HTMLButtonElement;\n readonly #title: HTMLSpanElement;\n readonly #skillsMenu: SkillsMenu;\n readonly #drawer: ThreadDrawer;\n /** Checkpoint panel; rows load only when `data-runs-url` is set. */\n readonly #checkpoints: CheckpointMenu;\n /** Built lazily from `data-runs-url`; `null` when the host didn't opt in. */\n #runIndex: RunIndex | null = null;\n readonly #skillHint: HTMLDivElement;\n /** File-picker button + hidden input + tray slot; the tray mounts on connect. */\n readonly #attachButton: HTMLButtonElement;\n readonly #fileInput: HTMLInputElement;\n readonly #attachSlot: HTMLDivElement;\n /** Optional built-in header theme toggle; shown only with `data-theme-toggle`. */\n readonly #themeToggle: HTMLButtonElement;\n /** What the collapsed widget shrinks to: the floating launcher, or the sidebar rail. */\n readonly #launcher: HTMLButtonElement;\n /** The launcher's unread badge; hidden at zero, and when the host opts out. */\n readonly #badge: HTMLSpanElement;\n // Answers that finished while the widget was collapsed. Expanding clears it.\n #unread = 0;\n /** Empty-state region at the top of the message list; hidden once anything renders. */\n readonly #emptyWrap: HTMLDivElement;\n /** Upload tray; created on connect only when `data-attachments-url` is set. */\n #attachTray: AttachmentTray | null = null;\n /** Mic button mount point (input row); the control mounts on connect when enabled. */\n readonly #voiceSlot: HTMLSpanElement;\n /** Voice-input control; created on connect when transcription is available. */\n #voice: VoiceInput | null = null;\n /** Whether the element is currently in the DOM; gates the connect-time warning. */\n #connected = false;\n\n #client: AgUiClient | null = null;\n // Seed for the next client. Once one exists it owns the live value (the\n // agent applies STATE_SNAPSHOT / STATE_DELTA into it), so this is only the\n // starting point \u2014 `sharedState` reads through to the client when present.\n #sharedState: Record<string, unknown> = {};\n // Whether an interaction is in flight (first onRunStart \u2192 onSettled). Drives\n // the Send\u21C4Stop button: `agent.isRunning` is false between frontend-tool\n // rounds, but the user must still be able to stop there.\n #running = false;\n // The page the current round's context describes, captured when that context\n // was built. `null` until the first round. Compared in `#executeTool` to\n // catch a page that moved under a round still in flight.\n #contextHref: string | null = null;\n // Aborting this dismisses (declines) an open confirmation card when the run\n // is cancelled while the card awaits a decision. One controller per card.\n #confirmAbort: AbortController | null = null;\n #streamingBubble: HTMLDivElement | null = null;\n // Text deltas applied to the current streaming bubble. >1 \u21D2 the message\n // revealed progressively as it streamed, so the word reveal must not re-animate\n // it; \u22641 \u21D2 it arrived at once and the word reveal is appropriate.\n #streamDeltas = 0;\n #pending: HTMLDivElement | null = null;\n // The current assistant turn's grouping container. One `.answer`\n // wraps everything a single answer produces \u2014 streamed text, tool cards, the\n // pending indicator \u2014 so it can be boxed as one \"well\" by CSS. Opened on the\n // turn's first run start, closed at settle, so it spans the whole multi-round\n // frontend-tool loop (which is several AG-UI runs), not one run. `null`\n // between turns; user bubbles never enter it.\n #currentGroup: HTMLDivElement | null = null;\n // The current turn's streamed-reasoning region, shown at the top of\n // the answer group while a reasoning model thinks and collapsed once the\n // answer's first text token arrives. `null` outside a reasoning turn.\n #thoughts: ThoughtsBlock | null = null;\n #threadId = \"\";\n // Per-instance suffix for the origin-scoped storage keys (collapsed / theme /\n // active thread), so two instances on one origin don't clobber each other.\n // Empty \u21D2 the pre-namespacing global keys (back-compat). Resolved on connect.\n #storageNs = \"\";\n // Bumped on every #rehydrate; a replay whose generation is stale (a newer\n // thread switch started while it awaited a slow store) drops its result.\n #rehydrateGeneration = 0;\n #initialMessages: readonly Message[] = [];\n // Skill catalog by source; merged backend \u2192 embed \u2192 client (later wins).\n #backendSkills: readonly Skill[] = [];\n #embedSkills: readonly Skill[] = [];\n #clientSkills: readonly Skill[] = [];\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: \"open\" });\n this.#chat = document.createElement(\"div\");\n this.#messages = document.createElement(\"div\");\n this.#input = document.createElement(\"textarea\");\n this.#send = document.createElement(\"button\");\n this.#title = document.createElement(\"span\");\n this.#skillHint = document.createElement(\"div\");\n this.#attachButton = document.createElement(\"button\");\n this.#fileInput = document.createElement(\"input\");\n this.#attachSlot = document.createElement(\"div\");\n this.#voiceSlot = document.createElement(\"span\");\n this.#themeToggle = document.createElement(\"button\");\n this.#launcher = document.createElement(\"button\");\n this.#badge = document.createElement(\"span\");\n this.#emptyWrap = document.createElement(\"div\");\n this.#skillsMenu = new SkillsMenu((skill) => this.#applySkill(skill));\n this.#drawer = new ThreadDrawer({\n onSelect: (threadId) => {\n void this.#switchThread(threadId);\n },\n onNew: () => {\n this.newChat();\n void this.#refreshDrawer();\n },\n onRename: (threadId, title) => {\n this.conversationStore.renameThread(threadId, title);\n void this.#refreshDrawer();\n },\n onDelete: (threadId) => {\n this.#deleteThread(threadId);\n },\n });\n this.#checkpoints = new CheckpointMenu((runId, verb) => {\n void this.#continueRun(runId, verb);\n });\n }\n\n /** The run index, built once from `data-runs-url`; `null` when unset. */\n #runs(): RunIndex | null {\n const url = this.getAttribute(\"data-runs-url\");\n if (url === null || url === \"\") {\n return null;\n }\n if (this.#runIndex === null) {\n this.#runIndex = new RunIndex(\n url,\n () => this.#requestHeaders(),\n () => this.#requestCredentials(),\n );\n }\n return this.#runIndex;\n }\n\n /**\n * Continue `runId` as a **new** run, seeded server-side from its snapshot.\n *\n * Uses a short-lived agent pointed at the resume / fork endpoint and seeded\n * with no history, because those endpoints supply the prior turns from the\n * snapshot and re-sending them would duplicate. A separate agent makes that\n * structural \u2014 the main agent keeps its own history \u2014 and mints the fresh\n * `run_id` the endpoints also require.\n *\n * Handlers are the element's own, so the continuation streams into the same\n * transcript the user is looking at.\n */\n async #continueRun(runId: string, verb: CheckpointVerb): Promise<void> {\n const index = this.#runs();\n if (index === null) {\n return;\n }\n const content = this.#input.value.trim();\n if (content === \"\") {\n return;\n }\n this.#input.value = \"\";\n this.#autoGrow();\n const endpoint = verb === \"resume\" ? index.resumeUrl(runId) : index.forkUrl(runId);\n const agent = this.agentFactory({\n endpoint,\n headers: this.#requestHeaders(),\n getHeaders: () => this.#requestHeaders(),\n ...this.#credentialsOption(),\n threadId: this.#threadId,\n // The seed the endpoints assume: nothing. The snapshot is the history.\n initialMessages: [],\n });\n const client = new AgUiClient({\n agent,\n handlers: this.#handlers(),\n getTools: () => this.getTools(),\n getContext: () => this.#buildContext(),\n executeTool: (call) => this.#executeTool(call),\n resolveInterrupts: (interrupts) => this.#resolveInterrupts(interrupts),\n connectionLostMessage: this.#strings.connectionLost,\n });\n await client.send(content);\n }\n\n /** Load the checkpoint panel with the runs that can actually be continued. */\n async #refreshCheckpoints(): Promise<void> {\n const index = this.#runs();\n this.#checkpoints.setRuns(index === null ? [] : await index.continuable());\n }\n\n /** Attributes the element reacts to after it has been connected. */\n static get observedAttributes(): string[] {\n return [\"title-text\", \"placement\", \"credentials\", ...CONNECT_TIME_ATTRIBUTES];\n }\n\n attributeChangedCallback(name: string, previous: string | null, value: string | null): void {\n if (name === \"credentials\") {\n // Reported the moment the attribute is written \u2014 before connect, and\n // whether it came from markup or the property setter. An unrecognised\n // mode is otherwise inert, and the request it was meant to authorise\n // goes out anonymously with nothing to show for it.\n if (value !== null && !isCredentialsMode(value)) {\n console.error(\n `<ag-ui-chat>: credentials=\"${value}\" is not a fetch credentials mode ` +\n `(${CREDENTIALS_MODES.join(\" / \")}) \u2014 it is being ignored, so requests use ` +\n \"the browser default and cross-origin cookies will not be sent.\",\n );\n }\n return;\n }\n if (name === \"placement\") {\n // A placement owns the axes it fixes, so hand those back before anything\n // else: a size dragged under the previous placement would otherwise sit\n // inline and outrank the new one.\n this.#releaseOwnedAxes();\n // Placement also moves the panel, so the edges its layout holds still\n // change with it. Deferred a frame so the new rules have applied.\n requestAnimationFrame(() => this.#syncResizeAnchor());\n return;\n }\n if (name === \"title-text\") {\n // `#strings` is the resolved table once connected, the English defaults\n // before then.\n this.#title.textContent = value ?? this.#strings.title;\n return;\n }\n // Everything else here is read once, in connectedCallback, to build chrome\n // that then exists or does not. A later change is silently ignored and the\n // symptom is an affordance that never appears, which reads as a broken\n // component rather than a mis-timed assignment \u2014 the common React/Vue shape,\n // where the element mounts on one render pass and attributes are patched in\n // on the next. Observed purely so this can be said out loud.\n if (previous === value || !this.#connected) {\n return;\n }\n console.warn(\n `<ag-ui-chat>: \"${name}\" was changed after the element connected, and is ` +\n \"read only while connecting \u2014 this assignment has no effect. Set it \" +\n \"before the element enters the DOM (in the markup, or on the element \" +\n \"before appending it); frameworks that patch attributes after mount \" +\n \"should bind it at creation. To apply a new value now, remove and \" +\n \"re-insert the element.\",\n );\n }\n\n /** Declare a frontend tool the agent may call. */\n registerTool(tool: ClientTool): void {\n this.#toolRegistry.register(tool);\n }\n\n /**\n * AG-UI **shared state** for this conversation \u2014 the protocol's own state\n * channel, sent as `RunAgentInput.state` on every run and replaced in place\n * when the server streams `STATE_SNAPSHOT` / `STATE_DELTA`. Assigning seeds\n * the next run; reading returns whatever the agent last applied.\n *\n * Listen for {@link STATE_EVENT} to react to server-driven changes. Distinct\n * from {@link registerPageState}, which exposes host state as ordinary tools.\n */\n get sharedState(): Readonly<Record<string, unknown>> {\n return this.#client?.state ?? this.#sharedState;\n }\n\n set sharedState(state: Readonly<Record<string, unknown>>) {\n this.#sharedState = { ...state };\n // A client already exists for this conversation \u2014 push it through so the\n // next run sends it, rather than silently waiting for a new conversation.\n this.#client?.setState(this.#sharedState);\n }\n\n /** Bind a piece of host page state to `read_<name>` / `set_<name>` tools. */\n registerPageState(binding: PageState): void {\n for (const tool of createPageStateTools(binding)) {\n this.#toolRegistry.register(tool);\n }\n }\n\n /**\n * @deprecated Renamed to {@link registerPageState} \u2014 the old name read as\n * AG-UI shared-state sync. Behaviour is unchanged; the alias will be removed\n * in a future major.\n */\n registerStateHook(binding: PageState): void {\n this.registerPageState(binding);\n }\n\n /** The built-in `route.*` tools, present only when a route map is set. */\n #routeTools(): ClientTool[] {\n if (this.routeMap.length === 0) {\n return [];\n }\n return createRouteTools(\n () => this.routeMap,\n () => this.navigate,\n );\n }\n\n /**\n * The built-in `read_page` tool, present only when a {@link getPageMap}\n * provider is set. A *pull* the agent can call mid-turn to see the page after\n * it has acted (the auto-injected context is a send-time snapshot).\n */\n #pageTools(): ClientTool[] {\n const getPageMap = this.getPageMap;\n if (getPageMap === null) {\n return [];\n }\n return [\n {\n name: READ_PAGE_TOOL,\n description:\n \"Read the current page's structure (fields, buttons, route). Call after \" +\n \"acting to observe the result within the same turn.\",\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n [X_SUMMARY_KEY]: \"Read the page\",\n },\n handler: () => getPageMap(),\n },\n ];\n }\n\n /**\n * Opt-in page-action tools (`scroll_to` / `drag_and_drop`), enabled per token\n * via the `data-page-actions` attribute (e.g. `\"scroll,drag\"`). Targets resolve\n * through {@link resolvePageTarget} so a host controls the agent's interaction\n * surface; absent attribute \u21D2 no tools registered.\n */\n #pageActionTools(): ClientTool[] {\n const attr = this.getAttribute(\"data-page-actions\");\n if (attr === null) {\n return [];\n }\n const enabled = new Set(\n attr\n .split(\",\")\n .map((token) => token.trim())\n .filter((token) => token !== \"\"),\n );\n return createPageActionTools(enabled, (target) => this.resolvePageTarget(target));\n }\n\n /** All built-in (route + page + page-action + ask_user) frontend tools. */\n #builtinTools(): ClientTool[] {\n return [\n ...this.#routeTools(),\n ...this.#pageTools(),\n ...this.#pageActionTools(),\n ...this.#askUserTool(),\n ];\n }\n\n /**\n * The built-in `ask_user` frontend tool, or `[]` when {@link askUser} is off.\n *\n * The agent calls it, the client executes it locally through the normal\n * frontend-tool path by rendering a {@link requestQuestion} card, and the\n * answer flows back as the tool result. No new protocol.\n */\n #askUserTool(): ClientTool[] {\n if (!this.askUser) {\n return [];\n }\n return [\n {\n name: \"ask_user\",\n description:\n \"Ask the user a question and wait for their answer. Provide `options` for a \" +\n \"multiple-choice prompt; set `allow_custom` to also accept a free-text answer.\",\n parameters: {\n type: \"object\",\n properties: {\n question: { type: \"string\", description: \"The question to ask the user.\" },\n options: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Preset choices offered as radio buttons.\",\n },\n allow_custom: {\n type: \"boolean\",\n description: \"Allow a free-text answer in addition to any options.\",\n },\n },\n required: [\"question\"],\n },\n handler: (args) => this.#askUser(args),\n },\n ];\n }\n\n /** Render the `ask_user` question card and resolve with the user's answer. */\n async #askUser(args: Record<string, unknown>): Promise<string> {\n const question = typeof args[\"question\"] === \"string\" ? args[\"question\"] : \"\";\n const request: QuestionRequest = { question };\n const rawOptions = args[\"options\"];\n if (Array.isArray(rawOptions)) {\n request.options = rawOptions.filter((option): option is string => typeof option === \"string\");\n }\n if (args[\"allow_custom\"] === true) {\n request.allowCustom = true;\n }\n // The run is suspended on the card; a Stop aborts the controller, resolving\n // it with an empty answer (the run is then cancelled).\n this.#confirmAbort = new AbortController();\n const signal = this.#confirmAbort.signal;\n this.#hidePending();\n // A host-supplied renderer takes full control of the UI; otherwise the\n // built-in inline card renders into the current answer group.\n const answer =\n this.askUserRenderer !== null\n ? await this.askUserRenderer(request, { signal })\n : await requestQuestion(this.#ensureGroup(), request, {\n signal,\n strings: this.#strings,\n });\n this.#confirmAbort = null;\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return answer;\n }\n\n /** Resolve a tool by name: built-in tools first, then the registry. */\n #resolveTool(name: string): ClientTool | null {\n const builtin = this.#builtinTools().find((t) => t.name === name);\n if (builtin !== undefined) {\n return builtin;\n }\n return this.#toolRegistry.has(name) ? this.#toolRegistry.get(name) : null;\n }\n\n /** The AG-UI endpoint URL, read from the `endpoint` attribute. */\n get endpoint(): string {\n return this.getAttribute(\"endpoint\") ?? \"\";\n }\n\n // Reflecting setter so frameworks (e.g. React 19) that assign matching\n // props as element *properties* don't hit a read-only property. Read at\n // use-time, so a runtime change applies to the next run.\n set endpoint(value: string) {\n this.setAttribute(\"endpoint\", value);\n }\n\n /**\n * Cookie policy for **every** request this element makes, as `fetch`'s own\n * `credentials` mode (`\"omit\"` / `\"same-origin\"` / `\"include\"`). Mirrored to\n * the `credentials` attribute, so markup embeds can set it without script.\n *\n * `null` (the default) leaves the browser's `same-origin` default in place,\n * which sends no cookies at all to an endpoint on a different origin \u2014 and\n * the request goes out anonymously rather than failing, so the symptom is a\n * 401 from a server that looks correctly configured. A cookie-authenticated\n * cross-origin deployment wants `\"include\"`, plus\n * `Access-Control-Allow-Credentials: true` and a concrete, non-wildcard\n * `Access-Control-Allow-Origin` on the server.\n *\n * Read per request, so a late assignment applies to everything after it.\n * `\"omit\"` cannot be honoured by the built-in upload transport, an\n * `XMLHttpRequest` with only a two-state cookie switch; every other endpoint\n * honours all three modes.\n */\n get credentials(): RequestCredentials | null {\n const attr = this.getAttribute(\"credentials\");\n return attr !== null && isCredentialsMode(attr) ? attr : null;\n }\n\n set credentials(value: RequestCredentials | null) {\n if (value === null) {\n this.removeAttribute(\"credentials\");\n return;\n }\n // Thrown, not warned: an unrecognised mode is inert at request time, and\n // the whole failure this option exists to fix is a request that goes out\n // wrong without saying so. Fail where the mistake was made instead.\n if (!isCredentialsMode(value)) {\n throw new TypeError(\n `<ag-ui-chat>: credentials must be one of ${CREDENTIALS_MODES.map((mode) => `\"${mode}\"`).join(\", \")} ` +\n `(got ${JSON.stringify(value)}).`,\n );\n }\n this.setAttribute(\"credentials\", value);\n }\n\n /**\n * The headers for the request about to go out: the static {@link headers}\n * with {@link getHeaders}'s live values overlaid, per key.\n *\n * Every request site goes through here, so \"how this element authenticates\"\n * is one answer rather than one per endpoint.\n */\n #requestHeaders(): Record<string, string> {\n return { ...this.headers, ...this.getHeaders?.() };\n }\n\n /** The configured cookie policy as `fetch` spells it; `undefined` when unset. */\n #requestCredentials(): RequestCredentials | undefined {\n return this.credentials ?? undefined;\n }\n\n /**\n * The `credentials` entry for an {@link AgentFactory} call, or nothing at all.\n *\n * Spread rather than assigned: `exactOptionalPropertyTypes` rejects an\n * explicit `credentials: undefined`, and a factory should see the field\n * absent \u2014 not present-and-empty \u2014 when no policy is configured. The agent\n * reads it when it is built (first send, thread switch, continuation), by\n * which time any host configuration has landed.\n */\n #credentialsOption(): { credentials?: RequestCredentials } {\n const credentials = this.#requestCredentials();\n return credentials === undefined ? {} : { credentials };\n }\n\n /** The `fetch` init for the element's own plain GETs (catalogs). */\n #fetchInit(): RequestInit | undefined {\n return withCredentials({ headers: this.#requestHeaders() }, this.#requestCredentials());\n }\n\n /**\n * How much detail tool-call cards show, from the `data-tool-display`\n * attribute (`minimal` / `inline` / `compact` / `full`). Defaults to `full`.\n *\n * Applied by the shadow CSS from the attribute itself, so changing it\n * restyles every card already in the transcript rather than only the ones\n * built afterwards.\n */\n get toolDisplay(): ToolDisplayMode {\n const attr = this.getAttribute(\"data-tool-display\");\n if (\n attr === TOOL_DISPLAY.INLINE ||\n attr === TOOL_DISPLAY.MINIMAL ||\n attr === TOOL_DISPLAY.COMPACT\n ) {\n return attr;\n }\n return TOOL_DISPLAY.FULL;\n }\n\n set toolDisplay(value: ToolDisplayMode) {\n this.setAttribute(\"data-tool-display\", value);\n }\n\n connectedCallback(): void {\n // Resolve the per-instance storage namespace (id, else endpoint) before any\n // key read/write, so this instance doesn't share collapsed/theme/thread\n // state with another on the same origin.\n this.#storageNs = this.id !== \"\" ? this.id : this.endpoint;\n // Restore a dragged size before the panel paints, so it does not snap from\n // the placement default to the user's width on the first frame.\n this.#applySize(this.#readSize());\n // Position the grip at the corner this layout grows toward. Deferred to a\n // frame so the host's own stylesheet has applied; re-measured on every drag\n // anyway, so a wrong first guess costs a grip in the wrong corner and never\n // a wrong resize.\n requestAnimationFrame(() => this.#syncResizeAnchor());\n // Resolve the string table before rendering any chrome (defaults are the\n // floor; `data-strings` then the `strings` property layer over them).\n this.#strings = mergeUiStrings({ ...this.#readStringOverrides(), ...this.strings });\n // Restore a theme the built-in toggle persisted last visit (opt-in only, so\n // it never overrides a host that drives `theme` itself).\n if (this.getAttribute(\"data-theme-toggle\") !== null) {\n const saved = this.#readScopedItem(THEME_KEY);\n if (saved !== null) {\n this.setAttribute(\"theme\", saved);\n }\n }\n this.#render();\n this.#drawer.setStrings(this.#strings);\n this.#checkpoints.setStrings(this.#strings);\n if (this.#readScopedItem(COLLAPSED_KEY) === \"1\") {\n this.setAttribute(\"collapsed\", \"\");\n }\n this.#syncLauncher();\n this.#initSkills();\n // Namespace the built-in default store too (a host-injected store is used\n // verbatim). Must precede #wireThreadStore, which wraps the current store.\n if (this.#storageNs !== \"\" && this.conversationStore instanceof SessionStorageStore) {\n this.conversationStore = new SessionStorageStore(this.#storageNs);\n }\n this.#wireThreadStore();\n this.#wireAttachments();\n this.#wireVoice();\n this.#threadId = this.conversationStore.threadId();\n // The catalog requests go out a microtask later, so a host configuring\n // through a framework ref still has a chance to be heard \u2014 see #startup.\n queueMicrotask(() => this.#startup());\n void this.#rehydrate();\n // Last: everything above reads (and some of it sets) attributes, and none\n // of that should trip the connect-time warning.\n this.#connected = true;\n }\n\n /**\n * The catalog requests the element issues on startup: the tool labels\n * (`data-tools-url`) and the backend skills (`data-skills-url`).\n *\n * Deliberately one microtask behind `connectedCallback`. A framework ref is\n * attached after the node is inserted but within the same commit, so a\n * request issued from `connectedCallback` itself goes out before `headers`,\n * {@link getHeaders} or {@link credentials} exist and 401s in a way that\n * reads as a server fault. A microtask lands after that commit, still before\n * paint.\n *\n * It is not a fix for configuration arriving later than the commit (a passive\n * effect, an awaited token fetch): configure before insertion, or call\n * {@link reload}, since a longer timer would hide that race rather than close\n * it.\n *\n * The history replay stays in `connectedCallback` on purpose. It renders into\n * the transcript, so deferring it would let a `sendMessage()` in the same\n * task land first and be duplicated by the replay.\n */\n #startup(): void {\n // An element can be inserted and removed inside one task (a discarded\n // render, a double-mount); nothing should go out for a node that has\n // already left the document.\n if (!this.#connected) {\n return;\n }\n void this.#fetchToolCatalog();\n void this.#fetchSkills();\n }\n\n /**\n * Re-run everything the element loads on startup \u2014 the tool-label catalog,\n * the backend skill catalog and the thread's history \u2014 with the transport\n * configuration as it stands now.\n *\n * For a host that can only configure the element after the fact (a token\n * fetched in a passive effect, an async auth handshake), this re-issues the\n * startup requests authenticated, without removing and re-inserting the node.\n *\n * A reload, not a merge: the in-flight run is cancelled and the transcript is\n * rebuilt from persisted history, so anything streamed since is dropped. Call\n * it once, when configuration lands, not between turns.\n */\n async reload(): Promise<void> {\n this.#cancelRun();\n this.#resetState();\n this.#setRunning(false);\n await Promise.all([this.#fetchToolCatalog(), this.#fetchSkills(), this.#rehydrate()]);\n }\n\n /**\n * Tear down live resources when the element leaves the DOM: cancel the\n * in-flight run so its stream closes, abort in-flight uploads so they do not\n * orphan server-side files, and release the mic so the browser's recording\n * indicator clears. Without this a removed element leaks all three.\n */\n disconnectedCallback(): void {\n this.#connected = false;\n this.#cancelRun();\n this.#attachTray?.dispose();\n this.#voice?.dispose();\n }\n\n /**\n * Read an opt-in flag attribute the way HTML reads a boolean attribute.\n *\n * Present means on: bare (`data-prompt-chips`), empty (`=\"\"`), or any value\n * except the literal `\"false\"`. Comparing against `\"true\"` instead would make\n * the bare spelling every native boolean attribute uses silently disable the\n * feature it names. `=\"false\"` still turns it off.\n */\n #flag(name: string): boolean {\n const value = this.getAttribute(name);\n return value !== null && value !== \"false\";\n }\n\n /** Parse the inline `data-strings` JSON overrides (empty when absent/malformed). */\n #readStringOverrides(): Partial<UiStrings> {\n const raw = this.getAttribute(\"data-strings\");\n if (raw === null) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null) {\n return parsed as Partial<UiStrings>;\n }\n } catch {\n // Malformed JSON \u2014 fall back to the defaults rather than failing to mount.\n }\n return {};\n }\n\n /**\n * Enable the composer's file-upload tray when uploads are possible \u2014 either a\n * custom {@link uploadHandler} is set or `data-attachments-url` provides the\n * built-in multipart endpoint: reveal the \uD83D\uDCCE button, wire the hidden file\n * input + drag-and-drop, and mount the tray. With neither, the affordance\n * stays hidden and the chat degrades to text-only.\n */\n #wireAttachments(): void {\n const url = this.getAttribute(\"data-attachments-url\");\n const upload = this.uploadHandler ?? this.#defaultUploadHandler(url);\n if (upload === null) {\n return;\n }\n const accept = this.getAttribute(\"data-attachment-accept\") ?? \"\";\n // Bound to the local rather than the field: the hook can only fire from a\n // tray that exists, so passing it removes a null check no caller can reach.\n const tray: AttachmentTray = new AttachmentTray({\n upload,\n maxBytes: this.#attachmentMaxBytes(),\n accept,\n strings: this.#strings,\n // The tray's change hook, surfaced to the host as an event. A host\n // driving its own composer could otherwise not tell a settled upload from\n // one still in flight, which is the state sendMessage() has to be called\n // with knowledge of.\n onChange: () => this.#dispatchAttachments(tray),\n });\n this.#attachTray = tray;\n this.#attachSlot.appendChild(this.#attachTray.element);\n this.#fileInput.accept = accept;\n this.#attachButton.hidden = false;\n this.#enableDragAndDrop();\n }\n\n /** The built-in multipart upload handler for `data-attachments-url`, or `null`. */\n #defaultUploadHandler(url: string | null): UploadHandler | null {\n if (url === null) {\n return null;\n }\n // Forward the tray's abort signal so removing a chip (or tearing the\n // element down) cancels the XHR.\n return (file, onProgress, signal) =>\n uploadAttachment(file, {\n url,\n headers: this.#requestHeaders(),\n ...this.#credentialsOption(),\n onProgress,\n signal,\n });\n }\n\n /**\n * Reveal the composer's \uD83C\uDFA4 mic button when transcription is possible \u2014 either\n * a custom {@link transcribeHandler} is set or `data-transcribe-url` provides\n * the built-in POST endpoint. The control records via `MediaRecorder` and\n * drops the transcript into the composer; with neither configured the mic\n * stays hidden and the chat is text-only.\n */\n #wireVoice(): void {\n const url = this.getAttribute(\"data-transcribe-url\");\n const transcribe = this.transcribeHandler ?? this.#defaultTranscribeHandler(url);\n if (transcribe === null) {\n return;\n }\n this.#voice = new VoiceInput({\n transcribe,\n onText: (text) => this.#insertVoiceText(text),\n strings: this.#strings,\n });\n this.#voiceSlot.appendChild(this.#voice.element);\n }\n\n /** The built-in transcription handler for `data-transcribe-url`, or `null`. */\n #defaultTranscribeHandler(url: string | null): TranscribeHandler | null {\n if (url === null) {\n return null;\n }\n return (audio) =>\n transcribeAudio(audio, {\n url,\n headers: this.#requestHeaders(),\n ...this.#credentialsOption(),\n });\n }\n\n /** Drop a voice transcript into the composer (appended to any typed text). */\n #insertVoiceText(text: string): void {\n const current = this.#input.value.trim();\n this.#input.value = current === \"\" ? text : `${current} ${text}`;\n this.#onInput();\n this.#input.focus();\n }\n\n /** The client-side upload size cap from `data-attachment-max-bytes`. */\n #attachmentMaxBytes(): number {\n const attr = this.getAttribute(\"data-attachment-max-bytes\");\n if (attr === null) {\n return DEFAULT_ATTACHMENT_MAX_BYTES;\n }\n const parsed = Number.parseInt(attr, 10);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_ATTACHMENT_MAX_BYTES;\n }\n\n /** Queue every file from the picker into the tray, then reset the input. */\n #onFilesPicked(): void {\n const files = this.#fileInput.files;\n if (files !== null) {\n for (const file of Array.from(files)) {\n this.#attachTray?.add(file);\n }\n }\n // Reset so re-picking the same file fires `change` again.\n this.#fileInput.value = \"\";\n }\n\n /** Accept files dropped anywhere on the chat shell into the tray. */\n #enableDragAndDrop(): void {\n this.#chat.addEventListener(\"dragover\", (event) => {\n event.preventDefault();\n this.#chat.classList.add(\"chat--dragover\");\n });\n this.#chat.addEventListener(\"dragleave\", () => {\n this.#chat.classList.remove(\"chat--dragover\");\n });\n this.#chat.addEventListener(\"drop\", (event) => {\n event.preventDefault();\n this.#chat.classList.remove(\"chat--dragover\");\n const files = event.dataTransfer?.files;\n if (files !== undefined) {\n for (const file of Array.from(files)) {\n this.#attachTray?.add(file);\n }\n }\n });\n }\n\n /**\n * When `data-threads-url` is set, route thread enumeration / load / rename /\n * delete through that server endpoint (wrapping the current store as the\n * client-only fallback), so the history drawer shows durable, cross-device\n * threads. Without it, the client store's per-tab threads are used.\n */\n #wireThreadStore(): void {\n const url = this.getAttribute(\"data-threads-url\");\n if (url !== null) {\n this.conversationStore = new RemoteConversationStore(\n url,\n () => this.#requestHeaders(),\n this.conversationStore,\n () => this.#requestCredentials(),\n );\n }\n }\n\n /** Fetch the server tool-label catalog from `data-tools-url`, if set. */\n async #fetchToolCatalog(): Promise<void> {\n const url = this.getAttribute(\"data-tools-url\");\n if (url === null) {\n return;\n }\n try {\n const response = await fetch(url, this.#fetchInit());\n this.#toolCatalog = parseToolCatalog(await response.json());\n } catch {\n // Network/parse failure: cards fall back to toolSummaries / raw names.\n }\n }\n\n /**\n * Replace the host-supplied (client) skill catalog. Merged after the embedded\n * and fetched skills (so a client skill overrides a same-named server one).\n */\n setSkills(skills: readonly Skill[]): void {\n this.#clientSkills = skills;\n this.#recomputeSkills();\n }\n\n /**\n * Wire the skill surfaces: opt-in flags and the embedded catalog. The backend\n * catalog is fetched from `#startup`, a microtask later, so it carries the\n * host's transport configuration.\n */\n #initSkills(): void {\n this.#skillsMenu.enableChips(this.#flag(\"data-prompt-chips\"));\n this.#skillsMenu.enableSlash(this.#flag(\"data-slash-commands\"));\n this.#embedSkills = this.#readEmbeddedSkills();\n this.#recomputeSkills();\n }\n\n /** Parse the inline `data-skills` JSON catalog (empty when absent/malformed). */\n #readEmbeddedSkills(): readonly Skill[] {\n const raw = this.getAttribute(\"data-skills\");\n if (raw === null) {\n return [];\n }\n try {\n return parseSkills(JSON.parse(raw));\n } catch {\n return [];\n }\n }\n\n /** Fetch the backend skills catalog from `data-skills-url`, if set. */\n async #fetchSkills(): Promise<void> {\n const url = this.getAttribute(\"data-skills-url\");\n if (url === null) {\n return;\n }\n try {\n const response = await fetch(url, this.#fetchInit());\n this.#backendSkills = parseSkills(await response.json());\n this.#recomputeSkills();\n } catch {\n // Network/parse failure: skills just stay as the embedded/client set.\n }\n }\n\n /** Merge the three sources (backend \u2192 embed \u2192 client; later wins by name). */\n #recomputeSkills(): void {\n const merged = new Map<string, Skill>();\n for (const skill of [...this.#backendSkills, ...this.#embedSkills, ...this.#clientSkills]) {\n merged.set(skill.name, skill);\n }\n this.#skillsMenu.setSkills([...merged.values()]);\n }\n\n /**\n * Act on a picked skill.\n *\n * A skill with no `prompt` is server-resolved: picking it sends the bare\n * `/name` token for the agent to expand, so the wording never reaches the\n * browser. Prefer that shape \u2014 a skill often states a project's internal\n * workflow most plainly, and a catalog endpoint is a plain GET.\n *\n * A skill carrying a `prompt` has the client fill its `{placeholder}`s from\n * the page instead, which is right for placeholders only the page can supply.\n *\n * Either way a pick sends; `sendImmediately: false` opts into pre-filling the\n * composer instead.\n */\n #applySkill(skill: Skill): void {\n if (skill.prompt === undefined) {\n this.#skillHint.hidden = true;\n void this.sendMessage(`/${skill.name}`);\n return;\n }\n const { text, missing } = fillTemplate(skill.prompt, this.skillContext());\n if (missing.length > 0) {\n // Hand the user something to work with rather than only a refusal. The\n // partially-filled template goes into the composer with its unresolved\n // `{placeholder}`s intact and the first one selected, so the next\n // keystroke replaces it. Blocking with a hint alone left whatever the\n // user had typed to open the palette \u2014 a lone \"/\" \u2014 sitting there, which\n // says nothing about what the skill wanted or how to give it.\n this.#skillHint.textContent = this.#strings.skillNeeds\n .replace(\"{title}\", skill.title)\n .replace(\"{fields}\", missing.join(\", \"));\n this.#skillHint.hidden = false;\n this.#input.value = text;\n this.#autoGrow();\n this.#input.focus();\n this.#selectFirstPlaceholder(text);\n return;\n }\n this.#skillHint.hidden = true;\n this.#input.value = text;\n this.#autoGrow();\n if (skill.sendImmediately === false) {\n this.#input.focus();\n return;\n }\n void this.#submit();\n }\n\n /**\n * Put the caret on the first unresolved placeholder, selected.\n *\n * Typing then replaces it, which is the shortest path from \"this skill needs\n * a topic\" to a sendable prompt.\n */\n #selectFirstPlaceholder(text: string): void {\n // The first surviving brace *is* the first unresolved placeholder \u2014 a\n // resolved one was substituted away \u2014 so this needs no search through the\n // missing keys and no not-found branch to defend.\n const start = text.indexOf(\"{\");\n this.#input.setSelectionRange(start, text.indexOf(\"}\", start) + 1);\n }\n\n /** Whether the widget is collapsed (reflected as the `collapsed` attribute). */\n get collapsed(): boolean {\n return this.hasAttribute(\"collapsed\");\n }\n\n // Property setter (framework interop) \u2014 delegates to setCollapsed so a\n // `collapsed` prop assignment persists + emits the toggle event.\n set collapsed(value: boolean) {\n this.setCollapsed(value);\n }\n\n /**\n * Set the collapsed state: reflect the `collapsed` attribute, persist it\n * per-tab, and emit a {@link TOGGLE_EVENT} so a host can mirror the state in\n * its own chrome.\n */\n setCollapsed(collapsed: boolean): void {\n if (collapsed) {\n this.setAttribute(\"collapsed\", \"\");\n } else {\n this.removeAttribute(\"collapsed\");\n }\n sessionStorage.setItem(this.#storageKey(COLLAPSED_KEY), collapsed ? \"1\" : \"0\");\n // Expanding is what marks the waiting answers read; collapsing starts a\n // fresh count. Either way the badge is cleared and the host told.\n this.#setUnread(0);\n this.dispatchEvent(\n new CustomEvent<ToggleDetail>(TOGGLE_EVENT, {\n detail: { collapsed },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /**\n * Answers that finished while the widget was collapsed, and that the user has\n * therefore not seen. Expanding (or {@link newChat}) clears it. The launcher's\n * badge renders this; {@link UNREAD_EVENT} announces every change, so a host\n * chrome can render its own instead.\n */\n get unread(): number {\n return this.#unread;\n }\n\n /** Flip the collapsed state. Bound to the built-in header toggle. */\n toggleCollapsed(): void {\n this.setCollapsed(!this.collapsed);\n }\n\n /**\n * Flip the `theme` attribute between `light` and `dark` and persist the choice\n * per tab. Bound to the optional built-in header theme toggle\n * (`data-theme-toggle`); any non-dark theme (incl. `auto` / `code`) flips to\n * `dark` first.\n */\n toggleTheme(): void {\n const next = this.getAttribute(\"theme\") === \"dark\" ? \"light\" : \"dark\";\n this.setAttribute(\"theme\", next);\n sessionStorage.setItem(this.#storageKey(THEME_KEY), next);\n this.#syncThemeGlyph();\n }\n\n /**\n * Which axes the current placement allows.\n *\n * A full-bleed layout is `100vw`/`100vh` by definition and cannot be resized\n * at all; a docked panel owns its height, leaving only its inner edge. Read\n * per interaction, because `placement` is a live attribute.\n */\n #resizeAxis(): ResizeAxis {\n switch (this.getAttribute(\"placement\")) {\n case \"full\":\n case \"page\":\n return \"none\";\n case \"sidebar\":\n case \"side\":\n return \"width\";\n default:\n return \"both\";\n }\n }\n\n /**\n * Which edges the layout is holding still, by measuring rather than guessing:\n * nudge the size by a pixel, see which edges stayed put, and undo. One forced\n * reflow per drag.\n *\n * `placement` cannot answer this \u2014 an embedded panel goes wherever the page's\n * CSS puts it \u2014 and see {@link createResizeHandle} for why guessing produces\n * a visibly broken control.\n */\n #measureAnchor(): ResizeAnchor {\n const before = this.getBoundingClientRect();\n const width = this.style.getPropertyValue(\"--ag-ui-width\");\n const height = this.style.getPropertyValue(\"--ag-ui-height\");\n this.#applySize({ width: before.width + 1, height: before.height + 1 });\n const after = this.getBoundingClientRect();\n // Restore exactly what was there, including \"nothing\" \u2014 leaving a probe\n // value behind would pin a panel that had been sizing itself.\n this.#restoreProperty(\"--ag-ui-width\", width);\n this.#restoreProperty(\"--ag-ui-height\", height);\n return {\n x: Math.abs(after.left - before.left) < 0.5 ? \"left\" : \"right\",\n y: Math.abs(after.top - before.top) < 0.5 ? \"top\" : \"bottom\",\n };\n }\n\n /** Stamp the measured anchor so the shadow CSS can place the grip. */\n #syncResizeAnchor(): void {\n if (!this.#connected) {\n return;\n }\n const anchor = this.#measureAnchor();\n this.setAttribute(\"data-resize-anchor\", `${anchor.y}-${anchor.x}`);\n }\n\n /** Put a custom property back to a previous value, or remove it if there was none. */\n #restoreProperty(name: string, value: string): void {\n if (value === \"\") {\n this.style.removeProperty(name);\n return;\n }\n this.style.setProperty(name, value);\n }\n\n /**\n * Write a dragged size onto the host, on the axes this placement leaves free.\n *\n * Writing the custom property rather than inline `width` / `height` does not\n * by itself leave placement in charge: an inline custom property still\n * outranks a `:host([placement=\u2026])` rule setting the same property, so a\n * height dragged while floating would cap a docked sidebar asking for\n * `100vh`. The cascade cannot arbitrate this, so the axis check must \u2014 a\n * placement owns the axes it fixes, and a persisted size is applied only to\n * the ones it leaves free.\n */\n #applySize(size: ResizeSize): void {\n const axis = this.#resizeAxis();\n if (axis === \"none\") {\n return;\n }\n if (size.width !== undefined) {\n this.style.setProperty(\"--ag-ui-width\", `${size.width}px`);\n }\n if (size.height !== undefined && axis === \"both\") {\n this.style.setProperty(\"--ag-ui-height\", `${size.height}px`);\n }\n }\n\n /**\n * Drop any dragged size the new placement has taken ownership of.\n *\n * Without this a size survives the switch as an inline property and silently\n * overrides the placement it moved to \u2014 the panel keeps a floating height\n * while docked, and reads as a component that cannot do full height.\n */\n #releaseOwnedAxes(): void {\n const axis = this.#resizeAxis();\n if (axis !== \"both\") {\n this.style.removeProperty(\"--ag-ui-height\");\n }\n if (axis === \"none\") {\n this.style.removeProperty(\"--ag-ui-width\");\n }\n }\n\n /** Persist a dragged size per tab, alongside the collapsed/theme preferences. */\n #persistSize(size: ResizeSize): void {\n const stored = { ...this.#readSize(), ...size };\n sessionStorage.setItem(this.#storageKey(SIZE_KEY), JSON.stringify(stored));\n }\n\n /** The persisted size for this instance, or an empty record. */\n #readSize(): ResizeSize {\n const raw = this.#readScopedItem(SIZE_KEY);\n if (raw === null) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as ResizeSize) : {};\n } catch {\n // A corrupt entry is not worth failing a mount over; fall back to the\n // placement's own size.\n return {};\n }\n }\n\n /** This instance's namespaced form of an origin-scoped storage key. */\n #storageKey(base: string): string {\n return this.#storageNs === \"\" ? base : `${base}:${this.#storageNs}`;\n }\n\n /**\n * Read a namespaced origin-scoped value, falling back once to the legacy\n * pre-namespacing global key (left in place) so an existing collapsed/theme\n * preference survives the upgrade.\n */\n #readScopedItem(base: string): string | null {\n const scoped = sessionStorage.getItem(this.#storageKey(base));\n if (scoped !== null || this.#storageNs === \"\") {\n return scoped;\n }\n return sessionStorage.getItem(base);\n }\n\n /** Reflect the current theme on the toggle: show the destination's glyph. */\n #syncThemeGlyph(): void {\n const dark = this.getAttribute(\"theme\") === \"dark\";\n this.#themeToggle.textContent = dark ? \"\u2600\uFE0F\" : \"\uD83C\uDF19\";\n }\n\n /**\n * Open the thread-history drawer: the imperative route to the control that\n * renders as `::part(history-button)`.\n *\n * A host that hides `::part(header)` for its own title bar hides the history,\n * new-chat and collapse buttons with it. Each has a method so that chrome can\n * be rebuilt: this one, {@link openCheckpoints}, {@link newChat},\n * {@link toggleCollapsed} and {@link toggleTheme}.\n */\n openThreads(): void {\n // Two overlapping surfaces, so opening one dismisses the other. Clicking away\n // already covers the built-in buttons, but a host driving its own chrome\n // through these methods raises no pointer event \u2014 and the drawer would then\n // open *underneath* a popover still floating over it.\n this.#checkpoints.close();\n void this.#refreshDrawer();\n this.#drawer.open();\n }\n\n /**\n * Open the checkpoints panel (the `::part(checkpoints-button)` route).\n *\n * It lists the runs the `data-runs-url` server reports as continuable;\n * without that attribute the built-in button is never rendered and this opens\n * an empty panel.\n */\n openCheckpoints(): void {\n // The other half of the pair \u2014 see `openThreads`.\n this.#drawer.close();\n void this.#refreshCheckpoints();\n this.#checkpoints.open();\n }\n\n /** Close the checkpoints panel, if it is open. */\n closeCheckpoints(): void {\n this.#checkpoints.close();\n }\n\n /**\n * Open the checkpoints panel, or close it if it is already open \u2014 what the\n * built-in \u2B6F button does, because a control that opens a panel is read as the\n * control that also dismisses it. {@link openCheckpoints} stays open-only for a\n * host that means exactly that.\n */\n toggleCheckpoints(): void {\n if (this.#checkpoints.open_) {\n this.#checkpoints.close();\n return;\n }\n this.openCheckpoints();\n }\n\n /**\n * Start a fresh conversation: forget the persisted history, drop the\n * in-memory run state, clear the transcript, and mint a new thread id.\n */\n newChat(): void {\n // Stop any in-flight run first \u2014 discarding the client mid-run would\n // leave the old agent streaming into a cleared transcript.\n this.#cancelRun();\n this.conversationStore.clear(this.#threadId);\n this.#resetState();\n this.#threadId = this.conversationStore.threadId();\n this.#setRunning(false);\n this.#setUnread(0);\n }\n\n /** Drop the in-memory run + transcript, leaving the thread id untouched. */\n #resetState(): void {\n this.#client = null;\n this.#streamingBubble = null;\n this.#currentGroup = null;\n this.#thoughts = null;\n this.#hidePending();\n this.#toolCards.clear();\n this.#serverSettled.clear();\n this.#cardElements.clear();\n this.#activityBlocks.clear();\n this.#initialMessages = [];\n this.#attachTray?.clear();\n // Keep the empty-state region; everything else clears.\n this.#messages.replaceChildren(this.#emptyWrap);\n this.#updateEmptyState();\n }\n\n /** Switch the active conversation to an existing thread and replay it. */\n async #switchThread(threadId: string): Promise<void> {\n if (threadId === this.#threadId) {\n return;\n }\n this.#cancelRun();\n this.#resetState();\n this.conversationStore.setActiveThread(threadId);\n this.#threadId = threadId;\n this.#setRunning(false);\n await this.#rehydrate();\n }\n\n /** Delete a thread; if it was the active one, fall back to a fresh chat. */\n #deleteThread(threadId: string): void {\n const wasActive = threadId === this.#threadId;\n if (wasActive) {\n this.#cancelRun();\n }\n this.conversationStore.clear(threadId);\n if (wasActive) {\n this.#resetState();\n this.#threadId = this.conversationStore.threadId();\n this.#setRunning(false);\n }\n void this.#refreshDrawer();\n }\n\n /** Reload the drawer's thread list, marking the active thread. */\n async #refreshDrawer(): Promise<void> {\n this.#drawer.setThreads(await this.conversationStore.listThreads(), this.#threadId);\n }\n\n /**\n * Restore the conversation from the store on mount, then \u2014 if a navigating\n * tool reloaded the page mid-run \u2014 resume the loop by supplying that tool's\n * result from the page we landed on.\n */\n async #rehydrate(): Promise<void> {\n // Guard against a thread-switch race: with a slow remote store, picking\n // thread B then C would interleave both replays into one transcript. Each\n // rehydrate claims a generation before awaiting and bails if a newer one\n // started meanwhile (its `#resetState` already cleared the transcript).\n this.#rehydrateGeneration += 1;\n const generation = this.#rehydrateGeneration;\n const messages = await this.conversationStore.loadMessages(this.#threadId);\n if (generation !== this.#rehydrateGeneration) {\n return;\n }\n if (messages !== null) {\n this.#initialMessages = messages;\n for (const message of messages) {\n this.#renderHistoricMessage(message);\n }\n }\n const checkpoint = this.conversationStore.loadCheckpoint(this.#threadId);\n if (checkpoint !== null) {\n await this.#resumeFrom(checkpoint);\n return;\n }\n this.#noticeIfRunUnfinished(messages);\n }\n\n /**\n * Notice a previous run that never produced a response.\n *\n * {@link AgUiClient.send} persists the user's message before starting the\n * run, so a transcript ending on that user message means nothing came back.\n * The transcript's shape alone detects it, needing no store method and no\n * `pagehide` listener \u2014 neither of which fires on a crash or force-quit.\n *\n * An agent-initiated reload is not this case: a navigating tool leaves a\n * checkpoint and resumes, so the caller returns early on one.\n *\n * Deliberately a notice, never a resume. AG-UI has no resume-an-aborted-run\n * primitive, and re-sending the accumulated messages is semantically a new\n * run, so any server-side tool already executed would run a second time.\n */\n /**\n * Build a round's context, recording which page it describes.\n *\n * The AG-UI client re-invokes this at the top of **every** tool round, not\n * once per `send()`, so the page map the agent sees is already refreshed\n * between rounds and the href captured here is the page it was shown for\n * *this* round. {@link #executeTool} compares against it to catch a page that\n * moved under a round still in flight.\n */\n #buildContext(): Context[] {\n this.#contextHref = window.location.href;\n return this.getContext();\n }\n\n /**\n * Whether the page moved since the current round's context was built.\n *\n * `null` means no round has built context yet (nothing to compare), which is\n * not a move.\n */\n #pageMoved(): boolean {\n return this.#contextHref !== null && this.#contextHref !== window.location.href;\n }\n\n #noticeIfRunUnfinished(messages: readonly Message[] | null): void {\n const last = messages?.at(-1);\n if (last === undefined || last.role !== MESSAGE_ROLE.USER) {\n return;\n }\n this.#appendNotice(\"\u26A0\", this.#strings.runInterrupted, \"interrupted\");\n }\n\n /**\n * Replay a restored message: text bubbles *and* tool activity. An assistant\n * turn may carry `toolCalls` (rendered as cards) and/or text; a `tool` turn\n * carries a result that settles the matching card. So a refreshed page shows\n * the full transcript \u2014 tool calls and their results \u2014 not just the prose.\n */\n #renderHistoricMessage(message: Message): void {\n const text = typeof message.content === \"string\" ? message.content : \"\";\n if (message.role === MESSAGE_ROLE.USER) {\n const attachments = messageAttachments(message);\n if (text !== \"\" || attachments.length > 0) {\n const bubble = this.appendMessage(MESSAGE_ROLE.USER, text);\n if (attachments.length > 0) {\n bubble.appendChild(renderAttachmentChips(attachments));\n }\n }\n return;\n }\n if (message.role === MESSAGE_ROLE.ASSISTANT) {\n if (text !== \"\") {\n // Restored history must appear statically \u2014 entrance animations\n // (fade / word) are for freshly-arriving messages. On reload the whole\n // transcript mounts at once, so animating every bubble's text in\n // parallel looks wrong. Mark it so the fade CSS skips it, and don't\n // wrap words.\n this.appendMessage(MESSAGE_ROLE.ASSISTANT, text).classList.add(\"message--restored\");\n }\n // Narrowed rather than trusted, for the same reason `messageAttachments`\n // narrows the neighbouring field: anything that throws in this loop aborts\n // the replay at this message, and every later turn silently disappears from\n // the transcript. See `restoredToolCalls`.\n for (const call of restoredToolCalls(message.toolCalls)) {\n const restored = {\n id: call.id,\n name: call.function.name,\n args: this.#parseArgs(call.function.arguments),\n };\n // Restored history goes through the same interception as the live\n // stream \u2014 otherwise a reload resurrects the raw `load_capability`\n // card the live path deliberately replaced.\n if (this.#noticeIfSkillLoad(restored)) {\n continue;\n }\n this.#cardElements.set(restored.id, this.#cardFor(restored).element);\n // Only `render` is replayed, never `handler`. A restored transcript\n // redraws what the call drew; it must not re-run what the call *did*.\n const tool = this.#resolveTool(restored.name);\n if (tool !== null) {\n this.#renderToolOutput(tool, restored);\n }\n }\n return;\n }\n if (message.role === \"activity\") {\n // The client materialises a pushed activity as a message of its own, so a\n // chart's data is in the transcript already and survives a reload. Only\n // the drawing had to be put back.\n const activity = message as unknown as { activityType?: unknown; content?: unknown };\n if (activity.activityType === CHART_ACTIVITY_TYPE && this.#chartActivity) {\n this.#drawActivityChart(message.id, activity.content);\n }\n return;\n }\n if (message.role === \"tool\") {\n const card = this.#toolCards.get(message.toolCallId);\n if (card !== undefined) {\n card.settle(TOOL_CALL_STATUS.DONE, message.content);\n }\n }\n }\n\n /** Parse a tool call's JSON `arguments` from history into an object. */\n #parseArgs(raw: unknown): Record<string, unknown> {\n if (typeof raw !== \"string\") {\n // A restored call whose `arguments` are missing or not a string still has\n // a name worth showing, so this renders an empty-args card rather than\n // dropping the card.\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // Malformed history \u2014 fall back to empty args rather than failing replay.\n }\n return {};\n }\n\n /**\n * Word-by-word reveal for the `word` text-animation mode, applied to a\n * completed assistant bubble. `fade` is pure CSS (no JS); `none` is a no-op.\n */\n #revealWords(bubble: HTMLDivElement): void {\n if (this.getAttribute(\"data-text-animation\") === \"word\") {\n wrapWords(bubble);\n }\n }\n\n /** Complete the checkpointed navigating tool call and continue the run. */\n async #resumeFrom(checkpoint: NavigationCheckpoint): Promise<void> {\n this.conversationStore.saveCheckpoint(this.#threadId, null);\n const client = this.#ensureClient();\n client.addToolResult(checkpoint.toolCallId, JSON.stringify(this.navigationResult(checkpoint)));\n await client.resume();\n }\n\n /**\n * Append a message bubble and return it.\n *\n * Assistant content renders as sanitised markdown/HTML; user content stays\n * literal text, which also avoids rendering user-authored markup.\n *\n * Assistant bubbles land in the current answer group, opening one if needed;\n * a user bubble closes the prior group and sits directly in the list, the\n * well wrapping only the assistant turn.\n */\n appendMessage(role: MessageRole, content: string): HTMLDivElement {\n const bubble = document.createElement(\"div\");\n bubble.className = `message message--${role}`;\n bubble.setAttribute(\"part\", `message message-${role}`);\n if (role === MESSAGE_ROLE.ASSISTANT) {\n bubble.innerHTML = renderMarkdown(content, { allowImages: this.allowImages });\n // A finished bubble: rehydrated history, or a whole message appended at\n // once. The streaming bubble gets its buttons in onTextEnd instead.\n attachCopyButtons(bubble, this.#strings);\n this.#ensureGroup().appendChild(bubble);\n } else {\n this.#currentGroup = null;\n bubble.textContent = content;\n this.#messages.appendChild(bubble);\n }\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return bubble;\n }\n\n /**\n * The open answer group, creating and appending it on first use. Everything a\n * single assistant turn renders (text, tool cards, the pending indicator)\n * goes inside it, so the opt-in `data-answer-well` styling can box the whole\n * turn. Idempotent across the turn's runs \u2014 it persists until {@link #handlers}'\n * `onSettled` nulls it.\n */\n #ensureGroup(): HTMLDivElement {\n if (this.#currentGroup === null) {\n const group = document.createElement(\"div\");\n group.className = \"answer\";\n group.setAttribute(\"part\", \"answer\");\n this.#currentGroup = group;\n this.#messages.appendChild(group);\n this.#updateEmptyState();\n }\n return this.#currentGroup;\n }\n\n #render(): void {\n const style = document.createElement(\"style\");\n style.textContent = STYLES;\n\n this.#chat.className = \"chat\";\n this.#chat.setAttribute(\"part\", \"panel\");\n\n const header = document.createElement(\"div\");\n header.className = \"header\";\n header.setAttribute(\"part\", \"header\");\n\n const title = this.#title;\n title.className = \"header-title\";\n title.setAttribute(\"part\", \"title\");\n title.textContent = this.getAttribute(\"title-text\") ?? this.#strings.title;\n\n // Optional header icon: a slot (any markup) with a `data-icon-url` <img>\n // fallback. Rendered only when one of the two is provided, so the header has\n // no phantom gap otherwise.\n if (\n this.querySelector('[slot=\"icon\"]') !== null ||\n this.getAttribute(\"data-icon-url\") !== null\n ) {\n header.append(this.#iconElement(\"icon\", \"icon\", null));\n }\n\n // A coarse slot for host-provided header actions, between title and controls.\n const headerActions = document.createElement(\"slot\");\n headerActions.name = \"header-actions\";\n\n const controls = document.createElement(\"div\");\n controls.className = \"header-controls\";\n controls.setAttribute(\"part\", \"header-controls\");\n\n // Both controls delegate to the public methods, so a host chrome driving\n // them imperatively takes exactly the path the built-in button takes.\n const history = this.#headerButton(\"history\", this.#strings.chatHistory, \"\u2630\");\n history.addEventListener(\"click\", () => this.openThreads());\n\n // \u21BA rather than \u2B6F: the same idea in a glyph that has a font behind it in\n // every browser. The obscure one rendered as an unreadable mark at 14px, and a\n // header control nobody can name is one nobody presses.\n const checkpoints = this.#headerButton(\"checkpoints\", this.#strings.checkpoints, \"\u21BA\");\n checkpoints.addEventListener(\"click\", () => this.toggleCheckpoints());\n\n const newChat = this.#headerButton(\"new\", this.#strings.newChat, \"\u271A\");\n newChat.addEventListener(\"click\", () => this.newChat());\n\n const collapse = this.#headerButton(\"collapse\", this.#strings.collapse, \"\u2014\");\n collapse.addEventListener(\"click\", () => this.toggleCollapsed());\n\n // Only offered when the server actually indexes runs \u2014 without\n // `data-runs-url` there is nothing to continue and the button would open\n // a permanently empty panel. Asks `#runs()` rather than re-testing the\n // attribute, so \"configured\" means one thing everywhere (an empty value\n // is unset, not a relative URL to the current page).\n if (this.#runs() !== null) {\n controls.append(history, checkpoints, newChat);\n } else {\n controls.append(history, newChat);\n }\n // Optional built-in theme toggle: off unless the host opts in, so\n // it never competes with a host-supplied switch in `slot=\"header-actions\"`.\n if (this.getAttribute(\"data-theme-toggle\") !== null) {\n this.#themeToggle.type = \"button\";\n this.#themeToggle.className = \"header-btn header-btn--theme\";\n this.#themeToggle.setAttribute(\"part\", \"header-button theme-toggle\");\n this.#themeToggle.title = this.#strings.toggleTheme;\n this.#themeToggle.setAttribute(\"aria-label\", this.#strings.toggleTheme);\n this.#themeToggle.addEventListener(\"click\", () => this.toggleTheme());\n this.#syncThemeGlyph();\n controls.append(this.#themeToggle);\n }\n controls.append(collapse);\n header.append(title, headerActions, controls);\n\n this.#messages.className = \"messages\";\n this.#messages.setAttribute(\"part\", \"messages\");\n // Screen readers announce streamed messages as they arrive.\n this.#messages.setAttribute(\"role\", \"log\");\n this.#messages.setAttribute(\"aria-live\", \"polite\");\n this.#messages.setAttribute(\"aria-label\", this.#strings.conversation);\n\n // Empty-state region: a host slot at the top of the list, hidden as soon as\n // anything renders.\n this.#emptyWrap.className = \"empty\";\n this.#emptyWrap.setAttribute(\"part\", \"empty\");\n const emptySlot = document.createElement(\"slot\");\n emptySlot.name = \"empty\";\n this.#emptyWrap.append(emptySlot);\n this.#messages.append(this.#emptyWrap);\n\n const inputRow = document.createElement(\"div\");\n inputRow.className = \"input-row\";\n inputRow.setAttribute(\"part\", \"composer\");\n\n // One bordered surface holds the field and the tool row under it, so the\n // icon buttons stop competing with the field for weight.\n const composer = document.createElement(\"div\");\n composer.className = \"composer\";\n composer.setAttribute(\"part\", \"composer-surface\");\n\n const tools = document.createElement(\"div\");\n tools.className = \"composer-tools\";\n tools.setAttribute(\"part\", \"composer-tools\");\n\n this.#input.className = \"input\";\n this.#input.setAttribute(\"part\", \"input\");\n this.#input.setAttribute(\"aria-label\", this.#strings.message);\n this.#input.rows = 1;\n this.#input.placeholder = this.#strings.inputPlaceholder;\n this.#input.addEventListener(\"keydown\", (event) => this.#onKeydown(event));\n this.#input.addEventListener(\"input\", () => this.#onInput());\n\n // Icon-only, with both glyphs mounted at once and CSS showing the one the\n // state calls for \u2014 swapping a single glyph would leave a host that slotted\n // its own Send mark holding a stop icon mid-run.\n this.#send.className = \"send\";\n this.#send.type = \"button\";\n this.#send.setAttribute(\"part\", \"send\");\n this.#send.append(\n this.#glyphSlot(\"icon-send\", \"send-send\", ICON_SEND),\n this.#glyphSlot(\"icon-stop\", \"send-stop\", ICON_STOP),\n );\n this.#send.title = this.#strings.send;\n this.#send.setAttribute(\"aria-label\", this.#strings.send);\n this.#send.dataset[\"state\"] = \"idle\";\n this.#send.addEventListener(\"click\", () => {\n // One button, two states: Send while idle, Stop while a run is in\n // flight (no layout change).\n if (this.#running) {\n this.#cancelRun();\n return;\n }\n void this.#submit();\n });\n\n this.#skillHint.className = \"skill-hint\";\n this.#skillHint.setAttribute(\"part\", \"skill-hint\");\n this.#skillHint.hidden = true;\n\n // File-upload affordance: a paperclip button (hidden until\n // `data-attachments-url` is wired) opening a hidden multi-file input.\n // Drag-and-drop covers the whole shell (wired in #enableDragAndDrop).\n this.#attachButton.className = \"attach-btn\";\n this.#attachButton.type = \"button\";\n this.#attachButton.setAttribute(\"part\", \"attach-button\");\n this.#attachButton.append(this.#glyphSlot(\"icon-attach\", \"attach-glyph\", ICON_ATTACH));\n this.#attachButton.title = this.#strings.attachFiles;\n this.#attachButton.setAttribute(\"aria-label\", this.#strings.attachFiles);\n this.#attachButton.hidden = true;\n this.#attachButton.addEventListener(\"click\", () => this.#fileInput.click());\n\n this.#fileInput.className = \"attach-input\";\n this.#fileInput.type = \"file\";\n this.#fileInput.multiple = true;\n this.#fileInput.hidden = true;\n this.#fileInput.addEventListener(\"change\", () => this.#onFilesPicked());\n\n this.#attachSlot.className = \"attachment-slot\";\n\n // Mic button mount point (kept empty until #wireVoice mounts the control).\n this.#voiceSlot.className = \"voice-slot\";\n\n // A coarse footer slot below the composer.\n const footer = document.createElement(\"slot\");\n footer.name = \"footer\";\n\n tools.append(this.#attachButton, this.#voiceSlot, this.#send);\n composer.append(this.#input, tools);\n inputRow.append(composer, this.#fileInput);\n // Skill surfaces sit just above the input: palette (opens on `/`), chips,\n // the missing-placeholder hint, and the pending-attachments tray.\n this.#chat.append(\n header,\n this.#messages,\n this.#skillsMenu.palette,\n this.#skillsMenu.chips,\n this.#skillHint,\n this.#attachSlot,\n inputRow,\n footer,\n this.#drawer.element,\n this.#checkpoints.element,\n );\n\n // Clicking away dismisses the checkpoints popover. Escape already did, and the\n // drawer has a backdrop that swallows the click \u2014 this popover has neither, so\n // it could only be closed by answering it.\n //\n // `pointerdown`, and the header button excluded: pointerdown runs *before* the\n // button's own click, so closing here and toggling there would land back open.\n // Composed path rather than `target`, because the event is retargeted at the\n // shadow boundary and every one of these nodes is inside it.\n this.#chat.addEventListener(\"pointerdown\", (event) => {\n if (!this.#checkpoints.open_) {\n return;\n }\n const path = event.composedPath();\n if (path.includes(this.#checkpoints.element) || path.includes(checkpoints)) {\n return;\n }\n this.#checkpoints.close();\n });\n\n // What a collapsed widget shrinks to: a round floating button, or the slim\n // edge rail under `placement=\"sidebar\"` \u2014 one element, shaped by CSS.\n // A sibling of the panel, so it survives the panel being hidden.\n this.#launcher.className = \"launcher\";\n this.#launcher.type = \"button\";\n this.#launcher.setAttribute(\"part\", \"launcher\");\n this.#launcher.setAttribute(\"aria-label\", this.#strings.expand);\n this.#badge.className = \"launcher-badge\";\n this.#badge.setAttribute(\"part\", \"launcher-badge\");\n // The count is announced through the launcher's own label, so the badge is\n // decoration to a screen reader rather than a second, context-free number.\n this.#badge.setAttribute(\"aria-hidden\", \"true\");\n this.#badge.hidden = true;\n this.#launcher.append(\n this.#iconElement(\"launcher\", \"launcher-icon\", ICON_LAUNCHER, this.#launcherIconUrl()),\n this.#badge,\n );\n this.#launcher.addEventListener(\"click\", () => this.setCollapsed(false));\n\n this.#chat.append(\n createResizeHandle({\n axis: () => this.#resizeAxis(),\n anchor: () => this.#measureAnchor(),\n rect: () => this.getBoundingClientRect(),\n apply: (size) => this.#applySize(size),\n commit: (size) => {\n this.#persistSize(size);\n // Re-stamp after the drag: a host whose layout changed underneath us\n // would otherwise keep the grip in the old corner, which reads as the\n // control being in the wrong place even though the drag was right.\n this.#syncResizeAnchor();\n },\n label: this.#strings.resizePanel,\n }),\n );\n this.#root.append(style, this.#chat, this.#launcher);\n }\n\n /**\n * Build a header control button: a named slot a host can project markup into,\n * with the built-in glyph as the slot's fallback.\n *\n * The slot is what lets a host replace the mark with its own `<img>` or\n * `<svg>` rather than only restyle it through the `part`; the same\n * slot-with-fallback idiom the header icon uses.\n */\n #headerButton(modifier: string, label: string, glyph: string): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.className = `header-btn header-btn--${modifier}`;\n button.setAttribute(\"part\", `header-button ${modifier}-button`);\n button.title = label;\n button.setAttribute(\"aria-label\", label);\n const slot = document.createElement(\"slot\");\n slot.name = `icon-${modifier}`;\n slot.append(document.createTextNode(glyph));\n button.append(slot);\n return button;\n }\n\n /**\n * A `<slot>` a host can project its own mark into, falling back to one of the\n * built-in glyphs. The markup is an author-written constant, never user or\n * server data, so it is assigned directly rather than sanitised.\n */\n #glyphSlot(slotName: string, className: string, markup: string): HTMLSlotElement {\n const slot = document.createElement(\"slot\");\n slot.name = slotName;\n slot.className = className;\n slot.innerHTML = markup;\n return slot;\n }\n\n /**\n * The launcher's own image URL. `data-launcher-icon-url` lets the collapsed\n * button carry a different mark from the header's \u2014 a product logo reads at\n * 22px in a header bar but rarely at 26px in a circle \u2014 and falls back to the\n * header icon so a single `data-icon-url` still feeds both.\n */\n #launcherIconUrl(): string | null {\n return this.getAttribute(\"data-launcher-icon-url\") ?? this.getAttribute(\"data-icon-url\");\n }\n\n /**\n * An icon holder wrapping a `<slot>` so a host can project custom markup;\n * with an `<img>` as the slot's fallback when an icon URL is configured, or\n * the given glyph markup when it is not.\n */\n #iconElement(\n slotName: string,\n part: string,\n fallbackGlyph: string | null,\n iconUrl: string | null = this.getAttribute(\"data-icon-url\"),\n ): HTMLSpanElement {\n const holder = document.createElement(\"span\");\n holder.className = \"icon-holder\";\n holder.setAttribute(\"part\", part);\n const slot = document.createElement(\"slot\");\n slot.name = slotName;\n if (iconUrl !== null) {\n const img = document.createElement(\"img\");\n img.className = \"icon-img\";\n img.src = iconUrl;\n img.alt = \"\";\n slot.append(img);\n } else if (fallbackGlyph !== null) {\n slot.innerHTML = fallbackGlyph;\n }\n holder.append(slot);\n return holder;\n }\n\n /**\n * Reflect the collapsed state and the unread count on the launcher.\n *\n * The count is also the launcher's accessible name: a badge that only exists\n * as a coloured dot says nothing to a screen reader, and \"Expand\" alone would\n * be a lie once answers are waiting behind it.\n */\n #syncLauncher(): void {\n this.#launcher.setAttribute(\"aria-expanded\", String(!this.collapsed));\n const unread = this.#unread;\n // Past 9 the exact number stops being information and starts being a\n // layout problem \u2014 the badge is a circle, not a field.\n this.#badge.textContent = unread > 9 ? \"9+\" : String(unread);\n this.#badge.hidden = unread === 0 || !this.#badgeEnabled();\n const label = this.#badge.hidden\n ? this.#strings.expand\n : this.#strings.expandUnread.replace(\"{count}\", String(unread));\n this.#launcher.setAttribute(\"aria-label\", label);\n this.#launcher.title = label;\n }\n\n /**\n * The unread badge, unlike every other affordance here, is on by default:\n * a collapsed widget is the one state where an answer can arrive with nothing\n * on screen to say so. `data-unread-badge=\"false\"` turns it off for a host\n * that drives its own chrome from the `ag-ui-unread` event.\n */\n #badgeEnabled(): boolean {\n return this.getAttribute(\"data-unread-badge\") !== \"false\";\n }\n\n /**\n * Set the unread count, repaint the badge, and tell the host.\n *\n * The count is kept whether or not the badge renders it, so `unread` stays\n * truthful for a host chrome and switching the badge on mid-session doesn't\n * start from a number that was never counted.\n */\n #setUnread(count: number): void {\n this.#unread = count;\n this.#syncLauncher();\n this.dispatchEvent(\n new CustomEvent<UnreadDetail>(UNREAD_EVENT, {\n detail: { unread: count },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /**\n * Count an answer the user cannot have seen: one that finished while the\n * widget was collapsed. Expanding is what marks them read.\n */\n #noteUnread(): void {\n if (!this.collapsed) {\n return;\n }\n this.#setUnread(this.#unread + 1);\n }\n\n /** Hide the empty-state region once the message list holds anything else. */\n #updateEmptyState(): void {\n this.#emptyWrap.hidden = this.#messages.childElementCount > 1;\n }\n\n /** Forward input changes to the skills palette and clear any stale hint. */\n #onInput(): void {\n this.#skillsMenu.onInput(this.#input.value);\n this.#skillHint.hidden = true;\n this.#autoGrow();\n }\n\n #onKeydown(event: KeyboardEvent): void {\n // The skills palette consumes arrows/enter/escape while open.\n if (this.#skillsMenu.onKeydown(event)) {\n event.preventDefault();\n return;\n }\n // Escape-to-cancel \u2014 only reachable when the palette is closed (it\n // consumed the key above otherwise), so the two Escapes don't clash.\n if (event.key === \"Escape\" && this.#running) {\n event.preventDefault();\n this.#cancelRun();\n return;\n }\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n void this.#submit();\n }\n }\n\n /**\n * Stop the in-flight run: decline any confirmation card awaiting a decision\n * (the loop is suspended on it), then cancel the client run \u2014 the abort\n * closes the streaming request, which is AG-UI's cancel (the server\n * observes the disconnect).\n */\n #cancelRun(): void {\n this.#confirmAbort?.abort();\n this.#client?.cancel();\n }\n\n /**\n * Swap the composer button between Send (idle) and Stop (running).\n *\n * The glyph is swapped by CSS from `data-state` \u2014 both are mounted \u2014 so this\n * only has to move the accessible name, which is the button's whole label now\n * that it carries no text.\n */\n #setRunning(running: boolean): void {\n this.#running = running;\n const label = running ? this.#strings.stop : this.#strings.send;\n this.#send.title = label;\n this.#send.setAttribute(\"aria-label\", label);\n this.#send.dataset[\"state\"] = running ? \"running\" : \"idle\";\n }\n\n /**\n * Size the field to its content: one row when empty, growing with what is\n * typed until the CSS ceiling takes over and it scrolls.\n *\n * Resetting to `auto` first is what makes it shrink again \u2014 `scrollHeight`\n * never reports less than the current height, so measuring without the reset\n * would ratchet the composer taller and never back down.\n */\n #autoGrow(): void {\n this.#input.style.height = \"auto\";\n this.#input.style.height = `${this.#input.scrollHeight}px`;\n }\n\n async #submit(): Promise<void> {\n // Ignore a submit while a run is in flight \u2014 the single choke point for\n // both Enter and the Send button. The button already turns into Stop, but\n // Enter has no such guard; without this it would start a second concurrent\n // SSE run that orphans the first (unabortable) and lets the second run's\n // settle sweep corrupt the first's still-pending tool cards.\n if (this.#running) {\n return;\n }\n const content = this.#input.value.trim();\n const attachments = this.#attachTray?.readyRefs() ?? [];\n // Allow an attachments-only message (no typed text), but nothing empty.\n if (content === \"\" && attachments.length === 0) {\n return;\n }\n this.#input.value = \"\";\n this.#autoGrow();\n // A file still uploading does not ride along \u2014 `readyRefs()` returns only\n // settled ones, and `clearReady()` deliberately keeps the rest for a\n // follow-up. Nothing said so, which is the whole defect: attachments are\n // frequently the entire point of the message, and the user had no way to\n // tell theirs had been left behind. Say it before dropping the chips,\n // while `hasPending()` still describes this send.\n if (this.#attachTray?.hasPending() === true) {\n this.#appendNotice(\n \"\\u{1F4CE}\",\n this.#strings.attachmentsStillUploading.replace(\n \"{n}\",\n String(this.#attachTray.pendingCount()),\n ),\n \"attachment-pending\",\n );\n }\n // The refs ride the message from here; drop the settled chips, keep any\n // still uploading for a follow-up message.\n this.#attachTray?.clearReady();\n await this.sendMessage(content, attachments);\n }\n\n /**\n * Send a message as if the user had typed it \u2014 renders the user bubble,\n * dispatches {@link SUBMIT_EVENT}, and starts the run.\n *\n * The programmatic half of the composer, for a host driving its own input.\n * Everything the built-in Send does happens here; Send reads the composer,\n * clears it, and calls this.\n *\n * `attachments` are durable {@link AttachmentRef}s \u2014 what {@link attachFile}\n * resolves to and what {@link ATTACHMENT_EVENT} reports.\n *\n * No-ops on an empty message, and while a run is in flight, since a second\n * concurrent run would orphan the first. Unlike the built-in Send it does not\n * consult the tray: what you pass is what is sent.\n */\n async sendMessage(content: string, attachments: readonly AttachmentRef[] = []): Promise<void> {\n if (this.#running || (content === \"\" && attachments.length === 0)) {\n return;\n }\n const bubble = this.appendMessage(MESSAGE_ROLE.USER, content);\n if (attachments.length > 0) {\n bubble.appendChild(renderAttachmentChips(attachments));\n }\n this.dispatchEvent(\n new CustomEvent<SubmitDetail>(SUBMIT_EVENT, {\n detail: { content, attachments },\n bubbles: true,\n composed: true,\n }),\n );\n await this.#client_send(content, attachments);\n }\n\n /**\n * Queue a file for upload into the attachment tray, exactly as the file\n * picker and drag-and-drop do \u2014 validation, progress chip, and all.\n *\n * Returns `false` when uploads are not configured (no `data-attachments-url`\n * and no {@link uploadHandler}) \u2014 the only signal a host gets, since the tray\n * does not exist to report anything then.\n *\n * Uploading is asynchronous: watch {@link ATTACHMENT_EVENT} for the resulting\n * {@link AttachmentRef} and pass it to {@link sendMessage} once `pending`\n * reaches zero.\n */\n attachFile(file: File): boolean {\n if (this.#attachTray === null) {\n return false;\n }\n this.#attachTray.add(file);\n return true;\n }\n\n /** Tell the host what the tray now holds \u2014 see {@link ATTACHMENT_EVENT}. */\n #dispatchAttachments(tray: AttachmentTray): void {\n this.dispatchEvent(\n new CustomEvent<AttachmentsDetail>(ATTACHMENT_EVENT, {\n detail: { attachments: tray.readyRefs(), pending: tray.pendingCount() },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n async #client_send(content: string, attachments: readonly AttachmentRef[]): Promise<void> {\n if (this.endpoint === \"\") {\n return;\n }\n await this.#ensureClient().send(content, attachments);\n }\n\n #ensureClient(): AgUiClient {\n if (this.#client === null) {\n const agent = this.agentFactory({\n endpoint: this.endpoint,\n headers: this.#requestHeaders(),\n // Live getter: the client is built once and cached, but a rotated\n // token must still reach every request \u2014 the factory's fetch wrapper\n // re-reads this on each call.\n getHeaders: () => this.#requestHeaders(),\n ...this.#credentialsOption(),\n threadId: this.#threadId,\n initialMessages: this.#initialMessages,\n initialState: this.#sharedState,\n });\n this.#client = new AgUiClient({\n agent,\n handlers: this.#handlers(),\n getTools: () => this.getTools(),\n getContext: () => this.#buildContext(),\n executeTool: (call) => this.#executeTool(call),\n resolveInterrupts: (interrupts) => this.#resolveInterrupts(interrupts),\n onPersist: (messages) => this.conversationStore.saveMessages(this.#threadId, messages),\n onStateChanged: (state) => this.#onSharedStateChanged(state),\n connectionLostMessage: this.#strings.connectionLost,\n });\n }\n return this.#client;\n }\n\n /** Mirror the agent's applied state and tell the host it moved. */\n #onSharedStateChanged(state: Readonly<Record<string, unknown>>): void {\n this.#sharedState = { ...state };\n this.dispatchEvent(\n new CustomEvent<StateDetail>(STATE_EVENT, {\n detail: { state: this.#sharedState },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /** Whether ``call`` should be gated behind the confirmation card. */\n async #needsConfirmation(call: AgUiToolCall, tool: ClientTool): Promise<boolean> {\n if (this.autoConfirm) {\n return false;\n }\n if (this.confirmPredicate !== null) {\n return (await this.confirmPredicate(call.name, call.args)) === true;\n }\n return isDestructive(tool.parameters);\n }\n\n async #executeTool(call: AgUiToolCall): Promise<ToolExecution | null> {\n // A skill load already rendered as a notice on the stream; it is never a\n // client tool and its result is pydantic-ai's business, so it must not\n // acquire a card here on the way to the no-result fallback below.\n if (skillNameFrom(call) !== null) {\n return null;\n }\n const card = this.#cardFor(call);\n this.#toolCards.delete(call.id);\n // Kept after the card leaves `#toolCards`: a tool that renders into the\n // transcript places itself against its own card, and by the time it runs the\n // card is no longer reachable by id.\n this.#cardElements.set(call.id, card.element);\n const tool = this.#resolveTool(call.name);\n if (tool === null) {\n // Not a client tool. A server-side tool's real output arrives via\n // `onToolResult` (TOOL_CALL_RESULT) and already settled the card \u2014 only\n // fall back when it didn't. When no result ever arrived, the call wasn't\n // executed by either side (no handler, no server result), so say so\n // honestly rather than claiming server execution. We do NOT show the\n // pending indicator: nothing here triggers another client round, so it\n // would hang after the run ended.\n if (!this.#serverSettled.has(call.id)) {\n card.settle(TOOL_CALL_STATUS.DONE, this.#strings.noResult);\n }\n return null;\n }\n // The page moved under this round. Acting now would target whatever\n // matches on the new page, and the case worth preventing is a same-named\n // control matching silently \u2014 the only way the agent acts on the wrong page\n // without either side noticing.\n //\n // Must precede the confirmation prompt, so the user is never asked to\n // approve an action about to be refused. Navigating tools are exempt, since\n // moving the page is their job, as is read_page, the documented recovery.\n // Gated on a page-map provider: without one there is no read_page to\n // recommend and the host's tools are not page-scoped anyway.\n if (\n this.getPageMap !== null &&\n call.name !== READ_PAGE_TOOL &&\n !isNavigates(tool.parameters) &&\n this.#pageMoved()\n ) {\n const message = this.#strings.pageMoved;\n card.settle(TOOL_CALL_STATUS.ERROR, message);\n this.#showPending();\n return { content: `Error: ${message}`, error: message };\n }\n if (await this.#needsConfirmation(call, tool)) {\n const request: ConfirmationRequest = { toolName: call.name, args: call.args };\n const confirmText = tool.parameters[X_CONFIRM_KEY];\n if (typeof confirmText === \"string\") {\n request.message = confirmText;\n }\n // The run loop is suspended on this card; a Stop while it's open aborts\n // the controller, resolving the decision as declined.\n this.#confirmAbort = new AbortController();\n // Into the turn's answer group, like every other inline card. Appending\n // to the message list made it a sibling *after* the group, so anything\n // that streamed afterwards rendered above it and the prompt drifted to\n // the foot of the turn no matter when it was asked.\n const decision = requestConfirmation(this.#ensureGroup(), request, {\n signal: this.#confirmAbort.signal,\n strings: this.#strings,\n });\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n const accepted = await decision;\n this.#confirmAbort = null;\n card.recordDecision(accepted ? \"approved\" : \"declined\");\n if (!accepted) {\n const message = this.#strings.declinedAction;\n card.settle(TOOL_CALL_STATUS.DECLINED, message);\n this.#showPending();\n return { content: message };\n }\n }\n // A navigating tool reloads only without a client-side router; with a\n // host `navigate()` (SPA) it routes in-page and the loop just continues.\n const navigates = isNavigates(tool.parameters) && this.navigate === null;\n if (navigates) {\n // Checkpoint before the handler reloads the page; the history (incl.\n // this tool call) was already persisted when the run that produced it\n // settled. The result is supplied on the next mount via the resume path.\n this.conversationStore.saveCheckpoint(this.#threadId, { toolCallId: call.id });\n }\n try {\n // The call id lets a handler that renders into the transcript find its\n // own card; handlers that only act on the page ignore it.\n const result = await tool.handler(call.args, call.id);\n // Drawn from the arguments rather than the result, so the live path and\n // the replay path render the same thing from the same input.\n this.#renderToolOutput(tool, call);\n if (navigates) {\n card.settle(TOOL_CALL_STATUS.DONE, this.#strings.navigating);\n return { content: \"\", halt: true };\n }\n const content = JSON.stringify(result ?? null);\n card.settle(TOOL_CALL_STATUS.DONE, content);\n this.#showPending();\n return { content };\n } catch (error) {\n if (navigates) {\n // The navigation never happened; drop the dangling checkpoint.\n this.conversationStore.saveCheckpoint(this.#threadId, null);\n }\n const message = error instanceof Error ? error.message : String(error);\n card.settle(TOOL_CALL_STATUS.ERROR, message);\n this.#showPending();\n return { content: `Error: ${message}`, error: message };\n }\n }\n\n /**\n * Render an approval card per server-side-tool interrupt and collect the\n * user's decisions (approve \u2192 run it, deny \u2192 decline it).\n *\n * **One card per gated call, in that call's own tool card, all at once.** A run\n * can defer several calls, and the wire answers each independently \u2014 so the UI\n * has to let a person answer each independently, which means saying which is\n * which. The prompt cannot: it comes from the tool's `x-confirm` and is\n * identical for every call of that tool. The tool card can, by position, and it\n * is already showing the arguments. Asking them serially was the other half of\n * the problem: the second question only appeared once the first was answered,\n * so a person could neither compare them nor tell that more were coming.\n *\n * Each gated card is marked `deferred` for the wait. That is not cosmetic \u2014 at\n * `pending` it read \"running\u2026\" while the stream was over and the server idle.\n *\n * The run is suspended on these cards. A Stop while any is open aborts the\n * shared {@link #confirmAbort} controller, resolving every still-open card as\n * denied. An approved tool runs on the follow-up resume run and streams its\n * result into the same card (returned to `pending`, since it now really is\n * running); a denied one settles here, as no result will ever arrive.\n */\n async #resolveInterrupts(\n interrupts: readonly Interrupt[],\n ): Promise<Record<string, InterruptResponse>> {\n // One controller covers the whole batch: a single Stop denies all of them.\n this.#confirmAbort = new AbortController();\n this.#hidePending();\n const signal = this.#confirmAbort.signal;\n const answered = await Promise.all(\n interrupts.map(async (interrupt) => {\n const card =\n interrupt.toolCallId !== undefined\n ? this.#toolCards.get(interrupt.toolCallId)\n : undefined;\n const request: ApprovalRequest = {};\n const phrase = confirmPhrase(interrupt) ?? interrupt.message;\n if (phrase !== undefined) {\n request.message = phrase;\n }\n const toolName = card?.element.getAttribute(\"data-tool-name\");\n if (toolName !== null && toolName !== undefined) {\n request.toolName = toolName;\n }\n card?.mark(TOOL_CALL_STATUS.DEFERRED);\n // A host-supplied renderer takes full control of the approval UI. The\n // built-in card renders into the gated call's own card, falling back to\n // the answer group when the interrupt names no call we hold one for.\n const approved =\n this.approvalRenderer !== null\n ? await this.approvalRenderer(request, { signal })\n : await requestApproval(card?.approvalSlot ?? this.#ensureGroup(), request, {\n signal,\n strings: this.#strings,\n });\n // Same annotation as the client-side confirmation gate. Without it the\n // two gates read differently for the same act: a locally-confirmed call\n // said who let it through and a server-gated one said nothing, which is\n // backwards, since the server-side gate is the one guarding the tools\n // that actually run on the backend.\n card?.recordDecision(approved ? \"approved\" : \"declined\");\n if (approved) {\n card?.mark(TOOL_CALL_STATUS.PENDING);\n } else {\n // No TOOL_CALL_RESULT will stream for a denied tool \u2014 settle its card\n // now rather than leaving it hanging until the onSettled sweep.\n card?.settle(TOOL_CALL_STATUS.DECLINED, this.#strings.declinedAction);\n }\n return { id: interrupt.id, approved };\n }),\n );\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n this.#confirmAbort = null;\n const responses: Record<string, InterruptResponse> = {};\n for (const { id, approved } of answered) {\n responses[id] = approved\n ? { status: \"resolved\", payload: { approved: true } }\n : { status: \"cancelled\" };\n }\n return responses;\n }\n\n #handlers(): AgUiClientHandlers {\n return {\n onRunStart: () => {\n this.#setRunning(true);\n // Open the answer group on the turn's first run so the pending\n // indicator (and everything after) lands inside the well. Idempotent:\n // later rounds of the same turn reuse it.\n this.#ensureGroup();\n this.#showPending();\n },\n onReasoningStart: () => {\n // The model is thinking: swap the pending dots for a live thoughts\n // region at the top of the turn's answer group.\n this.#hidePending();\n this.#showThoughts();\n },\n onReasoningDelta: (buffer) => {\n this.#showThoughts().stream(buffer);\n },\n onReasoningEnd: () => {\n // Leave the region expanded until the answer text starts \u2014 it collapses\n // on the first text delta (onTextDelta).\n },\n onTextDelta: (buffer) => {\n this.#hidePending();\n // The answer has begun \u2014 fold the thoughts away so they don't crowd it.\n this.#thoughts?.collapse();\n this.#streamInto(buffer);\n this.#streamDeltas += 1;\n },\n onTextEnd: (buffer) => {\n const bubble = this.#streamInto(buffer);\n // Only reveal word-by-word when the message arrived at once. If it\n // streamed across multiple deltas it already revealed progressively, so\n // wrapping it now would re-animate the whole message \u2014 the awkward\n // \"finished response replays one word at a time\" bug.\n if (this.#streamDeltas <= 1) {\n this.#revealWords(bubble);\n }\n attachCopyButtons(bubble, this.#strings);\n this.#streamingBubble = null;\n this.#noteUnread();\n },\n onToolCall: (call) => {\n this.#hidePending();\n // A skill activation is an ordinary `load_capability` tool call \u2014 the\n // deferred-capability mechanism pydantic-ai already uses \u2014 so it arrives\n // here rather than on a channel of its own. Render it as a notice and\n // *return*: falling through would show a raw tool card beside the chip,\n // which is worse than the card alone.\n if (this.#noticeIfSkillLoad(call)) {\n return;\n }\n // Recorded after the skill-load return: a capability load is the agent\n // arranging itself, not work a host's data could have moved under.\n this.#runTools.push({ id: call.id, name: call.name });\n this.#cardFor(call);\n },\n onActivity: (activityType, content, messageId) => {\n if (activityType === CHART_ACTIVITY_TYPE) {\n if (this.#chartActivity) {\n this.#drawActivityChart(messageId, content);\n }\n return;\n }\n if (activityType !== COMPACTION_ACTIVITY_TYPE) {\n return;\n }\n const removed = compactionRemoved(content);\n if (removed === null) {\n return;\n }\n this.#appendNotice(\n \"\uD83D\uDDDC\",\n this.#strings.historyCompacted.replace(\"{count}\", String(removed)),\n \"compaction\",\n );\n },\n onToolResult: (toolCallId, content) => {\n const card = this.#toolCards.get(toolCallId);\n if (card === undefined) {\n return;\n }\n card.settle(TOOL_CALL_STATUS.DONE, content);\n this.#serverSettled.add(toolCallId);\n // The card stops being the live thing the moment it settles, and the\n // server goes straight back to the model with the result -- a wait with\n // nothing on screen to own it, and the longest one in a run when the\n // result is a large inlined attachment being re-sent with every request.\n // The dots go back where ``onToolCall`` took them from, after the card,\n // and whatever comes next clears them: reasoning, the first text delta,\n // the round ending, or ``onSettled``'s terminal guarantee.\n //\n // Not the same case as the one ``#executeTool`` refuses to show them\n // for. That runs after the run has ended, so there is nothing left to\n // clear them and they would hang -- which is what happened before 0.2.1\n // and is why they were removed from here too. The terminal guarantee\n // that shipped in the same release is what makes showing them safe now.\n this.#showPending();\n },\n onActivityChanged: (messageId, activityType, content) => {\n if (activityType === CHART_ACTIVITY_TYPE && this.#chartActivity) {\n this.#drawActivityChart(messageId, content);\n }\n },\n onRunEnd: () => {\n // Per-round end; the button stays on Stop until the whole interaction\n // settles \u2014 the user must be able to cancel between tool rounds.\n this.#hidePending();\n this.#streamingBubble = null;\n },\n onError: (message) => {\n this.#hidePending();\n this.#revealWords(this.appendMessage(MESSAGE_ROLE.ASSISTANT, `\u26A0\uFE0F ${message}`));\n this.#streamingBubble = null;\n },\n onCancelled: () => {\n // Deliberate stop, not a failure: keep whatever partial text already\n // streamed and add a muted note instead of an error bubble.\n this.#hidePending();\n this.#appendStoppedNote();\n this.#streamingBubble = null;\n },\n onSettled: () => {\n // Terminal guarantee: whatever path ended the run, return to rest.\n this.#hidePending();\n this.#setRunning(false);\n this.#streamingBubble = null;\n // Belt-and-suspenders: a tool card still pending at settle (e.g. a\n // server tool whose result never streamed because the connection\n // dropped) would hang forever \u2014 settle it to the no-result fallback.\n for (const card of this.#toolCards.values()) {\n if (!card.settled) {\n card.settle(TOOL_CALL_STATUS.DONE, this.#strings.noResult);\n }\n }\n // Close the turn's answer group. Drop it if the turn rendered nothing\n // (e.g. a server-only round that streamed no text/card) so an opted-in\n // well leaves no empty box behind.\n if (this.#currentGroup !== null && this.#currentGroup.childElementCount === 0) {\n this.#currentGroup.remove();\n this.#updateEmptyState();\n }\n this.#currentGroup = null;\n this.#thoughts = null;\n this.#dispatchRunFinished();\n },\n };\n }\n\n /**\n * Tell the host the interaction is over and what ran in it.\n *\n * Last thing in `onSettled`, so a listener that refetches sees a transcript\n * that has already stopped changing. `side` is read from the streamed-result\n * bookkeeping rather than from the tool list: whether a call executed on the\n * server is a fact about the run, and a name can appear on both sides across a\n * conversation.\n */\n #dispatchRunFinished(): void {\n const tools: ToolRun[] = this.#runTools.map(({ id, name }) => ({\n name,\n side: this.#serverSettled.has(id) ? \"server\" : \"client\",\n }));\n this.#runTools = [];\n this.dispatchEvent(\n new CustomEvent<RunFinishedDetail>(RUN_FINISHED_EVENT, {\n detail: { tools },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /** A muted \"\u23F9 Stopped\" line in the transcript (distinct from the \u26A0\uFE0F error bubble). */\n #appendStoppedNote(): void {\n const note = document.createElement(\"div\");\n note.className = \"stopped-note\";\n note.setAttribute(\"part\", \"stopped\");\n note.setAttribute(\"role\", \"status\");\n note.textContent = this.#strings.stopped;\n this.#ensureGroup().appendChild(note);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n /**\n * Show a \"thinking\" indicator while the agent is being awaited \u2014 both the\n * silent stretch before the first token and the gap after a tool result\n * while the next round is requested. Idempotent.\n */\n #showPending(): void {\n if (this.#pending !== null) {\n return;\n }\n const pending = document.createElement(\"div\");\n pending.className = \"pending\";\n pending.setAttribute(\"part\", \"pending\");\n pending.setAttribute(\"role\", \"status\");\n pending.setAttribute(\"aria-label\", this.#strings.thinking);\n for (let i = 0; i < 3; i += 1) {\n const dot = document.createElement(\"span\");\n dot.className = \"pending-dot\";\n pending.appendChild(dot);\n }\n this.#pending = pending;\n this.#ensureGroup().appendChild(pending);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n /** Remove the pending indicator if shown. */\n #hidePending(): void {\n this.#pending?.remove();\n this.#pending = null;\n }\n\n /**\n * The current turn's thoughts region, creating it (at the top of the answer\n * group, above any streamed text or tool cards) on first sight. Idempotent\n * across a turn's reasoning tokens.\n */\n #showThoughts(): ThoughtsBlock {\n if (this.#thoughts === null) {\n this.#thoughts = new ThoughtsBlock(this.#strings);\n const group = this.#ensureGroup();\n group.insertBefore(this.#thoughts.element, group.firstChild);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n return this.#thoughts;\n }\n\n #streamInto(buffer: string): HTMLDivElement {\n if (this.#streamingBubble === null) {\n this.#streamingBubble = this.appendMessage(MESSAGE_ROLE.ASSISTANT, \"\");\n this.#streamDeltas = 0;\n }\n this.#streamingBubble.innerHTML = renderMarkdown(buffer, { allowImages: this.allowImages });\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return this.#streamingBubble;\n }\n\n /**\n * The card for ``call``, creating and appending it on first sight.\n *\n * {@link AgUiClientHandlers.onToolCall} creates the card (pending) during the\n * run; {@link #executeTool} later retrieves the same card to settle it.\n */\n /**\n * Append an ambient run notice to the current group.\n *\n * Goes through {@link #ensureGroup} like a tool card so it lands *inside* the\n * assistant turn it annotates rather than floating between turns, and shares\n * the same pending-hide / scroll behaviour.\n */\n /**\n * Render a skill notice for a `load_capability` call; ``true`` when handled.\n *\n * Shared by the live stream and history replay so the transcript looks the\n * same before and after a reload.\n */\n #noticeIfSkillLoad(call: AgUiToolCall): boolean {\n const skill = skillNameFrom(call);\n if (skill === null) {\n return false;\n }\n this.#appendNotice(\"\u2728\", this.#strings.usingSkill.replace(\"{name}\", skill), \"skill\");\n return true;\n }\n\n #appendNotice(icon: string, text: string, kind: string): void {\n this.#ensureGroup().appendChild(renderRunNotice(icon, text, kind));\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n /**\n * Turn on chart rendering, by whichever route this consumer wants.\n *\n * Both routes converge on one renderer deliberately. Built apart they become\n * two chart implementations with two sets of bugs, and the choice between them\n * is about *where the data lives* rather than how a bar should look:\n *\n * - `\"tool\"` registers the built-in `render_chart`. The agent decides a chart\n * helps and calls it, so the numbers are in its context and it can discuss\n * them afterwards. Costs one model round, and works over any transport.\n * - `\"activity\"` draws a server-pushed `ACTIVITY_SNAPSHOT` of type `chart`.\n * No round trip, and the data never enters the model's context at all \u2014\n * which is what makes it the one for a large or sensitive dataset. Only this\n * route can update a chart in place as the server computes.\n *\n * Off unless asked for, both of them: a component that renders whatever\n * arrives is not something to switch on for everybody.\n */\n enableCharts(routes: readonly (\"tool\" | \"activity\")[] = [\"tool\", \"activity\"]): void {\n if (routes.includes(\"activity\")) {\n this.#chartActivity = true;\n }\n if (routes.includes(\"tool\")) {\n this.registerTool(createChartTool());\n }\n }\n\n /**\n * Place a tool's rendered node against its own card.\n *\n * Anchored rather than appended because a client tool's handler does not run\n * until the round is over: appending would put the node after everything the\n * model said next, visibly detached from the call that produced it, and in a\n * different order than the same transcript takes on reload. The card was\n * created inline, in the right place, so anchoring makes *when* the handler\n * runs stop mattering.\n */\n #renderToolOutput(tool: ClientTool, call: AgUiToolCall): void {\n if (tool.render === undefined) {\n return;\n }\n let node: Node | null;\n try {\n node = tool.render(call.args);\n } catch (error) {\n // `render` is consumer code and this runs inside the history replay, where\n // a throw abandons the loop and takes every later turn of the transcript\n // with it -- silently, and again on every reload. A chart that fails to\n // draw is worth losing; the rest of the conversation is not. Reported so\n // the failure is findable rather than merely survived.\n console.warn(`ag-ui-chat: render failed for tool ${call.name}`, error);\n return;\n }\n if (node === null) {\n return;\n }\n // `after` rather than an insert-or-append branch: both callers set the card\n // element immediately before calling, and a parentless anchor makes `after`\n // a no-op, so the alternative would be a branch nothing can reach.\n this.#cardElements.get(call.id)?.after(node);\n this.#afterTranscriptGrew();\n }\n\n /** Draw, or redraw in place, the chart for one activity message. */\n #drawActivityChart(messageId: string, content: unknown): void {\n const spec = chartSpecFrom(content);\n if (spec === null) {\n return;\n }\n const block = renderChart(spec);\n if (block === null) {\n return;\n }\n const existing = this.#activityBlocks.get(messageId);\n if (existing === undefined) {\n this.#ensureGroup().appendChild(block);\n } else {\n // Replaced rather than appended: a server redrawing a chart under the same\n // id means *this chart changed*, and a second copy below the first would\n // read as two measurements instead of one that moved.\n existing.replaceWith(block);\n }\n this.#activityBlocks.set(messageId, block);\n this.#afterTranscriptGrew();\n }\n\n #afterTranscriptGrew(): void {\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n #cardFor(call: AgUiToolCall): ToolCallCard {\n const existing = this.#toolCards.get(call.id);\n if (existing !== undefined) {\n return existing;\n }\n // Prefer the tool's own `x-summary`; then an explicit `toolSummaries`\n // entry; then the fetched server catalog (`data-tools-url`). All cover\n // server-side tools whose schema never reached the browser.\n const labelled = this.#resolveTool(call.name)?.parameters[X_SUMMARY_KEY];\n const summary =\n typeof labelled === \"string\"\n ? labelled\n : (this.toolSummaries[call.name] ??\n this.#toolCatalog[call.name] ??\n prettifyToolName(call.name));\n const card = new ToolCallCard(call.name, call.args, summary, this.#strings);\n this.#toolCards.set(call.id, card);\n this.#ensureGroup().appendChild(card.element);\n this.#updateEmptyState();\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return card;\n }\n}\n\n/**\n * A server-authored question for a gated call, read off the interrupt's metadata.\n *\n * The question an AG-UI interrupt carries by default is the call itself, spelled\n * out: `Approve create_event({\"title\": \"Design sync\", \u2026})?`. Accurate, and not\n * something to put in front of a person. A client-side confirmation has\n * `x-confirm` on the tool's schema for exactly this, so the same key is read here\n * \u2014 whichever end gates a call, the phrase comes from one place, and a server\n * that supplies none keeps the generated text.\n *\n * Narrowed rather than trusted: `metadata` is `Record<string, any>` on the wire,\n * so anything at all can arrive under that key, and a non-string would render as\n * \"[object Object]\" in the one place a person is being asked to allow a write.\n */\nfunction confirmPhrase(interrupt: Interrupt): string | undefined {\n const phrase = interrupt.metadata?.[X_CONFIRM_KEY];\n return typeof phrase === \"string\" && phrase.trim() !== \"\" ? phrase : undefined;\n}\n\n/** One tool call as a restored assistant message carries it. */\ninterface RestoredToolCall {\n readonly id: string;\n readonly function: { readonly name: string; readonly arguments?: unknown };\n}\n\n/**\n * The tool calls a restored assistant turn carries, with anything shapeless dropped.\n *\n * Narrowing here rather than trusting the declared type, for three reasons that\n * point the same way.\n *\n * **`null` is a value this field really takes.** `@ag-ui/core` types `toolCalls`\n * as optional (`z.ZodOptional`), so TypeScript offers only `undefined` \u2014 but the\n * protocol's Python models declare `tool_calls: list[ToolCall] | None`, and a\n * server dumping them without `exclude_none` sends `null`. The two SDKs disagree\n * about the wire, and a client cannot afford to take either one's word for it.\n *\n * **A throw here costs the rest of the transcript.** This runs inside the replay\n * of stored history, one message at a time; an exception aborts the whole replay,\n * so a single bad entry silently truncates the conversation from that point on \u2014\n * with no error state and nothing on screen to explain the gap.\n *\n * **Storage is untrusted anyway** \u2014 hand-edited, truncated, written by an older\n * version, or supplied by a host's own store. `messageAttachments` already takes\n * exactly this stance for the neighbouring field on the same message.\n */\nfunction restoredToolCalls(value: unknown): readonly RestoredToolCall[] {\n return Array.isArray(value) ? value.filter(isRestoredToolCall) : [];\n}\n\n/** Whether an unknown history entry has enough shape to render a tool card. */\nfunction isRestoredToolCall(value: unknown): value is RestoredToolCall {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const call = value as { id?: unknown; function?: { name?: unknown } };\n return typeof call.id === \"string\" && typeof call.function?.name === \"string\";\n}\n\n/**\n * The skill name a `load_capability` call activated, or `null` when the call is\n * something else.\n *\n * Every deferred capability loads through this one tool, so the id is a skill\n * name only when the project wired agent skills; another project's capability\n * id surfaces here too. Acceptable for a muted notice, and better than a\n * parallel signal \u2014 the id is exactly what the model selected.\n */\nfunction skillNameFrom(call: AgUiToolCall): string | null {\n if (call.name !== LOAD_CAPABILITY_TOOL) {\n return null;\n }\n const id = (call.args as { id?: unknown } | null | undefined)?.id;\n return typeof id === \"string\" && id !== \"\" ? id : null;\n}\n\n/** The `removed` count from a compaction activity payload, or `null` if absent. */\nfunction compactionRemoved(content: unknown): number | null {\n const removed = (content as { removed?: unknown } | null | undefined)?.removed;\n return typeof removed === \"number\" ? removed : null;\n}\n", "import { ELEMENT_TAG } from \"../constants.js\";\nimport { AgUiChat } from \"./ag_ui_chat.js\";\n\n/**\n * Register the `<ag-ui-chat>` Custom Element.\n *\n * Idempotent: calling it more than once (or after another module already\n * registered the tag) is a no-op. Registration is an explicit step rather\n * than an import side effect so the package is SSR-safe and tree-shakeable.\n */\nexport function defineAgUiChat(): void {\n if (customElements.get(ELEMENT_TAG) === undefined) {\n customElements.define(ELEMENT_TAG, AgUiChat);\n }\n}\n", "import {\n type FlashOptions,\n focusWithFlash,\n type HighlightClickOptions,\n highlightThenClick,\n type PressOptions,\n pressThenClick,\n type SelectOptions,\n scrollIntoCenterView,\n selectOption,\n type TextLikeElement,\n type ToggleOptions,\n type TypeOptions,\n toggleControl,\n typeInto,\n} from \"./animations.js\";\nimport { setNativeChecked, setNativeValue } from \"./native_setter.js\";\n\n/**\n * Generic, framework-free DOM-driving primitives.\n *\n * Each operates on an element the caller has already located. Host packages\n * (e.g. `django-admin-agent`) wrap these with environment-aware lookups \u2014\n * `fill_field(name, value)` finds `#id_<name>` then calls {@link fillField}.\n */\n\n/**\n * Every flash option except `focus`, which is not on offer: a field has to hold\n * focus to be typed into.\n */\nexport interface FillFieldOptions extends TypeOptions, Omit<FlashOptions, \"focus\"> {}\n\n/**\n * Scroll to, focus (with a flash), and type `value` into a text field.\n *\n * The scroll is awaited \u2014 typing into an element still gliding past shows the\n * user nothing.\n */\nexport async function fillField(\n el: TextLikeElement,\n value: string,\n options: FillFieldOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await focusWithFlash(el, { ...options, flashMs: options.flashMs ?? 0 });\n await typeInto(el, value, options);\n}\n\n/** Scroll to, highlight, and click an element. */\nexport async function clickElement(\n el: HTMLElement,\n options: HighlightClickOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await highlightThenClick(el, options);\n}\n\n/** Scroll to a button/control and click it with a visible \"press\" animation. */\nexport async function pressButton(el: HTMLElement, options: PressOptions = {}): Promise<void> {\n await scrollIntoCenterView(el);\n await pressThenClick(el, options);\n}\n\n/** Scroll to a `<select>`, highlight it, and pick the matching option (animated). */\nexport async function selectControl(\n el: HTMLSelectElement,\n value: string,\n options: SelectOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await selectOption(el, value, options);\n}\n\n/** Scroll to a checkbox/radio, flash it, and set its checked state (animated). */\nexport async function toggleCheckbox(\n el: HTMLInputElement,\n checked: boolean,\n options: ToggleOptions = {},\n): Promise<void> {\n await scrollIntoCenterView(el);\n await toggleControl(el, checked, options);\n}\n\n/**\n * Set a `<select>` or checkbox value without animation, dispatching the `input`\n * and `change` events frameworks listen for.\n */\nexport function setControlValue(\n el: HTMLInputElement | HTMLSelectElement,\n value: string | boolean,\n): void {\n if (el instanceof HTMLInputElement && el.type === \"checkbox\") {\n setNativeChecked(el, Boolean(value));\n } else {\n setNativeValue(el, String(value));\n }\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n", "export const VERSION: string = \"0.26.0\";\n"],
|
|
5
|
+
"mappings": "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AAEY,SAAM;AACN,WAAO;EACT;AACF;ACnSO,IAAMC,SAAOlG,OAAO,CACzB,KACA,QACA,WACA,WACA,QACA,WACA,SACA,SACA,KACA,OACA,OACA,OACA,SACA,cACA,QACA,MACA,UACA,UACA,WACA,UACA,QACA,QACA,OACA,YACA,WACA,QACA,YACA,MACA,aACA,OACA,WACA,OACA,UACA,OACA,OACA,MACA,MACA,WACA,MACA,YACA,cACA,UACA,QACA,UACA,QACA,MACA,MACA,MACA,MACA,MACA,MACA,QACA,UACA,UACA,MACA,QACA,KACA,OACA,SACA,OACA,OACA,SACA,UACA,MACA,QACA,OACA,QACA,WACA,QACA,YACA,SACA,OACA,QACA,MACA,YACA,UACA,UACA,KACA,WACA,OACA,YACA,KACA,MACA,MACA,QACA,KACA,QACA,UACA,WACA,UACA,UACA,QACA,SACA,UACA,UACA,QACA,UACA,UACA,SACA,OACA,WACA,OACA,SACA,SACA,MACA,YACA,YACA,SACA,MACA,SACA,QACA,MACA,SACA,MACA,KACA,MACA,OACA,SACA,KAAK,CACG;AAEH,IAAMmG,QAAMnG,OAAO,CACxB,OACA,KACA,YACA,eACA,gBACA,gBACA,iBACA,oBACA,UACA,YACA,QACA,QACA,WACA,gBACA,eACA,UACA,QACA,KACA,SACA,YACA,SACA,SACA,aACA,QACA,kBACA,UACA,QACA,YACA,SACA,QACA,QACA,WACA,WACA,YACA,kBACA,QACA,QACA,SACA,UACA,UACA,QACA,YACA,SACA,QACA,SACA,QACA,OAAO,CACC;AAEH,IAAMoG,aAAapG,OAAO,CAC/B,WACA,iBACA,uBACA,eACA,oBACA,qBACA,qBACA,kBACA,gBACA,WACA,WACA,WACA,WACA,WACA,kBACA,WACA,WACA,eACA,gBACA,YACA,gBACA,sBACA,eACA,UACA,cAAc,CACN;AAMH,IAAMqG,gBAAgBrG,OAAO,CAClC,WACA,iBACA,UACA,WACA,aACA,oBACA,kBACA,iBACA,iBACA,iBACA,SACA,aACA,QACA,gBACA,aACA,WACA,iBACA,UACA,OACA,cACA,WACA,KAAK,CACG;AAEH,IAAMsG,WAAStG,OAAO,CAC3B,QACA,YACA,UACA,WACA,SACA,UACA,MACA,cACA,iBACA,MACA,MACA,SACA,WACA,YACA,SACA,QACA,MACA,UACA,SACA,UACA,QACA,QACA,WACA,UACA,OACA,SACA,OACA,UACA,cACA,aAAa,CACL;AAIH,IAAMuG,mBAAmBvG,OAAO,CACrC,WACA,eACA,cACA,YACA,aACA,WACA,WACA,UACA,UACA,SACA,aACA,cACA,kBACA,eACA,MAAM,CACE;AAEH,IAAMwG,QAAOxG,OAAO,CAAC,OAAO,CAAU;AC1RtC,IAAMkG,OAAOlG,OAAO,CACzB,UACA,UACA,SACA,OACA,kBACA,gBACA,wBACA,YACA,cACA,WACA,UACA,WACA,eACA,eACA,WACA,QACA,SACA,SACA,SACA,QACA,WACA,WACA,cACA,YACA,gBACA,UACA,eACA,YACA,YACA,WACA,OACA,YACA,2BACA,yBACA,YACA,aACA,WACA,gBACA,eACA,QACA,OACA,WACA,UACA,UACA,QACA,QACA,YACA,MACA,SACA,aACA,aACA,SACA,QACA,SACA,QACA,QACA,WACA,QACA,OACA,OACA,aACA,SACA,UACA,OACA,aACA,YACA,SACA,QACA,SACA,WACA,cACA,UACA,QACA,WACA,QACA,WACA,eACA,eACA,WACA,iBACA,uBACA,UACA,WACA,WACA,cACA,YACA,OACA,YACA,OACA,YACA,QACA,QACA,WACA,cACA,SACA,YACA,SACA,QACA,SACA,QACA,QACA,WACA,SACA,OACA,UACA,QACA,SACA,WACA,YACA,SACA,aACA,QACA,UACA,UACA,SACA,SACA,QACA,OAAO,CACC;AAEH,IAAMmG,MAAMnG,OAAO,CACxB,iBACA,cACA,YACA,sBACA,aACA,UACA,iBACA,iBACA,WACA,iBACA,kBACA,SACA,QACA,MACA,SACA,QACA,iBACA,aACA,aACA,SACA,uBACA,+BACA,iBACA,mBACA,MACA,MACA,KACA,MACA,MACA,mBACA,aACA,WACA,WACA,qBACA,OACA,YACA,aACA,OACA,YACA,QACA,gBACA,aACA,UACA,eACA,eACA,iBACA,eACA,aACA,oBACA,gBACA,cACA,gBACA,eACA,MACA,MACA,MACA,MACA,cACA,YACA,iBACA,qBACA,UACA,QACA,MACA,mBACA,MACA,OACA,aACA,KACA,MACA,MACA,MACA,MACA,WACA,aACA,cACA,YACA,QACA,gBACA,kBACA,gBACA,oBACA,kBACA,SACA,cACA,cACA,gBACA,gBACA,eACA,eACA,oBACA,aACA,OACA,QACA,aACA,SACA,UACA,QACA,OACA,QACA,cACA,UACA,YACA,WACA,SACA,UACA,eACA,UACA,YACA,eACA,QACA,cACA,uBACA,oBACA,gBACA,UACA,iBACA,uBACA,kBACA,KACA,MACA,MACA,UACA,QACA,QACA,eACA,aACA,WACA,UACA,UACA,SACA,QACA,mBACA,SACA,oBACA,oBACA,gBACA,eACA,gBACA,eACA,cACA,gBACA,oBACA,qBACA,kBACA,mBACA,qBACA,kBACA,UACA,gBACA,SACA,gBACA,kBACA,YACA,eACA,WACA,WACA,aACA,oBACA,eACA,mBACA,oBACA,kBACA,cACA,QACA,MACA,MACA,WACA,UACA,WACA,cACA,WACA,cACA,iBACA,iBACA,SACA,gBACA,QACA,gBACA,oBACA,oBACA,KACA,MACA,MACA,SACA,KACA,MACA,MACA,KACA,YAAY,CACJ;AAEH,IAAMsG,SAAStG,OAAO,CAC3B,UACA,eACA,SACA,YACA,SACA,eACA,eACA,iBACA,cACA,cACA,SACA,OACA,WACA,gBACA,YACA,SACA,SACA,UACA,QACA,MACA,WACA,UACA,iBACA,UACA,UACA,kBACA,aACA,YACA,eACA,WACA,WACA,iBACA,YACA,YACA,QACA,YACA,YACA,cACA,WACA,UACA,UACA,eACA,iBACA,wBACA,aACA,aACA,cACA,YACA,kBACA,kBACA,aACA,WACA,SACA,OAAO,CACR;AAEM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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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",
|
|
6
|
+
"names": ["text", "el", "el", "button", "text", "svg", "y", "entries", "el", "button", "actionButton", "button", "confirm", "text", "entries", "Object", "setPrototypeOf", "isFrozen", "getPrototypeOf", "getOwnPropertyDescriptor", "freeze", "seal", "create", "_ref", "Reflect", "apply", "construct", "x", "func", "thisArg", "_len", "arguments", "length", "args", "Array", "_key", "Func", "_len2", "_key2", "arrayForEach", "unapply", "prototype", "forEach", "arrayLastIndexOf", "lastIndexOf", "arrayPop", "pop", "arrayPush", "push", "arraySplice", "splice", "arrayIsArray", "isArray", "stringToLowerCase", "String", "toLowerCase", "stringToString", "toString", "stringMatch", "match", "stringReplace", "replace", "stringIndexOf", "indexOf", "stringTrim", "trim", "numberToString", "Number", "booleanToString", "Boolean", "bigintToString", "BigInt", "symbolToString", "Symbol", "objectHasOwnProperty", "hasOwnProperty", "objectToString", "regExpTest", "RegExp", "test", "typeErrorCreate", "unconstruct", "TypeError", "lastIndex", "_len3", "_key3", "_len4", "_key4", "addToSet", "set", "array", "transformCaseFunc", "l", "element", "lcElement", "cleanArray", "index", "isPropertyExist", "clone", "object", "newObject", "_ref2", "_ref3", "_slicedToArray", "property", "value", "constructor", "stringifyValue", "valueAsRecord", "valueToString", "lookupGetter", "stringified", "prop", "desc", "get", "fallbackValue", "isRegex", "_unused", "html", "svg", "svgFilters", "svgDisallowed", "mathMl", "mathMlDisallowed", "text", "xml", "MUSTACHE_EXPR", "ERB_EXPR", "TMPLIT_EXPR", "DATA_ATTR", "ARIA_ATTR", "IS_ALLOWED_URI", "IS_SCRIPT_OR_DATA", "ATTR_WHITESPACE", "DOCTYPE_NAME", "CUSTOM_ELEMENT", "ELEMENT_MARKUP_PROBE", "COMMENT_MARKUP_PROBE", "FALLBACK_TAG_CLOSE", "SELF_CLOSING_TAG", "NODE_TYPE", "attribute", "cdataSection", "entityReference", "entityNode", "processingInstruction", "comment", "document", "documentType", "documentFragment", "notation", "getGlobal", "window", "_createTrustedTypesPolicy", "trustedTypes", "purifyHostElement", "createPolicy", "suffix", "ATTR_NAME", "hasAttribute", "getAttribute", "policyName", "createHTML", "createScriptURL", "scriptUrl", "_", "console", "warn", "_createHooksMap", "afterSanitizeAttributes", "afterSanitizeElements", "afterSanitizeShadowDOM", "beforeSanitizeAttributes", "beforeSanitizeElements", "beforeSanitizeShadowDOM", "uponSanitizeAttribute", "uponSanitizeElement", "uponSanitizeShadowNode", "_resolveSetOption", "cfg", "key", "fallback", "options", "base", "transform", "createDOMPurify", "undefined", "DOMPurify", "root", "version", "VERSION", "removed", "nodeType", "Element", "isSupported", "originalDocument", "currentScript", "DocumentFragment", "HTMLTemplateElement", "Node", "NodeFilter", "_window$NamedNodeMap", "NamedNodeMap", "MozNamedAttrMap", "HTMLFormElement", "DOMParser", "ElementPrototype", "cloneNode", "remove", "getNextSibling", "getChildNodes", "getParentNode", "getShadowRoot", "getAttributes", "getNodeType", "getNodeName", "getOwnerDocument", "template", "createElement", "content", "ownerDocument", "trustedTypesPolicy", "emptyHTML", "defaultTrustedTypesPolicy", "defaultTrustedTypesPolicyResolved", "IN_TRUSTED_TYPES_POLICY", "_assertNotInTrustedTypesPolicy", "_createTrustedHTML", "_createTrustedScriptURL", "_getDefaultTrustedTypesPolicy", "_document", "implementation", "createNodeIterator", "createDocumentFragment", "getElementsByTagName", "importNode", "hooks", "createHTMLDocument", "EXPRESSIONS", "ALLOWED_TAGS", "DEFAULT_ALLOWED_TAGS", "TAGS", "ALLOWED_ATTR", "DEFAULT_ALLOWED_ATTR", "ATTRS", "CUSTOM_ELEMENT_HANDLING", "tagNameCheck", "writable", "configurable", "enumerable", "attributeNameCheck", "allowCustomizedBuiltInElements", "FORBID_TAGS", "FORBID_ATTR", "EXTRA_ELEMENT_HANDLING", "tagCheck", "attributeCheck", "ALLOW_ARIA_ATTR", "ALLOW_DATA_ATTR", "ALLOW_UNKNOWN_PROTOCOLS", "ALLOW_SELF_CLOSE_IN_ATTR", "SAFE_FOR_TEMPLATES", "SAFE_FOR_XML", "WHOLE_DOCUMENT", "SET_CONFIG", "SET_CONFIG_ALLOWED_TAGS", "SET_CONFIG_ALLOWED_ATTR", "FORCE_BODY", "RETURN_DOM", "RETURN_DOM_FRAGMENT", "RETURN_TRUSTED_TYPE", "SANITIZE_DOM", "SANITIZE_NAMED_PROPS", "SANITIZE_NAMED_PROPS_PREFIX", "KEEP_CONTENT", "IN_PLACE", "USE_PROFILES", "FORBID_CONTENTS", "DEFAULT_FORBID_CONTENTS", "DATA_URI_TAGS", "DEFAULT_DATA_URI_TAGS", "URI_SAFE_ATTRIBUTES", "DEFAULT_URI_SAFE_ATTRIBUTES", "MATHML_NAMESPACE", "SVG_NAMESPACE", "HTML_NAMESPACE", "NAMESPACE", "IS_EMPTY_INPUT", "ALLOWED_NAMESPACES", "DEFAULT_ALLOWED_NAMESPACES", "DEFAULT_MATHML_TEXT_INTEGRATION_POINTS", "MATHML_TEXT_INTEGRATION_POINTS", "DEFAULT_HTML_INTEGRATION_POINTS", "HTML_INTEGRATION_POINTS", "COMMON_SVG_AND_HTML_ELEMENTS", "PARSER_MEDIA_TYPE", "SUPPORTED_PARSER_MEDIA_TYPES", "DEFAULT_PARSER_MEDIA_TYPE", "CONFIG", "formElement", "isRegexOrFunction", "testValue", "Function", "_parseConfig", "ALLOWED_URI_REGEXP", "customElementHandling", "ADD_TAGS", "ADD_ATTR", "ADD_URI_SAFE_ATTR", "ADD_FORBID_CONTENTS", "table", "tbody", "TRUSTED_TYPES_POLICY", "previousTrustedTypesPolicy", "error", "ALL_SVG_TAGS", "ALL_MATHML_TAGS", "_checkSvgNamespace", "tagName", "parent", "parentTagName", "namespaceURI", "_checkMathMlNamespace", "_checkHtmlNamespace", "_checkValidNamespace", "_forceRemove", "node", "removeChild", "_neutralizeRoot", "_neutralizeSubtree", "childNodes", "snapshot", "child", "attributes", "i", "name", "removeAttribute", "_removeAttribute", "getAttributeNode", "from", "setAttribute", "_stripDisallowedAttributes", "stack", "_neutralizePatchLinkage", "data", "lcTag", "nodeName", "_initDocument", "dirty", "doc", "leadingWhitespace", "matches", "dirtyPayload", "parseFromString", "documentElement", "createDocument", "innerHTML", "body", "insertBefore", "createTextNode", "call", "_createNodeIterator", "SHOW_ELEMENT", "SHOW_COMMENT", "SHOW_TEXT", "SHOW_PROCESSING_INSTRUCTION", "SHOW_CDATA_SECTION", "_stripTemplateExpressions", "_scrubTemplateExpressions", "_node$querySelectorAl", "normalize", "walker", "currentNode", "nextNode", "templates", "querySelectorAll", "tmpl", "_isDocumentFragment", "_isClobbered", "realTagName", "textContent", "hasChildNodes", "_isNode", "_executeHooks", "hook", "_isUnsafeNode", "firstElementChild", "_sanitizeDisallowedNode", "_isBasicCustomElement", "parentNode", "childCount", "hoisted", "_forkSharedAllowlist", "hookList", "defaultSet", "setConfigSet", "_sanitizeElements", "allowedTags", "nt", "_isValidAttribute", "lcName", "nameIsPermitted", "RESERVED_CUSTOM_ELEMENT_NAMES", "_applyTrustedTypesToAttribute", "getAttributeType", "_setAttributeValue", "setAttributeNS", "_sanitizeAttributes", "hookEvent", "attrName", "attrValue", "keepAttr", "allowedAttributes", "forceKeepAttr", "attr", "initValue", "_sanitizeShadowDOM", "fragment", "shadowNode", "shadowIterator", "shadowNodeType", "innerSr", "_sanitizeAttachedShadowRoots", "shadow", "item", "isElement", "rootName", "sr", "sanitize", "importedNode", "returnNode", "inPlace", "nn", "appendChild", "firstChild", "walkRoot", "nodeIterator", "entry", "shadowroot", "shadowrootmode", "serializedHTML", "outerHTML", "doctype", "setConfig", "clearConfig", "isValidAttribute", "tag", "addHook", "entryPoint", "hookFunction", "removeHook", "removeHooks", "removeAllHooks", "_getDefaults", "_defaults", "changeDefaults", "newDefaults", "noopTest", "cachedIndentRegex", "createRegex", "cache", "indent", "cacheIndex", "regex", "edit", "opt", "source", "obj", "name", "val", "valSource", "other", "supportsLookbehind", "a", "bull", "newline", "blockCode", "fences", "hr", "heading", "bullet", "lheadingCore", "lheading", "lheadingGfm", "_paragraph", "blockText", "_blockLabel", "def", "list", "_tag", "_comment", "html", "createParagraph", "listInterrupt", "paragraph", "blockquoteParagraph", "blockquote", "blockNormal", "gfmTable", "blockGfm", "blockPedantic", "escape", "inlineCode", "br", "inlineText", "_punctuation", "_punctuationOrSpace", "_notPunctuationOrSpace", "punctuation", "_openQuote", "_punctuationGfmStrongEm", "_punctuationOrSpaceGfmStrongEm", "_notPunctuationOrSpaceGfmStrongEm", "blockSkip", "emStrongLDelimCore", "emStrongLDelim", "emStrongLDelimGfm", "emStrongLDelimPedanticCore", "emStrongLDelimPedantic", "emStrongRDelimAstCore", "emStrongRDelimAst", "emStrongRDelimAstGfm", "emStrongRDelimAstPedanticCore", "emStrongRDelimAstPedantic", "emStrongRDelimUnd", "emStrongRDelimUndPedanticCore", "emStrongRDelimUndPedantic", "delLDelim", "delRDelimCore", "delRDelim", "anyPunctuation", "autolink", "_inlineComment", "tag", "_inlineLabel", "link", "reflink", "nolink", "reflinkSearch", "_caseInsensitiveProtocol", "inlineNormal", "inlinePedantic", "inlineGfm", "inlineBreaks", "block", "inline", "escapeReplacements", "getEscapeReplacement", "ch", "escapeHtmlEntities", "encode", "cleanUrl", "href", "splitCells", "tableRow", "count", "row", "match", "offset", "str", "escaped", "curr", "cells", "i", "rtrim", "c", "invert", "l", "suffLen", "currChar", "trimTrailingBlankLines", "lines", "end", "findClosingBracket", "b", "level", "expandTabs", "line", "col", "expanded", "char", "added", "outputLink", "cap", "raw", "lexer", "rules", "title", "text", "token", "indentCodeCompensation", "matchIndentToCode", "indentToCode", "node", "matchIndentInNode", "indentInNode", "_Tokenizer", "options", "src", "trimmed", "tokens", "inBlockquote", "currentLines", "currentRaw", "currentText", "top", "lastToken", "oldToken", "continuation", "newText", "newToken", "isordered", "itemRegex", "endsWithBlankLine", "endEarly", "itemContents", "nextLine", "blankLine", "nextBulletRegex", "hrRegex", "fencesBeginRegex", "headingBeginRegex", "htmlBeginRegex", "blockquoteBeginRegex", "rawLine", "nextLineWithoutTabs", "lastItem", "item", "itemToken", "taskRaw", "checkboxToken", "spacers", "t", "hasMultipleLineBreaks", "headers", "aligns", "rows", "align", "cell", "trimmedUrl", "rtrimSlash", "lastParenIndex", "linkLen", "links", "linkString", "maskedSrc", "prevChar", "lLength", "rDelim", "rLength", "delimTotal", "midDelimTotal", "delimChar", "midRun", "endReg", "lastCharLength", "hasNonSpaceChars", "hasSpaceCharsOnBothEnds", "prevCapZero", "_Lexer", "__Lexer", "next", "lastParagraphClipped", "srcLength", "extTokenizer", "cutSrc", "startIndex", "tempSrc", "tempStart", "getStartIndex", "match0", "_link", "context", "keepPrevChar", "byte", "errMsg", "_Renderer", "lang", "langString", "code", "depth", "ordered", "start", "body", "j", "type", "startAttr", "checked", "header", "k", "content", "cleanHref", "out", "_TextRenderer", "_Parser", "__Parser", "anyToken", "genericToken", "ret", "renderer", "_Hooks", "markdown", "Marked", "args", "callback", "values", "tableToken", "listToken", "childTokens", "extensions", "pack", "opts", "ext", "prevRenderer", "extLevel", "prop", "rendererProp", "rendererFunc", "tokenizer", "tokenizerProp", "tokenizerFunc", "prevTokenizer", "hooks", "hooksProp", "hooksFunc", "prevHook", "arg", "walkTokens", "packWalktokens", "blockType", "origOpt", "throwError", "processedSrc", "processedTokens", "e", "silent", "async", "msg", "markedInstance", "marked", "useExtension", "setOptions", "parseInline", "parser", "_Parser", "lexer", "_Lexer", "text", "x", "y", "text", "button", "el", "confirm", "text", "text", "randomUUID", "randomUUID", "randomUUID", "b", "text", "errorMessage", "text", "button", "el"]
|
|
7
7
|
}
|