@invergent/website-widget 2.17.8 → 2.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/surogates-widget.global.js +1 -1
- package/dist/surogates-widget.global.js.map +1 -1
- package/dist/ui.cjs +6 -0
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.js +6 -0
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
package/dist/ui.js
CHANGED
|
@@ -336,6 +336,12 @@ function paywallCopy(code) {
|
|
|
336
336
|
if (code === "subscription_required") {
|
|
337
337
|
return "This assistant requires an active subscription.";
|
|
338
338
|
}
|
|
339
|
+
if (code === "free_plan_available") {
|
|
340
|
+
return "This assistant needs a plan, and there is a free one.";
|
|
341
|
+
}
|
|
342
|
+
if (code === "upgrade_required") {
|
|
343
|
+
return "You have used this month\u2019s free allowance. Upgrade to keep chatting.";
|
|
344
|
+
}
|
|
339
345
|
if (code === "insufficient_tokens") {
|
|
340
346
|
return "You\u2019re out of tokens for this assistant.";
|
|
341
347
|
}
|
package/dist/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/styles.ts","../src/ui/markdown.ts","../src/ui/next-action.ts","../src/ui/widget.tsx","../src/ui/mount.tsx"],"names":["jsx"],"mappings":";;;;;;AAWO,IAAM,aAAA,GAAgB;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;;;ACM7B,IAAM,UAAA,GAAqC;AAAA,E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","file":"ui.js","sourcesContent":["/**\n * Scoped CSS for the chat widget, injected into the Shadow DOM root so\n * it can neither leak into nor be overridden by the host page. All\n * colours derive from two custom properties (``--surg-accent`` and its\n * readable foreground) set at mount time from the caller's\n * ``accentColor`` so theming is a one-line change.\n *\n * Returned as a string (rather than a constructable stylesheet) because\n * a ``<style>`` element in the shadow root is the most broadly supported\n * path across the browsers a public embed has to serve.\n */\nexport const WIDGET_STYLES = `\n:host { all: initial; }\n* { box-sizing: border-box; }\n\n.surg-root {\n --surg-radius: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #0f172a;\n}\n\n.surg-launcher {\n position: fixed;\n bottom: 20px;\n width: 56px;\n height: 56px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n box-shadow: 0 6px 24px rgba(15, 23, 42, 0.25);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n z-index: 2147483000;\n}\n.surg-launcher:hover { transform: scale(1.06); box-shadow: 0 8px 28px rgba(15, 23, 42, 0.3); }\n.surg-launcher svg { width: 26px; height: 26px; }\n.surg-pos-bottom-right { right: 20px; }\n.surg-pos-bottom-left { left: 20px; }\n\n.surg-panel {\n position: fixed;\n bottom: 88px;\n width: 380px;\n max-width: calc(100vw - 40px);\n height: 560px;\n max-height: calc(100vh - 120px);\n background: #ffffff;\n border-radius: var(--surg-radius);\n box-shadow: 0 12px 48px rgba(15, 23, 42, 0.28);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n z-index: 2147483000;\n animation: surg-rise 0.18s ease;\n}\n@keyframes surg-rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }\n\n.surg-inline {\n position: relative;\n bottom: auto; right: auto; left: auto;\n width: 100%;\n height: 100%;\n box-shadow: none;\n border: 1px solid #e2e8f0;\n animation: none;\n}\n\n.surg-header {\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n padding: 14px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n}\n.surg-header-id { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.surg-header-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }\n.surg-title { font-weight: 600; font-size: 15px; }\n.surg-subtitle { font-size: 11px; font-weight: 400; opacity: 0.85; }\n.surg-logo {\n width: 32px; height: 32px; border-radius: 50%; object-fit: cover;\n background: rgba(255, 255, 255, 0.2); flex-shrink: 0;\n}\n.surg-launcher-logo {\n width: 32px; height: 32px; border-radius: 50%; object-fit: cover;\n}\n.surg-close {\n background: transparent;\n border: none;\n color: inherit;\n cursor: pointer;\n opacity: 0.85;\n padding: 4px;\n display: flex;\n border-radius: 6px;\n}\n.surg-close:hover { opacity: 1; background: rgba(255, 255, 255, 0.18); }\n.surg-close svg { width: 18px; height: 18px; }\n\n.surg-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n background: #f8fafc;\n}\n\n.surg-bubble {\n max-width: 82%;\n padding: 9px 13px;\n border-radius: 14px;\n word-wrap: break-word;\n white-space: normal;\n}\n.surg-bubble p { margin: 0 0 8px; }\n.surg-bubble p:last-child { margin-bottom: 0; }\n.surg-bubble ul, .surg-bubble ol { margin: 4px 0; padding-left: 20px; }\n.surg-bubble code {\n background: rgba(15, 23, 42, 0.08);\n padding: 1px 5px;\n border-radius: 5px;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.9em;\n}\n.surg-bubble pre {\n background: #0f172a;\n color: #e2e8f0;\n padding: 10px 12px;\n border-radius: 10px;\n overflow-x: auto;\n margin: 6px 0;\n}\n.surg-bubble pre code { background: transparent; padding: 0; color: inherit; }\n.surg-bubble a { color: var(--surg-accent); }\n\n.surg-user {\n align-self: flex-end;\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n border-bottom-right-radius: 4px;\n white-space: pre-wrap;\n}\n.surg-user a { color: var(--surg-accent-fg); text-decoration: underline; }\n.surg-assistant {\n align-self: flex-start;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n border-bottom-left-radius: 4px;\n}\n\n.surg-typing { display: flex; gap: 4px; padding: 4px 2px; }\n.surg-typing span {\n width: 7px; height: 7px; border-radius: 50%;\n background: #94a3b8;\n animation: surg-blink 1.2s infinite ease-in-out;\n}\n.surg-typing span:nth-child(2) { animation-delay: 0.2s; }\n.surg-typing span:nth-child(3) { animation-delay: 0.4s; }\n@keyframes surg-blink { 0%, 60%, 100% { opacity: 0.3; } 30% { opacity: 1; } }\n\n.surg-error {\n margin: 0 16px;\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n color: #b91c1c;\n border-radius: 10px;\n font-size: 13px;\n flex-shrink: 0;\n}\n\n.surg-paywall {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin: 0 16px;\n padding: 12px;\n background: #fffbeb;\n border: 1px solid #fde68a;\n color: #92400e;\n border-radius: 10px;\n font-size: 13px;\n flex-shrink: 0;\n}\n.surg-paywall-cta {\n align-self: flex-start;\n padding: 6px 14px;\n background: var(--surg-accent, #0f172a);\n color: #ffffff;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n.surg-paywall-cta:hover { opacity: 0.9; }\n\n.surg-composer {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid #e2e8f0;\n background: #ffffff;\n flex-shrink: 0;\n}\n.surg-input {\n flex: 1;\n resize: none;\n border: 1px solid #cbd5e1;\n border-radius: 12px;\n padding: 9px 12px;\n font: inherit;\n color: inherit;\n max-height: 120px;\n outline: none;\n}\n.surg-input:focus { border-color: var(--surg-accent); }\n.surg-send {\n border: none;\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n border-radius: 12px;\n width: 40px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.surg-send:disabled { opacity: 0.5; cursor: not-allowed; }\n.surg-send svg { width: 18px; height: 18px; }\n\n.surg-powered {\n text-align: center;\n font-size: 11px;\n color: #94a3b8;\n padding: 0 0 8px;\n background: #ffffff;\n}\n.surg-powered a { color: inherit; font-weight: 500; text-decoration: none; }\n.surg-powered a:hover { text-decoration: underline; }\n`;\n","/**\n * Minimal, dependency-free Markdown → HTML renderer for assistant text.\n *\n * Assistant output is *semi-trusted* (it comes from the agent, not the\n * visitor), but the widget renders into a Shadow DOM via\n * ``dangerouslySetInnerHTML``, so a careless renderer would still be an\n * XSS vector if the model ever echoed attacker-supplied HTML. The\n * contract here is therefore: **escape first, then re-introduce only the\n * small, known-safe subset of HTML the formatter produces.** No raw\n * HTML from the source string ever survives — every ``<`` in the input\n * is entity-escaped before any tag is emitted.\n *\n * Supported: fenced code blocks, inline code, bold, italic, links\n * (http/https/mailto only), unordered + ordered lists, and paragraphs\n * with line breaks. Everything else degrades to escaped plain text.\n */\n\nconst ESCAPE_MAP: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) => ESCAPE_MAP[c] ?? c);\n}\n\n/** Allow only links the browser can't be tricked into executing. */\nfunction safeHref(raw: string): string | undefined {\n const url = raw.trim();\n if (/^(https?:|mailto:)/i.test(url)) return url;\n return undefined;\n}\n\n/**\n * Apply inline formatting to an *already HTML-escaped* fragment. Order\n * matters: links before emphasis so ``[a](b)`` brackets aren't eaten by\n * the italic rule, and bold (``**``) before italic (``*``).\n */\nfunction renderInline(escaped: string): string {\n let out = escaped;\n\n // Inline code first — its contents must not be touched by later rules.\n // The buffer is already escaped, so the captured group is literal text.\n out = out.replace(/`([^`]+)`/g, (_m, code: string) => `<code>${code}</code>`);\n\n // Links: [text](href). ``href`` is validated; bad schemes render as\n // the original (escaped) text without an anchor.\n out = out.replace(\n /\\[([^\\]]+)\\]\\(([^)\\s]+)\\)/g,\n (_m, text: string, href: string) => {\n const safe = safeHref(href);\n if (!safe) return `${text}`;\n return `<a href=\"${safe}\" target=\"_blank\" rel=\"noopener noreferrer\">${text}</a>`;\n },\n );\n\n out = out.replace(/\\*\\*([^*]+)\\*\\*/g, (_m, t: string) => `<strong>${t}</strong>`);\n out = out.replace(/(^|[^*])\\*([^*\\n]+)\\*/g, (_m, pre: string, t: string) => `${pre}<em>${t}</em>`);\n\n return out;\n}\n\n/**\n * Render ``src`` Markdown to a safe HTML string. Splits on fenced code\n * blocks so their bodies bypass inline formatting entirely, then groups\n * the remaining text into list and paragraph blocks.\n */\nexport function renderMarkdown(src: string): string {\n const parts = src.split(/```/);\n const html: string[] = [];\n\n parts.forEach((part, index) => {\n const isCodeFence = index % 2 === 1;\n if (isCodeFence) {\n // Drop an optional language hint on the first line.\n const body = part.replace(/^[^\\n]*\\n/, (m) => (part.includes('\\n') ? '' : m));\n html.push(`<pre><code>${escapeHtml(body.replace(/\\n$/, ''))}</code></pre>`);\n return;\n }\n\n const blocks = part.split(/\\n{2,}/);\n for (const block of blocks) {\n const lines = block.split('\\n').filter((l) => l.trim().length > 0);\n if (lines.length === 0) continue;\n\n const isUnordered = lines.every((l) => /^\\s*[-*]\\s+/.test(l));\n const isOrdered = lines.every((l) => /^\\s*\\d+\\.\\s+/.test(l));\n if (isUnordered || isOrdered) {\n const items = lines\n .map((l) => l.replace(/^\\s*(?:[-*]|\\d+\\.)\\s+/, ''))\n .map((l) => `<li>${renderInline(escapeHtml(l))}</li>`)\n .join('');\n html.push(isOrdered ? `<ol>${items}</ol>` : `<ul>${items}</ul>`);\n continue;\n }\n\n const paragraph = lines.map((l) => renderInline(escapeHtml(l))).join('<br>');\n html.push(`<p>${paragraph}</p>`);\n }\n });\n\n return html.join('');\n}\n","/**\n * Strip the per-turn ``<next_action>`` footer from assistant text.\n *\n * The harness instructs the assistant to end every final response with a\n * ``<next_action complexity=\"...\" summary=\"...\">...</next_action>`` block\n * (see ``surogates/harness/prompts/guidance/next_action.md``). It is\n * harness/UI metadata, not user-facing content — by design the *client*\n * strips it: the full chat console does so in\n * ``agent-chat-react/src/lib/next-action.ts``, and messaging channels\n * strip it server-side. This widget streams raw ``llm.delta`` frames, so\n * it must strip it too or the XML footer flashes in the bubble.\n *\n * We only need the stripping half here (the console additionally parses\n * the block into a status pill). Streaming-safe: a dangling, not-yet-\n * closed footer is hidden the moment its opener appears so partial tags\n * never flicker.\n */\n\n// Complete ``<next_action ...>...</next_action>`` blocks (+ trailing ws).\nconst NEXT_ACTION_RE = /<next_action([^>]*)>([\\s\\S]*?)<\\/next_action>\\s*/gi;\n\n// A trailing, still-streaming footer: any prefix of the literal\n// ``<next_action`` token at the start of a line through end-of-text,\n// then everything after the whole word arrives (attributes + partial\n// body, closing tag not yet seen). Anchored to start-of-line so a stray\n// ``<`` mid-sentence is never mistaken for the footer.\nconst PARTIAL_FOOTER_RE =\n /(?:^|\\n)\\s*<(?:n(?:e(?:x(?:t(?:_(?:a(?:c(?:t(?:i(?:o(?:n[\\s\\S]*)?)?)?)?)?)?)?)?)?)?)?$/i;\n\n/** Return *text* with every (complete or streaming-partial) footer removed. */\nexport function stripNextAction(text: string): string {\n if (!text) return text;\n const withoutBlocks = text.replace(NEXT_ACTION_RE, '').trimEnd();\n const match = PARTIAL_FOOTER_RE.exec(withoutBlocks);\n return match ? withoutBlocks.slice(0, match.index).trimEnd() : withoutBlocks;\n}\n","/**\n * The Preact chat UI rendered inside the widget's Shadow DOM.\n *\n * It is a thin presentation layer over the headless :class:`WebsiteAgent`:\n * all transport, auth, and streaming live in the agent; this component\n * only subscribes to the AG-UI event stream, mirrors ``agent.messages``\n * into local state, and drives ``runAgent`` from the composer.\n */\nimport { useEffect, useRef, useState } from 'preact/hooks';\n\nimport type { WebsiteAgent } from '../agent.js';\nimport { SurogatesAuthError, SurogatesRateLimitError } from '../errors.js';\nimport { renderMarkdown } from './markdown.js';\nimport { stripNextAction } from './next-action.js';\nimport type { MountConfig } from './types.js';\n\n// Shown when the operator hasn't set their own. Kept friendly and\n// provider-neutral so an unconfigured widget still looks finished.\nconst DEFAULT_SUBTITLE = 'Typically replies instantly';\nconst DEFAULT_WELCOME = 'Hi! 👋 How can I help you today?';\n\ninterface ChatMessage {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n}\n\ninterface WidgetProps {\n agent: WebsiteAgent;\n config: MountConfig;\n /** Lets the imperative handle in ``mount`` drive the open/closed state. */\n registerOpenControl: (setOpen: (open: boolean) => void) => void;\n /** Reports open-state changes back so ``mount``'s ``toggle()`` stays in sync. */\n onOpenChange?: (open: boolean) => void;\n}\n\nfunction uid(): string {\n return `u-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\n/** Project ``agent.messages`` down to the renderable user/assistant turns. */\nfunction snapshot(messages: ReadonlyArray<{ id?: string; role?: string; content?: unknown }>): ChatMessage[] {\n const out: ChatMessage[] = [];\n for (const m of messages) {\n if (m.role !== 'user' && m.role !== 'assistant') continue;\n const content = typeof m.content === 'string' ? m.content : '';\n out.push({ id: m.id ?? uid(), role: m.role, content });\n }\n return out;\n}\n\n/** Only render CTA links with a web protocol — the buy URL rides in\n * from server config, but an SDK running on third-party sites must\n * not let any upstream compromise turn it into a `javascript:` URI. */\nfunction safeBuyUrl(url: string | undefined): string | undefined {\n return url && /^https?:\\/\\//i.test(url) ? url : undefined;\n}\n\n/** Visitor-facing copy per paywall sentinel from the server. */\nfunction paywallCopy(code: string): string {\n if (code === 'sign_in_required') {\n return 'This assistant requires an account. Get access, sign in on this site, then send your message again.';\n }\n if (code === 'subscription_required') {\n return 'This assistant requires an active subscription.';\n }\n if (code === 'insufficient_tokens') {\n return 'You’re out of tokens for this assistant.';\n }\n return 'This assistant requires paid access.';\n}\n\n/** Map an SDK error (thrown or via RUN_ERROR) to visitor-facing copy. */\nfunction friendlyError(err: { code?: string; message?: string } | unknown): string {\n if (err instanceof SurogatesAuthError) {\n return 'This chat isn’t accepting messages from this site yet. The site owner needs to allow this origin.';\n }\n if (err instanceof SurogatesRateLimitError) {\n return 'You’re sending messages too quickly. Please wait a moment and try again.';\n }\n if (err && typeof err === 'object') {\n const code = (err as { code?: string }).code;\n if (code === 'auth') {\n return 'This chat isn’t accepting messages from this site yet. The site owner needs to allow this origin.';\n }\n if (code === 'sse_closed') return 'Connection lost. Please send your message again.';\n const message = (err as { message?: string }).message;\n if (message && message.length < 160) return message;\n }\n return 'Something went wrong. Please try again.';\n}\n\nconst ICON_CHAT = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\" />\n </svg>\n);\nconst ICON_CLOSE = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\nconst ICON_SEND = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n\nexport function Widget({ agent, config, registerOpenControl, onOpenChange }: WidgetProps) {\n const inline = !!config.inline;\n const [open, setOpen] = useState(inline || !!config.openByDefault);\n const [messages, setMessages] = useState<ChatMessage[]>(() => snapshot(agent.messages));\n const [running, setRunning] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [paywall, setPaywall] = useState<{ code: string; buyUrl?: string } | null>(null);\n const [input, setInput] = useState('');\n // Only the async input is state; the title is derived at render so a\n // configured title (incl. live handle.update()) always wins, falling back\n // to the bootstrapped agent name, then a generic label.\n const [agentName, setAgentName] = useState('');\n const title = config.title || agentName || 'Assistant';\n\n const listRef = useRef<HTMLDivElement>(null);\n const bootstrapStarted = useRef(false);\n\n // Expose the open setter to the mount() imperative handle.\n useEffect(() => registerOpenControl(setOpen), [registerOpenControl]);\n useEffect(() => onOpenChange?.(open), [open, onOpenChange]);\n\n // Mirror the agent's event stream into local UI state.\n useEffect(() => {\n const sub = agent.subscribe({\n onMessagesChanged: () => setMessages(snapshot(agent.messages)),\n onRunStartedEvent: () => {\n setRunning(true);\n setError(null);\n setPaywall(null);\n },\n onRunFinishedEvent: () => setRunning(false),\n onRunErrorEvent: ({ event }) => {\n setRunning(false);\n const code = (event as { code?: string }).code;\n if (code === 'paywall') {\n setPaywall(agent.lastPaywall ?? { code: 'payment_required' });\n return;\n }\n setError(friendlyError(event));\n },\n });\n return () => sub.unsubscribe();\n }, [agent]);\n\n // Validate config + resolve the header title the first time the panel\n // is opened. Eager bootstrap on open (not page-load) means visitors\n // who never open the chat don't create server sessions; opening is a\n // clear intent signal and surfaces misconfiguration immediately.\n useEffect(() => {\n if (!open || bootstrapStarted.current) return;\n bootstrapStarted.current = true;\n agent\n .ensureBootstrapped()\n .then((res) => {\n if (res.agentName) setAgentName(res.agentName);\n })\n .catch((err) => {\n // Allow a retry the next time the panel opens (transient network, etc.).\n bootstrapStarted.current = false;\n setError(friendlyError(err));\n });\n }, [open, agent]);\n\n // Keep the transcript pinned to the latest message.\n useEffect(() => {\n const el = listRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n }, [messages, running]);\n\n const send = () => {\n const content = input.trim();\n if (!content || running) return;\n setInput('');\n agent.addMessage({ id: uid(), role: 'user', content } as never);\n setMessages(snapshot(agent.messages));\n void agent.runAgent().catch(() => {\n /* Failures surface through onRunErrorEvent; swallow the rejection. */\n });\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n };\n\n // An unconfigured widget always shows sensible default copy: a missing\n // subtitle/welcome falls back to the defaults. Note Studio/the embed omit\n // empty fields, so *clearing* the field in Studio is indistinguishable from\n // never setting it — both show the default. There is intentionally no\n // \"show nothing\" state today; if suppression is ever needed, add an explicit\n // sentinel rather than relying on empty string.\n const subtitle = config.subtitle ?? DEFAULT_SUBTITLE;\n const welcomeText = config.welcomeMessage ?? DEFAULT_WELCOME;\n const hasAssistant = messages.some((m) => m.role === 'assistant');\n const showWelcome = !!welcomeText && !hasAssistant;\n const showTyping = running && messages[messages.length - 1]?.role !== 'assistant';\n\n if (!inline && !open) {\n return (\n <button\n type=\"button\"\n class={`surg-launcher surg-pos-${config.position ?? 'bottom-right'}`}\n aria-label=\"Open chat\"\n onClick={() => setOpen(true)}\n >\n {config.logoUrl ? (\n <img class=\"surg-launcher-logo\" src={config.logoUrl} alt=\"\" />\n ) : (\n ICON_CHAT\n )}\n </button>\n );\n }\n\n const panelClass = inline\n ? 'surg-panel surg-inline'\n : `surg-panel surg-pos-${config.position ?? 'bottom-right'}`;\n\n return (\n <div class={panelClass} role=\"dialog\" aria-label={title}>\n <div class=\"surg-header\">\n <div class=\"surg-header-id\">\n {config.logoUrl && <img class=\"surg-logo\" src={config.logoUrl} alt=\"\" />}\n <div class=\"surg-header-text\">\n <span class=\"surg-title\">{title}</span>\n {subtitle && <span class=\"surg-subtitle\">{subtitle}</span>}\n </div>\n </div>\n {!inline && (\n <button type=\"button\" class=\"surg-close\" aria-label=\"Close chat\" onClick={() => setOpen(false)}>\n {ICON_CLOSE}\n </button>\n )}\n </div>\n\n <div class=\"surg-messages\" ref={listRef}>\n {showWelcome && (\n <div\n class=\"surg-bubble surg-assistant\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: renderMarkdown(welcomeText) }}\n />\n )}\n {messages.map((m) =>\n m.role === 'assistant' ? (\n <div\n key={m.id}\n class=\"surg-bubble surg-assistant\"\n dangerouslySetInnerHTML={{ __html: renderMarkdown(stripNextAction(m.content)) }}\n />\n ) : (\n <div key={m.id} class=\"surg-bubble surg-user\">\n {m.content}\n </div>\n ),\n )}\n {showTyping && (\n <div class=\"surg-bubble surg-assistant surg-typing\">\n <span /><span /><span />\n </div>\n )}\n </div>\n\n {error && <div class=\"surg-error\">{error}</div>}\n\n {paywall && (\n <div class=\"surg-paywall\">\n <span>{paywallCopy(paywall.code)}</span>\n {safeBuyUrl(paywall.buyUrl) && (\n <a\n class=\"surg-paywall-cta\"\n href={safeBuyUrl(paywall.buyUrl)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Get access\n </a>\n )}\n </div>\n )}\n\n <div class=\"surg-composer\">\n <textarea\n class=\"surg-input\"\n rows={1}\n placeholder=\"Type a message…\"\n value={input}\n disabled={running}\n onInput={(e) => setInput((e.target as HTMLTextAreaElement).value)}\n onKeyDown={onKeyDown}\n />\n <button type=\"button\" class=\"surg-send\" aria-label=\"Send\" disabled={running || !input.trim()} onClick={send}>\n {ICON_SEND}\n </button>\n </div>\n <div class=\"surg-powered\">\n Powered by{' '}\n <a href=\"https://surogate.ai/\" target=\"_blank\" rel=\"noopener noreferrer\">\n Surogate\n </a>\n </div>\n </div>\n );\n}\n","/**\n * ``mount()`` — the drop-in entry point.\n *\n * A single call stands up a complete chat widget: it creates a host\n * element, isolates the UI in a Shadow DOM (so neither the host page's\n * CSS nor the widget's styles can bleed across), instantiates the\n * headless :class:`WebsiteAgent`, and renders the Preact UI into the\n * shadow root. Returns an imperative :type:`WidgetHandle` for hosts\n * that want to open/close/destroy the widget programmatically.\n *\n * This is what the ``<script>``-tag embed and the Studio live preview\n * both call. Everything cosmetic is optional; ``apiUrl`` and\n * ``publishableKey`` are the only required fields.\n */\nimport { render } from 'preact';\n\nimport { WebsiteAgent } from '../agent.js';\nimport { DEFAULT_PAIRING_BASE } from '../constants.js';\nimport { resolvePairing } from '../protocol.js';\nimport { WIDGET_STYLES } from './styles.js';\nimport type { MountConfig, WidgetHandle } from './types.js';\nimport { Widget } from './widget.js';\n\nexport type { MountConfig, WidgetHandle, WidgetAppearance } from './types.js';\n\nconst DEFAULT_ACCENT = '#4f46e5';\n\n/**\n * Pick a readable foreground (near-black vs white) for text/icons that\n * sit on the accent colour, using an sRGB luminance approximation. A\n * pale accent gets dark text; a saturated one gets white.\n */\nfunction accentForeground(hex: string): string {\n const v = hex.replace('#', '');\n const full = v.length === 3 ? v.split('').map((c) => c + c).join('') : v;\n if (full.length !== 6 || /[^0-9a-f]/i.test(full)) return '#ffffff';\n const r = parseInt(full.slice(0, 2), 16);\n const g = parseInt(full.slice(2, 4), 16);\n const b = parseInt(full.slice(4, 6), 16);\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.62 ? '#0f172a' : '#ffffff';\n}\n\n/**\n * Key-only entry point. Resolves the publishable key to its agent +\n * ``api_web_url`` via the control-plane pairing endpoint, then mounts against\n * that base URL — so an embed can be just ``mountWithPairing({ publishableKey })``\n * with no hardcoded ``apiUrl``. If ``apiUrl`` is already supplied, pairing is\n * skipped and this is equivalent to :func:`mount`.\n */\nexport async function mountWithPairing(\n config: Omit<MountConfig, 'apiUrl'> & { apiUrl?: string },\n): Promise<WidgetHandle> {\n if (config?.apiUrl) {\n return mount(config as MountConfig);\n }\n if (!config?.publishableKey) {\n throw new Error(\n 'SurogatesWidget.mountWithPairing: \"publishableKey\" is required.',\n );\n }\n const { agentId, apiWebUrl } = await resolvePairing(\n config.pairingUrl ?? DEFAULT_PAIRING_BASE,\n config.publishableKey,\n );\n return mount({ ...config, apiUrl: apiWebUrl, agentId } as MountConfig);\n}\n\nexport function mount(config: MountConfig): WidgetHandle {\n if (!config || !config.apiUrl || !config.publishableKey) {\n throw new Error(\n 'SurogatesWidget.mount: \"apiUrl\" and \"publishableKey\" are required.',\n );\n }\n\n const accent = config.accentColor ?? DEFAULT_ACCENT;\n let destroyed = false;\n\n // Host element + Shadow DOM: total style isolation in both directions.\n const host = document.createElement('div');\n host.setAttribute('data-surogates-widget', '');\n const shadow = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = WIDGET_STYLES;\n shadow.appendChild(style);\n\n const root = document.createElement('div');\n root.className = 'surg-root';\n shadow.appendChild(root);\n\n // Accent drives CSS custom properties on the root, so it can be re-applied\n // on update() without re-rendering anything else.\n const applyAccent = (accentColor?: string) => {\n const a = accentColor ?? DEFAULT_ACCENT;\n root.style.setProperty('--surg-accent', a);\n root.style.setProperty('--surg-accent-fg', accentForeground(a));\n };\n applyAccent(accent);\n\n // Attach to the page. Drop-in embeds are often placed in <head>, where\n // document.body doesn't exist yet — defer the append until the DOM is ready.\n const attach = () => (config.target ?? document.body)?.appendChild(host);\n if (config.target || document.body) {\n attach();\n } else {\n document.addEventListener(\n \"DOMContentLoaded\",\n () => {\n if (!destroyed) attach();\n },\n { once: true },\n );\n }\n\n const agent = new WebsiteAgent(config);\n\n let setOpen: ((open: boolean) => void) | undefined;\n let isOpen = config.inline || !!config.openByDefault;\n\n // Stable callbacks so re-rendering on update() doesn't re-fire the\n // component's open-control / open-change effects.\n const registerOpenControl = (fn: (open: boolean) => void) => {\n setOpen = fn;\n };\n const onOpenChange = (o: boolean) => {\n isOpen = o;\n };\n\n // Current config is mutable so update() can re-render appearance without\n // tearing down the agent (no re-bootstrap, no lost conversation).\n let current: MountConfig = config;\n const renderWidget = () => {\n render(\n <Widget\n agent={agent}\n config={current}\n registerOpenControl={registerOpenControl}\n onOpenChange={onOpenChange}\n />,\n root,\n );\n };\n renderWidget();\n\n // Best-effort session close when the visitor navigates away.\n const endOnUnload = () => {\n void agent.end();\n };\n window.addEventListener('beforeunload', endOnUnload);\n\n return {\n agent,\n open: () => setOpen?.(true),\n close: () => setOpen?.(false),\n toggle: () => setOpen?.(!isOpen),\n update: (partial) => {\n if (destroyed) return;\n current = { ...current, ...partial };\n if ('accentColor' in partial) applyAccent(current.accentColor);\n renderWidget();\n },\n destroy: () => {\n if (destroyed) return;\n destroyed = true;\n window.removeEventListener('beforeunload', endOnUnload);\n void agent.end();\n render(null, root);\n host.remove();\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/ui/styles.ts","../src/ui/markdown.ts","../src/ui/next-action.ts","../src/ui/widget.tsx","../src/ui/mount.tsx"],"names":["jsx"],"mappings":";;;;;;AAWO,IAAM,aAAA,GAAgB;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;;;ACM7B,IAAM,UAAA,GAAqC;AAAA,EACzC,GAAA,EAAK,OAAA;AAAA,EACL,GAAA,EAAK,MAAA;AAAA,EACL,GAAA,EAAK,MAAA;AAAA,EACL,GAAA,EAAK,QAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAEA,SAAS,WAAW,CAAA,EAAmB;AACrC,EAAA,OAAO,CAAA,CAAE,QAAQ,UAAA,EAAY,CAAC,MAAM,UAAA,CAAW,CAAC,KAAK,CAAC,CAAA;AACxD;AAGA,SAAS,SAAS,GAAA,EAAiC;AACjD,EAAA,MAAM,GAAA,GAAM,IAAI,IAAA,EAAK;AACrB,EAAA,IAAI,qBAAA,CAAsB,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,GAAA;AAC5C,EAAA,OAAO,MAAA;AACT;AAOA,SAAS,aAAa,OAAA,EAAyB;AAC7C,EAAA,IAAI,GAAA,GAAM,OAAA;AAIV,EAAA,GAAA,GAAM,GAAA,CAAI,QAAQ,YAAA,EAAc,CAAC,IAAI,IAAA,KAAiB,CAAA,MAAA,EAAS,IAAI,CAAA,OAAA,CAAS,CAAA;AAI5E,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA;AAAA,IACR,4BAAA;AAAA,IACA,CAAC,EAAA,EAAI,IAAA,EAAc,IAAA,KAAiB;AAClC,MAAA,MAAM,IAAA,GAAO,SAAS,IAAI,CAAA;AAC1B,MAAA,IAAI,CAAC,IAAA,EAAM,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA;AACzB,MAAA,OAAO,CAAA,SAAA,EAAY,IAAI,CAAA,4CAAA,EAA+C,IAAI,CAAA,IAAA,CAAA;AAAA,IAC5E;AAAA,GACF;AAEA,EAAA,GAAA,GAAM,GAAA,CAAI,QAAQ,kBAAA,EAAoB,CAAC,IAAI,CAAA,KAAc,CAAA,QAAA,EAAW,CAAC,CAAA,SAAA,CAAW,CAAA;AAChF,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,wBAAA,EAA0B,CAAC,EAAA,EAAI,GAAA,EAAa,CAAA,KAAc,CAAA,EAAG,GAAG,CAAA,IAAA,EAAO,CAAC,CAAA,KAAA,CAAO,CAAA;AAEjG,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA;AAC7B,EAAA,MAAM,OAAiB,EAAC;AAExB,EAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,EAAM,KAAA,KAAU;AAC7B,IAAA,MAAM,WAAA,GAAc,QAAQ,CAAA,KAAM,CAAA;AAClC,IAAA,IAAI,WAAA,EAAa;AAEf,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAa,CAAC,CAAA,KAAO,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,GAAI,EAAA,GAAK,CAAE,CAAA;AAC5E,MAAA,IAAA,CAAK,IAAA,CAAK,cAAc,UAAA,CAAW,IAAA,CAAK,QAAQ,KAAA,EAAO,EAAE,CAAC,CAAC,CAAA,aAAA,CAAe,CAAA;AAC1E,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAClC,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAK,CAAE,MAAA,GAAS,CAAC,CAAA;AACjE,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAExB,MAAA,MAAM,WAAA,GAAc,MAAM,KAAA,CAAM,CAAC,MAAM,aAAA,CAAc,IAAA,CAAK,CAAC,CAAC,CAAA;AAC5D,MAAA,MAAM,SAAA,GAAY,MAAM,KAAA,CAAM,CAAC,MAAM,cAAA,CAAe,IAAA,CAAK,CAAC,CAAC,CAAA;AAC3D,MAAA,IAAI,eAAe,SAAA,EAAW;AAC5B,QAAA,MAAM,KAAA,GAAQ,MACX,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,OAAA,CAAQ,uBAAA,EAAyB,EAAE,CAAC,CAAA,CACjD,IAAI,CAAC,CAAA,KAAM,CAAA,IAAA,EAAO,YAAA,CAAa,UAAA,CAAW,CAAC,CAAC,CAAC,CAAA,KAAA,CAAO,CAAA,CACpD,IAAA,CAAK,EAAE,CAAA;AACV,QAAA,IAAA,CAAK,KAAK,SAAA,GAAY,CAAA,IAAA,EAAO,KAAK,CAAA,KAAA,CAAA,GAAU,CAAA,IAAA,EAAO,KAAK,CAAA,KAAA,CAAO,CAAA;AAC/D,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,SAAA,GAAY,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,YAAA,CAAa,UAAA,CAAW,CAAC,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA;AAC3E,MAAA,IAAA,CAAK,IAAA,CAAK,CAAA,GAAA,EAAM,SAAS,CAAA,IAAA,CAAM,CAAA;AAAA,IACjC;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,IAAA,CAAK,KAAK,EAAE,CAAA;AACrB;;;ACtFA,IAAM,cAAA,GAAiB,oDAAA;AAOvB,IAAM,iBAAA,GACJ,yFAAA;AAGK,SAAS,gBAAgB,IAAA,EAAsB;AACpD,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,MAAM,gBAAgB,IAAA,CAAK,OAAA,CAAQ,cAAA,EAAgB,EAAE,EAAE,OAAA,EAAQ;AAC/D,EAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,IAAA,CAAK,aAAa,CAAA;AAClD,EAAA,OAAO,KAAA,GAAQ,cAAc,KAAA,CAAM,CAAA,EAAG,MAAM,KAAK,CAAA,CAAE,SAAQ,GAAI,aAAA;AACjE;ACjBA,IAAM,gBAAA,GAAmB,6BAAA;AACzB,IAAM,eAAA,GAAkB,yCAAA;AAiBxB,SAAS,GAAA,GAAc;AACrB,EAAA,OAAO,KAAK,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,GAAG,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAC3E;AAGA,SAAS,SAAS,QAAA,EAA2F;AAC3G,EAAA,MAAM,MAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,IAAI,CAAA,CAAE,IAAA,KAAS,MAAA,IAAU,CAAA,CAAE,SAAS,WAAA,EAAa;AACjD,IAAA,MAAM,UAAU,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,GAAW,EAAE,OAAA,GAAU,EAAA;AAC5D,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,CAAA,CAAE,EAAA,IAAM,GAAA,EAAI,EAAG,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,OAAA,EAAS,CAAA;AAAA,EACvD;AACA,EAAA,OAAO,GAAA;AACT;AAKA,SAAS,WAAW,GAAA,EAA6C;AAC/D,EAAA,OAAO,GAAA,IAAO,eAAA,CAAgB,IAAA,CAAK,GAAG,IAAI,GAAA,GAAM,MAAA;AAClD;AAGA,SAAS,YAAY,IAAA,EAAsB;AACzC,EAAA,IAAI,SAAS,kBAAA,EAAoB;AAC/B,IAAA,OAAO,qGAAA;AAAA,EACT;AACA,EAAA,IAAI,SAAS,uBAAA,EAAyB;AACpC,IAAA,OAAO,iDAAA;AAAA,EACT;AACA,EAAA,IAAI,SAAS,qBAAA,EAAuB;AAClC,IAAA,OAAO,uDAAA;AAAA,EACT;AACA,EAAA,IAAI,SAAS,kBAAA,EAAoB;AAC/B,IAAA,OAAO,2EAAA;AAAA,EACT;AACA,EAAA,IAAI,SAAS,qBAAA,EAAuB;AAClC,IAAA,OAAO,+CAAA;AAAA,EACT;AACA,EAAA,OAAO,sCAAA;AACT;AAGA,SAAS,cAAc,GAAA,EAA4D;AACjF,EAAA,IAAI,eAAe,kBAAA,EAAoB;AACrC,IAAA,OAAO,wGAAA;AAAA,EACT;AACA,EAAA,IAAI,eAAe,uBAAA,EAAyB;AAC1C,IAAA,OAAO,+EAAA;AAAA,EACT;AACA,EAAA,IAAI,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AAClC,IAAA,MAAM,OAAQ,GAAA,CAA0B,IAAA;AACxC,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,OAAO,wGAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,KAAS,cAAc,OAAO,kDAAA;AAClC,IAAA,MAAM,UAAW,GAAA,CAA6B,OAAA;AAC9C,IAAA,IAAI,OAAA,IAAW,OAAA,CAAQ,MAAA,GAAS,GAAA,EAAK,OAAO,OAAA;AAAA,EAC9C;AACA,EAAA,OAAO,yCAAA;AACT;AAEA,IAAM,4BACJ,GAAA,CAAC,KAAA,EAAA,EAAI,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,gBAAa,GAAA,EAAI,gBAAA,EAAe,SAAQ,iBAAA,EAAgB,OAAA,EACjH,8BAAC,MAAA,EAAA,EAAK,CAAA,EAAE,4LAA2L,CAAA,EACrM,CAAA;AAEF,IAAM,UAAA,mBACJ,IAAA,CAAC,KAAA,EAAA,EAAI,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,cAAA,EAAa,GAAA,EAAI,gBAAA,EAAe,OAAA,EAAQ,mBAAgB,OAAA,EACjH,QAAA,EAAA;AAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,KAAI,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,CAAA;AAAA,kBAAE,GAAA,CAAC,UAAK,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK;AAAA,CAAA,EAC5E,CAAA;AAEF,IAAM,SAAA,mBACJ,IAAA,CAAC,KAAA,EAAA,EAAI,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,cAAA,EAAa,GAAA,EAAI,gBAAA,EAAe,OAAA,EAAQ,mBAAgB,OAAA,EACjH,QAAA,EAAA;AAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,KAAI,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,CAAA;AAAA,kBAAE,GAAA,CAAC,SAAA,EAAA,EAAQ,MAAA,EAAO,2BAAA,EAA4B;AAAA,CAAA,EACrF,CAAA;AAGK,SAAS,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,mBAAA,EAAqB,cAAa,EAAgB;AACxF,EAAA,MAAM,MAAA,GAAS,CAAC,CAAC,MAAA,CAAO,MAAA;AACxB,EAAA,MAAM,CAAC,MAAM,OAAO,CAAA,GAAI,SAAS,MAAA,IAAU,CAAC,CAAC,MAAA,CAAO,aAAa,CAAA;AACjE,EAAA,MAAM,CAAC,UAAU,WAAW,CAAA,GAAI,SAAwB,MAAM,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAC,CAAA;AACtF,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAmD,IAAI,CAAA;AACrF,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA;AAIrC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,EAAE,CAAA;AAC7C,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,IAAS,SAAA,IAAa,WAAA;AAE3C,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,gBAAA,GAAmB,OAAO,KAAK,CAAA;AAGrC,EAAA,SAAA,CAAU,MAAM,mBAAA,CAAoB,OAAO,CAAA,EAAG,CAAC,mBAAmB,CAAC,CAAA;AACnE,EAAA,SAAA,CAAU,MAAM,YAAA,GAAe,IAAI,GAAG,CAAC,IAAA,EAAM,YAAY,CAAC,CAAA;AAG1D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,GAAA,GAAM,MAAM,SAAA,CAAU;AAAA,MAC1B,mBAAmB,MAAM,WAAA,CAAY,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAC,CAAA;AAAA,MAC7D,mBAAmB,MAAM;AACvB,QAAA,UAAA,CAAW,IAAI,CAAA;AACf,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,UAAA,CAAW,IAAI,CAAA;AAAA,MACjB,CAAA;AAAA,MACA,kBAAA,EAAoB,MAAM,UAAA,CAAW,KAAK,CAAA;AAAA,MAC1C,eAAA,EAAiB,CAAC,EAAE,KAAA,EAAM,KAAM;AAC9B,QAAA,UAAA,CAAW,KAAK,CAAA;AAChB,QAAA,MAAM,OAAQ,KAAA,CAA4B,IAAA;AAC1C,QAAA,IAAI,SAAS,SAAA,EAAW;AACtB,UAAA,UAAA,CAAW,KAAA,CAAM,WAAA,IAAe,EAAE,IAAA,EAAM,oBAAoB,CAAA;AAC5D,UAAA;AAAA,QACF;AACA,QAAA,QAAA,CAAS,aAAA,CAAc,KAAK,CAAC,CAAA;AAAA,MAC/B;AAAA,KACD,CAAA;AACD,IAAA,OAAO,MAAM,IAAI,WAAA,EAAY;AAAA,EAC/B,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAMV,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,IAAQ,gBAAA,CAAiB,OAAA,EAAS;AACvC,IAAA,gBAAA,CAAiB,OAAA,GAAU,IAAA;AAC3B,IAAA,KAAA,CACG,kBAAA,EAAmB,CACnB,IAAA,CAAK,CAAC,GAAA,KAAQ;AACb,MAAA,IAAI,GAAA,CAAI,SAAA,EAAW,YAAA,CAAa,GAAA,CAAI,SAAS,CAAA;AAAA,IAC/C,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;AAEd,MAAA,gBAAA,CAAiB,OAAA,GAAU,KAAA;AAC3B,MAAA,QAAA,CAAS,aAAA,CAAc,GAAG,CAAC,CAAA;AAAA,IAC7B,CAAC,CAAA;AAAA,EACL,CAAA,EAAG,CAAC,IAAA,EAAM,KAAK,CAAC,CAAA;AAGhB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,KAAK,OAAA,CAAQ,OAAA;AACnB,IAAA,IAAI,EAAA,EAAI,EAAA,CAAG,SAAA,GAAY,EAAA,CAAG,YAAA;AAAA,EAC5B,CAAA,EAAG,CAAC,QAAA,EAAU,OAAO,CAAC,CAAA;AAEtB,EAAA,MAAM,OAAO,MAAM;AACjB,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,IAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,IAAA,QAAA,CAAS,EAAE,CAAA;AACX,IAAA,KAAA,CAAM,UAAA,CAAW,EAAE,EAAA,EAAI,GAAA,IAAO,IAAA,EAAM,MAAA,EAAQ,SAAkB,CAAA;AAC9D,IAAA,WAAA,CAAY,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAC,CAAA;AACpC,IAAA,KAAK,KAAA,CAAM,QAAA,EAAS,CAAE,KAAA,CAAM,MAAM;AAAA,IAElC,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAqB;AACtC,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAC,EAAE,QAAA,EAAU;AACpC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,IAAA,EAAK;AAAA,IACP;AAAA,EACF,CAAA;AAQA,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,gBAAA;AACpC,EAAA,MAAM,WAAA,GAAc,OAAO,cAAA,IAAkB,eAAA;AAC7C,EAAA,MAAM,eAAe,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,WAAW,CAAA;AAChE,EAAA,MAAM,WAAA,GAAc,CAAC,CAAC,WAAA,IAAe,CAAC,YAAA;AACtC,EAAA,MAAM,aAAa,OAAA,IAAW,QAAA,CAAS,SAAS,MAAA,GAAS,CAAC,GAAG,IAAA,KAAS,WAAA;AAEtE,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,IAAA,EAAM;AACpB,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,KAAA,EAAO,CAAA,uBAAA,EAA0B,MAAA,CAAO,QAAA,IAAY,cAAc,CAAA,CAAA;AAAA,QAClE,YAAA,EAAW,WAAA;AAAA,QACX,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,QAE1B,QAAA,EAAA,MAAA,CAAO,OAAA,mBACN,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,oBAAA,EAAqB,GAAA,EAAK,MAAA,CAAO,OAAA,EAAS,GAAA,EAAI,EAAA,EAAG,CAAA,GAE5D;AAAA;AAAA,KAEJ;AAAA,EAEJ;AAEA,EAAA,MAAM,aAAa,MAAA,GACf,wBAAA,GACA,CAAA,oBAAA,EAAuB,MAAA,CAAO,YAAY,cAAc,CAAA,CAAA;AAE5D,EAAA,4BACG,KAAA,EAAA,EAAI,KAAA,EAAO,YAAY,IAAA,EAAK,QAAA,EAAS,cAAY,KAAA,EAChD,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,OAAM,aAAA,EACT,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,OAAM,gBAAA,EACR,QAAA,EAAA;AAAA,QAAA,MAAA,CAAO,OAAA,wBAAY,KAAA,EAAA,EAAI,KAAA,EAAM,aAAY,GAAA,EAAK,MAAA,CAAO,OAAA,EAAS,GAAA,EAAI,EAAA,EAAG,CAAA;AAAA,wBACtE,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,kBAAA,EACT,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,YAAA,EAAc,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,UAC/B,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,iBAAiB,QAAA,EAAA,QAAA,EAAS;AAAA,SAAA,EACrD;AAAA,OAAA,EACF,CAAA;AAAA,MACC,CAAC,MAAA,oBACA,GAAA,CAAC,QAAA,EAAA,EAAO,MAAK,QAAA,EAAS,KAAA,EAAM,YAAA,EAAa,YAAA,EAAW,cAAa,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK,GAC1F,QAAA,EAAA,UAAA,EACH;AAAA,KAAA,EAEJ,CAAA;AAAA,oBAEA,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,eAAA,EAAgB,KAAK,OAAA,EAC7B,QAAA,EAAA;AAAA,MAAA,WAAA,oBACC,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,4BAAA;AAAA,UAEN,uBAAA,EAAyB,EAAE,MAAA,EAAQ,cAAA,CAAe,WAAW,CAAA;AAAE;AAAA,OACjE;AAAA,MAED,QAAA,CAAS,GAAA;AAAA,QAAI,CAAC,CAAA,KACb,CAAA,CAAE,IAAA,KAAS,WAAA,mBACT,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,KAAA,EAAM,4BAAA;AAAA,YACN,uBAAA,EAAyB,EAAE,MAAA,EAAQ,cAAA,CAAe,gBAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AAAE,WAAA;AAAA,UAFzE,CAAA,CAAE;AAAA,SAGT,uBAEC,KAAA,EAAA,EAAe,KAAA,EAAM,yBACnB,QAAA,EAAA,CAAA,CAAE,OAAA,EAAA,EADK,EAAE,EAEZ;AAAA,OAEJ;AAAA,MACC,UAAA,oBACC,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,wCAAA,EACT,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA;AAAA,4BAAG,MAAA,EAAA,EAAK,CAAA;AAAA,4BAAG,MAAA,EAAA,EAAK;AAAA,OAAA,EACxB;AAAA,KAAA,EAEJ,CAAA;AAAA,IAEC,KAAA,oBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,cAAc,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,IAExC,OAAA,oBACC,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,cAAA,EACT,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,WAAA,CAAY,OAAA,CAAQ,IAAI,CAAA,EAAE,CAAA;AAAA,MAChC,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA,oBACxB,GAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,kBAAA;AAAA,UACN,IAAA,EAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAAA,UAC/B,MAAA,EAAO,QAAA;AAAA,UACP,GAAA,EAAI,qBAAA;AAAA,UACL,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EAEJ,CAAA;AAAA,oBAGF,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,eAAA,EACT,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,YAAA;AAAA,UACN,IAAA,EAAM,CAAA;AAAA,UACN,WAAA,EAAY,sBAAA;AAAA,UACZ,KAAA,EAAO,KAAA;AAAA,UACP,QAAA,EAAU,OAAA;AAAA,UACV,SAAS,CAAC,CAAA,KAAM,QAAA,CAAU,CAAA,CAAE,OAA+B,KAAK,CAAA;AAAA,UAChE;AAAA;AAAA,OACF;AAAA,0BACC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,KAAA,EAAM,aAAY,YAAA,EAAW,MAAA,EAAO,QAAA,EAAU,OAAA,IAAW,CAAC,KAAA,CAAM,IAAA,EAAK,EAAG,OAAA,EAAS,MACpG,QAAA,EAAA,SAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,oBACA,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,cAAA,EAAe,QAAA,EAAA;AAAA,MAAA,YAAA;AAAA,MACb,GAAA;AAAA,sBACX,GAAA,CAAC,OAAE,IAAA,EAAK,sBAAA,EAAuB,QAAO,QAAA,EAAS,GAAA,EAAI,uBAAsB,QAAA,EAAA,UAAA,EAEzE;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;ACtSA,IAAM,cAAA,GAAiB,SAAA;AAOvB,SAAS,iBAAiB,GAAA,EAAqB;AAC7C,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAC7B,EAAA,MAAM,OAAO,CAAA,CAAE,MAAA,KAAW,CAAA,GAAI,CAAA,CAAE,MAAM,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,MAAM,CAAA,GAAI,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,GAAI,CAAA;AACvE,EAAA,IAAI,KAAK,MAAA,KAAW,CAAA,IAAK,aAAa,IAAA,CAAK,IAAI,GAAG,OAAO,SAAA;AACzD,EAAA,MAAM,IAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AACvC,EAAA,MAAM,IAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AACvC,EAAA,MAAM,IAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AACvC,EAAA,MAAM,aAAa,KAAA,GAAQ,CAAA,GAAI,KAAA,GAAQ,CAAA,GAAI,QAAQ,CAAA,IAAK,GAAA;AACxD,EAAA,OAAO,SAAA,GAAY,OAAO,SAAA,GAAY,SAAA;AACxC;AASA,eAAsB,iBACpB,MAAA,EACuB;AACvB,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,OAAO,MAAM,MAAqB,CAAA;AAAA,EACpC;AACA,EAAA,IAAI,CAAC,QAAQ,cAAA,EAAgB;AAC3B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAU,GAAI,MAAM,cAAA;AAAA,IACnC,OAAO,UAAA,IAAc,oBAAA;AAAA,IACrB,MAAA,CAAO;AAAA,GACT;AACA,EAAA,OAAO,MAAM,EAAE,GAAG,QAAQ,MAAA,EAAQ,SAAA,EAAW,SAAwB,CAAA;AACvE;AAEO,SAAS,MAAM,MAAA,EAAmC;AACvD,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAO,MAAA,IAAU,CAAC,OAAO,cAAA,EAAgB;AACvD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,OAAO,WAAA,IAAe,cAAA;AACrC,EAAA,IAAI,SAAA,GAAY,KAAA;AAGhB,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACzC,EAAA,IAAA,CAAK,YAAA,CAAa,yBAAyB,EAAE,CAAA;AAC7C,EAAA,MAAM,SAAS,IAAA,CAAK,YAAA,CAAa,EAAE,IAAA,EAAM,QAAQ,CAAA;AAEjD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,WAAA,GAAc,aAAA;AACpB,EAAA,MAAA,CAAO,YAAY,KAAK,CAAA;AAExB,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACzC,EAAA,IAAA,CAAK,SAAA,GAAY,WAAA;AACjB,EAAA,MAAA,CAAO,YAAY,IAAI,CAAA;AAIvB,EAAA,MAAM,WAAA,GAAc,CAAC,WAAA,KAAyB;AAC5C,IAAA,MAAM,IAAI,WAAA,IAAe,cAAA;AACzB,IAAA,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,eAAA,EAAiB,CAAC,CAAA;AACzC,IAAA,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,kBAAA,EAAoB,gBAAA,CAAiB,CAAC,CAAC,CAAA;AAAA,EAChE,CAAA;AACA,EAAA,WAAA,CAAY,MAAM,CAAA;AAIlB,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA,CAAO,UAAU,QAAA,CAAS,IAAA,GAAO,YAAY,IAAI,CAAA;AACvE,EAAA,IAAI,MAAA,CAAO,MAAA,IAAU,QAAA,CAAS,IAAA,EAAM;AAClC,IAAA,MAAA,EAAO;AAAA,EACT,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,gBAAA;AAAA,MACP,kBAAA;AAAA,MACA,MAAM;AACJ,QAAA,IAAI,CAAC,WAAW,MAAA,EAAO;AAAA,MACzB,CAAA;AAAA,MACA,EAAE,MAAM,IAAA;AAAK,KACf;AAAA,EACF;AAEA,EAAA,MAAM,KAAA,GAAQ,IAAI,YAAA,CAAa,MAAM,CAAA;AAErC,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,CAAC,CAAC,MAAA,CAAO,aAAA;AAIvC,EAAA,MAAM,mBAAA,GAAsB,CAAC,EAAA,KAAgC;AAC3D,IAAA,OAAA,GAAU,EAAA;AAAA,EACZ,CAAA;AACA,EAAA,MAAM,YAAA,GAAe,CAAC,CAAA,KAAe;AACnC,IAAA,MAAA,GAAS,CAAA;AAAA,EACX,CAAA;AAIA,EAAA,IAAI,OAAA,GAAuB,MAAA;AAC3B,EAAA,MAAM,eAAe,MAAM;AACzB,IAAA,MAAA;AAAA,sBACEA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,KAAA;AAAA,UACA,MAAA,EAAQ,OAAA;AAAA,UACR,mBAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA;AACA,EAAA,YAAA,EAAa;AAGb,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,KAAK,MAAM,GAAA,EAAI;AAAA,EACjB,CAAA;AACA,EAAA,MAAA,CAAO,gBAAA,CAAiB,gBAAgB,WAAW,CAAA;AAEnD,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,IAAA,EAAM,MAAM,OAAA,GAAU,IAAI,CAAA;AAAA,IAC1B,KAAA,EAAO,MAAM,OAAA,GAAU,KAAK,CAAA;AAAA,IAC5B,MAAA,EAAQ,MAAM,OAAA,GAAU,CAAC,MAAM,CAAA;AAAA,IAC/B,MAAA,EAAQ,CAAC,OAAA,KAAY;AACnB,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,OAAA,GAAU,EAAE,GAAG,OAAA,EAAS,GAAG,OAAA,EAAQ;AACnC,MAAA,IAAI,aAAA,IAAiB,OAAA,EAAS,WAAA,CAAY,OAAA,CAAQ,WAAW,CAAA;AAC7D,MAAA,YAAA,EAAa;AAAA,IACf,CAAA;AAAA,IACA,SAAS,MAAM;AACb,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,MAAA,CAAO,mBAAA,CAAoB,gBAAgB,WAAW,CAAA;AACtD,MAAA,KAAK,MAAM,GAAA,EAAI;AACf,MAAA,MAAA,CAAO,MAAM,IAAI,CAAA;AACjB,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,GACF;AACF","file":"ui.js","sourcesContent":["/**\n * Scoped CSS for the chat widget, injected into the Shadow DOM root so\n * it can neither leak into nor be overridden by the host page. All\n * colours derive from two custom properties (``--surg-accent`` and its\n * readable foreground) set at mount time from the caller's\n * ``accentColor`` so theming is a one-line change.\n *\n * Returned as a string (rather than a constructable stylesheet) because\n * a ``<style>`` element in the shadow root is the most broadly supported\n * path across the browsers a public embed has to serve.\n */\nexport const WIDGET_STYLES = `\n:host { all: initial; }\n* { box-sizing: border-box; }\n\n.surg-root {\n --surg-radius: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #0f172a;\n}\n\n.surg-launcher {\n position: fixed;\n bottom: 20px;\n width: 56px;\n height: 56px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n box-shadow: 0 6px 24px rgba(15, 23, 42, 0.25);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n z-index: 2147483000;\n}\n.surg-launcher:hover { transform: scale(1.06); box-shadow: 0 8px 28px rgba(15, 23, 42, 0.3); }\n.surg-launcher svg { width: 26px; height: 26px; }\n.surg-pos-bottom-right { right: 20px; }\n.surg-pos-bottom-left { left: 20px; }\n\n.surg-panel {\n position: fixed;\n bottom: 88px;\n width: 380px;\n max-width: calc(100vw - 40px);\n height: 560px;\n max-height: calc(100vh - 120px);\n background: #ffffff;\n border-radius: var(--surg-radius);\n box-shadow: 0 12px 48px rgba(15, 23, 42, 0.28);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n z-index: 2147483000;\n animation: surg-rise 0.18s ease;\n}\n@keyframes surg-rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }\n\n.surg-inline {\n position: relative;\n bottom: auto; right: auto; left: auto;\n width: 100%;\n height: 100%;\n box-shadow: none;\n border: 1px solid #e2e8f0;\n animation: none;\n}\n\n.surg-header {\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n padding: 14px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n}\n.surg-header-id { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.surg-header-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }\n.surg-title { font-weight: 600; font-size: 15px; }\n.surg-subtitle { font-size: 11px; font-weight: 400; opacity: 0.85; }\n.surg-logo {\n width: 32px; height: 32px; border-radius: 50%; object-fit: cover;\n background: rgba(255, 255, 255, 0.2); flex-shrink: 0;\n}\n.surg-launcher-logo {\n width: 32px; height: 32px; border-radius: 50%; object-fit: cover;\n}\n.surg-close {\n background: transparent;\n border: none;\n color: inherit;\n cursor: pointer;\n opacity: 0.85;\n padding: 4px;\n display: flex;\n border-radius: 6px;\n}\n.surg-close:hover { opacity: 1; background: rgba(255, 255, 255, 0.18); }\n.surg-close svg { width: 18px; height: 18px; }\n\n.surg-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n background: #f8fafc;\n}\n\n.surg-bubble {\n max-width: 82%;\n padding: 9px 13px;\n border-radius: 14px;\n word-wrap: break-word;\n white-space: normal;\n}\n.surg-bubble p { margin: 0 0 8px; }\n.surg-bubble p:last-child { margin-bottom: 0; }\n.surg-bubble ul, .surg-bubble ol { margin: 4px 0; padding-left: 20px; }\n.surg-bubble code {\n background: rgba(15, 23, 42, 0.08);\n padding: 1px 5px;\n border-radius: 5px;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.9em;\n}\n.surg-bubble pre {\n background: #0f172a;\n color: #e2e8f0;\n padding: 10px 12px;\n border-radius: 10px;\n overflow-x: auto;\n margin: 6px 0;\n}\n.surg-bubble pre code { background: transparent; padding: 0; color: inherit; }\n.surg-bubble a { color: var(--surg-accent); }\n\n.surg-user {\n align-self: flex-end;\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n border-bottom-right-radius: 4px;\n white-space: pre-wrap;\n}\n.surg-user a { color: var(--surg-accent-fg); text-decoration: underline; }\n.surg-assistant {\n align-self: flex-start;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n border-bottom-left-radius: 4px;\n}\n\n.surg-typing { display: flex; gap: 4px; padding: 4px 2px; }\n.surg-typing span {\n width: 7px; height: 7px; border-radius: 50%;\n background: #94a3b8;\n animation: surg-blink 1.2s infinite ease-in-out;\n}\n.surg-typing span:nth-child(2) { animation-delay: 0.2s; }\n.surg-typing span:nth-child(3) { animation-delay: 0.4s; }\n@keyframes surg-blink { 0%, 60%, 100% { opacity: 0.3; } 30% { opacity: 1; } }\n\n.surg-error {\n margin: 0 16px;\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n color: #b91c1c;\n border-radius: 10px;\n font-size: 13px;\n flex-shrink: 0;\n}\n\n.surg-paywall {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin: 0 16px;\n padding: 12px;\n background: #fffbeb;\n border: 1px solid #fde68a;\n color: #92400e;\n border-radius: 10px;\n font-size: 13px;\n flex-shrink: 0;\n}\n.surg-paywall-cta {\n align-self: flex-start;\n padding: 6px 14px;\n background: var(--surg-accent, #0f172a);\n color: #ffffff;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n.surg-paywall-cta:hover { opacity: 0.9; }\n\n.surg-composer {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid #e2e8f0;\n background: #ffffff;\n flex-shrink: 0;\n}\n.surg-input {\n flex: 1;\n resize: none;\n border: 1px solid #cbd5e1;\n border-radius: 12px;\n padding: 9px 12px;\n font: inherit;\n color: inherit;\n max-height: 120px;\n outline: none;\n}\n.surg-input:focus { border-color: var(--surg-accent); }\n.surg-send {\n border: none;\n background: var(--surg-accent);\n color: var(--surg-accent-fg);\n border-radius: 12px;\n width: 40px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.surg-send:disabled { opacity: 0.5; cursor: not-allowed; }\n.surg-send svg { width: 18px; height: 18px; }\n\n.surg-powered {\n text-align: center;\n font-size: 11px;\n color: #94a3b8;\n padding: 0 0 8px;\n background: #ffffff;\n}\n.surg-powered a { color: inherit; font-weight: 500; text-decoration: none; }\n.surg-powered a:hover { text-decoration: underline; }\n`;\n","/**\n * Minimal, dependency-free Markdown → HTML renderer for assistant text.\n *\n * Assistant output is *semi-trusted* (it comes from the agent, not the\n * visitor), but the widget renders into a Shadow DOM via\n * ``dangerouslySetInnerHTML``, so a careless renderer would still be an\n * XSS vector if the model ever echoed attacker-supplied HTML. The\n * contract here is therefore: **escape first, then re-introduce only the\n * small, known-safe subset of HTML the formatter produces.** No raw\n * HTML from the source string ever survives — every ``<`` in the input\n * is entity-escaped before any tag is emitted.\n *\n * Supported: fenced code blocks, inline code, bold, italic, links\n * (http/https/mailto only), unordered + ordered lists, and paragraphs\n * with line breaks. Everything else degrades to escaped plain text.\n */\n\nconst ESCAPE_MAP: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) => ESCAPE_MAP[c] ?? c);\n}\n\n/** Allow only links the browser can't be tricked into executing. */\nfunction safeHref(raw: string): string | undefined {\n const url = raw.trim();\n if (/^(https?:|mailto:)/i.test(url)) return url;\n return undefined;\n}\n\n/**\n * Apply inline formatting to an *already HTML-escaped* fragment. Order\n * matters: links before emphasis so ``[a](b)`` brackets aren't eaten by\n * the italic rule, and bold (``**``) before italic (``*``).\n */\nfunction renderInline(escaped: string): string {\n let out = escaped;\n\n // Inline code first — its contents must not be touched by later rules.\n // The buffer is already escaped, so the captured group is literal text.\n out = out.replace(/`([^`]+)`/g, (_m, code: string) => `<code>${code}</code>`);\n\n // Links: [text](href). ``href`` is validated; bad schemes render as\n // the original (escaped) text without an anchor.\n out = out.replace(\n /\\[([^\\]]+)\\]\\(([^)\\s]+)\\)/g,\n (_m, text: string, href: string) => {\n const safe = safeHref(href);\n if (!safe) return `${text}`;\n return `<a href=\"${safe}\" target=\"_blank\" rel=\"noopener noreferrer\">${text}</a>`;\n },\n );\n\n out = out.replace(/\\*\\*([^*]+)\\*\\*/g, (_m, t: string) => `<strong>${t}</strong>`);\n out = out.replace(/(^|[^*])\\*([^*\\n]+)\\*/g, (_m, pre: string, t: string) => `${pre}<em>${t}</em>`);\n\n return out;\n}\n\n/**\n * Render ``src`` Markdown to a safe HTML string. Splits on fenced code\n * blocks so their bodies bypass inline formatting entirely, then groups\n * the remaining text into list and paragraph blocks.\n */\nexport function renderMarkdown(src: string): string {\n const parts = src.split(/```/);\n const html: string[] = [];\n\n parts.forEach((part, index) => {\n const isCodeFence = index % 2 === 1;\n if (isCodeFence) {\n // Drop an optional language hint on the first line.\n const body = part.replace(/^[^\\n]*\\n/, (m) => (part.includes('\\n') ? '' : m));\n html.push(`<pre><code>${escapeHtml(body.replace(/\\n$/, ''))}</code></pre>`);\n return;\n }\n\n const blocks = part.split(/\\n{2,}/);\n for (const block of blocks) {\n const lines = block.split('\\n').filter((l) => l.trim().length > 0);\n if (lines.length === 0) continue;\n\n const isUnordered = lines.every((l) => /^\\s*[-*]\\s+/.test(l));\n const isOrdered = lines.every((l) => /^\\s*\\d+\\.\\s+/.test(l));\n if (isUnordered || isOrdered) {\n const items = lines\n .map((l) => l.replace(/^\\s*(?:[-*]|\\d+\\.)\\s+/, ''))\n .map((l) => `<li>${renderInline(escapeHtml(l))}</li>`)\n .join('');\n html.push(isOrdered ? `<ol>${items}</ol>` : `<ul>${items}</ul>`);\n continue;\n }\n\n const paragraph = lines.map((l) => renderInline(escapeHtml(l))).join('<br>');\n html.push(`<p>${paragraph}</p>`);\n }\n });\n\n return html.join('');\n}\n","/**\n * Strip the per-turn ``<next_action>`` footer from assistant text.\n *\n * The harness instructs the assistant to end every final response with a\n * ``<next_action complexity=\"...\" summary=\"...\">...</next_action>`` block\n * (see ``surogates/harness/prompts/guidance/next_action.md``). It is\n * harness/UI metadata, not user-facing content — by design the *client*\n * strips it: the full chat console does so in\n * ``agent-chat-react/src/lib/next-action.ts``, and messaging channels\n * strip it server-side. This widget streams raw ``llm.delta`` frames, so\n * it must strip it too or the XML footer flashes in the bubble.\n *\n * We only need the stripping half here (the console additionally parses\n * the block into a status pill). Streaming-safe: a dangling, not-yet-\n * closed footer is hidden the moment its opener appears so partial tags\n * never flicker.\n */\n\n// Complete ``<next_action ...>...</next_action>`` blocks (+ trailing ws).\nconst NEXT_ACTION_RE = /<next_action([^>]*)>([\\s\\S]*?)<\\/next_action>\\s*/gi;\n\n// A trailing, still-streaming footer: any prefix of the literal\n// ``<next_action`` token at the start of a line through end-of-text,\n// then everything after the whole word arrives (attributes + partial\n// body, closing tag not yet seen). Anchored to start-of-line so a stray\n// ``<`` mid-sentence is never mistaken for the footer.\nconst PARTIAL_FOOTER_RE =\n /(?:^|\\n)\\s*<(?:n(?:e(?:x(?:t(?:_(?:a(?:c(?:t(?:i(?:o(?:n[\\s\\S]*)?)?)?)?)?)?)?)?)?)?)?$/i;\n\n/** Return *text* with every (complete or streaming-partial) footer removed. */\nexport function stripNextAction(text: string): string {\n if (!text) return text;\n const withoutBlocks = text.replace(NEXT_ACTION_RE, '').trimEnd();\n const match = PARTIAL_FOOTER_RE.exec(withoutBlocks);\n return match ? withoutBlocks.slice(0, match.index).trimEnd() : withoutBlocks;\n}\n","/**\n * The Preact chat UI rendered inside the widget's Shadow DOM.\n *\n * It is a thin presentation layer over the headless :class:`WebsiteAgent`:\n * all transport, auth, and streaming live in the agent; this component\n * only subscribes to the AG-UI event stream, mirrors ``agent.messages``\n * into local state, and drives ``runAgent`` from the composer.\n */\nimport { useEffect, useRef, useState } from 'preact/hooks';\n\nimport type { WebsiteAgent } from '../agent.js';\nimport { SurogatesAuthError, SurogatesRateLimitError } from '../errors.js';\nimport { renderMarkdown } from './markdown.js';\nimport { stripNextAction } from './next-action.js';\nimport type { MountConfig } from './types.js';\n\n// Shown when the operator hasn't set their own. Kept friendly and\n// provider-neutral so an unconfigured widget still looks finished.\nconst DEFAULT_SUBTITLE = 'Typically replies instantly';\nconst DEFAULT_WELCOME = 'Hi! 👋 How can I help you today?';\n\ninterface ChatMessage {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n}\n\ninterface WidgetProps {\n agent: WebsiteAgent;\n config: MountConfig;\n /** Lets the imperative handle in ``mount`` drive the open/closed state. */\n registerOpenControl: (setOpen: (open: boolean) => void) => void;\n /** Reports open-state changes back so ``mount``'s ``toggle()`` stays in sync. */\n onOpenChange?: (open: boolean) => void;\n}\n\nfunction uid(): string {\n return `u-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\n/** Project ``agent.messages`` down to the renderable user/assistant turns. */\nfunction snapshot(messages: ReadonlyArray<{ id?: string; role?: string; content?: unknown }>): ChatMessage[] {\n const out: ChatMessage[] = [];\n for (const m of messages) {\n if (m.role !== 'user' && m.role !== 'assistant') continue;\n const content = typeof m.content === 'string' ? m.content : '';\n out.push({ id: m.id ?? uid(), role: m.role, content });\n }\n return out;\n}\n\n/** Only render CTA links with a web protocol — the buy URL rides in\n * from server config, but an SDK running on third-party sites must\n * not let any upstream compromise turn it into a `javascript:` URI. */\nfunction safeBuyUrl(url: string | undefined): string | undefined {\n return url && /^https?:\\/\\//i.test(url) ? url : undefined;\n}\n\n/** Visitor-facing copy per paywall sentinel from the server. */\nfunction paywallCopy(code: string): string {\n if (code === 'sign_in_required') {\n return 'This assistant requires an account. Get access, sign in on this site, then send your message again.';\n }\n if (code === 'subscription_required') {\n return 'This assistant requires an active subscription.';\n }\n if (code === 'free_plan_available') {\n return 'This assistant needs a plan, and there is a free one.';\n }\n if (code === 'upgrade_required') {\n return 'You have used this month’s free allowance. Upgrade to keep chatting.';\n }\n if (code === 'insufficient_tokens') {\n return 'You’re out of tokens for this assistant.';\n }\n return 'This assistant requires paid access.';\n}\n\n/** Map an SDK error (thrown or via RUN_ERROR) to visitor-facing copy. */\nfunction friendlyError(err: { code?: string; message?: string } | unknown): string {\n if (err instanceof SurogatesAuthError) {\n return 'This chat isn’t accepting messages from this site yet. The site owner needs to allow this origin.';\n }\n if (err instanceof SurogatesRateLimitError) {\n return 'You’re sending messages too quickly. Please wait a moment and try again.';\n }\n if (err && typeof err === 'object') {\n const code = (err as { code?: string }).code;\n if (code === 'auth') {\n return 'This chat isn’t accepting messages from this site yet. The site owner needs to allow this origin.';\n }\n if (code === 'sse_closed') return 'Connection lost. Please send your message again.';\n const message = (err as { message?: string }).message;\n if (message && message.length < 160) return message;\n }\n return 'Something went wrong. Please try again.';\n}\n\nconst ICON_CHAT = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\" />\n </svg>\n);\nconst ICON_CLOSE = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\nconst ICON_SEND = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n\nexport function Widget({ agent, config, registerOpenControl, onOpenChange }: WidgetProps) {\n const inline = !!config.inline;\n const [open, setOpen] = useState(inline || !!config.openByDefault);\n const [messages, setMessages] = useState<ChatMessage[]>(() => snapshot(agent.messages));\n const [running, setRunning] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [paywall, setPaywall] = useState<{ code: string; buyUrl?: string } | null>(null);\n const [input, setInput] = useState('');\n // Only the async input is state; the title is derived at render so a\n // configured title (incl. live handle.update()) always wins, falling back\n // to the bootstrapped agent name, then a generic label.\n const [agentName, setAgentName] = useState('');\n const title = config.title || agentName || 'Assistant';\n\n const listRef = useRef<HTMLDivElement>(null);\n const bootstrapStarted = useRef(false);\n\n // Expose the open setter to the mount() imperative handle.\n useEffect(() => registerOpenControl(setOpen), [registerOpenControl]);\n useEffect(() => onOpenChange?.(open), [open, onOpenChange]);\n\n // Mirror the agent's event stream into local UI state.\n useEffect(() => {\n const sub = agent.subscribe({\n onMessagesChanged: () => setMessages(snapshot(agent.messages)),\n onRunStartedEvent: () => {\n setRunning(true);\n setError(null);\n setPaywall(null);\n },\n onRunFinishedEvent: () => setRunning(false),\n onRunErrorEvent: ({ event }) => {\n setRunning(false);\n const code = (event as { code?: string }).code;\n if (code === 'paywall') {\n setPaywall(agent.lastPaywall ?? { code: 'payment_required' });\n return;\n }\n setError(friendlyError(event));\n },\n });\n return () => sub.unsubscribe();\n }, [agent]);\n\n // Validate config + resolve the header title the first time the panel\n // is opened. Eager bootstrap on open (not page-load) means visitors\n // who never open the chat don't create server sessions; opening is a\n // clear intent signal and surfaces misconfiguration immediately.\n useEffect(() => {\n if (!open || bootstrapStarted.current) return;\n bootstrapStarted.current = true;\n agent\n .ensureBootstrapped()\n .then((res) => {\n if (res.agentName) setAgentName(res.agentName);\n })\n .catch((err) => {\n // Allow a retry the next time the panel opens (transient network, etc.).\n bootstrapStarted.current = false;\n setError(friendlyError(err));\n });\n }, [open, agent]);\n\n // Keep the transcript pinned to the latest message.\n useEffect(() => {\n const el = listRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n }, [messages, running]);\n\n const send = () => {\n const content = input.trim();\n if (!content || running) return;\n setInput('');\n agent.addMessage({ id: uid(), role: 'user', content } as never);\n setMessages(snapshot(agent.messages));\n void agent.runAgent().catch(() => {\n /* Failures surface through onRunErrorEvent; swallow the rejection. */\n });\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n };\n\n // An unconfigured widget always shows sensible default copy: a missing\n // subtitle/welcome falls back to the defaults. Note Studio/the embed omit\n // empty fields, so *clearing* the field in Studio is indistinguishable from\n // never setting it — both show the default. There is intentionally no\n // \"show nothing\" state today; if suppression is ever needed, add an explicit\n // sentinel rather than relying on empty string.\n const subtitle = config.subtitle ?? DEFAULT_SUBTITLE;\n const welcomeText = config.welcomeMessage ?? DEFAULT_WELCOME;\n const hasAssistant = messages.some((m) => m.role === 'assistant');\n const showWelcome = !!welcomeText && !hasAssistant;\n const showTyping = running && messages[messages.length - 1]?.role !== 'assistant';\n\n if (!inline && !open) {\n return (\n <button\n type=\"button\"\n class={`surg-launcher surg-pos-${config.position ?? 'bottom-right'}`}\n aria-label=\"Open chat\"\n onClick={() => setOpen(true)}\n >\n {config.logoUrl ? (\n <img class=\"surg-launcher-logo\" src={config.logoUrl} alt=\"\" />\n ) : (\n ICON_CHAT\n )}\n </button>\n );\n }\n\n const panelClass = inline\n ? 'surg-panel surg-inline'\n : `surg-panel surg-pos-${config.position ?? 'bottom-right'}`;\n\n return (\n <div class={panelClass} role=\"dialog\" aria-label={title}>\n <div class=\"surg-header\">\n <div class=\"surg-header-id\">\n {config.logoUrl && <img class=\"surg-logo\" src={config.logoUrl} alt=\"\" />}\n <div class=\"surg-header-text\">\n <span class=\"surg-title\">{title}</span>\n {subtitle && <span class=\"surg-subtitle\">{subtitle}</span>}\n </div>\n </div>\n {!inline && (\n <button type=\"button\" class=\"surg-close\" aria-label=\"Close chat\" onClick={() => setOpen(false)}>\n {ICON_CLOSE}\n </button>\n )}\n </div>\n\n <div class=\"surg-messages\" ref={listRef}>\n {showWelcome && (\n <div\n class=\"surg-bubble surg-assistant\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: renderMarkdown(welcomeText) }}\n />\n )}\n {messages.map((m) =>\n m.role === 'assistant' ? (\n <div\n key={m.id}\n class=\"surg-bubble surg-assistant\"\n dangerouslySetInnerHTML={{ __html: renderMarkdown(stripNextAction(m.content)) }}\n />\n ) : (\n <div key={m.id} class=\"surg-bubble surg-user\">\n {m.content}\n </div>\n ),\n )}\n {showTyping && (\n <div class=\"surg-bubble surg-assistant surg-typing\">\n <span /><span /><span />\n </div>\n )}\n </div>\n\n {error && <div class=\"surg-error\">{error}</div>}\n\n {paywall && (\n <div class=\"surg-paywall\">\n <span>{paywallCopy(paywall.code)}</span>\n {safeBuyUrl(paywall.buyUrl) && (\n <a\n class=\"surg-paywall-cta\"\n href={safeBuyUrl(paywall.buyUrl)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Get access\n </a>\n )}\n </div>\n )}\n\n <div class=\"surg-composer\">\n <textarea\n class=\"surg-input\"\n rows={1}\n placeholder=\"Type a message…\"\n value={input}\n disabled={running}\n onInput={(e) => setInput((e.target as HTMLTextAreaElement).value)}\n onKeyDown={onKeyDown}\n />\n <button type=\"button\" class=\"surg-send\" aria-label=\"Send\" disabled={running || !input.trim()} onClick={send}>\n {ICON_SEND}\n </button>\n </div>\n <div class=\"surg-powered\">\n Powered by{' '}\n <a href=\"https://surogate.ai/\" target=\"_blank\" rel=\"noopener noreferrer\">\n Surogate\n </a>\n </div>\n </div>\n );\n}\n","/**\n * ``mount()`` — the drop-in entry point.\n *\n * A single call stands up a complete chat widget: it creates a host\n * element, isolates the UI in a Shadow DOM (so neither the host page's\n * CSS nor the widget's styles can bleed across), instantiates the\n * headless :class:`WebsiteAgent`, and renders the Preact UI into the\n * shadow root. Returns an imperative :type:`WidgetHandle` for hosts\n * that want to open/close/destroy the widget programmatically.\n *\n * This is what the ``<script>``-tag embed and the Studio live preview\n * both call. Everything cosmetic is optional; ``apiUrl`` and\n * ``publishableKey`` are the only required fields.\n */\nimport { render } from 'preact';\n\nimport { WebsiteAgent } from '../agent.js';\nimport { DEFAULT_PAIRING_BASE } from '../constants.js';\nimport { resolvePairing } from '../protocol.js';\nimport { WIDGET_STYLES } from './styles.js';\nimport type { MountConfig, WidgetHandle } from './types.js';\nimport { Widget } from './widget.js';\n\nexport type { MountConfig, WidgetHandle, WidgetAppearance } from './types.js';\n\nconst DEFAULT_ACCENT = '#4f46e5';\n\n/**\n * Pick a readable foreground (near-black vs white) for text/icons that\n * sit on the accent colour, using an sRGB luminance approximation. A\n * pale accent gets dark text; a saturated one gets white.\n */\nfunction accentForeground(hex: string): string {\n const v = hex.replace('#', '');\n const full = v.length === 3 ? v.split('').map((c) => c + c).join('') : v;\n if (full.length !== 6 || /[^0-9a-f]/i.test(full)) return '#ffffff';\n const r = parseInt(full.slice(0, 2), 16);\n const g = parseInt(full.slice(2, 4), 16);\n const b = parseInt(full.slice(4, 6), 16);\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.62 ? '#0f172a' : '#ffffff';\n}\n\n/**\n * Key-only entry point. Resolves the publishable key to its agent +\n * ``api_web_url`` via the control-plane pairing endpoint, then mounts against\n * that base URL — so an embed can be just ``mountWithPairing({ publishableKey })``\n * with no hardcoded ``apiUrl``. If ``apiUrl`` is already supplied, pairing is\n * skipped and this is equivalent to :func:`mount`.\n */\nexport async function mountWithPairing(\n config: Omit<MountConfig, 'apiUrl'> & { apiUrl?: string },\n): Promise<WidgetHandle> {\n if (config?.apiUrl) {\n return mount(config as MountConfig);\n }\n if (!config?.publishableKey) {\n throw new Error(\n 'SurogatesWidget.mountWithPairing: \"publishableKey\" is required.',\n );\n }\n const { agentId, apiWebUrl } = await resolvePairing(\n config.pairingUrl ?? DEFAULT_PAIRING_BASE,\n config.publishableKey,\n );\n return mount({ ...config, apiUrl: apiWebUrl, agentId } as MountConfig);\n}\n\nexport function mount(config: MountConfig): WidgetHandle {\n if (!config || !config.apiUrl || !config.publishableKey) {\n throw new Error(\n 'SurogatesWidget.mount: \"apiUrl\" and \"publishableKey\" are required.',\n );\n }\n\n const accent = config.accentColor ?? DEFAULT_ACCENT;\n let destroyed = false;\n\n // Host element + Shadow DOM: total style isolation in both directions.\n const host = document.createElement('div');\n host.setAttribute('data-surogates-widget', '');\n const shadow = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = WIDGET_STYLES;\n shadow.appendChild(style);\n\n const root = document.createElement('div');\n root.className = 'surg-root';\n shadow.appendChild(root);\n\n // Accent drives CSS custom properties on the root, so it can be re-applied\n // on update() without re-rendering anything else.\n const applyAccent = (accentColor?: string) => {\n const a = accentColor ?? DEFAULT_ACCENT;\n root.style.setProperty('--surg-accent', a);\n root.style.setProperty('--surg-accent-fg', accentForeground(a));\n };\n applyAccent(accent);\n\n // Attach to the page. Drop-in embeds are often placed in <head>, where\n // document.body doesn't exist yet — defer the append until the DOM is ready.\n const attach = () => (config.target ?? document.body)?.appendChild(host);\n if (config.target || document.body) {\n attach();\n } else {\n document.addEventListener(\n \"DOMContentLoaded\",\n () => {\n if (!destroyed) attach();\n },\n { once: true },\n );\n }\n\n const agent = new WebsiteAgent(config);\n\n let setOpen: ((open: boolean) => void) | undefined;\n let isOpen = config.inline || !!config.openByDefault;\n\n // Stable callbacks so re-rendering on update() doesn't re-fire the\n // component's open-control / open-change effects.\n const registerOpenControl = (fn: (open: boolean) => void) => {\n setOpen = fn;\n };\n const onOpenChange = (o: boolean) => {\n isOpen = o;\n };\n\n // Current config is mutable so update() can re-render appearance without\n // tearing down the agent (no re-bootstrap, no lost conversation).\n let current: MountConfig = config;\n const renderWidget = () => {\n render(\n <Widget\n agent={agent}\n config={current}\n registerOpenControl={registerOpenControl}\n onOpenChange={onOpenChange}\n />,\n root,\n );\n };\n renderWidget();\n\n // Best-effort session close when the visitor navigates away.\n const endOnUnload = () => {\n void agent.end();\n };\n window.addEventListener('beforeunload', endOnUnload);\n\n return {\n agent,\n open: () => setOpen?.(true),\n close: () => setOpen?.(false),\n toggle: () => setOpen?.(!isOpen),\n update: (partial) => {\n if (destroyed) return;\n current = { ...current, ...partial };\n if ('accentColor' in partial) applyAccent(current.accentColor);\n renderWidget();\n },\n destroy: () => {\n if (destroyed) return;\n destroyed = true;\n window.removeEventListener('beforeunload', endOnUnload);\n void agent.end();\n render(null, root);\n host.remove();\n },\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@invergent/website-widget",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.18.1",
|
|
4
4
|
"description": "AG-UI-compatible TypeScript client for the Surogates public-website channel. Wraps the publishable-key bootstrap, HttpOnly cookie, CSRF double-submit, and SSE streaming behind a standard AbstractAgent so widgets built for AG-UI work out of the box.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"surogates",
|