@neuronection/assistant-ui 0.53.0 → 0.53.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @neuronection/assistant-ui
2
2
 
3
+ ## 0.53.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`a37510a`](https://github.com/neuronection/assistant-ui/commit/a37510a192ab38f2086787bd0ae79088500d2bd8) Thanks [@constLiakos](https://github.com/constLiakos)! - **Default accent contrast (a11y):** the family blue `--as-accent` deepens from `oklch(0.55 0.16 258)` (#2d6fcd) to `oklch(0.52 0.17 258)` (#1c65c8), lifting white/tone-50 text on primary surfaces (user chat bubbles, primary buttons, links, focus rings) from 4.72:1 to **5.39:1** — WCAG AA for normal-size text with headroom. `--as-accent-strong` is unchanged and stays the darker hover tier.
8
+
9
+ **User bubble legibility:** two fixes for text inside primary user bubbles. `MarkdownSurface` no longer hard-codes `text-[var(--as-fg)]` on its root — it inherits color from its context, so user messages render in `--as-primary-fg` (white) instead of near-black text on the blue bubble; and user bubbles render `font-medium`, since 14px regular strokes read washed-out on saturated backgrounds even when the ratio passes.
10
+
11
+ Apps that brand their own accent (health-assistant overrides `--as-accent`) are unaffected by the token change. Apps consuming the default — or duplicating it, as study-assistant's palette currently does — should bump their `--primary` to `oklch(0.52 0.17 258)` to match.
12
+
3
13
  ## 0.53.0
4
14
 
5
15
  ### Minor Changes
@@ -1,3 +1,3 @@
1
- export { MarkdownCodeBlock, MarkdownSurface, MermaidDiagram } from './chunk-KQLKITZL.js';
1
+ export { MarkdownCodeBlock, MarkdownSurface, MermaidDiagram } from './chunk-KLCULTOQ.js';
2
2
  //# sourceMappingURL=chat-markdown.js.map
3
3
  //# sourceMappingURL=chat-markdown.js.map
@@ -1,3 +1,3 @@
1
- export { ChatMessage, ChatMessageEditor, MessageVariantSwitcher } from './chunk-NOAKHVBJ.js';
1
+ export { ChatMessage, ChatMessageEditor, MessageVariantSwitcher } from './chunk-56QSIK4Y.js';
2
2
  //# sourceMappingURL=chat-message.js.map
3
3
  //# sourceMappingURL=chat-message.js.map
@@ -1,3 +1,3 @@
1
- export { ChatSearchField, ChatTranscript } from './chunk-HXU6P5FD.js';
1
+ export { ChatSearchField, ChatTranscript } from './chunk-E2NNTHFB.js';
2
2
  //# sourceMappingURL=chat-transcript.js.map
3
3
  //# sourceMappingURL=chat-transcript.js.map
@@ -166,7 +166,7 @@ var ChatMessage = React3.forwardRef(
166
166
  className: cn(
167
167
  "relative flex max-w-[92%] flex-col gap-1.5 rounded-[var(--as-radius)] px-3 py-2 text-sm",
168
168
  compact && "px-2.5 py-1.5",
169
- isUser ? "rounded-br-[var(--as-radius-sm)] bg-[var(--as-primary)] text-[var(--as-primary-fg)]" : design === "flat" ? "max-w-full rounded-bl-[var(--as-radius-sm)] bg-transparent px-0 py-0" : "rounded-bl-[var(--as-radius-sm)] bg-[var(--as-muted)] text-[var(--as-fg)]"
169
+ isUser ? "rounded-br-[var(--as-radius-sm)] bg-[var(--as-primary)] font-medium text-[var(--as-primary-fg)]" : design === "flat" ? "max-w-full rounded-bl-[var(--as-radius-sm)] bg-transparent px-0 py-0" : "rounded-bl-[var(--as-radius-sm)] bg-[var(--as-muted)] text-[var(--as-fg)]"
170
170
  ),
171
171
  children: [
172
172
  reasoning ? /* @__PURE__ */ jsx("div", { className: "not-prose", children: reasoning }) : null,
@@ -260,5 +260,5 @@ var ChatMessage = React3.forwardRef(
260
260
  );
261
261
 
262
262
  export { ChatMessage, ChatMessageEditor, MessageVariantSwitcher };
263
- //# sourceMappingURL=chunk-NOAKHVBJ.js.map
264
- //# sourceMappingURL=chunk-NOAKHVBJ.js.map
263
+ //# sourceMappingURL=chunk-56QSIK4Y.js.map
264
+ //# sourceMappingURL=chunk-56QSIK4Y.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/chat-message/ChatMessageEditor.tsx","../src/components/chat-message/MessageVariantSwitcher.tsx","../src/components/chat-message/ChatMessage.tsx"],"names":["React","ChatMessageEditor","React2","MessageVariantSwitcher","jsxs","jsx","ChatMessage"],"mappings":"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","file":"chunk-NOAKHVBJ.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button/Button'\n\nexport interface ChatMessageEditorLabels {\n save: string\n cancel: string\n ariaLabel: string\n}\n\nexport interface ChatMessageEditorProps {\n value: string\n onValueChange: (value: string) => void\n /** Save & resend — branches the tree (family `edit` endpoint) and reruns the turn. */\n onSubmit: () => void\n onCancel: () => void\n submitDisabled?: boolean\n rows?: number\n labels?: Partial<ChatMessageEditorLabels>\n className?: string\n}\n\n/**\n * Inline user-prompt editor for the edit-and-resend flow (study pattern):\n * controlled textarea, Cmd/Ctrl+Enter saves, Escape cancels.\n */\nexport const ChatMessageEditor = React.forwardRef<HTMLDivElement, ChatMessageEditorProps>(\n function ChatMessageEditor(\n { value, onValueChange, onSubmit, onCancel, submitDisabled = false, rows = 3, labels, className },\n ref,\n ) {\n const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n onCancel()\n return\n }\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n if (!submitDisabled) {\n onSubmit()\n }\n }\n }\n\n return (\n <div ref={ref} data-as=\"chat-message-editor\" className={cn('as-anim-slide-up flex w-full flex-col gap-2', className)}>\n <textarea\n autoFocus\n value={value}\n rows={rows}\n aria-label={labels?.ariaLabel ?? 'Edit message'}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"w-full resize-y rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n />\n <div className=\"flex items-center justify-end gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n {labels?.cancel ?? 'Cancel'}\n </Button>\n <Button size=\"sm\" disabled={submitDisabled} onClick={onSubmit}>\n {labels?.save ?? 'Save & resend'}\n </Button>\n </div>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\n\nimport type { ChatMessageVariants } from '../chat-core/types'\nimport { cn } from '../../lib/utils'\n\nexport interface MessageVariantSwitcherLabels {\n group: string\n variantOf: (index: number, count: number) => string\n previous: string\n next: string\n}\n\nexport interface MessageVariantSwitcherProps {\n variants: ChatMessageVariants\n /** Flip the parent's active-child pointer to the sibling id (family `select` endpoint). */\n onSelect: (messageId: string) => void\n labels?: Partial<MessageVariantSwitcherLabels>\n className?: string\n}\n\n/**\n * The `‹ n/N ›` sibling-variant switcher under a branched message\n * (study's inline switcher, family branching contract).\n */\nexport const MessageVariantSwitcher = React.forwardRef<HTMLDivElement, MessageVariantSwitcherProps>(\n function MessageVariantSwitcher({ variants, onSelect, labels, className }, ref) {\n const { index, count, siblingIds } = variants\n const previousId = index > 1 ? siblingIds[index - 2] : undefined\n const nextId = index < count ? siblingIds[index] : undefined\n\n const select = (event: React.MouseEvent<HTMLButtonElement>, messageId: string | undefined) => {\n event.stopPropagation()\n if (messageId !== undefined) {\n onSelect(messageId)\n }\n }\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={labels?.group ?? 'Message variants'}\n data-as=\"message-variant-switcher\"\n className={cn('flex items-center gap-0.5 text-xs text-[var(--as-muted-fg)]', className)}\n >\n <button\n type=\"button\"\n disabled={previousId === undefined}\n aria-label={labels?.previous ?? 'Previous variant'}\n title={labels?.previous ?? 'Previous variant'}\n onClick={(event) => select(event, previousId)}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronLeft className=\"size-3.5\" aria-hidden />\n </button>\n <span className=\"tabular-nums\" title={labels?.variantOf?.(index, count) ?? `Variant ${index} of ${count}`}>\n {index}/{count}\n </span>\n <button\n type=\"button\"\n disabled={nextId === undefined}\n aria-label={labels?.next ?? 'Next variant'}\n title={labels?.next ?? 'Next variant'}\n onClick={(event) => select(event, nextId)}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronRight className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { Check, Copy, Pencil, RotateCcw, TriangleAlert } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button/Button'\nimport type { ChatError, ChatMessageVariants, ChatRole } from '../chat-core/types'\nimport { ChatMessageEditor, type ChatMessageEditorLabels } from './ChatMessageEditor'\nimport { MessageVariantSwitcher, type MessageVariantSwitcherLabels } from './MessageVariantSwitcher'\n\nexport interface ChatMessageAction {\n key: string\n label: string\n icon?: LucideIcon\n onClick: () => void\n danger?: boolean\n}\n\nexport interface ChatMessageActions {\n onCopy?: () => void\n /**\n * Controlled copied feedback for the copy action (check morph).\n * Uncontrolled by default: the library shows the check for 1.5 s\n * after each copy click.\n */\n copied?: boolean\n onEdit?: () => void\n onRegenerate?: () => void\n onRetry?: () => void\n /** Extra icon actions (app-specific). */\n extras?: ChatMessageAction[]\n /**\n * Extra node rendered inside the error card next to the Retry button —\n * e.g. an \"Open AI settings\" link when the error is a not-configured\n * failure. Rendered only while the error card is visible.\n */\n errorExtra?: React.ReactNode\n}\n\nexport interface ChatMessageLabels {\n copy: string\n copied: string\n edit: string\n regenerate: string\n retry: string\n interrupted: string\n error: string\n}\n\nexport interface ChatMessageProps {\n role: ChatRole\n /** Usually a `MarkdownSurface`; any node graph renders here. */\n content: React.ReactNode\n /** Thinking block slot (usually `ChatReasoning`). */\n reasoning?: React.ReactNode\n /** Tool cards / HITL cards below the content. */\n children?: React.ReactNode\n status?: 'streaming' | 'done' | 'error' | 'interrupted'\n error?: ChatError\n actions?: ChatMessageActions\n /** Edit-and-resend mode for user messages (renders `ChatMessageEditor`). */\n editing?: false | { value: string; onValueChange: (value: string) => void; onSubmit: () => void; onCancel: () => void; submitDisabled?: boolean }\n variants?: ChatMessageVariants\n onSelectVariant?: (messageId: string) => void\n /** Badge row (model, latency, tokens — app-defined). */\n meta?: React.ReactNode\n /** Deep-link chip row (career references, health citations). */\n chips?: React.ReactNode\n /** Attachment rail above the content. */\n attachments?: React.ReactNode\n /** Leading identity node beside the bubble (user: trailing). Render group-start avatars only when grouping transcripts. */\n avatar?: React.ReactNode\n /**\n * Visual design: `bubbles` (default) — paired role bubbles; `flat` —\n * assistant content renders as prose on the panel surface (user keeps\n * its bubble). Reasoning/tool cards are unaffected.\n */\n design?: 'bubbles' | 'flat'\n labels?: Partial<ChatMessageLabels & ChatMessageEditorLabels & MessageVariantSwitcherLabels>\n compact?: boolean\n className?: string\n}\n\nconst actionButtonClass =\n 'rounded-[var(--as-radius-sm)] p-1 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]'\n\nconst COPIED_FEEDBACK_MS = 1500\n\n/**\n * The family chat bubble: role-aligned, hover action row (copy / edit /\n * regenerate + app extras), variant switcher under branched messages,\n * reasoning and below-content slots, inline edit-and-resend, error +\n * interrupted states. Presentational — state lives app-side.\n */\nexport const ChatMessage = React.forwardRef<HTMLDivElement, ChatMessageProps>(\n function ChatMessage(\n {\n role,\n content,\n reasoning,\n children,\n status = 'done',\n error,\n actions,\n editing = false,\n variants,\n onSelectVariant,\n meta,\n chips,\n attachments,\n avatar,\n design = 'bubbles',\n labels,\n compact = false,\n className,\n },\n ref,\n ) {\n const isUser = role === 'user'\n const isSystem = role === 'system'\n const showActions =\n actions !== undefined && (actions.onCopy !== undefined || actions.onEdit !== undefined || actions.onRegenerate !== undefined || (actions.extras?.length ?? 0) > 0)\n const editorLabels = { save: labels?.save, cancel: labels?.cancel, ariaLabel: labels?.ariaLabel }\n const switcherLabels = { group: labels?.group, variantOf: labels?.variantOf, previous: labels?.previous, next: labels?.next }\n const [copiedAt, setCopiedAt] = React.useState<number | null>(null)\n const copied = actions?.copied ?? copiedAt !== null\n\n React.useEffect(() => {\n if (copiedAt === null) {\n return\n }\n const id = window.setTimeout(() => setCopiedAt(null), COPIED_FEEDBACK_MS)\n return () => window.clearTimeout(id)\n }, [copiedAt])\n\n const onCopyClick = () => {\n actions?.onCopy?.()\n if (actions?.copied === undefined) {\n setCopiedAt(Date.now())\n }\n }\n\n if (isSystem) {\n return (\n <div\n ref={ref}\n data-as=\"chat-message\"\n data-role={role}\n className={cn('flex justify-center', className)}\n >\n <div className=\"rounded-full border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-1 text-xs text-[var(--as-muted-fg)]\">\n {content}\n </div>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-as=\"chat-message\"\n data-role={role}\n data-status={status}\n data-design={design}\n className={cn('as-anim-message-in group/message flex w-full flex-col', isUser ? 'items-end' : 'items-start', className)}\n >\n {attachments ? <div className=\"mb-1.5 flex w-full flex-wrap justify-end gap-1.5\">{attachments}</div> : null}\n {(() => {\n const bubble = (\n <div\n className={cn(\n 'relative flex max-w-[92%] flex-col gap-1.5 rounded-[var(--as-radius)] px-3 py-2 text-sm',\n compact && 'px-2.5 py-1.5',\n isUser\n ? 'rounded-br-[var(--as-radius-sm)] bg-[var(--as-primary)] text-[var(--as-primary-fg)]'\n : design === 'flat'\n ? 'max-w-full rounded-bl-[var(--as-radius-sm)] bg-transparent px-0 py-0'\n : 'rounded-bl-[var(--as-radius-sm)] bg-[var(--as-muted)] text-[var(--as-fg)]',\n )}\n >\n {reasoning ? <div className=\"not-prose\">{reasoning}</div> : null}\n {editing ? (\n <ChatMessageEditor\n value={editing.value}\n onValueChange={editing.onValueChange}\n onSubmit={editing.onSubmit}\n onCancel={editing.onCancel}\n submitDisabled={editing.submitDisabled}\n labels={editorLabels}\n />\n ) : (\n <div\n key={variants && variants.count > 1 ? `variant-${variants.index}` : undefined}\n className={cn('min-w-0', variants && variants.count > 1 && 'as-anim-fade-swap')}\n >\n {content}\n </div>\n )}\n {status === 'interrupted' ? (\n <span className=\"as-anim-slide-up as-anim-pulse-once [--as-pulse-color:var(--as-warning)] self-start rounded-full bg-[var(--as-warning)]/15 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-[var(--as-warning)]\">\n {labels?.interrupted ?? 'Stopped'}\n </span>\n ) : null}\n {status === 'error' && error ? (\n <div\n role=\"alert\"\n className=\"as-anim-slide-up flex flex-col gap-1 rounded-[var(--as-radius)] border border-[var(--as-danger)]/40 bg-[var(--as-danger)]/10 px-2.5 py-1.5 text-xs text-[var(--as-danger)]\"\n >\n <span className=\"font-mono font-semibold uppercase tracking-wide\">{error.code}</span>\n <span className=\"whitespace-pre-wrap break-words\">{error.message}</span>\n {error.retryable && actions?.onRetry ? (\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Button variant=\"outline\" size=\"sm\" className=\"self-start\" onClick={actions.onRetry}>\n {labels?.retry ?? 'Retry'}\n </Button>\n {actions?.errorExtra}\n </div>\n ) : actions?.errorExtra ? (\n <div className=\"self-start\">{actions.errorExtra}</div>\n ) : null}\n </div>\n ) : null}\n {chips ? <div className=\"flex flex-wrap gap-1.5\">{chips}</div> : null}\n {children ? <div className=\"flex flex-col gap-1.5\">{children}</div> : null}\n {showActions && !editing ? (\n <div\n data-as=\"chat-message-actions\"\n className={cn(\n 'absolute top-1 flex items-center gap-0.5 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] p-0.5 shadow-[var(--as-shadow-1)]',\n isUser ? '-left-9' : '-right-9',\n )}\n >\n {actions?.onCopy ? (\n <button\n type=\"button\"\n className={actionButtonClass}\n aria-label={copied ? (labels?.copied ?? 'Copied') : (labels?.copy ?? 'Copy')}\n title={copied ? (labels?.copied ?? 'Copied') : (labels?.copy ?? 'Copy')}\n onClick={onCopyClick}\n >\n {copied ? (\n <Check className=\"as-anim-fade-swap size-3.5 text-[var(--as-success)]\" aria-hidden />\n ) : (\n <Copy className=\"size-3.5\" aria-hidden />\n )}\n </button>\n ) : null}\n {actions?.onEdit ? (\n <button type=\"button\" className={actionButtonClass} aria-label={labels?.edit ?? 'Edit'} title={labels?.edit ?? 'Edit'} onClick={actions.onEdit}>\n <Pencil className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {actions?.onRegenerate ? (\n <button type=\"button\" className={actionButtonClass} aria-label={labels?.regenerate ?? 'Regenerate'} title={labels?.regenerate ?? 'Regenerate'} onClick={actions.onRegenerate}>\n <RotateCcw className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {actions?.extras?.map((extra) => (\n <button\n key={extra.key}\n type=\"button\"\n className={cn(actionButtonClass, extra.danger && 'hover:text-[var(--as-danger)]')}\n aria-label={extra.label}\n title={extra.label}\n onClick={extra.onClick}\n >\n {extra.icon ? <extra.icon className=\"size-3.5\" aria-hidden /> : <TriangleAlert className=\"size-3.5\" aria-hidden />}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n )\n return avatar !== undefined ? (\n <div className={cn('flex w-full items-end gap-2', isUser ? 'flex-row-reverse' : 'flex-row')}>\n <div data-as=\"chat-message-avatar\" className=\"shrink-0 pb-1\">\n {avatar}\n </div>\n {bubble}\n </div>\n ) : (\n bubble\n )\n })()}\n {meta ? <div className=\"mt-0.5 flex flex-wrap items-center gap-1.5 px-1 text-[10px] text-[var(--as-muted-fg)]\">{meta}</div> : null}\n {variants && variants.count > 1 && onSelectVariant ? (\n <MessageVariantSwitcher variants={variants} onSelect={onSelectVariant} labels={switcherLabels} className=\"mt-0.5 px-1\" />\n ) : null}\n </div>\n )\n },\n)\n"]}
1
+ {"version":3,"sources":["../src/components/chat-message/ChatMessageEditor.tsx","../src/components/chat-message/MessageVariantSwitcher.tsx","../src/components/chat-message/ChatMessage.tsx"],"names":["React","ChatMessageEditor","React2","MessageVariantSwitcher","jsxs","jsx","ChatMessage"],"mappings":"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","file":"chunk-56QSIK4Y.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button/Button'\n\nexport interface ChatMessageEditorLabels {\n save: string\n cancel: string\n ariaLabel: string\n}\n\nexport interface ChatMessageEditorProps {\n value: string\n onValueChange: (value: string) => void\n /** Save & resend — branches the tree (family `edit` endpoint) and reruns the turn. */\n onSubmit: () => void\n onCancel: () => void\n submitDisabled?: boolean\n rows?: number\n labels?: Partial<ChatMessageEditorLabels>\n className?: string\n}\n\n/**\n * Inline user-prompt editor for the edit-and-resend flow (study pattern):\n * controlled textarea, Cmd/Ctrl+Enter saves, Escape cancels.\n */\nexport const ChatMessageEditor = React.forwardRef<HTMLDivElement, ChatMessageEditorProps>(\n function ChatMessageEditor(\n { value, onValueChange, onSubmit, onCancel, submitDisabled = false, rows = 3, labels, className },\n ref,\n ) {\n const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n onCancel()\n return\n }\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n if (!submitDisabled) {\n onSubmit()\n }\n }\n }\n\n return (\n <div ref={ref} data-as=\"chat-message-editor\" className={cn('as-anim-slide-up flex w-full flex-col gap-2', className)}>\n <textarea\n autoFocus\n value={value}\n rows={rows}\n aria-label={labels?.ariaLabel ?? 'Edit message'}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"w-full resize-y rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n />\n <div className=\"flex items-center justify-end gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n {labels?.cancel ?? 'Cancel'}\n </Button>\n <Button size=\"sm\" disabled={submitDisabled} onClick={onSubmit}>\n {labels?.save ?? 'Save & resend'}\n </Button>\n </div>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\n\nimport type { ChatMessageVariants } from '../chat-core/types'\nimport { cn } from '../../lib/utils'\n\nexport interface MessageVariantSwitcherLabels {\n group: string\n variantOf: (index: number, count: number) => string\n previous: string\n next: string\n}\n\nexport interface MessageVariantSwitcherProps {\n variants: ChatMessageVariants\n /** Flip the parent's active-child pointer to the sibling id (family `select` endpoint). */\n onSelect: (messageId: string) => void\n labels?: Partial<MessageVariantSwitcherLabels>\n className?: string\n}\n\n/**\n * The `‹ n/N ›` sibling-variant switcher under a branched message\n * (study's inline switcher, family branching contract).\n */\nexport const MessageVariantSwitcher = React.forwardRef<HTMLDivElement, MessageVariantSwitcherProps>(\n function MessageVariantSwitcher({ variants, onSelect, labels, className }, ref) {\n const { index, count, siblingIds } = variants\n const previousId = index > 1 ? siblingIds[index - 2] : undefined\n const nextId = index < count ? siblingIds[index] : undefined\n\n const select = (event: React.MouseEvent<HTMLButtonElement>, messageId: string | undefined) => {\n event.stopPropagation()\n if (messageId !== undefined) {\n onSelect(messageId)\n }\n }\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={labels?.group ?? 'Message variants'}\n data-as=\"message-variant-switcher\"\n className={cn('flex items-center gap-0.5 text-xs text-[var(--as-muted-fg)]', className)}\n >\n <button\n type=\"button\"\n disabled={previousId === undefined}\n aria-label={labels?.previous ?? 'Previous variant'}\n title={labels?.previous ?? 'Previous variant'}\n onClick={(event) => select(event, previousId)}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronLeft className=\"size-3.5\" aria-hidden />\n </button>\n <span className=\"tabular-nums\" title={labels?.variantOf?.(index, count) ?? `Variant ${index} of ${count}`}>\n {index}/{count}\n </span>\n <button\n type=\"button\"\n disabled={nextId === undefined}\n aria-label={labels?.next ?? 'Next variant'}\n title={labels?.next ?? 'Next variant'}\n onClick={(event) => select(event, nextId)}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronRight className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { Check, Copy, Pencil, RotateCcw, TriangleAlert } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button/Button'\nimport type { ChatError, ChatMessageVariants, ChatRole } from '../chat-core/types'\nimport { ChatMessageEditor, type ChatMessageEditorLabels } from './ChatMessageEditor'\nimport { MessageVariantSwitcher, type MessageVariantSwitcherLabels } from './MessageVariantSwitcher'\n\nexport interface ChatMessageAction {\n key: string\n label: string\n icon?: LucideIcon\n onClick: () => void\n danger?: boolean\n}\n\nexport interface ChatMessageActions {\n onCopy?: () => void\n /**\n * Controlled copied feedback for the copy action (check morph).\n * Uncontrolled by default: the library shows the check for 1.5 s\n * after each copy click.\n */\n copied?: boolean\n onEdit?: () => void\n onRegenerate?: () => void\n onRetry?: () => void\n /** Extra icon actions (app-specific). */\n extras?: ChatMessageAction[]\n /**\n * Extra node rendered inside the error card next to the Retry button —\n * e.g. an \"Open AI settings\" link when the error is a not-configured\n * failure. Rendered only while the error card is visible.\n */\n errorExtra?: React.ReactNode\n}\n\nexport interface ChatMessageLabels {\n copy: string\n copied: string\n edit: string\n regenerate: string\n retry: string\n interrupted: string\n error: string\n}\n\nexport interface ChatMessageProps {\n role: ChatRole\n /** Usually a `MarkdownSurface`; any node graph renders here. */\n content: React.ReactNode\n /** Thinking block slot (usually `ChatReasoning`). */\n reasoning?: React.ReactNode\n /** Tool cards / HITL cards below the content. */\n children?: React.ReactNode\n status?: 'streaming' | 'done' | 'error' | 'interrupted'\n error?: ChatError\n actions?: ChatMessageActions\n /** Edit-and-resend mode for user messages (renders `ChatMessageEditor`). */\n editing?: false | { value: string; onValueChange: (value: string) => void; onSubmit: () => void; onCancel: () => void; submitDisabled?: boolean }\n variants?: ChatMessageVariants\n onSelectVariant?: (messageId: string) => void\n /** Badge row (model, latency, tokens — app-defined). */\n meta?: React.ReactNode\n /** Deep-link chip row (career references, health citations). */\n chips?: React.ReactNode\n /** Attachment rail above the content. */\n attachments?: React.ReactNode\n /** Leading identity node beside the bubble (user: trailing). Render group-start avatars only when grouping transcripts. */\n avatar?: React.ReactNode\n /**\n * Visual design: `bubbles` (default) — paired role bubbles; `flat` —\n * assistant content renders as prose on the panel surface (user keeps\n * its bubble). Reasoning/tool cards are unaffected.\n */\n design?: 'bubbles' | 'flat'\n labels?: Partial<ChatMessageLabels & ChatMessageEditorLabels & MessageVariantSwitcherLabels>\n compact?: boolean\n className?: string\n}\n\nconst actionButtonClass =\n 'rounded-[var(--as-radius-sm)] p-1 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-surface-raised)] hover:text-[var(--as-fg)] focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]'\n\nconst COPIED_FEEDBACK_MS = 1500\n\n/**\n * The family chat bubble: role-aligned, hover action row (copy / edit /\n * regenerate + app extras), variant switcher under branched messages,\n * reasoning and below-content slots, inline edit-and-resend, error +\n * interrupted states. Presentational — state lives app-side.\n */\nexport const ChatMessage = React.forwardRef<HTMLDivElement, ChatMessageProps>(\n function ChatMessage(\n {\n role,\n content,\n reasoning,\n children,\n status = 'done',\n error,\n actions,\n editing = false,\n variants,\n onSelectVariant,\n meta,\n chips,\n attachments,\n avatar,\n design = 'bubbles',\n labels,\n compact = false,\n className,\n },\n ref,\n ) {\n const isUser = role === 'user'\n const isSystem = role === 'system'\n const showActions =\n actions !== undefined && (actions.onCopy !== undefined || actions.onEdit !== undefined || actions.onRegenerate !== undefined || (actions.extras?.length ?? 0) > 0)\n const editorLabels = { save: labels?.save, cancel: labels?.cancel, ariaLabel: labels?.ariaLabel }\n const switcherLabels = { group: labels?.group, variantOf: labels?.variantOf, previous: labels?.previous, next: labels?.next }\n const [copiedAt, setCopiedAt] = React.useState<number | null>(null)\n const copied = actions?.copied ?? copiedAt !== null\n\n React.useEffect(() => {\n if (copiedAt === null) {\n return\n }\n const id = window.setTimeout(() => setCopiedAt(null), COPIED_FEEDBACK_MS)\n return () => window.clearTimeout(id)\n }, [copiedAt])\n\n const onCopyClick = () => {\n actions?.onCopy?.()\n if (actions?.copied === undefined) {\n setCopiedAt(Date.now())\n }\n }\n\n if (isSystem) {\n return (\n <div\n ref={ref}\n data-as=\"chat-message\"\n data-role={role}\n className={cn('flex justify-center', className)}\n >\n <div className=\"rounded-full border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-1 text-xs text-[var(--as-muted-fg)]\">\n {content}\n </div>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-as=\"chat-message\"\n data-role={role}\n data-status={status}\n data-design={design}\n className={cn('as-anim-message-in group/message flex w-full flex-col', isUser ? 'items-end' : 'items-start', className)}\n >\n {attachments ? <div className=\"mb-1.5 flex w-full flex-wrap justify-end gap-1.5\">{attachments}</div> : null}\n {(() => {\n const bubble = (\n <div\n className={cn(\n 'relative flex max-w-[92%] flex-col gap-1.5 rounded-[var(--as-radius)] px-3 py-2 text-sm',\n compact && 'px-2.5 py-1.5',\n isUser\n ? 'rounded-br-[var(--as-radius-sm)] bg-[var(--as-primary)] font-medium text-[var(--as-primary-fg)]'\n : design === 'flat'\n ? 'max-w-full rounded-bl-[var(--as-radius-sm)] bg-transparent px-0 py-0'\n : 'rounded-bl-[var(--as-radius-sm)] bg-[var(--as-muted)] text-[var(--as-fg)]',\n )}\n >\n {reasoning ? <div className=\"not-prose\">{reasoning}</div> : null}\n {editing ? (\n <ChatMessageEditor\n value={editing.value}\n onValueChange={editing.onValueChange}\n onSubmit={editing.onSubmit}\n onCancel={editing.onCancel}\n submitDisabled={editing.submitDisabled}\n labels={editorLabels}\n />\n ) : (\n <div\n key={variants && variants.count > 1 ? `variant-${variants.index}` : undefined}\n className={cn('min-w-0', variants && variants.count > 1 && 'as-anim-fade-swap')}\n >\n {content}\n </div>\n )}\n {status === 'interrupted' ? (\n <span className=\"as-anim-slide-up as-anim-pulse-once [--as-pulse-color:var(--as-warning)] self-start rounded-full bg-[var(--as-warning)]/15 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-[var(--as-warning)]\">\n {labels?.interrupted ?? 'Stopped'}\n </span>\n ) : null}\n {status === 'error' && error ? (\n <div\n role=\"alert\"\n className=\"as-anim-slide-up flex flex-col gap-1 rounded-[var(--as-radius)] border border-[var(--as-danger)]/40 bg-[var(--as-danger)]/10 px-2.5 py-1.5 text-xs text-[var(--as-danger)]\"\n >\n <span className=\"font-mono font-semibold uppercase tracking-wide\">{error.code}</span>\n <span className=\"whitespace-pre-wrap break-words\">{error.message}</span>\n {error.retryable && actions?.onRetry ? (\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Button variant=\"outline\" size=\"sm\" className=\"self-start\" onClick={actions.onRetry}>\n {labels?.retry ?? 'Retry'}\n </Button>\n {actions?.errorExtra}\n </div>\n ) : actions?.errorExtra ? (\n <div className=\"self-start\">{actions.errorExtra}</div>\n ) : null}\n </div>\n ) : null}\n {chips ? <div className=\"flex flex-wrap gap-1.5\">{chips}</div> : null}\n {children ? <div className=\"flex flex-col gap-1.5\">{children}</div> : null}\n {showActions && !editing ? (\n <div\n data-as=\"chat-message-actions\"\n className={cn(\n 'absolute top-1 flex items-center gap-0.5 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] p-0.5 shadow-[var(--as-shadow-1)]',\n isUser ? '-left-9' : '-right-9',\n )}\n >\n {actions?.onCopy ? (\n <button\n type=\"button\"\n className={actionButtonClass}\n aria-label={copied ? (labels?.copied ?? 'Copied') : (labels?.copy ?? 'Copy')}\n title={copied ? (labels?.copied ?? 'Copied') : (labels?.copy ?? 'Copy')}\n onClick={onCopyClick}\n >\n {copied ? (\n <Check className=\"as-anim-fade-swap size-3.5 text-[var(--as-success)]\" aria-hidden />\n ) : (\n <Copy className=\"size-3.5\" aria-hidden />\n )}\n </button>\n ) : null}\n {actions?.onEdit ? (\n <button type=\"button\" className={actionButtonClass} aria-label={labels?.edit ?? 'Edit'} title={labels?.edit ?? 'Edit'} onClick={actions.onEdit}>\n <Pencil className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {actions?.onRegenerate ? (\n <button type=\"button\" className={actionButtonClass} aria-label={labels?.regenerate ?? 'Regenerate'} title={labels?.regenerate ?? 'Regenerate'} onClick={actions.onRegenerate}>\n <RotateCcw className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {actions?.extras?.map((extra) => (\n <button\n key={extra.key}\n type=\"button\"\n className={cn(actionButtonClass, extra.danger && 'hover:text-[var(--as-danger)]')}\n aria-label={extra.label}\n title={extra.label}\n onClick={extra.onClick}\n >\n {extra.icon ? <extra.icon className=\"size-3.5\" aria-hidden /> : <TriangleAlert className=\"size-3.5\" aria-hidden />}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n )\n return avatar !== undefined ? (\n <div className={cn('flex w-full items-end gap-2', isUser ? 'flex-row-reverse' : 'flex-row')}>\n <div data-as=\"chat-message-avatar\" className=\"shrink-0 pb-1\">\n {avatar}\n </div>\n {bubble}\n </div>\n ) : (\n bubble\n )\n })()}\n {meta ? <div className=\"mt-0.5 flex flex-wrap items-center gap-1.5 px-1 text-[10px] text-[var(--as-muted-fg)]\">{meta}</div> : null}\n {variants && variants.count > 1 && onSelectVariant ? (\n <MessageVariantSwitcher variants={variants} onSelect={onSelectVariant} labels={switcherLabels} className=\"mt-0.5 px-1\" />\n ) : null}\n </div>\n )\n },\n)\n"]}
@@ -1,5 +1,5 @@
1
- import { MarkdownSurface } from './chunk-KQLKITZL.js';
2
- import { ChatMessage } from './chunk-NOAKHVBJ.js';
1
+ import { MarkdownSurface } from './chunk-KLCULTOQ.js';
2
+ import { ChatMessage } from './chunk-56QSIK4Y.js';
3
3
  import { cn } from './chunk-RVVXVTH3.js';
4
4
  import * as React2 from 'react';
5
5
  import { Search, X, ChevronUp, ChevronDown, Square, ArrowDown } from 'lucide-react';
@@ -475,5 +475,5 @@ var ChatTranscript = React2.forwardRef(
475
475
  );
476
476
 
477
477
  export { ChatSearchField, ChatTranscript };
478
- //# sourceMappingURL=chunk-HXU6P5FD.js.map
479
- //# sourceMappingURL=chunk-HXU6P5FD.js.map
478
+ //# sourceMappingURL=chunk-E2NNTHFB.js.map
479
+ //# sourceMappingURL=chunk-E2NNTHFB.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/chat-transcript/ChatSearchField.tsx","../src/components/chat-transcript/ChatTranscript.tsx"],"names":["React","ChatSearchField","jsx","ChatTranscript","jsxs"],"mappings":";;;;;;;;;AAiCO,IAAM,eAAA,GAAwBA,MAAA,CAAA,UAAA;AAAA,EACnC,SAASC,gBAAAA,CACP,EAAE,KAAA,EAAO,aAAA,EAAe,UAAA,EAAY,WAAA,EAAa,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,SAAA,EAAU,EACvF,GAAA,EACA;AACA,IAAA,MAAM,UAAgBD,MAAA,CAAA,KAAA,EAAM;AAE5B,IAAA,MAAM,SAAA,GAA0D,CAAC,KAAA,KAAU;AACzE,MAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC1B,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,aAAA,CAAc,EAAE,CAAA;AAChB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAA,CAAM,QAAQ,OAAA,EAAS;AACzB,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,IAAI,MAAM,QAAA,EAAU;AAClB,UAAA,UAAA,IAAa;AAAA,QACf,CAAA,MAAO;AACL,UAAA,MAAA,IAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,UAAA,GAAa,UAAA,KAAe,MAAA,IAAa,UAAA,GAAa,CAAA;AAC5D,IAAA,MAAM,OAAA,GACJ,UAAA,KAAe,MAAA,GACX,IAAA,GACA,UAAA,GACE,CAAA,EAAA,CAAI,WAAA,IAAe,CAAA,IAAK,CAAC,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,GACvC,GAAA;AAER,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAQ,mBAAA;AAAA,QACR,SAAA,EAAW,EAAA;AAAA,UACT,sHAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,6CAAA,EAA8C,aAAA,EAAW,IAAA,EAAC,CAAA;AAAA,0BAC5E,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,EAAA,EAAI,OAAA;AAAA,cACJ,IAAA,EAAK,MAAA;AAAA,cACL,KAAA,EAAO,KAAA;AAAA,cACP,WAAA,EAAa,QAAQ,WAAA,IAAe,qBAAA;AAAA,cACpC,YAAA,EAAY,QAAQ,MAAA,IAAU,qBAAA;AAAA,cAC9B,UAAU,CAAC,KAAA,KAAU,aAAA,CAAc,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,cACrD,SAAA;AAAA,cACA,SAAA,EAAU;AAAA;AAAA,WACZ;AAAA,UACC,YAAY,IAAA,mBACX,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,YAAA,EAAY,QAAQ,OAAA,IAAW,SAAA;AAAA,cAC/B,SAAA,EAAU,uEAAA;AAAA,cAET,QAAA,EAAA;AAAA;AAAA,WACH,GACE,IAAA;AAAA,UACH,UAAU,EAAA,mBACT,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,YAAA,EAAY,QAAQ,KAAA,IAAS,cAAA;AAAA,cAC7B,OAAA,EAAS,MAAM,aAAA,CAAc,EAAE,CAAA;AAAA,cAC/B,SAAA,EAAU,+MAAA;AAAA,cAEV,QAAA,kBAAA,GAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC;AAAA;AAAA,WACtC,GACE,IAAA;AAAA,0BACJ,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,YAAA,EAAY,QAAQ,QAAA,IAAY,gBAAA;AAAA,cAChC,UAAU,CAAC,UAAA;AAAA,cACX,OAAA,EAAS,UAAA;AAAA,cACT,SAAA,EAAU,gQAAA;AAAA,cAEV,QAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC;AAAA;AAAA,WAC9C;AAAA,0BACA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,YAAA,EAAY,QAAQ,IAAA,IAAQ,YAAA;AAAA,cAC5B,UAAU,CAAC,UAAA;AAAA,cACX,OAAA,EAAS,MAAA;AAAA,cACT,SAAA,EAAU,gQAAA;AAAA,cAEV,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC;AAAA;AAAA;AAChD;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AC/GA,SAAS,OAAO,KAAA,EAA6D;AAC3E,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,iBAAiB,IAAA,EAAM;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,IAAI,KAAK,KAAK,CAAA;AAAA,EACvB;AACA,EAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,KAAK,CAAA;AAC7B,EAAA,OAAO,OAAO,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,IAAI,MAAA,GAAY,MAAA;AACtD;AAuEA,SAAS,iBAAA,CAAkB,OAAA,EAA0B,MAAA,EAA4B,KAAA,EAAgB;AAC/F,EAAA,uBACEE,GAAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,MAAA;AAAA,MACA,OAAA,kBAASA,GAAAA,CAAC,eAAA,EAAA,EAAgB,KAAA,EAAO,OAAA,CAAQ,OAAA,EAAS,SAAA,EAAW,OAAA,CAAQ,MAAA,KAAW,WAAA,EAAa,KAAA,EAAc,CAAA;AAAA,MAC3G,UAAU,OAAA,CAAQ;AAAA;AAAA,GACpB;AAEJ;AASO,IAAM,cAAA,GAAuB,MAAA,CAAA,UAAA;AAAA,EAClC,SAASC,eAAAA,CACP;AAAA,IACE,KAAA;AAAA,IACA,UAAA;AAAA,IACA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA,GAAa,IAAA;AAAA,IACb,iBAAA,GAAoB,GAAA;AAAA,IACpB,WAAA,GAAc,KAAA;AAAA,IACd,gBAAA,GAAmB,KAAA;AAAA,IACnB,MAAA,GAAS,SAAA;AAAA,IACT,MAAA;AAAA,IACA,kBAAA,GAAqB,KAAA;AAAA,IACrB,UAAA;AAAA,IACA,cAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,KAEF,GAAA,EACA;AACA,IAAA,MAAM,SAAA,GAAkB,cAA8B,IAAI,CAAA;AAC1D,IAAA,MAAM,WAAA,GAAoB,cAAO,IAAI,CAAA;AACrC,IAAA,MAAM,gBAAA,GAAyB,cAAO,CAAC,CAAA;AACvC,IAAA,MAAM,aAAA,GAAsB,cAAsB,IAAI,CAAA;AACtD,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,gBAAS,KAAK,CAAA;AACpD,IAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAU,gBAAS,KAAK,CAAA;AAClD,IAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAU,gBAAS,CAAC,CAAA;AAC5C,IAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAU,gBAAS,EAAE,CAAA;AACzD,IAAA,MAAM,gBAAA,GAAyB,cAAO,EAAE,CAAA;AACxC,IAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAU,gBAAS,CAAC,CAAA;AACxD,IAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAU,gBAAwB,IAAI,CAAA;AAEhE,IAAA,MAAM,eAAe,MAAA,EAAQ,KAAA,CAAM,IAAA,EAAK,CAAE,aAAY,IAAK,EAAA;AAC3D,IAAA,MAAM,aAAA,GAAsB,eAAQ,MAAM;AACxC,MAAA,IAAI,iBAAiB,EAAA,EAAI;AACvB,QAAA,OAAO,EAAC;AAAA,MACV;AACA,MAAA,OAAO,KAAA,CACJ,GAAA;AAAA,QAAI,CAAC,OAAA,EAAS,KAAA,KACb,OAAA,CAAQ,OAAA,CAAQ,aAAY,CAAE,QAAA,CAAS,YAAY,CAAA,GAAI,KAAA,GAAQ;AAAA,OACjE,CACC,MAAA,CAAO,CAAC,KAAA,KAAU,SAAS,CAAC,CAAA;AAAA,IACjC,CAAA,EAAG,CAAC,KAAA,EAAO,YAAY,CAAC,CAAA;AAExB,IAAM,iBAAU,MAAM;AACpB,MAAA,eAAA,CAAgB,CAAC,CAAA;AACjB,MAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,QAAA,WAAA,CAAY,CAAC,CAAA;AAAA,MACf;AAAA,IAEF,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAEjB,IAAM,iBAAU,MAAM;AACpB,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAK,MAAA,CAAO,UAAA,CAAW,MAAM,UAAA,CAAW,IAAI,GAAG,IAAI,CAAA;AACzD,MAAA,OAAO,MAAM,MAAA,CAAO,YAAA,CAAa,EAAE,CAAA;AAAA,IACrC,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,IAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KAAkB;AACrC,MAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,QAAA;AAAA,MACF;AACA,MAAA,MAAM,WAAY,KAAA,GAAQ,aAAA,CAAc,MAAA,GAAU,aAAA,CAAc,UAAU,aAAA,CAAc,MAAA;AACxF,MAAA,eAAA,CAAgB,OAAO,CAAA;AACvB,MAAA,MAAM,YAAA,GAAe,cAAc,OAAO,CAAA;AAC1C,MAAA,MAAM,YAAY,YAAA,KAAiB,MAAA,GAAY,KAAA,CAAM,YAAY,GAAG,EAAA,GAAK,MAAA;AACzE,MAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,QAAA;AAAA,MACF;AACA,MAAA,UAAA,CAAW,SAAS,CAAA;AACpB,MAAA,IAAI,CAAC,WAAA,EAAa;AAChB,QAAA,MAAM,MAAM,SAAA,CAAU,OAAA,EAAS,aAAA,CAAc,CAAA,kBAAA,EAAqB,SAAS,CAAA,EAAA,CAAI,CAAA;AAC/E,QAAA,GAAA,EAAK,eAAe,EAAE,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,UAAU,CAAA;AAAA,MAC7D;AAAA,IACF,CAAA;AAEA,IAAM,iBAAU,MAAM;AACpB,MAAA,IAAI,cAAA,KAAmB,IAAA,IAAQ,cAAA,KAAmB,MAAA,EAAW;AAC3D,QAAA;AAAA,MACF;AACA,MAAA,UAAA,CAAW,cAAc,CAAA;AACzB,MAAA,IAAI,CAAC,WAAA,EAAa;AAChB,QAAA,MAAM,MAAM,SAAA,CAAU,OAAA,EAAS,aAAA,CAAc,CAAA,kBAAA,EAAqB,cAAc,CAAA,EAAA,CAAI,CAAA;AACpF,QAAA,GAAA,EAAK,eAAe,EAAE,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,UAAU,CAAA;AAAA,MAC7D;AAAA,IACF,CAAA,EAAG,CAAC,cAAA,EAAgB,WAAW,CAAC,CAAA;AAEhC,IAAA,MAAM,MAAA,GAAS,CAAC,OAAA,KAA4C;AAC1D,MAAA,IAAI,OAAA,CAAQ,cAAc,MAAA,EAAW;AACnC,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA;AACrC,MAAA,OAAO,IAAA,KAAS,MAAA,GACZ,IAAA,GACA,CAAA,EAAG,KAAK,WAAA,EAAa,CAAA,CAAA,EAAI,IAAA,CAAK,QAAA,EAAU,CAAA,CAAA,EAAI,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,IAChE,CAAA;AAEA,IAAA,MAAM,QAAA,GAAW,CAAC,OAAA,KAA4C;AAC5D,MAAA,IAAI,OAAA,CAAQ,cAAc,MAAA,EAAW;AACnC,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA;AACrC,MAAA,IAAI,SAAS,MAAA,EAAW;AACtB,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,MAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAAgB,IAAI,KAAK,KAAA,CAAM,WAAA,EAAY,EAAG,KAAA,CAAM,UAAS,EAAG,KAAA,CAAM,OAAA,EAAS,EAAE,OAAA,EAAQ;AAC1G,MAAA,MAAM,OAAA,GAAU,KAAK,KAAA,CAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,GAAI,OAAA,CAAQ,IAAI,CAAA,IAAK,KAAU,CAAA;AACtE,MAAA,IAAI,YAAY,CAAA,EAAG;AACjB,QAAA,OAAO,QAAQ,KAAA,IAAS,OAAA;AAAA,MAC1B;AACA,MAAA,IAAI,YAAY,CAAA,EAAG;AACjB,QAAA,OAAO,QAAQ,SAAA,IAAa,WAAA;AAAA,MAC9B;AACA,MAAA,OAAO,eAAe,MAAA,GAAY,UAAA,CAAW,IAAI,CAAA,GAAI,MAAA,CAAO,MAAM,aAAa,CAAA;AAAA,IACjF,CAAA;AAEA,IAAA,MAAM,WAAW,MAAM;AACrB,MAAA,MAAM,UAAU,SAAA,CAAU,OAAA;AAC1B,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,YAAA,GAAe,OAAA,CAAQ,YAAY,OAAA,CAAQ,YAAA;AACpE,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,SAAA,GAAY,gBAAA,CAAiB,OAAA;AACrD,MAAA,gBAAA,CAAiB,UAAU,OAAA,CAAQ,SAAA;AACnC,MAAA,MAAM,QAAA,GAAW,QAAA,IAAY,iBAAA,IAAqB,EAAE,WAAW,QAAA,GAAW,CAAA,CAAA;AAC1E,MAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AACtB,MAAA,WAAA,CAAY,OAAA,CAAQ,YAAA,GAAe,OAAA,CAAQ,YAAA,IAAgB,CAAC,QAAQ,CAAA;AACpE,MAAA,UAAA,CAAW,OAAA,CAAQ,YAAY,CAAC,CAAA;AAChC,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,SAAA,CAAU,CAAC,CAAA;AAAA,MACb;AAAA,IACF,CAAA;AAUA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,MAAM,UAAU,SAAA,CAAU,OAAA;AAC1B,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA;AAAA,MACF;AACA,MAAA,WAAA,CAAY,OAAA,GAAU,KAAA;AACtB,MAAA,WAAA,CAAY,OAAA,CAAQ,YAAA,GAAe,OAAA,CAAQ,YAAY,CAAA;AAAA,IACzD,CAAA;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAA4C;AAC3D,MAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,QAAA,WAAA,EAAY;AAAA,MACd;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KAA4C;AAChE,MAAA,aAAA,CAAc,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,CAAC,GAAG,OAAA,IAAW,IAAA;AAAA,IACvD,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KAA4C;AAC/D,MAAA,MAAM,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAA;AAC5B,MAAA,IAAI,MAAM,MAAA,EAAW;AACnB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,aAAA,CAAc,OAAA,KAAY,IAAA,IAAQ,CAAA,GAAI,cAAc,OAAA,EAAS;AAC/D,QAAA,WAAA,EAAY;AAAA,MACd;AACA,MAAA,aAAA,CAAc,OAAA,GAAU,CAAA;AAAA,IAC1B,CAAA;AAEA,IAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAA+C;AAChE,MAAA,IACE,KAAA,CAAM,GAAA,KAAQ,SAAA,IACd,KAAA,CAAM,GAAA,KAAQ,QAAA,IACd,KAAA,CAAM,GAAA,KAAQ,MAAA,IACb,KAAA,CAAM,GAAA,KAAQ,GAAA,IAAO,MAAM,QAAA,EAC5B;AACA,QAAA,WAAA,EAAY;AAAA,MACd;AAAA,IACF,CAAA;AAEA,IAAM,iBAAU,MAAM;AACpB,MAAA,MAAM,UAAU,SAAA,CAAU,OAAA;AAC1B,MAAA,IAAI,YAAY,IAAA,IAAQ,CAAC,UAAA,IAAc,CAAC,YAAY,OAAA,EAAS;AAC3D,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAA,GAAQ,sBAAsB,MAAM;AACxC,QAAA,OAAA,CAAQ,YAAY,OAAA,CAAQ,YAAA;AAAA,MAC9B,CAAC,CAAA;AACD,MAAA,OAAO,MAAM,qBAAqB,KAAK,CAAA;AAAA,IACzC,CAAC,CAAA;AAED,IAAM,iBAAU,MAAM;AACpB,MAAA,IAAI,gBAAA,CAAiB,YAAY,EAAA,EAAI;AACnC,QAAA,gBAAA,CAAiB,UAAU,KAAA,CAAM,MAAA;AACjC,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAA,CAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS;AAC3C,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,gBAAA,CAAiB,OAAO,CAAA;AAClD,QAAA,gBAAA,CAAiB,UAAU,KAAA,CAAM,MAAA;AACjC,QAAA,MAAM,cAAA,GAAiB,MAAM,MAAA,CAAO,CAAC,YAAY,OAAA,CAAQ,IAAA,KAAS,MAAM,CAAA,CAAE,MAAA;AAC1E,QAAA,IAAI,cAAA,GAAiB,CAAA,IAAK,CAAC,WAAA,CAAY,OAAA,EAAS;AAC9C,UAAA,SAAA,CAAU,CAAC,KAAA,KAAU,KAAA,GAAQ,cAAc,CAAA;AAAA,QAC7C;AACA,QAAA,IAAI,MAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,EAAG,SAAS,MAAA,EAAQ;AAC5C,UAAA,eAAA,CAAgB,MAAA,EAAQ,WAAW,mBAAmB,CAAA;AAAA,QACxD;AACA,QAAA;AAAA,MACF;AACA,MAAA,gBAAA,CAAiB,UAAU,KAAA,CAAM,MAAA;AAAA,IACnC,CAAA,EAAG,CAAC,KAAA,EAAO,MAAM,CAAC,CAAA;AAElB,IAAA,MAAM,iBAAiB,MAAM;AAC3B,MAAA,MAAM,UAAU,SAAA,CAAU,OAAA;AAC1B,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,SAAA,CAAU,CAAC,CAAA;AACX,QAAA,OAAA,CAAQ,SAAS,EAAE,GAAA,EAAK,QAAQ,YAAA,EAAc,QAAA,EAAU,UAAU,CAAA;AAAA,MACpE;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAA0C;AAC1D,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAK,CAAA,EAAG,IAAA;AAC3B,MAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,QAAA,EAAU;AAC3C,QAAA,OAAO,QAAA;AAAA,MACT;AACA,MAAA,MAAM,QAAA,GAAW,KAAA,GAAQ,CAAA,IAAK,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA,EAAG,IAAA,KAAS,IAAA,IAAQ,KAAA,CAAM,KAAA,GAAQ,CAAC,GAAG,IAAA,KAAS,QAAA;AAC5F,MAAA,MAAM,QAAA,GAAW,KAAA,GAAQ,KAAA,CAAM,MAAA,GAAS,KAAK,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA,EAAG,SAAS,IAAA,IAAQ,KAAA,CAAM,KAAA,GAAQ,CAAC,GAAG,IAAA,KAAS,QAAA;AAC3G,MAAA,IAAI,YAAY,QAAA,EAAU;AACxB,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,OAAA;AAAA,MACT;AACA,MAAA,OAAO,QAAA;AAAA,IACT,CAAA;AAEA,IAAA,MAAM,SAAA,GAAY,CAAC,OAAA,EAA0B,KAAA,KAAkB;AAC7D,MAAA,MAAM,GAAA,GAAM,gBAAA,GAAmB,QAAA,CAAS,KAAK,CAAA,GAAI,MAAA;AACjD,MAAA,MAAM,IAAA,GAAO,aACT,UAAA,CAAW,OAAA,EAAS,OAAO,GAAA,EAAK,YAAA,KAAiB,EAAA,GAAK,MAAA,GAAY,MAAA,EAAQ,KAAA,CAAM,MAAM,CAAA,GACtF,iBAAA,CAAkB,OAAA,EAAS,MAAA,EAAQ,YAAA,KAAiB,KAAK,MAAA,GAAY,MAAA,EAAQ,KAAA,CAAM,IAAA,EAAM,CAAA;AAC7F,MAAA,MAAM,OAAA,GAAU,GAAA,KAAQ,KAAA,IAAS,GAAA,KAAQ,KAAA;AACzC,MAAA,uBACED,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,mBAAiB,OAAA,CAAQ,EAAA;AAAA,UACzB,gBAAA,EAAgB,GAAA;AAAA,UAChB,mBAAA,EAAmB,OAAA,CAAQ,EAAA,KAAO,OAAA,IAAW,MAAA;AAAA,UAC7C,SAAA,EAAW,EAAA,CAAG,gBAAA,IAAoB,OAAA,IAAW,OAAO,CAAA;AAAA,UAEnD,QAAA,EAAA;AAAA,SAAA;AAAA,QANI,OAAA,CAAQ;AAAA,OAOf;AAAA,IAEJ,CAAA;AAEA,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,MAAA,IAAU,IAAA,KAAS,SAAY,CAAA,GAAI,CAAA,CAAA;AAC1D,IAAA,MAAM,cAAc,cAAA,CAAe;AAAA,MACjC,KAAA,EAAO,cAAc,QAAA,GAAW,CAAA;AAAA,MAChC,gBAAA,EAAkB,MAAM,SAAA,CAAU,OAAA;AAAA,MAClC,cAAc,MAAM,GAAA;AAAA,MACpB,QAAA,EAAU,CAAA;AAAA,MACV,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,GAAA;AAAI,KACxC,CAAA;AAED,IAAA,MAAM,SAAA,GAAY,QAAQ,cAAA,IAAkB,kBAAA;AAC5C,IAAA,MAAM,aAAA,GACJ,MAAA,GAAS,CAAA,GAAI,CAAA,EAAG,SAAS,CAAA,QAAA,EAAM,MAAM,CAAA,CAAA,EAAI,MAAA,EAAQ,WAAA,IAAe,cAAc,CAAA,CAAA,GAAK,SAAA;AAErF,IAAA,uBACEE,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAQ,iBAAA;AAAA,QACR,gBAAc,gBAAA,IAAoB,MAAA;AAAA,QAClC,iBAAe,OAAA,IAAW,MAAA;AAAA,QAC1B,SAAA,EAAW,EAAA,CAAG,uCAAA,EAAyC,SAAS,CAAA;AAAA,QAE/D,QAAA,EAAA;AAAA,UAAA,MAAA,mBACCF,GAAAA;AAAA,YAAC,eAAA;AAAA,YAAA;AAAA,cACC,OAAO,MAAA,CAAO,KAAA;AAAA,cACd,eAAe,MAAA,CAAO,aAAA;AAAA,cACtB,YAAY,aAAA,CAAc,MAAA;AAAA,cAC1B,WAAA,EAAa,YAAA;AAAA,cACb,UAAA,EAAY,MAAM,WAAA,CAAY,YAAA,GAAe,CAAC,CAAA;AAAA,cAC9C,MAAA,EAAQ,MAAM,WAAA,CAAY,YAAA,GAAe,CAAC,CAAA;AAAA,cAC1C,QACE,MAAA,GACK;AAAA,gBACC,QAAQ,MAAA,CAAO,MAAA;AAAA,gBACf,aAAa,MAAA,CAAO,iBAAA;AAAA,gBACpB,UAAU,MAAA,CAAO,aAAA;AAAA,gBACjB,MAAM,MAAA,CAAO,SAAA;AAAA,gBACb,OAAO,MAAA,CAAO,WAAA;AAAA,gBACd,SAAS,MAAA,CAAO;AAAA,eAClB,GACA,MAAA;AAAA,cAEN,SAAA,EAAU;AAAA;AAAA,WACZ,GACE,IAAA;AAAA,0BACJA,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,SAAA;AAAA,cACL,QAAA;AAAA,cACA,OAAA;AAAA,cACA,YAAA;AAAA,cACA,WAAA;AAAA,cACA,SAAA;AAAA,cACA,IAAA,EAAK,KAAA;AAAA,cACL,YAAA,EAAY,QAAQ,GAAA,IAAO,cAAA;AAAA,cAC3B,aAAW,IAAA,KAAS,MAAA;AAAA,cACpB,SAAA,EAAU,6DAAA;AAAA,cAET,QAAA,EAAA,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,IAAA,KAAS,yBAC9BA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wFAAA,EACZ,QAAA,EAAA,UAAA,KAAe,MAAA,EAAQ,KAAA,IAAS,2BACnC,CAAA,GACE,WAAA,mBACFA,GAAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,MAAA,EAAQ,YAAY,YAAA,EAAa,EAAG,QAAA,EAAU,UAAA,IACzD,QAAA,EAAA,WAAA,CAAY,eAAA,EAAgB,CAAE,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC1C,gBAAA,MAAM,MAAA,GAAS,GAAA,CAAI,KAAA,IAAS,KAAA,CAAM,MAAA;AAClC,gBAAA,MAAM,IAAA,GAAO,SAAS,IAAA,GAAO,SAAA,CAAU,MAAM,GAAA,CAAI,KAAK,CAAA,EAAI,GAAA,CAAI,KAAK,CAAA;AACnE,gBAAA,uBACEA,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBAEC,cAAY,GAAA,CAAI,KAAA;AAAA,oBAChB,KAAK,WAAA,CAAY,cAAA;AAAA,oBACjB,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA,EAAY,KAAK,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAW,CAAA,WAAA,EAAc,GAAA,CAAI,KAAK,CAAA,GAAA,CAAA,EAAM;AAAA,oBACvG,SAAA,EAAU,aAAA;AAAA,oBAET,QAAA,EAAA;AAAA,mBAAA;AAAA,kBANI,GAAA,CAAI;AAAA,iBAOX;AAAA,cAEJ,CAAC,CAAA,EACH,CAAA,mBAEAE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0BAAA,EACZ,QAAA,EAAA;AAAA,gBAAA,KAAA,CAAM,GAAA,CAAI,CAAC,OAAA,EAAS,KAAA,KAAU;AAC7B,kBAAA,MAAM,OAA0B,EAAC;AACjC,kBAAA,IAAI,kBAAA,IAAsB,QAAQ,CAAA,EAAG;AACnC,oBAAA,MAAM,GAAA,GAAM,OAAO,OAAO,CAAA;AAC1B,oBAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAE,CAAA;AAC5C,oBAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,WAAA,EAAa;AACvC,sBAAA,MAAM,KAAA,GAAQ,SAAS,OAAO,CAAA;AAC9B,sBAAA,IAAI,UAAU,IAAA,EAAM;AAClB,wBAAA,IAAA,CAAK,IAAA;AAAA,0CACHA,IAAAA,CAAC,KAAA,EAAA,EAAqC,SAAA,EAAQ,qBAAA,EAAsB,WAAU,8BAAA,EAA+B,IAAA,EAAK,WAAA,EAAY,YAAA,EAAY,KAAA,EACxI,QAAA,EAAA;AAAA,4CAAAF,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAoC,eAAW,IAAA,EAAC,CAAA;AAAA,4CAChEA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6EAA6E,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,4CACnGA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAoC,eAAW,IAAA,EAAC;AAAA,2BAAA,EAAA,EAHxD,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA,EAAI,OAAA,CAAQ,EAAE,CAAA,CAIlC;AAAA,yBACF;AAAA,sBACF;AAAA,oBACF;AAAA,kBACF;AACA,kBAAA,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,OAAA,EAAS,KAAK,CAAC,CAAA;AACnC,kBAAA,uBAAOA,GAAAA,CAAO,MAAA,CAAA,QAAA,EAAN,EAAiC,QAAA,EAAA,IAAA,EAAA,EAAb,QAAQ,EAAU,CAAA;AAAA,gBAChD,CAAC,CAAA;AAAA,gBACA,IAAA,KAAS,yBAAYA,GAAAA,CAAC,SAAI,SAAA,EAAQ,sBAAA,EAAwB,gBAAK,CAAA,GAAS;AAAA,eAAA,EAC3E;AAAA;AAAA,WAEJ;AAAA,0BACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,aAAU,QAAA,EAAS,SAAA,EAAU,WAC/B,QAAA,EAAA,YAAA,EACH,CAAA;AAAA,UACC,QAAA,IAAY,IAAA,KAAS,MAAA,IAAa,MAAA,KAAW,yBAC5CA,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,MAAA;AAAA,cACT,YAAA,EAAY,QAAQ,IAAA,IAAQ,iBAAA;AAAA,cAC5B,KAAA,EAAO,QAAQ,IAAA,IAAQ,iBAAA;AAAA,cACvB,SAAA,EAAU,qWAAA;AAAA,cAEV,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC;AAAA;AAAA,WAC3C,GACE,IAAA;AAAA,UACH,2BACCE,IAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,cAAA;AAAA,cACT,YAAA,EAAY,aAAA;AAAA,cACZ,KAAA,EAAO,aAAA;AAAA,cACP,SAAA,EAAU,4WAAA;AAAA,cAEV,QAAA,EAAA;AAAA,gCAAAF,GAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,QAAA,EAAS,eAAW,IAAA,EAAC,CAAA;AAAA,gBACzC,MAAA,GAAS,oBACRA,GAAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,aAAA,EAAW,IAAA;AAAA,oBACX,SAAA,EAAU,uLAAA;AAAA,oBAET,QAAA,EAAA,MAAA,GAAS,IAAI,IAAA,GAAO;AAAA;AAAA,iBACvB,GACE;AAAA;AAAA;AAAA,WACN,GACE;AAAA;AAAA;AAAA,KACN;AAAA,EAEJ;AACF","file":"chunk-HXU6P5FD.js","sourcesContent":["import * as React from 'react'\nimport { ChevronDown, ChevronUp, Search, X } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nexport interface ChatSearchFieldLabels {\n search: string\n placeholder: string\n previous: string\n next: string\n clear: string\n matches: string\n}\n\nexport interface ChatSearchFieldProps {\n query: string\n onQueryChange: (query: string) => void\n /** Total matches in the transcript (drives the `n/N` readout). */\n matchCount?: number\n /** 0-based active match index. */\n activeIndex?: number\n onPrevious?: () => void\n onNext?: () => void\n labels?: Partial<ChatSearchFieldLabels>\n className?: string\n}\n\n/**\n * The in-conversation search field (plan 101 P2): controlled query input\n * with an `n/N` match readout and prev/next controls. Enter jumps to the\n * next match, Shift+Enter to the previous, Escape clears. Composed by\n * `ChatTranscript` when its `search` prop is given, or standalone.\n */\nexport const ChatSearchField = React.forwardRef<HTMLDivElement, ChatSearchFieldProps>(\n function ChatSearchField(\n { query, onQueryChange, matchCount, activeIndex, onPrevious, onNext, labels, className },\n ref,\n ) {\n const inputId = React.useId()\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n onQueryChange('')\n return\n }\n if (event.key === 'Enter') {\n event.preventDefault()\n if (event.shiftKey) {\n onPrevious?.()\n } else {\n onNext?.()\n }\n }\n }\n\n const hasMatches = matchCount !== undefined && matchCount > 0\n const readout =\n matchCount === undefined\n ? null\n : hasMatches\n ? `${(activeIndex ?? 0) + 1}/${matchCount}`\n : '0'\n\n return (\n <div\n ref={ref}\n data-as=\"chat-search-field\"\n className={cn(\n 'flex items-center gap-1 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1',\n className,\n )}\n >\n <Search className=\"size-3.5 shrink-0 text-[var(--as-muted-fg)]\" aria-hidden />\n <input\n id={inputId}\n type=\"text\"\n value={query}\n placeholder={labels?.placeholder ?? 'Search conversation'}\n aria-label={labels?.search ?? 'Search conversation'}\n onChange={(event) => onQueryChange(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"min-w-0 flex-1 bg-transparent text-xs text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-none\"\n />\n {readout !== null ? (\n <span\n aria-label={labels?.matches ?? 'matches'}\n className=\"shrink-0 font-mono text-[10px] tabular-nums text-[var(--as-muted-fg)]\"\n >\n {readout}\n </span>\n ) : null}\n {query !== '' ? (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear search'}\n onClick={() => onQueryChange('')}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n <button\n type=\"button\"\n aria-label={labels?.previous ?? 'Previous match'}\n disabled={!hasMatches}\n onClick={onPrevious}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronUp className=\"size-3.5\" aria-hidden />\n </button>\n <button\n type=\"button\"\n aria-label={labels?.next ?? 'Next match'}\n disabled={!hasMatches}\n onClick={onNext}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronDown className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { ArrowDown } from 'lucide-react'\nimport { useVirtualizer } from '@tanstack/react-virtual'\n\nimport { cn } from '../../lib/utils'\nimport { format } from 'date-fns'\nimport { Square } from 'lucide-react'\nimport { ChatMessage } from '../chat-message/ChatMessage'\nimport { MarkdownSurface } from '../chat-markdown/MarkdownSurface'\nimport type { ChatMessageView } from '../chat-core/types'\nimport { ChatSearchField, type ChatSearchFieldLabels } from './ChatSearchField'\n\nfunction toDate(value: string | number | Date | undefined): Date | undefined {\n if (value === undefined) {\n return undefined\n }\n if (value instanceof Date) {\n return value\n }\n if (typeof value === 'number') {\n return new Date(value)\n }\n const parsed = new Date(value)\n return Number.isNaN(parsed.getTime()) ? undefined : parsed\n}\n\nexport interface ChatTranscriptLabels {\n log: string\n scrollToBottom: string\n newMessages: string\n empty: string\n replied: string\n search: string\n searchPlaceholder: string\n previousMatch: string\n nextMatch: string\n clearSearch: string\n matches: string\n today: string\n yesterday: string\n stop: string\n}\n\nexport type ChatTranscriptGroupPos = 'single' | 'start' | 'mid' | 'end'\n\nexport interface ChatTranscriptSearch {\n query: string\n onQueryChange: (query: string) => void\n}\n\nexport interface ChatTranscriptProps {\n items: ChatMessageView[]\n /** Override the default `ChatMessage` + `MarkdownSurface` rendering (third arg: group position when `groupConsecutive`; fourth arg: active search query). */\n renderItem?: (message: ChatMessageView, index: number, groupPos?: ChatTranscriptGroupPos, query?: string) => React.ReactNode\n /** Streaming tail — the live turn bubble (or `ChatPending`) or any node. */\n live?: React.ReactNode\n emptyState?: React.ReactNode\n /** Stick to bottom while the user hasn't scrolled away. Default true. */\n autoScroll?: boolean\n /** Distance from the bottom that still counts as \"at the bottom\". Default 120 px. */\n scrollThresholdPx?: number\n /** Virtualize long transcripts (dynamic row measurement). Default false. */\n virtualized?: boolean\n /**\n * Tighten the spacing between consecutive same-role messages and tag\n * each row with `data-group-pos` (`single | start | mid | end`).\n * Default false.\n */\n groupConsecutive?: boolean\n /** Visual design for the default renderer: paired bubbles (default) or flat assistant prose over the panel surface. */\n design?: 'bubbles' | 'flat'\n /**\n * In-conversation search (plan 101 P2): renders `ChatSearchField`\n * above the log, highlights matches in the default renderer, and\n * jumps between them (Enter/Shift+Enter in the field, or the\n * prev/next buttons). Jump-scrolling requires a non-virtualized\n * transcript; virtualized transcripts highlight visible rows only.\n */\n search?: ChatTranscriptSearch\n /**\n * Today/Yesterday/date chips between day groups (reads\n * `ChatMessageView.createdAt`; rows without one join the previous\n * group). Default false.\n */\n showDateSeparators?: boolean\n /** Custom formatter for older-day chips (default `MMM d, yyyy`). */\n formatDate?: (date: Date) => string\n /** Scroll a message into view and flash it when this changes (branch-tree clicks, citations, deep links). */\n focusMessageId?: string | null\n /** Show a floating stop pill beside the jump pill while a live turn streams and the user scrolled away. */\n onStop?: () => void\n labels?: Partial<ChatTranscriptLabels & ChatSearchFieldLabels>\n className?: string\n}\n\nfunction defaultRenderItem(message: ChatMessageView, design: 'bubbles' | 'flat', query?: string) {\n return (\n <ChatMessage\n role={message.role}\n status={message.status}\n design={design}\n content={<MarkdownSurface value={message.content} streaming={message.status === 'streaming'} query={query} />}\n variants={message.variants}\n />\n )\n}\n\n/**\n * The conversation list: `role=\"log\"` with polite turn-completion\n * announcements, stick-to-bottom auto-scroll with an unread-counting\n * jump-to-latest pill, optional consecutive-message grouping, a top\n * fade mask while scrolled into the thread, thin themed scrollbars,\n * and optional virtualization for thousand-message threads.\n */\nexport const ChatTranscript = React.forwardRef<HTMLDivElement, ChatTranscriptProps>(\n function ChatTranscript(\n {\n items,\n renderItem,\n live,\n emptyState,\n autoScroll = true,\n scrollThresholdPx = 120,\n virtualized = false,\n groupConsecutive = false,\n design = 'bubbles',\n search,\n showDateSeparators = false,\n formatDate,\n focusMessageId,\n onStop,\n labels,\n className,\n },\n ref,\n ) {\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const atBottomRef = React.useRef(true)\n const lastScrollTopRef = React.useRef(0)\n const lastTouchYRef = React.useRef<number | null>(null)\n const [showJump, setShowJump] = React.useState(false)\n const [fadeTop, setFadeTop] = React.useState(false)\n const [unread, setUnread] = React.useState(0)\n const [announcement, setAnnouncement] = React.useState('')\n const previousCountRef = React.useRef(-1)\n const [searchActive, setSearchActive] = React.useState(0)\n const [flashId, setFlashId] = React.useState<string | null>(null)\n\n const searchNeedle = search?.query.trim().toLowerCase() ?? ''\n const searchMatches = React.useMemo(() => {\n if (searchNeedle === '') {\n return []\n }\n return items\n .map((message, index) =>\n message.content.toLowerCase().includes(searchNeedle) ? index : -1,\n )\n .filter((index) => index >= 0)\n }, [items, searchNeedle])\n\n React.useEffect(() => {\n setSearchActive(0)\n if (searchMatches.length > 0) {\n jumpToMatch(0)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [searchNeedle])\n\n React.useEffect(() => {\n if (flashId === null) {\n return\n }\n const id = window.setTimeout(() => setFlashId(null), 1200)\n return () => window.clearTimeout(id)\n }, [flashId])\n\n const jumpToMatch = (index: number) => {\n if (searchMatches.length === 0) {\n return\n }\n const bounded = ((index % searchMatches.length) + searchMatches.length) % searchMatches.length\n setSearchActive(bounded)\n const messageIndex = searchMatches[bounded]\n const messageId = messageIndex !== undefined ? items[messageIndex]?.id : undefined\n if (messageId === undefined) {\n return\n }\n setFlashId(messageId)\n if (!virtualized) {\n const row = scrollRef.current?.querySelector(`[data-message-id=\"${messageId}\"]`)\n row?.scrollIntoView({ block: 'center', behavior: 'smooth' })\n }\n }\n\n React.useEffect(() => {\n if (focusMessageId === null || focusMessageId === undefined) {\n return\n }\n setFlashId(focusMessageId)\n if (!virtualized) {\n const row = scrollRef.current?.querySelector(`[data-message-id=\"${focusMessageId}\"]`)\n row?.scrollIntoView({ block: 'center', behavior: 'smooth' })\n }\n }, [focusMessageId, virtualized])\n\n const dayKey = (message: ChatMessageView): string | null => {\n if (message.createdAt === undefined) {\n return null\n }\n const date = toDate(message.createdAt)\n return date === undefined\n ? null\n : `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`\n }\n\n const dayLabel = (message: ChatMessageView): string | null => {\n if (message.createdAt === undefined) {\n return null\n }\n const date = toDate(message.createdAt)\n if (date === undefined) {\n return null\n }\n const now = new Date()\n const startOf = (value: Date) => new Date(value.getFullYear(), value.getMonth(), value.getDate()).getTime()\n const dayDiff = Math.round((startOf(now) - startOf(date)) / 86_400_000)\n if (dayDiff === 0) {\n return labels?.today ?? 'Today'\n }\n if (dayDiff === 1) {\n return labels?.yesterday ?? 'Yesterday'\n }\n return formatDate !== undefined ? formatDate(date) : format(date, 'MMM d, yyyy')\n }\n\n const onScroll = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n const distance = element.scrollHeight - element.scrollTop - element.clientHeight\n const goingUp = element.scrollTop < lastScrollTopRef.current\n lastScrollTopRef.current = element.scrollTop\n const atBottom = distance <= scrollThresholdPx && !(goingUp && distance > 0)\n atBottomRef.current = atBottom\n setShowJump(element.scrollHeight > element.clientHeight && !atBottom)\n setFadeTop(element.scrollTop > 8)\n if (atBottom) {\n setUnread(0)\n }\n }\n\n /**\n * Fast streams re-pin the bottom on every render (rAF), which erases\n * a partial upward scroll before it can cross `scrollThresholdPx` —\n * so user scroll-up INTENT cancels stickiness synchronously here\n * (wheel up, touch drag up, scroll-up keys), and any upward scroll\n * event with distance left also breaks it. Scrolling back to the\n * bottom (or the jump pill) re-arms the follow.\n */\n const cancelStick = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n atBottomRef.current = false\n setShowJump(element.scrollHeight > element.clientHeight)\n }\n\n const onWheel = (event: React.WheelEvent<HTMLDivElement>) => {\n if (event.deltaY < 0) {\n cancelStick()\n }\n }\n\n const onTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {\n lastTouchYRef.current = event.touches[0]?.clientY ?? null\n }\n\n const onTouchMove = (event: React.TouchEvent<HTMLDivElement>) => {\n const y = event.touches[0]?.clientY\n if (y === undefined) {\n return\n }\n if (lastTouchYRef.current !== null && y > lastTouchYRef.current) {\n cancelStick()\n }\n lastTouchYRef.current = y\n }\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (\n event.key === 'ArrowUp' ||\n event.key === 'PageUp' ||\n event.key === 'Home' ||\n (event.key === ' ' && event.shiftKey)\n ) {\n cancelStick()\n }\n }\n\n React.useEffect(() => {\n const element = scrollRef.current\n if (element === null || !autoScroll || !atBottomRef.current) {\n return\n }\n const frame = requestAnimationFrame(() => {\n element.scrollTop = element.scrollHeight\n })\n return () => cancelAnimationFrame(frame)\n })\n\n React.useEffect(() => {\n if (previousCountRef.current === -1) {\n previousCountRef.current = items.length\n return\n }\n if (items.length > previousCountRef.current) {\n const added = items.slice(previousCountRef.current)\n previousCountRef.current = items.length\n const assistantAdded = added.filter((message) => message.role !== 'user').length\n if (assistantAdded > 0 && !atBottomRef.current) {\n setUnread((count) => count + assistantAdded)\n }\n if (added[added.length - 1]?.role !== 'user') {\n setAnnouncement(labels?.replied ?? 'Assistant replied')\n }\n return\n }\n previousCountRef.current = items.length\n }, [items, labels])\n\n const scrollToBottom = () => {\n const element = scrollRef.current\n if (element !== null) {\n setUnread(0)\n element.scrollTo({ top: element.scrollHeight, behavior: 'smooth' })\n }\n }\n\n const groupPos = (index: number): ChatTranscriptGroupPos => {\n const role = items[index]?.role\n if (role === undefined || role === 'system') {\n return 'single'\n }\n const prevSame = index > 0 && items[index - 1]?.role === role && items[index - 1]?.role !== 'system'\n const nextSame = index < items.length - 1 && items[index + 1]?.role === role && items[index + 1]?.role !== 'system'\n if (prevSame && nextSame) {\n return 'mid'\n }\n if (prevSame) {\n return 'end'\n }\n if (nextSame) {\n return 'start'\n }\n return 'single'\n }\n\n const renderRow = (message: ChatMessageView, index: number) => {\n const pos = groupConsecutive ? groupPos(index) : undefined\n const node = renderItem\n ? renderItem(message, index, pos, searchNeedle === '' ? undefined : search?.query.trim())\n : defaultRenderItem(message, design, searchNeedle === '' ? undefined : search?.query.trim())\n const grouped = pos === 'mid' || pos === 'end'\n return (\n <div\n key={message.id}\n data-message-id={message.id}\n data-group-pos={pos}\n data-search-flash={message.id === flashId || undefined}\n className={cn(groupConsecutive && grouped && '-mt-2')}\n >\n {node}\n </div>\n )\n }\n\n const rowCount = items.length + (live !== undefined ? 1 : 0)\n const virtualizer = useVirtualizer({\n count: virtualized ? rowCount : 0,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 120,\n overscan: 8,\n initialRect: { width: 480, height: 600 },\n })\n\n const jumpLabel = labels?.scrollToBottom ?? 'Scroll to latest'\n const jumpFullLabel =\n unread > 0 ? `${jumpLabel} — ${unread} ${labels?.newMessages ?? 'new messages'}` : jumpLabel\n\n return (\n <div\n ref={ref}\n data-as=\"chat-transcript\"\n data-grouped={groupConsecutive || undefined}\n data-fade-top={fadeTop || undefined}\n className={cn('relative flex min-h-0 flex-1 flex-col', className)}\n >\n {search ? (\n <ChatSearchField\n query={search.query}\n onQueryChange={search.onQueryChange}\n matchCount={searchMatches.length}\n activeIndex={searchActive}\n onPrevious={() => jumpToMatch(searchActive - 1)}\n onNext={() => jumpToMatch(searchActive + 1)}\n labels={\n labels\n ? ({\n search: labels.search,\n placeholder: labels.searchPlaceholder,\n previous: labels.previousMatch,\n next: labels.nextMatch,\n clear: labels.clearSearch,\n matches: labels.matches,\n } satisfies Partial<ChatSearchFieldLabels>)\n : undefined\n }\n className=\"mx-1 mb-1 shrink-0\"\n />\n ) : null}\n <div\n ref={scrollRef}\n onScroll={onScroll}\n onWheel={onWheel}\n onTouchStart={onTouchStart}\n onTouchMove={onTouchMove}\n onKeyDown={onKeyDown}\n role=\"log\"\n aria-label={labels?.log ?? 'Conversation'}\n aria-busy={live !== undefined}\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain px-1 py-2\"\n >\n {items.length === 0 && live === undefined ? (\n <div className=\"flex h-full min-h-40 items-center justify-center p-4 text-sm text-[var(--as-muted-fg)]\">\n {emptyState ?? (labels?.empty ?? 'Start the conversation')}\n </div>\n ) : virtualized ? (\n <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>\n {virtualizer.getVirtualItems().map((row) => {\n const isLive = row.index >= items.length\n const node = isLive ? live : renderRow(items[row.index]!, row.index)\n return (\n <div\n key={row.key}\n data-index={row.index}\n ref={virtualizer.measureElement}\n style={{ position: 'absolute', top: 0, left: 0, width: '100%', transform: `translateY(${row.start}px)` }}\n className=\"px-2 py-1.5\"\n >\n {node}\n </div>\n )\n })}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3 px-2\">\n {items.map((message, index) => {\n const rows: React.ReactNode[] = []\n if (showDateSeparators && index > 0) {\n const key = dayKey(message)\n const previousKey = dayKey(items[index - 1]!)\n if (key !== null && key !== previousKey) {\n const label = dayLabel(message)\n if (label !== null) {\n rows.push(\n <div key={`day-${key}-${message.id}`} data-as=\"chat-date-separator\" className=\"flex items-center gap-2 py-1\" role=\"separator\" aria-label={label}>\n <span className=\"h-px flex-1 bg-[var(--as-border)]\" aria-hidden />\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-[var(--as-muted-fg)]\">{label}</span>\n <span className=\"h-px flex-1 bg-[var(--as-border)]\" aria-hidden />\n </div>,\n )\n }\n }\n }\n rows.push(renderRow(message, index))\n return <React.Fragment key={message.id}>{rows}</React.Fragment>\n })}\n {live !== undefined ? <div data-as=\"chat-transcript-live\">{live}</div> : null}\n </div>\n )}\n </div>\n <div aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </div>\n {showJump && live !== undefined && onStop !== undefined ? (\n <button\n type=\"button\"\n onClick={onStop}\n aria-label={labels?.stop ?? 'Stop generating'}\n title={labels?.stop ?? 'Stop generating'}\n className=\"as-anim-slide-up absolute bottom-3 right-3 flex size-8 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] shadow-[var(--as-shadow-2)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <Square className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {showJump ? (\n <button\n type=\"button\"\n onClick={scrollToBottom}\n aria-label={jumpFullLabel}\n title={jumpFullLabel}\n className=\"as-anim-slide-up absolute bottom-3 left-1/2 -ml-4 flex size-8 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] shadow-[var(--as-shadow-2)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ArrowDown className=\"size-4\" aria-hidden />\n {unread > 0 ? (\n <span\n aria-hidden\n className=\"absolute -right-1.5 -top-1.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-[var(--as-primary)] px-1 text-[10px] font-semibold leading-none text-[var(--as-primary-fg)]\"\n >\n {unread > 9 ? '9+' : unread}\n </span>\n ) : null}\n </button>\n ) : null}\n </div>\n )\n },\n)\n"]}
1
+ {"version":3,"sources":["../src/components/chat-transcript/ChatSearchField.tsx","../src/components/chat-transcript/ChatTranscript.tsx"],"names":["React","ChatSearchField","jsx","ChatTranscript","jsxs"],"mappings":"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","file":"chunk-E2NNTHFB.js","sourcesContent":["import * as React from 'react'\nimport { ChevronDown, ChevronUp, Search, X } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nexport interface ChatSearchFieldLabels {\n search: string\n placeholder: string\n previous: string\n next: string\n clear: string\n matches: string\n}\n\nexport interface ChatSearchFieldProps {\n query: string\n onQueryChange: (query: string) => void\n /** Total matches in the transcript (drives the `n/N` readout). */\n matchCount?: number\n /** 0-based active match index. */\n activeIndex?: number\n onPrevious?: () => void\n onNext?: () => void\n labels?: Partial<ChatSearchFieldLabels>\n className?: string\n}\n\n/**\n * The in-conversation search field (plan 101 P2): controlled query input\n * with an `n/N` match readout and prev/next controls. Enter jumps to the\n * next match, Shift+Enter to the previous, Escape clears. Composed by\n * `ChatTranscript` when its `search` prop is given, or standalone.\n */\nexport const ChatSearchField = React.forwardRef<HTMLDivElement, ChatSearchFieldProps>(\n function ChatSearchField(\n { query, onQueryChange, matchCount, activeIndex, onPrevious, onNext, labels, className },\n ref,\n ) {\n const inputId = React.useId()\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n onQueryChange('')\n return\n }\n if (event.key === 'Enter') {\n event.preventDefault()\n if (event.shiftKey) {\n onPrevious?.()\n } else {\n onNext?.()\n }\n }\n }\n\n const hasMatches = matchCount !== undefined && matchCount > 0\n const readout =\n matchCount === undefined\n ? null\n : hasMatches\n ? `${(activeIndex ?? 0) + 1}/${matchCount}`\n : '0'\n\n return (\n <div\n ref={ref}\n data-as=\"chat-search-field\"\n className={cn(\n 'flex items-center gap-1 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1',\n className,\n )}\n >\n <Search className=\"size-3.5 shrink-0 text-[var(--as-muted-fg)]\" aria-hidden />\n <input\n id={inputId}\n type=\"text\"\n value={query}\n placeholder={labels?.placeholder ?? 'Search conversation'}\n aria-label={labels?.search ?? 'Search conversation'}\n onChange={(event) => onQueryChange(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"min-w-0 flex-1 bg-transparent text-xs text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-none\"\n />\n {readout !== null ? (\n <span\n aria-label={labels?.matches ?? 'matches'}\n className=\"shrink-0 font-mono text-[10px] tabular-nums text-[var(--as-muted-fg)]\"\n >\n {readout}\n </span>\n ) : null}\n {query !== '' ? (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear search'}\n onClick={() => onQueryChange('')}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n <button\n type=\"button\"\n aria-label={labels?.previous ?? 'Previous match'}\n disabled={!hasMatches}\n onClick={onPrevious}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronUp className=\"size-3.5\" aria-hidden />\n </button>\n <button\n type=\"button\"\n aria-label={labels?.next ?? 'Next match'}\n disabled={!hasMatches}\n onClick={onNext}\n className=\"rounded-[var(--as-radius-sm)] p-0.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ChevronDown className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n )\n },\n)\n","import * as React from 'react'\nimport { ArrowDown } from 'lucide-react'\nimport { useVirtualizer } from '@tanstack/react-virtual'\n\nimport { cn } from '../../lib/utils'\nimport { format } from 'date-fns'\nimport { Square } from 'lucide-react'\nimport { ChatMessage } from '../chat-message/ChatMessage'\nimport { MarkdownSurface } from '../chat-markdown/MarkdownSurface'\nimport type { ChatMessageView } from '../chat-core/types'\nimport { ChatSearchField, type ChatSearchFieldLabels } from './ChatSearchField'\n\nfunction toDate(value: string | number | Date | undefined): Date | undefined {\n if (value === undefined) {\n return undefined\n }\n if (value instanceof Date) {\n return value\n }\n if (typeof value === 'number') {\n return new Date(value)\n }\n const parsed = new Date(value)\n return Number.isNaN(parsed.getTime()) ? undefined : parsed\n}\n\nexport interface ChatTranscriptLabels {\n log: string\n scrollToBottom: string\n newMessages: string\n empty: string\n replied: string\n search: string\n searchPlaceholder: string\n previousMatch: string\n nextMatch: string\n clearSearch: string\n matches: string\n today: string\n yesterday: string\n stop: string\n}\n\nexport type ChatTranscriptGroupPos = 'single' | 'start' | 'mid' | 'end'\n\nexport interface ChatTranscriptSearch {\n query: string\n onQueryChange: (query: string) => void\n}\n\nexport interface ChatTranscriptProps {\n items: ChatMessageView[]\n /** Override the default `ChatMessage` + `MarkdownSurface` rendering (third arg: group position when `groupConsecutive`; fourth arg: active search query). */\n renderItem?: (message: ChatMessageView, index: number, groupPos?: ChatTranscriptGroupPos, query?: string) => React.ReactNode\n /** Streaming tail — the live turn bubble (or `ChatPending`) or any node. */\n live?: React.ReactNode\n emptyState?: React.ReactNode\n /** Stick to bottom while the user hasn't scrolled away. Default true. */\n autoScroll?: boolean\n /** Distance from the bottom that still counts as \"at the bottom\". Default 120 px. */\n scrollThresholdPx?: number\n /** Virtualize long transcripts (dynamic row measurement). Default false. */\n virtualized?: boolean\n /**\n * Tighten the spacing between consecutive same-role messages and tag\n * each row with `data-group-pos` (`single | start | mid | end`).\n * Default false.\n */\n groupConsecutive?: boolean\n /** Visual design for the default renderer: paired bubbles (default) or flat assistant prose over the panel surface. */\n design?: 'bubbles' | 'flat'\n /**\n * In-conversation search (plan 101 P2): renders `ChatSearchField`\n * above the log, highlights matches in the default renderer, and\n * jumps between them (Enter/Shift+Enter in the field, or the\n * prev/next buttons). Jump-scrolling requires a non-virtualized\n * transcript; virtualized transcripts highlight visible rows only.\n */\n search?: ChatTranscriptSearch\n /**\n * Today/Yesterday/date chips between day groups (reads\n * `ChatMessageView.createdAt`; rows without one join the previous\n * group). Default false.\n */\n showDateSeparators?: boolean\n /** Custom formatter for older-day chips (default `MMM d, yyyy`). */\n formatDate?: (date: Date) => string\n /** Scroll a message into view and flash it when this changes (branch-tree clicks, citations, deep links). */\n focusMessageId?: string | null\n /** Show a floating stop pill beside the jump pill while a live turn streams and the user scrolled away. */\n onStop?: () => void\n labels?: Partial<ChatTranscriptLabels & ChatSearchFieldLabels>\n className?: string\n}\n\nfunction defaultRenderItem(message: ChatMessageView, design: 'bubbles' | 'flat', query?: string) {\n return (\n <ChatMessage\n role={message.role}\n status={message.status}\n design={design}\n content={<MarkdownSurface value={message.content} streaming={message.status === 'streaming'} query={query} />}\n variants={message.variants}\n />\n )\n}\n\n/**\n * The conversation list: `role=\"log\"` with polite turn-completion\n * announcements, stick-to-bottom auto-scroll with an unread-counting\n * jump-to-latest pill, optional consecutive-message grouping, a top\n * fade mask while scrolled into the thread, thin themed scrollbars,\n * and optional virtualization for thousand-message threads.\n */\nexport const ChatTranscript = React.forwardRef<HTMLDivElement, ChatTranscriptProps>(\n function ChatTranscript(\n {\n items,\n renderItem,\n live,\n emptyState,\n autoScroll = true,\n scrollThresholdPx = 120,\n virtualized = false,\n groupConsecutive = false,\n design = 'bubbles',\n search,\n showDateSeparators = false,\n formatDate,\n focusMessageId,\n onStop,\n labels,\n className,\n },\n ref,\n ) {\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const atBottomRef = React.useRef(true)\n const lastScrollTopRef = React.useRef(0)\n const lastTouchYRef = React.useRef<number | null>(null)\n const [showJump, setShowJump] = React.useState(false)\n const [fadeTop, setFadeTop] = React.useState(false)\n const [unread, setUnread] = React.useState(0)\n const [announcement, setAnnouncement] = React.useState('')\n const previousCountRef = React.useRef(-1)\n const [searchActive, setSearchActive] = React.useState(0)\n const [flashId, setFlashId] = React.useState<string | null>(null)\n\n const searchNeedle = search?.query.trim().toLowerCase() ?? ''\n const searchMatches = React.useMemo(() => {\n if (searchNeedle === '') {\n return []\n }\n return items\n .map((message, index) =>\n message.content.toLowerCase().includes(searchNeedle) ? index : -1,\n )\n .filter((index) => index >= 0)\n }, [items, searchNeedle])\n\n React.useEffect(() => {\n setSearchActive(0)\n if (searchMatches.length > 0) {\n jumpToMatch(0)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [searchNeedle])\n\n React.useEffect(() => {\n if (flashId === null) {\n return\n }\n const id = window.setTimeout(() => setFlashId(null), 1200)\n return () => window.clearTimeout(id)\n }, [flashId])\n\n const jumpToMatch = (index: number) => {\n if (searchMatches.length === 0) {\n return\n }\n const bounded = ((index % searchMatches.length) + searchMatches.length) % searchMatches.length\n setSearchActive(bounded)\n const messageIndex = searchMatches[bounded]\n const messageId = messageIndex !== undefined ? items[messageIndex]?.id : undefined\n if (messageId === undefined) {\n return\n }\n setFlashId(messageId)\n if (!virtualized) {\n const row = scrollRef.current?.querySelector(`[data-message-id=\"${messageId}\"]`)\n row?.scrollIntoView({ block: 'center', behavior: 'smooth' })\n }\n }\n\n React.useEffect(() => {\n if (focusMessageId === null || focusMessageId === undefined) {\n return\n }\n setFlashId(focusMessageId)\n if (!virtualized) {\n const row = scrollRef.current?.querySelector(`[data-message-id=\"${focusMessageId}\"]`)\n row?.scrollIntoView({ block: 'center', behavior: 'smooth' })\n }\n }, [focusMessageId, virtualized])\n\n const dayKey = (message: ChatMessageView): string | null => {\n if (message.createdAt === undefined) {\n return null\n }\n const date = toDate(message.createdAt)\n return date === undefined\n ? null\n : `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`\n }\n\n const dayLabel = (message: ChatMessageView): string | null => {\n if (message.createdAt === undefined) {\n return null\n }\n const date = toDate(message.createdAt)\n if (date === undefined) {\n return null\n }\n const now = new Date()\n const startOf = (value: Date) => new Date(value.getFullYear(), value.getMonth(), value.getDate()).getTime()\n const dayDiff = Math.round((startOf(now) - startOf(date)) / 86_400_000)\n if (dayDiff === 0) {\n return labels?.today ?? 'Today'\n }\n if (dayDiff === 1) {\n return labels?.yesterday ?? 'Yesterday'\n }\n return formatDate !== undefined ? formatDate(date) : format(date, 'MMM d, yyyy')\n }\n\n const onScroll = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n const distance = element.scrollHeight - element.scrollTop - element.clientHeight\n const goingUp = element.scrollTop < lastScrollTopRef.current\n lastScrollTopRef.current = element.scrollTop\n const atBottom = distance <= scrollThresholdPx && !(goingUp && distance > 0)\n atBottomRef.current = atBottom\n setShowJump(element.scrollHeight > element.clientHeight && !atBottom)\n setFadeTop(element.scrollTop > 8)\n if (atBottom) {\n setUnread(0)\n }\n }\n\n /**\n * Fast streams re-pin the bottom on every render (rAF), which erases\n * a partial upward scroll before it can cross `scrollThresholdPx` —\n * so user scroll-up INTENT cancels stickiness synchronously here\n * (wheel up, touch drag up, scroll-up keys), and any upward scroll\n * event with distance left also breaks it. Scrolling back to the\n * bottom (or the jump pill) re-arms the follow.\n */\n const cancelStick = () => {\n const element = scrollRef.current\n if (element === null) {\n return\n }\n atBottomRef.current = false\n setShowJump(element.scrollHeight > element.clientHeight)\n }\n\n const onWheel = (event: React.WheelEvent<HTMLDivElement>) => {\n if (event.deltaY < 0) {\n cancelStick()\n }\n }\n\n const onTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {\n lastTouchYRef.current = event.touches[0]?.clientY ?? null\n }\n\n const onTouchMove = (event: React.TouchEvent<HTMLDivElement>) => {\n const y = event.touches[0]?.clientY\n if (y === undefined) {\n return\n }\n if (lastTouchYRef.current !== null && y > lastTouchYRef.current) {\n cancelStick()\n }\n lastTouchYRef.current = y\n }\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (\n event.key === 'ArrowUp' ||\n event.key === 'PageUp' ||\n event.key === 'Home' ||\n (event.key === ' ' && event.shiftKey)\n ) {\n cancelStick()\n }\n }\n\n React.useEffect(() => {\n const element = scrollRef.current\n if (element === null || !autoScroll || !atBottomRef.current) {\n return\n }\n const frame = requestAnimationFrame(() => {\n element.scrollTop = element.scrollHeight\n })\n return () => cancelAnimationFrame(frame)\n })\n\n React.useEffect(() => {\n if (previousCountRef.current === -1) {\n previousCountRef.current = items.length\n return\n }\n if (items.length > previousCountRef.current) {\n const added = items.slice(previousCountRef.current)\n previousCountRef.current = items.length\n const assistantAdded = added.filter((message) => message.role !== 'user').length\n if (assistantAdded > 0 && !atBottomRef.current) {\n setUnread((count) => count + assistantAdded)\n }\n if (added[added.length - 1]?.role !== 'user') {\n setAnnouncement(labels?.replied ?? 'Assistant replied')\n }\n return\n }\n previousCountRef.current = items.length\n }, [items, labels])\n\n const scrollToBottom = () => {\n const element = scrollRef.current\n if (element !== null) {\n setUnread(0)\n element.scrollTo({ top: element.scrollHeight, behavior: 'smooth' })\n }\n }\n\n const groupPos = (index: number): ChatTranscriptGroupPos => {\n const role = items[index]?.role\n if (role === undefined || role === 'system') {\n return 'single'\n }\n const prevSame = index > 0 && items[index - 1]?.role === role && items[index - 1]?.role !== 'system'\n const nextSame = index < items.length - 1 && items[index + 1]?.role === role && items[index + 1]?.role !== 'system'\n if (prevSame && nextSame) {\n return 'mid'\n }\n if (prevSame) {\n return 'end'\n }\n if (nextSame) {\n return 'start'\n }\n return 'single'\n }\n\n const renderRow = (message: ChatMessageView, index: number) => {\n const pos = groupConsecutive ? groupPos(index) : undefined\n const node = renderItem\n ? renderItem(message, index, pos, searchNeedle === '' ? undefined : search?.query.trim())\n : defaultRenderItem(message, design, searchNeedle === '' ? undefined : search?.query.trim())\n const grouped = pos === 'mid' || pos === 'end'\n return (\n <div\n key={message.id}\n data-message-id={message.id}\n data-group-pos={pos}\n data-search-flash={message.id === flashId || undefined}\n className={cn(groupConsecutive && grouped && '-mt-2')}\n >\n {node}\n </div>\n )\n }\n\n const rowCount = items.length + (live !== undefined ? 1 : 0)\n const virtualizer = useVirtualizer({\n count: virtualized ? rowCount : 0,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 120,\n overscan: 8,\n initialRect: { width: 480, height: 600 },\n })\n\n const jumpLabel = labels?.scrollToBottom ?? 'Scroll to latest'\n const jumpFullLabel =\n unread > 0 ? `${jumpLabel} — ${unread} ${labels?.newMessages ?? 'new messages'}` : jumpLabel\n\n return (\n <div\n ref={ref}\n data-as=\"chat-transcript\"\n data-grouped={groupConsecutive || undefined}\n data-fade-top={fadeTop || undefined}\n className={cn('relative flex min-h-0 flex-1 flex-col', className)}\n >\n {search ? (\n <ChatSearchField\n query={search.query}\n onQueryChange={search.onQueryChange}\n matchCount={searchMatches.length}\n activeIndex={searchActive}\n onPrevious={() => jumpToMatch(searchActive - 1)}\n onNext={() => jumpToMatch(searchActive + 1)}\n labels={\n labels\n ? ({\n search: labels.search,\n placeholder: labels.searchPlaceholder,\n previous: labels.previousMatch,\n next: labels.nextMatch,\n clear: labels.clearSearch,\n matches: labels.matches,\n } satisfies Partial<ChatSearchFieldLabels>)\n : undefined\n }\n className=\"mx-1 mb-1 shrink-0\"\n />\n ) : null}\n <div\n ref={scrollRef}\n onScroll={onScroll}\n onWheel={onWheel}\n onTouchStart={onTouchStart}\n onTouchMove={onTouchMove}\n onKeyDown={onKeyDown}\n role=\"log\"\n aria-label={labels?.log ?? 'Conversation'}\n aria-busy={live !== undefined}\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain px-1 py-2\"\n >\n {items.length === 0 && live === undefined ? (\n <div className=\"flex h-full min-h-40 items-center justify-center p-4 text-sm text-[var(--as-muted-fg)]\">\n {emptyState ?? (labels?.empty ?? 'Start the conversation')}\n </div>\n ) : virtualized ? (\n <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>\n {virtualizer.getVirtualItems().map((row) => {\n const isLive = row.index >= items.length\n const node = isLive ? live : renderRow(items[row.index]!, row.index)\n return (\n <div\n key={row.key}\n data-index={row.index}\n ref={virtualizer.measureElement}\n style={{ position: 'absolute', top: 0, left: 0, width: '100%', transform: `translateY(${row.start}px)` }}\n className=\"px-2 py-1.5\"\n >\n {node}\n </div>\n )\n })}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3 px-2\">\n {items.map((message, index) => {\n const rows: React.ReactNode[] = []\n if (showDateSeparators && index > 0) {\n const key = dayKey(message)\n const previousKey = dayKey(items[index - 1]!)\n if (key !== null && key !== previousKey) {\n const label = dayLabel(message)\n if (label !== null) {\n rows.push(\n <div key={`day-${key}-${message.id}`} data-as=\"chat-date-separator\" className=\"flex items-center gap-2 py-1\" role=\"separator\" aria-label={label}>\n <span className=\"h-px flex-1 bg-[var(--as-border)]\" aria-hidden />\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-[var(--as-muted-fg)]\">{label}</span>\n <span className=\"h-px flex-1 bg-[var(--as-border)]\" aria-hidden />\n </div>,\n )\n }\n }\n }\n rows.push(renderRow(message, index))\n return <React.Fragment key={message.id}>{rows}</React.Fragment>\n })}\n {live !== undefined ? <div data-as=\"chat-transcript-live\">{live}</div> : null}\n </div>\n )}\n </div>\n <div aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </div>\n {showJump && live !== undefined && onStop !== undefined ? (\n <button\n type=\"button\"\n onClick={onStop}\n aria-label={labels?.stop ?? 'Stop generating'}\n title={labels?.stop ?? 'Stop generating'}\n className=\"as-anim-slide-up absolute bottom-3 right-3 flex size-8 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] shadow-[var(--as-shadow-2)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <Square className=\"size-3.5\" aria-hidden />\n </button>\n ) : null}\n {showJump ? (\n <button\n type=\"button\"\n onClick={scrollToBottom}\n aria-label={jumpFullLabel}\n title={jumpFullLabel}\n className=\"as-anim-slide-up absolute bottom-3 left-1/2 -ml-4 flex size-8 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] shadow-[var(--as-shadow-2)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <ArrowDown className=\"size-4\" aria-hidden />\n {unread > 0 ? (\n <span\n aria-hidden\n className=\"absolute -right-1.5 -top-1.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-[var(--as-primary)] px-1 text-[10px] font-semibold leading-none text-[var(--as-primary-fg)]\"\n >\n {unread > 9 ? '9+' : unread}\n </span>\n ) : null}\n </button>\n ) : null}\n </div>\n )\n },\n)\n"]}
@@ -266,7 +266,7 @@ var MarkdownSurface = React3.memo(
266
266
  ref,
267
267
  "data-as": "chat-markdown",
268
268
  "data-streaming": streaming || void 0,
269
- className: cn("min-w-0 text-[var(--as-fg)]", className),
269
+ className: cn("min-w-0", className),
270
270
  children: [
271
271
  /* @__PURE__ */ jsx(
272
272
  ReactMarkdown,
@@ -286,5 +286,5 @@ var MarkdownSurface = React3.memo(
286
286
  );
287
287
 
288
288
  export { MarkdownCodeBlock, MarkdownSurface, MermaidDiagram };
289
- //# sourceMappingURL=chunk-KQLKITZL.js.map
290
- //# sourceMappingURL=chunk-KQLKITZL.js.map
289
+ //# sourceMappingURL=chunk-KLCULTOQ.js.map
290
+ //# sourceMappingURL=chunk-KLCULTOQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/chat-markdown/MarkdownCodeBlock.tsx","../src/components/chat-markdown/MermaidDiagram.tsx","../src/components/chat-markdown/MarkdownSurface.tsx"],"names":["React","MarkdownCodeBlock","React2","MermaidDiagram","jsx","MarkdownSurface","jsxs"],"mappings":"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","file":"chunk-KLCULTOQ.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { CopyButton } from '../copy-button/CopyButton'\n\nexport interface MarkdownCodeBlockLabels {\n copy: string\n code: string\n}\n\nexport interface MarkdownCodeBlockProps {\n code: string\n language?: string\n showLanguage?: boolean\n labels?: Partial<MarkdownCodeBlockLabels>\n className?: string\n}\n\n/**\n * Standalone fenced-code surface: mono block, optional language tag, hover\n * copy. Plain by design — no highlighting engine bundled (apps may wrap or\n * slot their own renderer through `MarkdownSurface.components`).\n */\nexport const MarkdownCodeBlock = React.forwardRef<HTMLDivElement, MarkdownCodeBlockProps>(\n function MarkdownCodeBlock({ code, language, showLanguage = true, labels, className }, ref) {\n const copyLabel = labels?.copy ?? 'Copy code'\n const codeLabel = labels?.code ?? 'Code'\n return (\n <div\n ref={ref}\n data-as=\"markdown-code-block\"\n className={cn(\n 'group/code relative my-3 overflow-hidden rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)]',\n className,\n )}\n >\n {showLanguage && language ? (\n <div className=\"flex items-center justify-between border-b border-[var(--as-border)] px-3 py-1 font-sans text-[10px] font-medium uppercase tracking-wide text-[var(--as-muted-fg)]\">\n <span>{language}</span>\n <CopyButton value={code} label={copyLabel} className=\"opacity-60 transition-opacity group-hover/code:opacity-100\" />\n </div>\n ) : (\n <CopyButton\n value={code}\n label={copyLabel}\n className=\"absolute right-2 top-2 opacity-0 transition-opacity focus-visible:opacity-100 group-hover/code:opacity-100\"\n />\n )}\n <pre className={cn('overflow-x-auto p-3 font-mono text-xs leading-relaxed', !showLanguage && 'pt-3')}>\n <code aria-label={language ? `${language} ${codeLabel}` : codeLabel}>{code}</code>\n </pre>\n </div>\n )\n },\n)\n","import * as React from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { MarkdownCodeBlock } from './MarkdownCodeBlock'\n\nexport interface MermaidDiagramProps {\n code: string\n theme?: 'neutral' | 'default' | 'dark' | 'forest'\n labels?: { diagram?: string }\n className?: string\n}\n\nlet mermaidInitialized = false\n\nasync function renderMermaid(id: string, code: string, theme: NonNullable<MermaidDiagramProps['theme']>): Promise<string> {\n const mermaid = (await import('mermaid')).default\n if (!mermaidInitialized) {\n mermaid.initialize({ startOnLoad: false, securityLevel: 'strict', theme })\n mermaidInitialized = true\n }\n const { svg } = await mermaid.render(id, code)\n return svg\n}\n\nexport function extractText(node: React.ReactNode): string {\n if (node === null || node === undefined || typeof node === 'boolean') {\n return ''\n }\n if (typeof node === 'string' || typeof node === 'number') {\n return String(node)\n }\n if (Array.isArray(node)) {\n return node.map(extractText).join('')\n }\n if (React.isValidElement(node)) {\n return extractText((node.props as { children?: React.ReactNode }).children)\n }\n return ''\n}\n\n/**\n * Lazily-rendered mermaid diagram (dynamic `import('mermaid')`, strict\n * security). Falls back to the plain code block when rendering fails —\n * study-assistant's proven behavior.\n */\nexport const MermaidDiagram = React.forwardRef<HTMLDivElement, MermaidDiagramProps>(\n function MermaidDiagram({ code, theme = 'neutral', labels, className }, ref) {\n const reactId = React.useId().replace(/[^a-zA-Z0-9]/g, '')\n const [svg, setSvg] = React.useState<string | null>(null)\n const [failed, setFailed] = React.useState(false)\n\n React.useEffect(() => {\n let cancelled = false\n setFailed(false)\n setSvg(null)\n renderMermaid(`as-mermaid-${reactId}`, code, theme)\n .then((result) => {\n if (!cancelled) {\n setSvg(result)\n }\n })\n .catch(() => {\n if (!cancelled) {\n setFailed(true)\n }\n })\n return () => {\n cancelled = true\n }\n }, [code, theme, reactId])\n\n if (failed || svg === null) {\n return (\n <MarkdownCodeBlock\n ref={failed ? ref : undefined}\n code={code}\n language=\"mermaid\"\n labels={{ code: labels?.diagram ?? 'Diagram' }}\n className={cn('my-3', svg === null && !failed ? 'opacity-60' : undefined, className)}\n />\n )\n }\n return (\n <div\n ref={ref}\n data-as=\"mermaid-diagram\"\n className={cn(\n 'my-3 flex justify-center overflow-x-auto rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] p-3 [&_svg]:max-w-full',\n className,\n )}\n // mermaid runs with securityLevel 'strict' — no user styles, scripts or links survive\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n )\n },\n)\n","import * as React from 'react'\nimport { defaultUrlTransform, type Components, type Options as ReactMarkdownOptions, type UrlTransform } from 'react-markdown'\nimport ReactMarkdown from 'react-markdown'\nimport rehypeKatex from 'rehype-katex'\nimport remarkGfm from 'remark-gfm'\nimport remarkMath from 'remark-math'\n\nimport { cn } from '../../lib/utils'\nimport { Modal, ModalContent } from '../modal/Modal'\nimport { MarkdownCodeBlock, type MarkdownCodeBlockLabels } from './MarkdownCodeBlock'\nimport { extractText, MermaidDiagram } from './MermaidDiagram'\n\nexport type MarkdownComponents = Components\nexport type { MarkdownCodeBlockLabels }\n\nexport interface MarkdownSurfaceProps {\n /** Markdown source (model output is untrusted — raw HTML never renders). */\n value: string\n /** Live turn: defers mermaid to the final render (streaming floods break diagrams). */\n streaming?: boolean\n /** Search highlight: case-insensitive matches wrap in `<mark data-as=\"chat-search-match\">`. */\n query?: string\n /** Click-to-zoom images in a modal (health's medical images, study screenshots). Default false. */\n lightbox?: boolean\n gfm?: boolean\n math?: boolean\n /** Render ```mermaid fences as diagrams (forced off while `streaming`). */\n mermaid?: boolean\n mermaidTheme?: 'neutral' | 'default' | 'dark' | 'forest'\n /** Per-key overrides of the default renderers (mentions, citations, links…). */\n components?: MarkdownComponents\n urlTransform?: UrlTransform\n showCodeLanguage?: boolean\n labels?: Partial<MarkdownCodeBlockLabels & { zoomImage: string; closeImage: string }>\n className?: string\n}\n\nconst fenceLanguage = (className: string | undefined): string | undefined =>\n /language-([\\w+-]+)/.exec(className ?? '')?.[1]\n\ninterface HastNode {\n type: string\n tagName?: string\n value?: string\n properties?: Record<string, unknown>\n children?: HastNode[]\n}\n\nfunction splitMatches(value: string, needle: string): { text: string; match: boolean }[] {\n const segments: { text: string; match: boolean }[] = []\n const lower = value.toLowerCase()\n let index = 0\n for (;;) {\n const found = lower.indexOf(needle, index)\n if (found === -1) {\n segments.push({ text: value.slice(index), match: false })\n break\n }\n if (found > index) {\n segments.push({ text: value.slice(index, found), match: false })\n }\n segments.push({ text: value.slice(found, found + needle.length), match: true })\n index = found + needle.length\n }\n return segments.filter((segment) => segment.text !== '')\n}\n\nfunction highlightTree(node: HastNode, needle: string): void {\n const children = node.children\n if (children === undefined) {\n return\n }\n for (let index = 0; index < children.length; index += 1) {\n const child = children[index]!\n if (child.type === 'text' && child.value !== undefined) {\n const segments = splitMatches(child.value, needle)\n if (segments.length > 1 || (segments.length === 1 && segments[0]!.match)) {\n const replaced = segments.map((segment) =>\n segment.match\n ? ({\n type: 'element',\n tagName: 'mark',\n properties: { 'data-as': 'chat-search-match' },\n children: [{ type: 'text', value: segment.text }],\n } satisfies HastNode)\n : { type: 'text', value: segment.text },\n )\n children.splice(index, 1, ...(replaced as HastNode[]))\n index += replaced.length - 1\n }\n } else {\n highlightTree(child, needle)\n }\n }\n}\n\nfunction rehypeHighlightMatches(needle: string) {\n return () => (tree: HastNode) => {\n highlightTree(tree, needle)\n }\n}\n\n/**\n * The family's read-only streaming markdown surface: GFM tables, KaTeX math\n * (error-tolerant while streaming), lazily-imported mermaid diagrams, and\n * copyable code blocks with language tags. Raw HTML is never rendered\n * (no `rehype-raw`) — model output is untrusted input (ai-features §7).\n */\nexport const MarkdownSurface = React.memo(\n React.forwardRef<HTMLDivElement, MarkdownSurfaceProps>(function MarkdownSurface(\n {\n value,\n streaming = false,\n query,\n lightbox = false,\n gfm = true,\n math = true,\n mermaid = true,\n mermaidTheme = 'neutral',\n components,\n urlTransform = defaultUrlTransform,\n showCodeLanguage = true,\n labels,\n className,\n },\n ref,\n ) {\n const mermaidEnabled = mermaid && !streaming\n const highlightQuery =\n query !== undefined && query.trim().length > 0 ? query.trim().toLowerCase() : null\n const [zoom, setZoom] = React.useState<{ src: string; alt: string } | null>(null)\n\n const defaultComponents = React.useMemo<MarkdownComponents>(\n () => ({\n pre: ({ children }) => {\n const child = Array.isArray(children) ? children[0] : children\n if (React.isValidElement(child)) {\n const childProps = child.props as { className?: string; children?: React.ReactNode }\n const text = extractText(childProps.children).replace(/\\n$/, '')\n const language = fenceLanguage(childProps.className)\n if (language === 'mermaid' && mermaidEnabled) {\n return <MermaidDiagram code={text} theme={mermaidTheme} labels={{ diagram: labels?.code }} />\n }\n return (\n <MarkdownCodeBlock code={text} language={language} showLanguage={showCodeLanguage} labels={labels} />\n )\n }\n return <pre>{children}</pre>\n },\n code: ({ className: codeClassName, children, ...rest }) => (\n <code\n className={cn(\n 'rounded-[var(--as-radius-sm)] bg-[var(--as-surface-raised)] px-1 py-0.5 font-mono text-[0.85em]',\n codeClassName,\n )}\n {...rest}\n >\n {children}\n </code>\n ),\n a: ({ href, children, ...rest }) => {\n const external =\n typeof href === 'string' && (href.startsWith('http://') || href.startsWith('https://'))\n return (\n <a\n href={href}\n className=\"text-[var(--as-primary)] underline underline-offset-2\"\n {...(external ? { target: '_blank', rel: 'noopener noreferrer' } : {})}\n {...rest}\n >\n {children}\n </a>\n )\n },\n table: ({ children, ...rest }) => (\n <div className=\"my-3 overflow-x-auto rounded-[var(--as-radius)] border border-[var(--as-border)]\">\n <table className=\"w-full border-collapse text-[0.875em]\" {...rest}>\n {children}\n </table>\n </div>\n ),\n img: ({ alt, ...rest }) => {\n const image = <img alt={alt ?? ''} className=\"my-2 max-w-full rounded-[var(--as-radius)]\" loading=\"lazy\" {...rest} />\n if (!lightbox || typeof rest.src !== 'string') {\n return image\n }\n const zoomLabel = `${labels?.zoomImage ?? 'Zoom image'}${alt ? `: ${alt}` : ''}`\n return (\n <button\n type=\"button\"\n aria-label={zoomLabel}\n title={zoomLabel}\n onClick={() => setZoom({ src: rest.src as string, alt: alt ?? '' })}\n className=\"block cursor-zoom-in rounded-[var(--as-radius)] transition-opacity hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n {image}\n </button>\n )\n },\n }),\n [labels, mermaidEnabled, mermaidTheme, showCodeLanguage, lightbox],\n )\n\n const mergedComponents = React.useMemo(\n () => ({ ...defaultComponents, ...components }),\n [defaultComponents, components],\n )\n\n const remarkPlugins = React.useMemo(\n () => [gfm ? remarkGfm : null, math ? remarkMath : null].filter((plugin) => plugin !== null),\n [gfm, math],\n )\n const rehypePlugins = React.useMemo<ReactMarkdownOptions['rehypePlugins']>(() => {\n const plugins: ReactMarkdownOptions['rehypePlugins'] = []\n if (math) {\n plugins.push([rehypeKatex, { strict: false, throwOnError: false, output: 'html' }])\n }\n if (highlightQuery !== null) {\n plugins.push(rehypeHighlightMatches(highlightQuery))\n }\n return plugins\n }, [math, highlightQuery])\n\n return (\n <div\n ref={ref}\n data-as=\"chat-markdown\"\n data-streaming={streaming || undefined}\n className={cn('min-w-0', className)}\n >\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={mergedComponents}\n urlTransform={urlTransform}\n >\n {value}\n </ReactMarkdown>\n <Modal open={zoom !== null} onOpenChange={(open) => (open ? undefined : setZoom(null))}>\n {zoom !== null ? (\n <ModalContent closeLabel={labels?.closeImage ?? 'Close image'} className=\"w-fit max-w-[92vw] items-center justify-center p-3\">\n <img src={zoom.src} alt={zoom.alt} className=\"max-h-[78vh] max-w-[86vw] rounded-[var(--as-radius)]\" />\n </ModalContent>\n ) : null}\n </Modal>\n </div>\n )\n }),\n)\n\nexport { MarkdownCodeBlock }\n"]}
@@ -1,5 +1,5 @@
1
1
  import { computeUnitDiff } from './chunk-QLP7K3PY.js';
2
- import { MarkdownSurface } from './chunk-KQLKITZL.js';
2
+ import { MarkdownSurface } from './chunk-KLCULTOQ.js';
3
3
  import { cn } from './chunk-RVVXVTH3.js';
4
4
  import * as React from 'react';
5
5
  import { useState, useRef, useMemo, useEffect } from 'react';
@@ -353,5 +353,5 @@ var MarkdownDiffView = React.forwardRef(function MarkdownDiffView2({
353
353
  });
354
354
 
355
355
  export { MarkdownDiffView, splitMarkdownBlocks };
356
- //# sourceMappingURL=chunk-I4R5BRC7.js.map
357
- //# sourceMappingURL=chunk-I4R5BRC7.js.map
356
+ //# sourceMappingURL=chunk-TLFEVL42.js.map
357
+ //# sourceMappingURL=chunk-TLFEVL42.js.map