quassel 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/ChatInputToolbar.d.ts +35 -6
  2. package/ChatMessages.d.ts +19 -15
  3. package/ChatPanel.d.ts +4 -2
  4. package/ChatSendContext.d.ts +7 -12
  5. package/DetailModeSwitch.d.ts +1 -1
  6. package/Markdown.d.ts +4 -11
  7. package/MessageActions.d.ts +1 -10
  8. package/PendingActionCard.d.ts +13 -0
  9. package/QuasselProvider.d.ts +76 -0
  10. package/README.md +39 -38
  11. package/StepPopover.d.ts +1 -1
  12. package/TimestampSwitch.d.ts +2 -2
  13. package/WorkingScenes.d.ts +3 -1
  14. package/attachments.d.ts +24 -0
  15. package/chat-attachments.d.ts +6 -0
  16. package/chat-scroll.d.ts +12 -0
  17. package/chat.css +2051 -0
  18. package/chunk-IGCFQJZB.js +183 -0
  19. package/chunk-IGCFQJZB.js.map +7 -0
  20. package/events.d.ts +74 -17
  21. package/events.js +11 -1
  22. package/index.d.ts +17 -10
  23. package/index.js +1615 -988
  24. package/index.js.map +4 -4
  25. package/options.d.ts +1 -1
  26. package/package.json +12 -10
  27. package/texts.d.ts +38 -11
  28. package/timestamps.d.ts +6 -4
  29. package/types.d.ts +6 -6
  30. package/ui/button.d.ts +8 -0
  31. package/ui/card.d.ts +5 -0
  32. package/ui/cn.d.ts +2 -0
  33. package/ui/popover.d.ts +4 -0
  34. package/ui/spinner.d.ts +2 -0
  35. package/ui/stop-button.d.ts +10 -0
  36. package/ui/toggle.d.ts +8 -0
  37. package/ui/useFileInput.d.ts +20 -0
  38. package/useChatAction.d.ts +6 -0
  39. package/QuestionCard.d.ts +0 -12
  40. package/chunk-DOLTANTM.js +0 -84
  41. package/chunk-DOLTANTM.js.map +0 -7
  42. package/css/chat.css +0 -927
  43. package/css/foundation/base.css +0 -24
  44. package/css/foundation/index.css +0 -3
  45. package/css/foundation/panel.css +0 -111
  46. package/css/foundation/tokens.css +0 -68
  47. package/css/foundation/wash.css +0 -26
  48. package/css/question.css +0 -149
  49. package/icons.d.ts +0 -15
  50. package/server/http.d.ts +0 -17
  51. package/server/index.d.ts +0 -6
  52. package/server/index.js +0 -478
  53. package/server/index.js.map +0 -7
  54. package/server/manager.d.ts +0 -12
  55. package/server/openai.d.ts +0 -16
  56. package/server/session.d.ts +0 -27
  57. package/server/store.d.ts +0 -18
  58. package/server/types.d.ts +0 -62
  59. package/useChat.d.ts +0 -14
package/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/types.ts", "../src/texts.ts", "../src/useChat.ts", "../src/ChatMessages.tsx", "../src/options.ts", "../src/timestamps.ts", "../src/MessageActions.tsx", "../src/ChatSendContext.ts", "../src/Markdown.tsx", "../src/announce.ts", "../src/StepPopover.tsx", "../src/icons.tsx", "../src/QuestionCard.tsx", "../src/WorkingScenes.tsx", "../src/ChatPanel.tsx", "../src/TimestampSwitch.tsx", "../src/ChatInputToolbar.tsx", "../src/DetailModeSwitch.tsx"],
4
- "sourcesContent": ["import type { Message } from \"./events\";\n\nexport type { Role, ToolInfo, Question, Message, ChatEvent } from \"./events\";\nexport { applyEvent, prettyJson, compactToolLine } from \"./events\";\n\n/**\n * off = nur Antworten, icons = Schritte als reine Symbole nebeneinander,\n * chips = Schritte als Symbol + Kurztext nebeneinander (mit Umbruch),\n * grouped = aufeinanderfolgende Schritte hinter einer aufklappbaren Kopfzeile, darin einzeilig,\n * compact = Denken und Werkzeuge einzeilig, full = alles ausgeklappt.\n */\nexport type DetailMode = \"off\" | \"icons\" | \"chips\" | \"grouped\" | \"compact\" | \"full\";\n\n/** running = call still open, thinking = thought block still open, done = finished, error = failed. */\nexport type StepState = \"running\" | \"thinking\" | \"done\" | \"error\";\n\n/** The single derivation of a step state, so chips, hosts and tests read the same signal. */\nexport function stepState(message: Message): StepState {\n if (message.tool?.isError) {\n return \"error\";\n }\n if (message.role === \"thinking\") {\n return message.closed ? \"done\" : \"thinking\";\n }\n return message.tool !== undefined && message.tool.result === undefined ? \"running\" : \"done\";\n}\n\n/** A moment worth one screen reader announcement: a finished reply or a new open question. */\nexport type ChatAnnouncement =\n | { kind: \"reply\"; message: Message }\n | { kind: \"question\"; message: Message };\n", "export interface ChatTexts {\n working: string;\n toolRunning: string;\n toolStillRunning: string;\n thinkingChip: string;\n stepGroupOne: string;\n stepGroupMany: string;\n stepGroupCollapse: string;\n thinkingTitle: string;\n toolTitle: string;\n argumentsLabel: string;\n resultLabel: string;\n close: string;\n jumpToEnd: string;\n send: string;\n sendIntoRun: string;\n stop: string;\n placeholder: string;\n steeringPlaceholder: string;\n timestamps: string;\n messageActions: string;\n questionSubmit: string;\n questionPlaceholder: string;\n questionAnswer: string;\n copyMessage: string;\n copyCode: string;\n copied: string;\n copyFailed: string;\n editMessage: string;\n retryMessage: string;\n detailModeTitle: string;\n detailModeOff: string;\n detailModeIcons: string;\n detailModeChips: string;\n detailModeGrouped: string;\n detailModeCompact: string;\n detailModeFull: string;\n}\n\nexport const defaultTexts: ChatTexts = {\n working: \"Arbeitet ...\",\n toolRunning: \"l\u00E4uft ...\",\n toolStillRunning: \"Werkzeug l\u00E4uft ...\",\n thinkingChip: \"Denken\",\n stepGroupOne: \"1 Schritt\",\n stepGroupMany: \"{count} Schritte\",\n stepGroupCollapse: \"Einklappen\",\n thinkingTitle: \"Thinking-Trace\",\n toolTitle: \"Tool-Call\",\n argumentsLabel: \"Argumente\",\n resultLabel: \"Ergebnis\",\n close: \"Schlie\u00DFen\",\n jumpToEnd: \"Zum Ende springen\",\n send: \"Senden\",\n sendIntoRun: \"In den laufenden Lauf schicken\",\n stop: \"Lauf abbrechen\",\n placeholder: \"Nachricht schreiben ...\",\n steeringPlaceholder: \"Dazwischenfunken ...\",\n timestamps: \"Zeitstempel\",\n messageActions: \"Nachrichtenaktionen\",\n questionSubmit: \"Auswahl \u00FCbernehmen\",\n questionPlaceholder: \"... oder frei antworten\",\n questionAnswer: \"Antworten\",\n copyMessage: \"Nachricht kopieren\",\n copyCode: \"Code kopieren\",\n copied: \"Kopiert\",\n copyFailed: \"Kopieren ist nicht verf\u00FCgbar.\",\n editMessage: \"Nachricht bearbeiten\",\n retryMessage: \"Erneut senden\",\n detailModeTitle: \"Detailgrad der Schritte\",\n detailModeOff: \"nur Antworten\",\n detailModeIcons: \"Symbole\",\n detailModeChips: \"kompakt\",\n detailModeGrouped: \"gruppiert\",\n detailModeCompact: \"einzeilig\",\n detailModeFull: \"alles\",\n};\n", "import { useCallback, useEffect, useReducer, useRef, useState } from \"react\";\nimport { applyEvent, ChatEvent, Message } from \"./events\";\n\n/**\n * Verbindet die Chat-Komponenten mit einem quassel/server-Endpunkt: ein dauerhafter\n * SSE-Strom liefert erst den Verlauf, dann live; Senden und Stoppen sind eigene Aufrufe\n * und erreichen so auch einen laufenden Turn. Bricht der Strom ab, verbindet der Hook\n * nach 3 Sekunden neu.\n */\nexport function useChat(baseUrl: string, headers: Record<string, string> = {}, onEvent?: (event: ChatEvent) => void): {\n messages: Message[];\n running: boolean;\n connected: boolean;\n send: (text: string) => Promise<void>;\n stop: () => Promise<void>;\n} {\n const [messages, dispatch] = useReducer(applyEvent, [] as Message[]);\n const [running, setRunning] = useState(false);\n const [connected, setConnected] = useState(false);\n const url = useRef(baseUrl);\n url.current = baseUrl;\n const zusatz = useRef(headers);\n zusatz.current = headers;\n const observer = useRef(onEvent);\n observer.current = onEvent;\n\n useEffect(() => {\n const controller = new AbortController();\n let active = true;\n\n async function verbinden() {\n while (active) {\n try {\n const response = await fetch(`${url.current}/stream`, {\n headers: { Accept: \"text/event-stream\", ...zusatz.current },\n signal: controller.signal,\n });\n if (!response.ok || !response.body) {\n throw new Error(`Stream fehlgeschlagen: ${response.status}`);\n }\n setConnected(true);\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let puffer = \"\";\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n puffer += decoder.decode(value, { stream: true });\n const teile = puffer.split(\"\\n\\n\");\n puffer = teile.pop() ?? \"\";\n for (const teil of teile) {\n const daten = teil\n .split(\"\\n\")\n .filter((zeile) => zeile.startsWith(\"data:\"))\n .map((zeile) => zeile.slice(5).trim())\n .join(\"\");\n if (!daten) {\n continue;\n }\n const event = JSON.parse(daten) as ChatEvent;\n if (event.kind === \"status\") {\n setRunning(event.running);\n }\n observer.current?.(event);\n dispatch(event);\n }\n }\n } catch {\n if (!active) {\n return;\n }\n }\n setConnected(false);\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n }\n\n void verbinden();\n return () => {\n active = false;\n controller.abort();\n };\n }, []);\n\n const send = useCallback(async (text: string) => {\n await fetch(`${url.current}/send`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...zusatz.current },\n body: JSON.stringify({ text }),\n });\n }, []);\n\n const stop = useCallback(async () => {\n await fetch(`${url.current}/stop`, { method: \"POST\", headers: { ...zusatz.current } });\n }, []);\n\n return { messages, running, connected, send, stop };\n}\n", "import { ReactNode, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { appearanceStyle, type ChatAppearance, type TimestampOptions, type CodeBlockOptions, type BubbleOptions, type MessageActionsOptions } from \"./options\";\nimport { timestampDate, formatTimestamp, timestampDay, formatDay } from \"./timestamps\";\nimport { MessageActions } from \"./MessageActions\";\nimport { ChatSendContext } from \"./ChatSendContext\";\nimport { ChatAnnouncement, compactToolLine, DetailMode, Message, prettyJson, stepState, ToolInfo } from \"./types\";\nimport { ChatTexts, defaultTexts } from \"./texts\";\nimport { Markdown, MarkdownLinks, MarkdownCodeBlocks, markdownPlainText, type LinkClickHandler } from \"./Markdown\";\nimport { announce as ansagen } from \"./announce\";\nimport { StepPopover } from \"./StepPopover\";\nimport { QuestionCard } from \"./QuestionCard\";\nimport { WorkingScenes } from \"./WorkingScenes\";\nimport { IconCheck, IconChevronDown, IconChevronRight, IconLayers, IconSpark, IconTool } from \"./icons\";\n\nconst collapseAtBottomFrom = 11;\nconst hoechstensAnsagenAufEinmal = 2;\n\nfunction istSchritt(message?: Message): boolean {\n return !!message && (message.role === \"thinking\" || message.role === \"tool\");\n}\n\nfunction defaultArgumentsText(tool: ToolInfo): string {\n return prettyJson(tool.arguments);\n}\n\n/**\n * Der Verlauf: eigener Scroll-Container mit Autoscroll, solange man unten ist,\n * und einem Zum-Ende-Knopf, sobald man liest. Ohne Eingabe read-only nutzbar.\n */\nexport function ChatMessages({\n messages,\n detailMode = \"compact\",\n running = false,\n working,\n workingTimeoutMs = 20000,\n stepsExpandable = true,\n texts,\n toolArgumentsText = defaultArgumentsText,\n renderTool,\n onAnswerQuestion,\n onLinkClick,\n announce,\n emptyState,\n className,\n showTimestamps = false,\n bottomThreshold = 120,\n scrollerRef,\n appearance,\n timestampOptions,\n codeBlockOptions,\n bubbleOptions,\n messageActions,\n}: {\n messages: Message[];\n appearance?: ChatAppearance;\n timestampOptions?: TimestampOptions;\n codeBlockOptions?: CodeBlockOptions;\n bubbleOptions?: BubbleOptions;\n messageActions?: MessageActionsOptions;\n detailMode?: DetailMode;\n running?: boolean;\n working?: ReactNode;\n /** Ohne neue Events verschwindet der Working-Indikator nach dieser Zeit, Default 20s. */\n workingTimeoutMs?: number;\n /** false = Denk- und Werkzeug-Schritte lassen sich nicht aufklappen (kein Popover). */\n stepsExpandable?: boolean;\n texts?: Partial<ChatTexts>;\n toolArgumentsText?: (tool: ToolInfo) => string;\n /** Eigene Darstellung fuer einzelne Werkzeuge; undefined = Standarddarstellung. */\n renderTool?: (tool: ToolInfo) => ReactNode | undefined;\n onAnswerQuestion?: (callId: string, text: string) => void;\n /** Faengt Klicks auf Markdown-Links ab; true = behandelt, der Browser folgt nicht. */\n onLinkClick?: LinkClickHandler;\n /** Screenreader-Ansage je fertiger Antwort und neuer R\u00FCckfrage: Default ist ihr Text, eine Funktion liefert eigenen Text (undefined = still), false schaltet ab. */\n announce?: false | ((announcement: ChatAnnouncement) => string | undefined);\n emptyState?: ReactNode;\n className?: string;\n /** true = dezente HH:MM-Spalte links an jedem Block (Message.at). */\n showTimestamps?: boolean;\n bottomThreshold?: number;\n /** Exposes the scroll container so hosts can scroll without querying the DOM. */\n scrollerRef?: (element: HTMLDivElement | null) => void;\n}) {\n const alleTexte = { ...defaultTexts, ...texts };\n const scrollBereich = useRef<HTMLDivElement>(null);\n const [amEnde, setAmEnde] = useState(true);\n const folgt = useRef(amEnde);\n folgt.current = amEnde;\n const panel = useContext(ChatSendContext);\n useLayoutEffect(() => panel?.registerJump(() => {\n setAmEnde(true);\n const viewport = scrollBereich.current;\n if (viewport) viewport.scrollTop = viewport.scrollHeight;\n }), [panel]);\n const [now, setNow] = useState(Date.now);\n const relative = showTimestamps && timestampOptions?.format === \"relative\";\n useEffect(() => {\n if (!relative) return;\n setNow(Date.now());\n const timer = window.setInterval(() => setNow(Date.now()), 1000);\n return () => window.clearInterval(timer);\n }, [relative]);\n\n // Der Indikator laeuft nur, solange wirklich Events eintreffen: jede Aenderung am Verlauf\n // gilt als Lebenszeichen, danach zaehlt der Timeout. Stop beendet ihn ohnehin (running).\n const [stromAktiv, setStromAktiv] = useState(true);\n useEffect(() => {\n setStromAktiv(true);\n const timer = window.setTimeout(() => setStromAktiv(false), workingTimeoutMs);\n return () => window.clearTimeout(timer);\n }, [messages, workingTimeoutMs]);\n\n // Der Verlauf beim Einh\u00E4ngen und ganze Sch\u00FCbe (Reset mit Replay) gelten als bekannt, nicht als neu.\n const angesagt = useRef<ReadonlySet<string>>(new Set(messages.map((message) => message.key)));\n useEffect(() => {\n const faellig = messages.filter((message, index) => !angesagt.current.has(message.key) && (\n message.role === \"question\"\n ? message.question !== undefined && message.question.answer === undefined\n : message.role === \"assistant\" && message.text.trim() !== \"\" && (message.closed === true || (!running && index === messages.length - 1))\n ));\n if (faellig.length === 0) {\n return;\n }\n angesagt.current = new Set([...angesagt.current, ...faellig.map((message) => message.key)]);\n if (announce === false || faellig.length > hoechstensAnsagenAufEinmal) {\n return;\n }\n faellig\n .map((message) => announce\n ? announce({ kind: message.role === \"question\" ? \"question\" : \"reply\", message })\n : markdownPlainText(message.text))\n .forEach((text) => text && ansagen(text));\n }, [messages, running, announce]);\n\n // Include content that fits without scrolling in the bottom tolerance.\n const pruefeEnde = useCallback(() => {\n const bereich = scrollBereich.current;\n if (bereich) {\n const abstandZumEnde = bereich.scrollHeight - bereich.scrollTop - bereich.clientHeight;\n setAmEnde(abstandZumEnde <= bottomThreshold);\n }\n }, [bottomThreshold]);\n\n // W\u00E4chst der Inhalt oder der Fu\u00DFraum der Eingabe, bleibt ein folgender Verlauf am Ende.\n useEffect(() => {\n const bereich = scrollBereich.current;\n if (!bereich) {\n return;\n }\n const beobachter = new ResizeObserver(() => {\n if (folgt.current) {\n bereich.scrollTop = bereich.scrollHeight;\n } else {\n pruefeEnde();\n }\n });\n beobachter.observe(bereich);\n for (const kind of bereich.children) {\n beobachter.observe(kind);\n }\n return () => beobachter.disconnect();\n }, [pruefeEnde, messages.length]);\n\n useEffect(() => {\n if (!amEnde) {\n return;\n }\n scrollBereich.current?.scrollTo({ top: scrollBereich.current.scrollHeight, behavior: running ? \"auto\" : \"smooth\" });\n }, [messages, running, amEnde]);\n\n const visible = useMemo(\n () =>\n messages.filter((message) => {\n if ((message.role === \"thinking\" || message.role === \"assistant\") && message.text.trim() === \"\") {\n return false;\n }\n if (message.role === \"thinking\" || message.role === \"tool\") {\n return detailMode !== \"off\";\n }\n return true;\n }),\n [messages, detailMode],\n );\n\n // Dezente HH:MM-Spalte links; ohne Zeitstempel bleibt der Block unverpackt.\n const zeitVon = (at: string | undefined) => {\n const date = timestampDate(at);\n return date ? formatTimestamp(date, timestampOptions, now) : \"\";\n };\n const mitZeit = (inhalt: ReactNode, key: string, at: string | undefined): ReactNode =>\n showTimestamps\n ? (\n <div className=\"qsl-line\" key={`zeit-${key}`}>\n <time className=\"qsl-time\" dateTime={timestampDate(at) ? at : undefined} style={timestampOptions?.format && timestampOptions.format !== \"time\" ? { width: \"auto\", maxWidth: \"35%\" } : undefined}>{zeitVon(at)}</time>\n <div className=\"qsl-line-body\">{inhalt}</div>\n </div>\n )\n : inhalt;\n\n // In den Chip-Modi ruecken aufeinanderfolgende Schritte in eine umbrechende Zeile zusammen, gruppiert hinter eine aufklappbare Zeile.\n const chipModus = detailMode === \"chips\" || detailMode === \"icons\";\n const gruppenModus = detailMode === \"grouped\";\n const bloecke: ReactNode[] = [];\n let gruppe: Message[] = [];\n const schliesseGruppe = () => {\n if (gruppe.length > 0) {\n const letzterZustand = stepState(gruppe[gruppe.length - 1]);\n bloecke.push(mitZeit(\n gruppenModus ? (\n <StepGroup\n aktiv={running && (letzterZustand === \"running\" || letzterZustand === \"thinking\")}\n expandierbar={stepsExpandable}\n key={gruppe[0].key}\n messages={gruppe}\n texts={alleTexte}\n toolArgumentsText={toolArgumentsText}\n />\n ) : (\n <StepRow\n expandierbar={stepsExpandable}\n key={gruppe[0].key}\n messages={gruppe}\n mitText={detailMode === \"chips\"}\n texts={alleTexte}\n toolArgumentsText={toolArgumentsText}\n />\n ),\n gruppe[0].key,\n gruppe[0].at,\n ));\n gruppe = [];\n }\n };\n let currentDay: string | undefined;\n visible.forEach((message, index) => {\n const date = timestampOptions?.showDaySeparators ? timestampDate(message.at) : undefined;\n if (date) {\n const day = timestampDay(date, timestampOptions?.timeZone);\n if (day !== currentDay) {\n schliesseGruppe();\n bloecke.push(<div className=\"qsl-day-separator\" role=\"separator\" key={`day-${message.key}`} aria-label={formatDay(date, timestampOptions)}>{formatDay(date, timestampOptions)}</div>);\n currentDay = day;\n }\n }\n const eigeneDarstellung = message.role === \"tool\" && message.tool ? renderTool?.(message.tool) : undefined;\n if (eigeneDarstellung !== undefined) {\n schliesseGruppe();\n bloecke.push(mitZeit(\n <div className=\"qsl-step\" key={message.key}>\n {eigeneDarstellung}\n </div>,\n message.key,\n message.at,\n ));\n return;\n }\n if ((chipModus || gruppenModus) && istSchritt(message)) {\n gruppe = [...gruppe, message];\n return;\n }\n schliesseGruppe();\n bloecke.push(mitZeit(\n <Bubble\n detailMode={detailMode}\n dicht={istSchritt(message) && istSchritt(visible[index - 1])}\n expandierbar={stepsExpandable}\n key={message.key}\n message={message}\n bubbleOptions={bubbleOptions}\n messageActions={messageActions}\n texts={alleTexte}\n toolArgumentsText={toolArgumentsText}\n onAnswerQuestion={onAnswerQuestion}\n />,\n message.key,\n message.at,\n ));\n });\n schliesseGruppe();\n\n const verlauf = (\n <div className={className ? `qsl-chat-wrap ${className}` : \"qsl-chat-wrap\"} style={appearanceStyle(appearance)}>\n <div\n className=\"qsl-chat\"\n onScroll={pruefeEnde}\n ref={(element) => {\n scrollBereich.current = element;\n scrollerRef?.(element);\n }}\n >\n {visible.length === 0 && !running ? (\n emptyState ?? null\n ) : (\n <div aria-busy={running || undefined} className=\"qsl-thread\">\n {bloecke}\n {running && stromAktiv && (working ?? <WorkingScenes label={alleTexte.working} />)}\n </div>\n )}\n </div>\n {!amEnde && (\n <div className=\"qsl-jump\">\n <button aria-label={alleTexte.jumpToEnd} onClick={() => scrollBereich.current?.scrollTo({ top: scrollBereich.current.scrollHeight, behavior: \"smooth\" })} type=\"button\">\n <IconChevronDown />\n </button>\n </div>\n )}\n </div>\n );\n\n return <MarkdownLinks onLinkClick={onLinkClick}><MarkdownCodeBlocks options={codeBlockOptions} texts={texts}>{verlauf}</MarkdownCodeBlocks></MarkdownLinks>;\n}\n\n/** Aufeinanderfolgende Schritte als Chips nebeneinander; bei Platzmangel bricht die Zeile um. */\nfunction StepRow({\n messages,\n mitText,\n expandierbar,\n texts,\n toolArgumentsText,\n}: {\n messages: Message[];\n mitText: boolean;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n}) {\n const [detail, setDetail] = useState<{ key: string; position: { x: number; y: number } }>();\n const offen = expandierbar && detail && messages.find((message) => message.key === detail.key);\n\n return (\n <div className=\"qsl-step qsl-steprow\">\n {messages.map((message) => {\n const thinking = message.role === \"thinking\";\n const tool = message.tool;\n const state = stepState(message);\n const running = state === \"running\" || state === \"thinking\";\n const label = thinking ? texts.thinkingChip : tool?.name ?? message.text;\n const content = (\n <>\n {thinking ? (\n <IconSpark size={11} />\n ) : (\n <IconTool className={tool?.isError ? \"qsl-chip__icon--error\" : undefined} size={11} />\n )}\n {mitText && <span className=\"qsl-chip__label\">{label}</span>}\n {mitText && <span className=\"qsl-chip__state\">{state === \"done\" && <IconCheck size={10} />}</span>}\n </>\n );\n const classes = `${mitText ? \"\" : \" qsl-chip--icon\"} qsl-chip--${state}${running ? \" qsl-pulse\" : \"\"}`;\n if (!expandierbar) {\n return (\n <span className={`qsl-chip qsl-chip--still${classes}`} key={message.key} title={label}>\n {content}\n </span>\n );\n }\n return (\n <button\n aria-haspopup=\"dialog\"\n className={`qsl-chip${classes}`}\n key={message.key}\n onClick={(event) => setDetail({ key: message.key, position: { x: event.clientX, y: event.clientY } })}\n title={label}\n type=\"button\"\n >\n {content}\n </button>\n );\n })}\n {offen && detail && (\n <StepPopover\n message={offen}\n position={detail.position}\n texts={texts}\n toolArgumentsText={toolArgumentsText}\n onClose={() => setDetail(undefined)}\n />\n )}\n </div>\n );\n}\n\n/** Aufeinanderfolgende Schritte hinter einer Kopfzeile; aufgeklappt stehen sie einzeilig darunter. */\nfunction StepGroup({\n messages,\n aktiv,\n expandierbar,\n texts,\n toolArgumentsText,\n}: {\n messages: Message[];\n aktiv: boolean;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n}) {\n const [offen, setOffen] = useState(false);\n const kopf = useRef<HTMLButtonElement>(null);\n const vonUntenEingeklappt = useRef(false);\n useLayoutEffect(() => {\n if (!offen && vonUntenEingeklappt.current) {\n vonUntenEingeklappt.current = false;\n kopf.current?.scrollIntoView({ block: \"nearest\" });\n }\n }, [offen]);\n const letzte = messages[messages.length - 1];\n const fehler = messages.some((message) => message.tool?.isError);\n const anzahl = messages.length === 1 ? texts.stepGroupOne : texts.stepGroupMany.replace(\"{count}\", String(messages.length));\n const laufend = aktiv ? (letzte.role === \"thinking\" ? texts.thinkingChip : letzte.tool?.name ?? letzte.text) : undefined;\n\n return (\n <div className=\"qsl-step qsl-stepgroup\">\n <button\n aria-expanded={offen}\n className={`qsl-trace qsl-trace--compact qsl-stepgroup__toggle${aktiv ? \" qsl-pulse\" : \"\"}`}\n onClick={() => setOffen((wert) => !wert)}\n ref={kopf}\n type=\"button\"\n >\n <IconChevronRight className=\"qsl-stepgroup__chevron\" size={12} />\n <IconLayers className={fehler ? \"qsl-trace__icon qsl-trace__icon--error\" : \"qsl-trace__icon\"} size={12} />\n <span className=\"qsl-trace__line\">\n {anzahl}\n {laufend && <span className=\"qsl-trace__running\">{laufend} {texts.toolRunning}</span>}\n </span>\n </button>\n {offen && (\n <div className=\"qsl-stepgroup__lines\">\n {messages.map((message) => (\n <TraceLine expandierbar={expandierbar} key={message.key} message={message} texts={texts} toolArgumentsText={toolArgumentsText} />\n ))}\n {messages.length >= collapseAtBottomFrom && (\n <button\n className=\"qsl-trace qsl-trace--compact qsl-stepgroup__toggle qsl-stepgroup__collapse\"\n onClick={() => {\n vonUntenEingeklappt.current = true;\n setOffen(false);\n }}\n type=\"button\"\n >\n <IconChevronRight className=\"qsl-stepgroup__chevron\" size={12} />\n <span className=\"qsl-trace__line\">{texts.stepGroupCollapse}</span>\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\n/** Ein Schritt als eine Zeile; mit Freigabe oeffnet ein Klick die Details im Popover. */\nfunction TraceLine({\n message,\n className,\n expandierbar,\n texts,\n toolArgumentsText,\n}: {\n message: Message;\n className?: string;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n}) {\n const [detailPosition, setDetailPosition] = useState<{ x: number; y: number }>();\n const classes = `${className ? `${className} ` : \"\"}qsl-trace qsl-trace--compact${message.role === \"thinking\" ? \" qsl-trace--thinking\" : \"\"}`;\n const inhalt = (\n <>\n <TraceIcon message={message} />\n <span className=\"qsl-trace__line\"><TraceText message={message} texts={texts} /></span>\n </>\n );\n if (!expandierbar) {\n return <div className={classes}>{inhalt}</div>;\n }\n return (\n <>\n <button\n aria-expanded={detailPosition !== undefined}\n aria-haspopup=\"dialog\"\n className={classes}\n onClick={(event) => setDetailPosition({ x: event.clientX, y: event.clientY })}\n type=\"button\"\n >\n {inhalt}\n </button>\n {detailPosition && (\n <StepPopover\n message={message}\n position={detailPosition}\n texts={texts}\n toolArgumentsText={toolArgumentsText}\n onClose={() => setDetailPosition(undefined)}\n />\n )}\n </>\n );\n}\n\nfunction TraceIcon({ message }: { message: Message }) {\n return message.role === \"thinking\"\n ? <IconSpark className=\"qsl-trace__icon\" size={12} />\n : <IconTool className={message.tool?.isError ? \"qsl-trace__icon qsl-trace__icon--error\" : \"qsl-trace__icon\"} size={12} />;\n}\n\nfunction TraceText({ message, texts }: { message: Message; texts: ChatTexts }) {\n return (\n <>\n {message.text}\n {message.tool && message.tool.result === undefined && <span className=\"qsl-trace__running\">{texts.toolRunning}</span>}\n </>\n );\n}\n\nfunction Bubble({\n message,\n bubbleOptions,\n messageActions,\n detailMode,\n dicht,\n expandierbar,\n texts,\n toolArgumentsText,\n onAnswerQuestion,\n}: {\n message: Message;\n bubbleOptions?: BubbleOptions;\n messageActions?: MessageActionsOptions;\n detailMode: DetailMode;\n dicht: boolean;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n onAnswerQuestion?: (callId: string, text: string) => void;\n}) {\n const schritt = dicht ? \"qsl-step qsl-step--dense\" : \"qsl-step\";\n\n if (message.role === \"thinking\" || (message.role === \"tool\" && message.tool)) {\n if (detailMode === \"compact\") {\n return <TraceLine className={schritt} expandierbar={expandierbar} message={message} texts={texts} toolArgumentsText={toolArgumentsText} />;\n }\n const tool = message.tool;\n return (\n <div className={`${schritt} qsl-trace${message.role === \"thinking\" ? \" qsl-trace--thinking\" : \"\"}`}>\n <TraceIcon message={message} />\n <div className=\"qsl-trace__body\">\n <div className=\"qsl-trace__line\"><TraceText message={message} texts={texts} /></div>\n {tool && (\n <div className=\"qsl-details\">\n <pre>{toolArgumentsText(tool)}</pre>\n {tool.result !== undefined && (\n <pre className={tool.isError ? \"qsl-details__pre--error\" : undefined}>{prettyJson(tool.result)}</pre>\n )}\n </div>\n )}\n </div>\n </div>\n );\n }\n\n if (message.role === \"question\" && message.question) {\n return (\n <div className={schritt}>\n <QuestionCard\n question={message.question}\n text={message.text}\n texts={texts}\n onAnswer={(text) => onAnswerQuestion?.(message.question!.callId, text)}\n />\n </div>\n );\n }\n\n if (message.role === \"system\") {\n return (\n <div className={`${schritt} qsl-system`}>\n <Markdown text={message.text} />\n </div>\n );\n }\n\n const content = message.text.trim();\n if (!content && message.role !== \"user\") return null;\n const plain = bubbleOptions?.variant === \"plain\";\n const isBubble = !plain && (message.role === \"user\" || message.bubble || bubbleOptions?.variant === \"bubbles\");\n const side = (message.role === \"user\" ? bubbleOptions?.userSide : bubbleOptions?.assistantSide)\n ?? message.bubble?.side ?? (message.role === \"user\" ? \"end\" : \"start\");\n const label = bubbleOptions?.showSender === false ? undefined\n : bubbleOptions?.senderLabel?.(message) ?? message.bubble?.label ?? (bubbleOptions?.showSender ? message.role : undefined);\n const body = <>\n {label && <span className=\"qsl-bubble__label\">{label}</span>}\n <Markdown text={message.role === \"user\" ? message.text : content} />\n <MessageActions message={message} options={messageActions} texts={texts} />\n </>;\n if (isBubble) {\n const user = message.role === \"user\" && !message.bubble;\n return <div className={`${schritt} ${user ? \"qsl-user\" : \"qsl-bubble\"}`} style={{ justifyContent: side === \"end\" ? \"flex-end\" : \"flex-start\" }}>\n <div style={{ background: message.bubble?.color ?? (user ? undefined : \"var(--qsl-accent)\"), maxWidth: bubbleOptions?.maxWidth }}>\n {body}\n </div>\n </div>;\n }\n return <div className={`${schritt} qsl-answer`}>{body}</div>;\n}\n", "import type { CSSProperties, ReactNode } from \"react\";\nimport type { Message } from \"./types\";\n\nexport interface ChatAppearance {\n fontSize?: CSSProperties[\"fontSize\"];\n lineHeight?: CSSProperties[\"lineHeight\"];\n messageGap?: CSSProperties[\"marginTop\"];\n denseMessageGap?: CSSProperties[\"marginTop\"];\n}\n\nexport interface TimestampOptions {\n format?: \"time\" | \"date-time\" | \"relative\";\n locale?: string;\n timeZone?: string;\n showDaySeparators?: boolean;\n}\n\nexport interface CodeBlockOptions {\n wrap?: boolean;\n maxHeight?: CSSProperties[\"maxHeight\"];\n showCopyButton?: boolean;\n}\n\nexport interface BubbleOptions {\n variant?: \"default\" | \"plain\" | \"bubbles\";\n maxWidth?: CSSProperties[\"maxWidth\"];\n userSide?: \"start\" | \"end\";\n assistantSide?: \"start\" | \"end\";\n showSender?: boolean;\n senderLabel?: (message: Message) => string | undefined;\n}\n\nexport interface MessageAction {\n id: string;\n label: string;\n icon?: ReactNode;\n disabled?: boolean;\n onClick: (message: Message) => void | Promise<void>;\n}\n\nexport interface MessageActionsOptions {\n copy?: boolean | ((message: Message) => boolean);\n edit?: (message: Message) => void | Promise<void>;\n retry?: (message: Message) => void | Promise<void>;\n custom?: (message: Message) => readonly MessageAction[];\n}\n\nexport type SendShortcut = \"enter\" | \"mod-enter\";\n\nconst length = (value: string | number | undefined) => typeof value === \"number\" ? `${value}px` : value;\n\nexport function appearanceStyle(appearance?: ChatAppearance): CSSProperties {\n return {\n \"--qsl-chat-font-size\": length(appearance?.fontSize),\n \"--qsl-chat-line-height\": appearance?.lineHeight,\n \"--qsl-message-gap\": length(appearance?.messageGap),\n \"--qsl-dense-message-gap\": length(appearance?.denseMessageGap),\n } as CSSProperties;\n}\n", "import type { TimestampOptions } from \"./options\";\n\nexport function timestampDate(at?: string): Date | undefined {\n if (!at) return undefined;\n const date = new Date(at);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\nexport function formatTimestamp(date: Date, options: TimestampOptions = {}, now = Date.now()): string {\n if (options.format === \"relative\") {\n const seconds = (date.getTime() - now) / 1000;\n const [unit, divisor]: [Intl.RelativeTimeFormatUnit, number] = Math.abs(seconds) < 60 ? [\"second\", 1]\n : Math.abs(seconds) < 3600 ? [\"minute\", 60] : Math.abs(seconds) < 86400 ? [\"hour\", 3600] : [\"day\", 86400];\n return new Intl.RelativeTimeFormat(options.locale ?? \"de\", { numeric: \"auto\" }).format(Math.round(seconds / divisor), unit);\n }\n if (options.format === \"date-time\") {\n return new Intl.DateTimeFormat(options.locale ?? \"de\", {\n dateStyle: \"short\", timeStyle: \"short\", timeZone: options.timeZone,\n }).format(date);\n }\n if (!options.locale && !options.timeZone) {\n return `${String(date.getHours()).padStart(2, \"0\")}:${String(date.getMinutes()).padStart(2, \"0\")}`;\n }\n return new Intl.DateTimeFormat(options.locale ?? \"de\", {\n hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\", timeZone: options.timeZone,\n }).format(date);\n}\n\nexport function timestampDay(date: Date, timeZone?: string): string {\n return new Intl.DateTimeFormat(\"en-CA\", {\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\", calendar: \"gregory\", numberingSystem: \"latn\", timeZone,\n }).format(date);\n}\n\nexport function formatDay(date: Date, options?: TimestampOptions): string {\n return new Intl.DateTimeFormat(options?.locale ?? \"de\", {\n dateStyle: \"long\", timeZone: options?.timeZone,\n }).format(date);\n}\n", "import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport type { MessageActionsOptions } from \"./options\";\nimport type { ChatTexts } from \"./texts\";\nimport type { Message } from \"./types\";\n\nexport function ActionButton({ label, icon, disabled, onClick, successLabel }: {\n label: string;\n icon?: ReactNode;\n disabled?: boolean;\n onClick: () => void | Promise<void>;\n successLabel?: string;\n}) {\n const pending = useRef(false);\n const [status, setStatus] = useState<\"idle\" | \"pending\" | \"done\">(\"idle\");\n const [error, setError] = useState<string>();\n useEffect(() => {\n if (status !== \"done\") return;\n const timer = window.setTimeout(() => setStatus(\"idle\"), 1800);\n return () => window.clearTimeout(timer);\n }, [status]);\n const run = async () => {\n if (pending.current) return;\n pending.current = true;\n setStatus(\"pending\");\n setError(undefined);\n try {\n await onClick();\n setStatus(\"done\");\n } catch (failure) {\n setStatus(\"idle\");\n setError(failure instanceof Error ? failure.message : String(failure));\n } finally {\n pending.current = false;\n }\n };\n return <>\n <button className=\"qsl-icon-button\" type=\"button\" disabled={disabled || status === \"pending\"} onClick={() => void run()}>\n {icon}{status === \"done\" && successLabel ? successLabel : label}\n </button>\n {error && <span className=\"qsl-action-error\" role=\"alert\">{error}</span>}\n </>;\n}\n\nexport async function copyText(text: string, error: string) {\n if (!navigator.clipboard) throw new Error(error);\n await navigator.clipboard.writeText(text);\n}\n\nexport function MessageActions({ message, options, texts }: { message: Message; options?: MessageActionsOptions; texts: ChatTexts }) {\n if (!options) return null;\n const copy = typeof options.copy === \"function\" ? options.copy(message) : options.copy;\n const edit = message.role === \"user\" ? options.edit : undefined;\n const retry = message.role === \"assistant\" ? options.retry : undefined;\n const custom = options.custom?.(message) ?? [];\n if (!copy && !edit && !retry && custom.length === 0) return null;\n return <div className=\"qsl-message-actions\" role=\"group\" aria-label={texts.messageActions}>\n {copy && <ActionButton label={texts.copyMessage} successLabel={texts.copied} onClick={() => copyText(message.text, texts.copyFailed)} />}\n {edit && <ActionButton label={texts.editMessage} onClick={() => edit(message)} />}\n {retry && <ActionButton label={texts.retryMessage} onClick={() => retry(message)} />}\n {custom.map(action => <ActionButton key={action.id} label={action.label} icon={action.icon} disabled={action.disabled} onClick={() => action.onClick(message)} />)}\n </div>;\n}\n", "import { createContext, useContext, useLayoutEffect, useRef, useState } from \"react\";\nimport type { KeyboardEvent } from \"react\";\nimport type { SendShortcut } from \"./options\";\n\nexport const ChatSendContext = createContext<{\n onSent: () => void;\n registerJump: (jump: () => void) => () => void;\n} | undefined>(undefined);\n\nexport function isSendKey(event: KeyboardEvent<HTMLTextAreaElement>, shortcut: SendShortcut): boolean {\n return event.key === \"Enter\" && !event.shiftKey && !event.altKey\n && !event.nativeEvent.isComposing && event.nativeEvent.keyCode !== 229\n && (shortcut === \"enter\" || event.ctrlKey || event.metaKey);\n}\n\nexport function useChatSubmit(onSend: (text: string) => void | Promise<void>) {\n const panel = useContext(ChatSendContext);\n const pending = useRef(false);\n const mounted = useRef(true);\n useLayoutEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n const [sending, setSending] = useState(false);\n const [error, setError] = useState<string>();\n const submit = async (text: string): Promise<boolean> => {\n if (pending.current) return false;\n pending.current = true;\n setSending(true);\n setError(undefined);\n try {\n await onSend(text);\n if (!mounted.current) return false;\n panel?.onSent();\n return true;\n } catch (failure) {\n if (mounted.current) setError(failure instanceof Error ? failure.message : String(failure));\n return false;\n } finally {\n pending.current = false;\n if (mounted.current) setSending(false);\n }\n };\n return { submit, sending, error };\n}\n", "import { createContext, ReactNode, useContext } from \"react\";\nimport type { CodeBlockOptions } from \"./options\";\nimport { defaultTexts, type ChatTexts } from \"./texts\";\nimport { ActionButton, copyText } from \"./MessageActions\";\n\nconst CodeBlockContext = createContext<{ options?: CodeBlockOptions; texts?: Partial<ChatTexts> }>({});\n\nexport function MarkdownCodeBlocks({ children, options, texts }: {\n children: ReactNode;\n options?: CodeBlockOptions;\n texts?: Partial<ChatTexts>;\n}) {\n return <CodeBlockContext.Provider value={{ options, texts }}>{children}</CodeBlockContext.Provider>;\n}\n\nfunction CodeBlock({ text }: { text: string }) {\n const { options, texts } = useContext(CodeBlockContext);\n const labels = { ...defaultTexts, ...texts };\n const content = <pre style={{\n whiteSpace: options?.wrap ? \"pre-wrap\" : undefined,\n overflowWrap: options?.wrap ? \"anywhere\" : undefined,\n maxHeight: options?.maxHeight,\n overflowY: options?.maxHeight === undefined ? undefined : \"auto\",\n }}><code>{text}</code></pre>;\n return options?.showCopyButton ? <div className=\"qsl-code-block\">\n <ActionButton label={labels.copyCode} successLabel={labels.copied} onClick={() => copyText(text, labels.copyFailed)} />\n {content}\n </div> : content;\n}\n\n/**\n * Schlanker Markdown-Renderer ohne Abh\u00E4ngigkeit: \u00DCberschriften, **fett**, *kursiv*,\n * `code`, Links, Listen, Blockquotes, Code-Bl\u00F6cke und Tabellen. Bewusst sicher (reines\n * React, kein dangerouslySetInnerHTML) und streaming-robust: zeilenbasiert, unvollst\u00E4ndige\n * Bl\u00F6cke werden so weit gerendert wie vorhanden.\n */\n/** true = der Host hat den Link behandelt, der Browser folgt ihm nicht. */\nexport type LinkClickHandler = (href: string, label: string) => boolean;\n\nconst LinkClickContext = createContext<LinkClickHandler | undefined>(undefined);\n\n/** Faengt Klicks auf Markdown-Links im Teilbaum ab, z.B. fuer eigene Ziele der Gastseite. */\nexport function MarkdownLinks({ children, onLinkClick }: { children: ReactNode; onLinkClick?: LinkClickHandler }) {\n return <LinkClickContext.Provider value={onLinkClick}>{children}</LinkClickContext.Provider>;\n}\n\nfunction MarkdownLink({ href, label }: { href: string; label: string }) {\n const onLinkClick = useContext(LinkClickContext);\n return (\n <a\n href={href}\n onClick={(event) => {\n if (onLinkClick?.(href, label)) {\n event.preventDefault();\n }\n }}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {label}\n </a>\n );\n}\n\nexport function Markdown({ text }: { text: string }) {\n const lines = text.split(\"\\n\");\n const blocks: ReactNode[] = [];\n let i = 0;\n let key = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n const fence = line.match(/^\\s*```(\\w*)\\s*$/);\n if (fence) {\n const body: string[] = [];\n i++;\n while (i < lines.length && !/^\\s*```\\s*$/.test(lines[i])) {\n body.push(lines[i]);\n i++;\n }\n if (i < lines.length) {\n i++;\n }\n blocks.push(\n <CodeBlock key={key++} text={body.join(\"\\n\")} />,\n );\n continue;\n }\n\n if (line.includes(\"|\") && i + 1 < lines.length && isTableDivider(lines[i + 1])) {\n const header = splitTableRow(line);\n i += 2;\n const rows: string[][] = [];\n while (i < lines.length && lines[i].includes(\"|\") && lines[i].trim() !== \"\") {\n rows.push(splitTableRow(lines[i]));\n i++;\n }\n blocks.push(\n <div className=\"qsl-md-scroll\" key={key++}>\n <table>\n <thead>\n <tr>\n {header.map((cell, ci) => (\n <th key={ci}>{renderInline(cell, `th${key}_${ci}`)}</th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, ri) => (\n <tr key={ri}>\n {header.map((_, ci) => (\n <td key={ci}>{renderInline(row[ci] ?? \"\", `td${key}_${ri}_${ci}`)}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>,\n );\n continue;\n }\n\n const heading = line.match(/^(#{1,4})\\s+(.*)$/);\n if (heading) {\n const level = heading[1].length;\n blocks.push(\n level === 1 ? (\n <h3 key={key++}>{renderInline(heading[2], `h${key}`)}</h3>\n ) : (\n <h4 key={key++}>{renderInline(heading[2], `h${key}`)}</h4>\n ),\n );\n i++;\n continue;\n }\n\n const quote = line.match(/^\\s*>\\s?(.*)$/);\n if (quote) {\n blocks.push(<blockquote key={key++}>{renderInline(quote[1], `q${key}`)}</blockquote>);\n i++;\n continue;\n }\n\n const bullet = line.match(/^\\s*[-*]\\s+(.*)$/);\n if (bullet) {\n blocks.push(\n <div className=\"qsl-md-bullet\" key={key++}>\n <span>&bull;</span>\n <span>{renderInline(bullet[1], `l${key}`)}</span>\n </div>,\n );\n i++;\n continue;\n }\n\n const numbered = line.match(/^\\s*(\\d+)\\.\\s+(.*)$/);\n if (numbered) {\n blocks.push(\n <div className=\"qsl-md-bullet\" key={key++}>\n <span>{numbered[1]}.</span>\n <span>{renderInline(numbered[2], `l${key}`)}</span>\n </div>,\n );\n i++;\n continue;\n }\n\n if (line.trim() === \"\") {\n blocks.push(<div className=\"qsl-md-gap\" key={key++} />);\n i++;\n continue;\n }\n\n blocks.push(<p key={key++}>{renderInline(line, `l${key}`)}</p>);\n i++;\n }\n\n return <div className=\"qsl-md\">{blocks}</div>;\n}\n\nfunction renderInline(text: string, keyPrefix: string): ReactNode[] {\n const out: ReactNode[] = [];\n const pattern = /\\[([^\\]]+)\\]\\(([^)]+)\\)|\\*\\*([^*]+)\\*\\*|\\*([^*]+)\\*|`([^`]+)`/g;\n let last = 0;\n let match: RegExpExecArray | null;\n let i = 0;\n\n while ((match = pattern.exec(text)) !== null) {\n if (match.index > last) {\n out.push(text.slice(last, match.index));\n }\n if (match[1] !== undefined) {\n out.push(<MarkdownLink href={match[2]} key={`${keyPrefix}a${i}`} label={match[1]} />);\n } else if (match[3] !== undefined) {\n out.push(<strong key={`${keyPrefix}b${i}`}>{match[3]}</strong>);\n } else if (match[4] !== undefined) {\n out.push(<em key={`${keyPrefix}i${i}`}>{match[4]}</em>);\n } else if (match[5] !== undefined) {\n out.push(<code key={`${keyPrefix}c${i}`}>{match[5]}</code>);\n }\n last = match.index + match[0].length;\n i++;\n }\n if (last < text.length) {\n out.push(text.slice(last));\n }\n return out;\n}\n\n/** Dieselbe Syntax wie der Renderer, als Klartext ohne Markup, etwa f\u00FCr Screenreader-Ansagen. */\nexport function markdownPlainText(text: string): string {\n return text\n .split(\"\\n\")\n .filter((line) => !/^\\s*```\\w*\\s*$/.test(line) && !isTableDivider(line))\n .map((line) => (line.trim().startsWith(\"|\") ? splitTableRow(line).join(\", \") : line)\n .replace(/^(#{1,4})\\s+/, \"\")\n .replace(/^\\s*>\\s?/, \"\")\n .replace(/^\\s*[-*]\\s+/, \"\")\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)|\\*\\*([^*]+)\\*\\*|\\*([^*]+)\\*|`([^`]+)`/g, (_, link, _href, fett, kursiv, code) => link ?? fett ?? kursiv ?? code)\n .trim())\n .filter((line) => line !== \"\")\n .join(\"\\n\");\n}\n\nfunction splitTableRow(line: string): string[] {\n let row = line.trim();\n if (row.startsWith(\"|\")) {\n row = row.slice(1);\n }\n if (row.endsWith(\"|\")) {\n row = row.slice(0, -1);\n }\n return row.split(\"|\").map((cell) => cell.trim());\n}\n\nfunction isTableDivider(line: string): boolean {\n return /^\\s*\\|?\\s*:?-{1,}:?\\s*(\\|\\s*:?-{1,}:?\\s*)*\\|?\\s*$/.test(line) && line.includes(\"-\");\n}\n", "const abstandMs = 400;\nconst hoechstensWartend = 5;\n\nlet region: HTMLElement | undefined;\nlet wartend: readonly string[] = [];\nlet laeuft = false;\n\nfunction ansageRegion(): HTMLElement {\n if (region?.isConnected) {\n return region;\n }\n const element = document.createElement(\"div\");\n element.setAttribute(\"role\", \"status\");\n element.setAttribute(\"aria-live\", \"polite\");\n element.setAttribute(\"aria-atomic\", \"true\");\n Object.assign(element.style, {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n margin: \"-1px\",\n padding: \"0\",\n border: \"0\",\n overflow: \"hidden\",\n clipPath: \"inset(50%)\",\n whiteSpace: \"nowrap\",\n });\n document.body.append(element);\n region = element;\n return element;\n}\n\nfunction naechste(): void {\n if (wartend.length === 0) {\n laeuft = false;\n return;\n }\n if (document.visibilityState === \"hidden\") {\n document.addEventListener(\"visibilitychange\", naechste, { once: true });\n return;\n }\n const [text, ...rest] = wartend;\n wartend = rest;\n const ziel = ansageRegion();\n ziel.textContent = ziel.textContent === text ? `${text}\u00A0` : text;\n window.setTimeout(naechste, abstandMs);\n}\n\n/** Sagt Text \u00FCber eine gemeinsame, versteckte Live-Region an: gedrosselt, und bei verstecktem Tab angehalten. */\nexport function announce(text: string): void {\n const inhalt = text.trim();\n if (!inhalt || typeof document === \"undefined\") {\n return;\n }\n wartend = [...wartend, inhalt].slice(-hoechstensWartend);\n if (laeuft) {\n return;\n }\n laeuft = true;\n ansageRegion();\n window.setTimeout(naechste, abstandMs);\n}\n", "import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Message, prettyJson } from \"./types\";\nimport { IconSpark, IconTool, IconX } from \"./icons\";\nimport { ChatTexts } from \"./texts\";\n\nexport function StepPopover({\n message,\n position,\n texts,\n toolArgumentsText,\n onClose,\n}: {\n message: Message;\n position: { x: number; y: number };\n texts: ChatTexts;\n toolArgumentsText: (tool: NonNullable<Message[\"tool\"]>) => string;\n onClose: () => void;\n}) {\n const popover = useRef<HTMLDivElement>(null);\n const [placement, setPlacement] = useState<{ left: number; top: number }>();\n\n useLayoutEffect(() => {\n const element = popover.current;\n if (!element) {\n return;\n }\n const margin = 16;\n const gap = 10;\n const bounds = element.getBoundingClientRect();\n const preferredLeft = position.x + gap;\n const preferredTop = position.y + gap;\n const left =\n preferredLeft + bounds.width <= window.innerWidth - margin\n ? preferredLeft\n : position.x - bounds.width - gap;\n const top =\n preferredTop + bounds.height <= window.innerHeight - margin\n ? preferredTop\n : position.y - bounds.height - gap;\n setPlacement({\n left: Math.max(margin, Math.min(left, window.innerWidth - bounds.width - margin)),\n top: Math.max(margin, Math.min(top, window.innerHeight - bounds.height - margin)),\n });\n }, [message.text, message.tool?.result, position]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [onClose]);\n\n // Klick daneben schliesst - auch wenn der Host etwas ueber den Backdrop legt.\n useEffect(() => {\n const handlePointerDown = (event: PointerEvent) => {\n if (!popover.current?.contains(event.target as Node)) {\n onClose();\n }\n };\n document.addEventListener(\"pointerdown\", handlePointerDown, true);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n }, [onClose]);\n\n const tool = message.tool;\n const title = message.role === \"thinking\" ? texts.thinkingTitle : texts.toolTitle;\n\n return createPortal(\n <>\n <div className=\"qsl-popover-backdrop\" onClick={onClose} />\n <div\n aria-label={title}\n className=\"qsl-popover\"\n ref={popover}\n role=\"dialog\"\n style={{\n left: placement?.left ?? position.x,\n top: placement?.top ?? position.y,\n visibility: placement ? \"visible\" : \"hidden\",\n }}\n >\n <div className=\"qsl-popover__head\">\n {message.role === \"thinking\" ? (\n <IconSpark className=\"qsl-popover__icon\" />\n ) : (\n <IconTool className={tool?.isError ? \"qsl-popover__icon qsl-popover__icon--error\" : \"qsl-popover__icon\"} />\n )}\n <span className=\"qsl-popover__title\">{title}</span>\n <button aria-label={texts.close} className=\"qsl-popover__close\" onClick={onClose} title={texts.close} type=\"button\">\n <IconX />\n </button>\n </div>\n <div className=\"qsl-popover__body\">\n {message.role === \"thinking\" ? (\n <div className=\"qsl-popover__thinking\">{message.text}</div>\n ) : tool ? (\n <div className=\"qsl-popover__sections\">\n <div className=\"qsl-popover__toolname\">{message.text}</div>\n <PopoverSection label={texts.argumentsLabel} value={toolArgumentsText(tool)} />\n {tool.result === undefined ? (\n <div className=\"qsl-popover__running\">{texts.toolStillRunning}</div>\n ) : (\n <PopoverSection error={tool.isError} label={texts.resultLabel} value={prettyJson(tool.result)} />\n )}\n </div>\n ) : null}\n </div>\n </div>\n </>,\n document.body,\n );\n}\n\nfunction PopoverSection({ label, value, error = false }: { label: string; value: string; error?: boolean }) {\n return (\n <section>\n <h3>{label}</h3>\n <pre className={error ? \"qsl-popover__pre qsl-popover__pre--error\" : \"qsl-popover__pre\"}>{value}</pre>\n </section>\n );\n}\n", "import { ReactNode } from \"react\";\n\ninterface IconProps {\n size?: number;\n className?: string;\n}\n\nfunction Svg({ size = 14, className, children }: IconProps & { children: ReactNode }) {\n return (\n <svg\n aria-hidden=\"true\"\n className={className}\n fill=\"none\"\n height={size}\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n viewBox=\"0 0 24 24\"\n width={size}\n >\n {children}\n </svg>\n );\n}\n\nexport function IconSend(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M22 2 11 13\" />\n <path d=\"M22 2 15 22 11 13 2 9Z\" />\n </Svg>\n );\n}\n\nexport function IconStop(props: IconProps) {\n return (\n <Svg {...props}>\n <rect fill=\"currentColor\" height={12} rx={2} stroke=\"none\" width={12} x={6} y={6} />\n </Svg>\n );\n}\n\nexport function IconX(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </Svg>\n );\n}\n\nexport function IconChevronDown(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </Svg>\n );\n}\n\nexport function IconChevronRight(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"m9 18 6-6-6-6\" />\n </Svg>\n );\n}\n\nexport function IconLayers(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"m12 2 10 5-10 5L2 7Z\" />\n <path d=\"m2 17 10 5 10-5\" />\n <path d=\"m2 12 10 5 10-5\" />\n </Svg>\n );\n}\n\nexport function IconCheck(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Svg>\n );\n}\n\nexport function IconSpark(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M12 3l1.9 6.1L20 11l-6.1 1.9L12 19l-1.9-6.1L4 11l6.1-1.9Z\" />\n </Svg>\n );\n}\n\nexport function IconClock(props: IconProps) {\n return (\n <Svg {...props}>\n <circle cx={12} cy={12} r={9} />\n <path d=\"M12 7v5l3 2\" />\n </Svg>\n );\n}\n\nexport function IconTool(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\" />\n </Svg>\n );\n}\n", "import { useState } from \"react\";\nimport { Question } from \"./types\";\nimport { IconCheck } from \"./icons\";\nimport type { ChatTexts } from \"./texts\";\n\n/**\n * R\u00FCckfrage-Karte: Optionen untereinander, wahlweise Einzel- oder Mehrfachauswahl\n * (question.multi), dazu immer eine freie Antwortzeile. Nach der Antwort nur noch Beleg.\n */\nexport function QuestionCard({\n text,\n question,\n texts,\n onAnswer,\n}: {\n text: string;\n question: Question;\n texts: ChatTexts;\n onAnswer: (text: string) => void;\n}) {\n const [gewaehlt, setGewaehlt] = useState<string[]>([]);\n const [frei, setFrei] = useState(\"\");\n\n if (question.answer !== undefined) {\n return (\n <div className=\"qsl-question\">\n <div className=\"qsl-question__text\">{text}</div>\n <div className=\"qsl-question__answered\">\n <IconCheck className=\"qsl-question__check\" size={12} />\n {question.answer}\n </div>\n </div>\n );\n }\n\n const umschalten = (option: string) =>\n setGewaehlt((bisher) =>\n bisher.includes(option) ? bisher.filter((o) => o !== option) : [...bisher, option]);\n\n const freiSenden = () => {\n const wert = frei.trim();\n if (wert) onAnswer(wert);\n };\n\n return (\n <div className=\"qsl-question\">\n <div className=\"qsl-question__text\">{text}</div>\n <div className=\"qsl-question__options\">\n {question.options.map((option) =>\n question.multi ? (\n <button\n aria-pressed={gewaehlt.includes(option)}\n className={\n gewaehlt.includes(option)\n ? \"qsl-question__option qsl-question__option--gewaehlt\"\n : \"qsl-question__option\"\n }\n key={option}\n onClick={() => umschalten(option)}\n type=\"button\"\n >\n <span className=\"qsl-question__kasten\">\n {gewaehlt.includes(option) && <IconCheck size={10} />}\n </span>\n {option}\n </button>\n ) : (\n <button className=\"qsl-question__option\" key={option} onClick={() => onAnswer(option)} type=\"button\">\n {option}\n </button>\n ),\n )}\n </div>\n {question.multi && (\n <button\n className=\"qsl-question__uebernehmen\"\n disabled={gewaehlt.length === 0}\n onClick={() => onAnswer(gewaehlt.join(\"; \"))}\n type=\"button\"\n >\n {texts.questionSubmit}\n </button>\n )}\n <div className=\"qsl-question__frei\">\n <input\n className=\"qsl-field qsl-question__frei-feld\"\n onChange={(event) => setFrei(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" && !event.nativeEvent.isComposing) freiSenden();\n }}\n placeholder={texts.questionPlaceholder}\n value={frei}\n />\n <button\n className=\"qsl-question__frei-senden\"\n disabled={frei.trim() === \"\"}\n onClick={freiSenden}\n type=\"button\"\n >\n {texts.questionAnswer}\n </button>\n </div>\n </div>\n );\n}\n", "import { useEffect, useState } from \"react\";\n\nconst SPUR = 13;\nconst GRUNDTAKT_MS = 90;\nconst SZENENWECHSEL_MS = 2600;\n\n/** Eine Zelle je Figur: Emoji und Satzzeichen teilen sich kein Raster, geschobener Text ruckelt. */\nfunction bahn(figuren: Record<number, string>, breite = SPUR): string[] {\n return Array.from({ length: breite }, (_, x) => figuren[x] ?? \" \");\n}\n\ninterface Szene {\n id: string;\n takt: number;\n laufend?: true;\n zeichne: (schritt: number) => string | string[];\n}\n\n/**\n * Kleine Szenen, in denen etwas Erkennbares passiert - der Zustand aendert sich sichtbar,\n * statt dass nur eine Figur vorbeilaeuft. Szenen mit Bewegung geben ihre Bahn als Zellen\n * zurueck, alle anderen als schlichten Text.\n */\nconst SZENEN: Szene[] = [\n {\n id: \"denken\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 10;\n if (takt >= 8) return \"\\u{1F929}\\u{1F4A1}\";\n return \"\\u{1F914}\" + \"\\u{1F4AD}\".repeat(Math.min(takt, 3));\n },\n },\n {\n // Fliegt nach rechts und zieht ihren Schweif hinterher.\n id: \"rakete\",\n takt: 2,\n laufend: true,\n zeichne: (schritt) => {\n const x = schritt % SPUR;\n return bahn({ [x - 2]: \"\u00B7\", [x - 1]: \"\\u{1F4A8}\", [x]: \"\\u{1F680}\" });\n },\n },\n {\n // Die Punkte bleiben stehen und werden einzeln gefressen.\n id: \"pacman\",\n takt: 2,\n laufend: true,\n zeichne: (schritt) => {\n const x = schritt % SPUR;\n const figuren: Record<number, string> = {};\n for (let i = x + 1; i < SPUR; i++) {\n figuren[i] = \"\u00B7\";\n }\n figuren[x] = schritt % 2 === 0 ? \"\\u{1F7E1}\" : \"\\u{1F315}\";\n return bahn(figuren);\n },\n },\n {\n // Aus einem Samen wird ein Baum, dann von vorn.\n id: \"wachsen\",\n takt: 2,\n zeichne: (schritt) => {\n const stufen = [\"\\u{1F331}\", \"\\u{1F331}\", \"\\u{1F33F}\", \"\\u{1F33F}\", \"\\u{1F343}\", \"\\u{1F333}\", \"\\u{1F333}\", \"\\u{1F333}\"];\n return stufen[schritt % stufen.length];\n },\n },\n {\n // Das Ei bekommt Risse, das Kueken schluepft.\n id: \"schluepfen\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 12;\n if (takt < 4) return \"\\u{1F95A}\";\n if (takt < 6) return \"\\u{1F95A}\u2728\";\n if (takt < 9) return \"\\u{1F423}\";\n return \"\\u{1F425}\";\n },\n },\n {\n // Morse-artiges Signal, das sich zu einem OK aufloest.\n id: \"signal\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 14;\n if (takt >= 11) return \"\\u{1F4E1} OK\";\n const muster = [\"\u00B7\", \"\u00B7\u00B7\", \"\u00B7-\", \"-\u00B7\", \"\u00B7\u00B7-\", \"-\u00B7\u00B7\"];\n return \"\\u{1F4E1} \" + muster[takt % muster.length];\n },\n },\n {\n // Sanduhr: der Sand laeuft durch, dann wird gedreht.\n id: \"sanduhr\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 12;\n const koerner = \"\u00B7\".repeat(Math.max(0, 5 - Math.floor(takt / 2)));\n return (takt < 10 ? \"\u23F3\" : \"\u231B\") + \" \" + koerner;\n },\n },\n {\n // Ei, Kueken, Henne - und die legt das naechste Ei.\n id: \"huhn-kreislauf\",\n takt: 3,\n zeichne: (schritt) => {\n const takt = schritt % 16;\n if (takt < 3) return \"\\u{1F95A}\";\n if (takt < 5) return \"\\u{1F95A}\u2728\";\n if (takt < 8) return \"\\u{1F423}\";\n if (takt < 11) return \"\\u{1F424}\";\n if (takt < 14) return \"\\u{1F414}\";\n return \"\\u{1F414}\\u{1F95A}\";\n },\n },\n {\n // Hut, Funken - und das Kaninchen tuermt.\n id: \"zauberhut\",\n takt: 3,\n zeichne: (schritt) => {\n const takt = schritt % 14;\n if (takt < 4) return \"\\u{1F3A9}\";\n if (takt < 7) return \"\\u{1F3A9}\u2728\";\n if (takt < 11) return \"\\u{1F3A9}\\u{1F407}\";\n return \"\\u{1F407}\\u{1F4A8}\";\n },\n },\n {\n // Rot, Gelb, Gruen - und ab.\n id: \"ampel\",\n takt: 3,\n zeichne: (schritt) => {\n const takt = schritt % 12;\n if (takt < 4) return \"\\u{1F534}\";\n if (takt < 6) return \"\\u{1F7E1}\";\n if (takt < 8) return \"\\u{1F7E2}\";\n return \"\\u{1F697}\\u{1F4A8}\";\n },\n },\n {\n // Klingeln, verschlafen, losrennen.\n id: \"wecker\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 14;\n if (takt < 5) return takt % 2 === 0 ? \"\u23F0\" : \"\\u{1F514}\";\n if (takt < 8) return \"\\u{1F634}\";\n if (takt < 10) return \"\\u{1F633}\";\n return \"\\u{1F3C3}\\u{1F4A8}\";\n },\n },\n {\n // Schnecke kriecht zur Flagge - und feiert.\n id: \"schnecke\",\n takt: 4,\n zeichne: (schritt) => {\n const takt = schritt % 8;\n if (takt < 5) return bahn({ [takt]: \"\\u{1F40C}\", 4: \"\\u{1F3C1}\" }, 5);\n return bahn({ 4: \"\\u{1F389}\" }, 5);\n },\n },\n];\n\nexport interface WorkingScenesProps {\n /** Text fuer Screenreader, Default \"Arbeitet ...\". */\n label?: string;\n}\n\n/**\n * Der Default-Working-Indikator: zufaellig rotierende Mini-Szenen. Zufaellige Reihenfolge\n * und Startphase, damit dieselben Szenen nie wie eine Schleife wirken. Ueber die\n * working-Prop von ChatMessages laesst er sich komplett ersetzen.\n */\nexport function WorkingScenes({ label = \"Arbeitet ...\" }: WorkingScenesProps) {\n const [szene, setSzene] = useState(() => SZENEN[Math.floor(Math.random() * SZENEN.length)]);\n const [versatz, setVersatz] = useState(() => Math.floor(Math.random() * 20));\n const [frameTick, setFrameTick] = useState(0);\n\n useEffect(() => {\n const timer = window.setInterval(() => {\n setSzene((bisher) => {\n const andere = SZENEN.filter((s) => s.id !== bisher.id);\n return andere[Math.floor(Math.random() * andere.length)];\n });\n setVersatz(Math.floor(Math.random() * 20));\n setFrameTick(0);\n }, SZENENWECHSEL_MS);\n return () => window.clearInterval(timer);\n }, []);\n\n useEffect(() => {\n const timer = window.setInterval(() => setFrameTick((value) => value + 1), GRUNDTAKT_MS);\n return () => window.clearInterval(timer);\n }, []);\n\n const bild = szene.zeichne(Math.floor(frameTick / szene.takt) + (szene.laufend ? versatz : 0));\n return (\n <div aria-label={label} className=\"qsl-working\" role=\"img\">\n <span aria-hidden=\"true\" className=\"qsl-working__stage\" key={szene.id}>\n <span className=\"qsl-working__character\">\n {typeof bild === \"string\"\n ? bild\n : bild.map((zelle, i) => (\n <span className=\"qsl-working__cell\" key={i}>\n {zelle}\n </span>\n ))}\n </span>\n </span>\n </div>\n );\n}\n", "import { useLayoutEffect, useMemo, useRef, type ReactNode, type Ref } from \"react\";\nimport { ChatSendContext } from \"./ChatSendContext\";\nimport { appearanceStyle, type ChatAppearance } from \"./options\";\n\n/**\n * Verlauf mit ueberlagerter Eingabe. Der Rahmen misst die Eingabe selbst und\n * gibt dem Verlauf den noetigen Fussraum, damit kein Host Innenmasse setzen muss.\n */\nexport function ChatPanel({\n children,\n composer,\n className,\n nodeRef,\n appearance,\n scrollOnSend = false,\n}: {\n children: ReactNode;\n /** Die Eingabe; sie liegt ueber dem Verlauf, nicht darunter. */\n composer?: ReactNode;\n className?: string;\n nodeRef?: Ref<HTMLDivElement>;\n appearance?: ChatAppearance;\n scrollOnSend?: boolean;\n}) {\n const jump = useRef<(() => void) | undefined>(undefined);\n const scrollOnSendRef = useRef(scrollOnSend);\n useLayoutEffect(() => { scrollOnSendRef.current = scrollOnSend; }, [scrollOnSend]);\n const sendContext = useMemo(() => ({\n onSent: () => { if (scrollOnSendRef.current) jump.current?.(); },\n registerJump: (callback: () => void) => {\n jump.current = callback;\n return () => { if (jump.current === callback) jump.current = undefined; };\n },\n }), []);\n const wurzel = useRef<HTMLDivElement>(null);\n const eingabe = useRef<HTMLDivElement>(null);\n const mitEingabe = composer !== undefined;\n\n useLayoutEffect(() => {\n const element = eingabe.current;\n const rahmen = wurzel.current;\n if (!rahmen) {\n return;\n }\n if (!element) {\n rahmen.style.removeProperty(\"--qsl-composer-height\");\n return;\n }\n const messen = () => rahmen.style.setProperty(\"--qsl-composer-height\", `${element.offsetHeight}px`);\n const beobachter = new ResizeObserver(messen);\n beobachter.observe(element);\n messen();\n return () => beobachter.disconnect();\n }, [mitEingabe]);\n\n return (\n <ChatSendContext.Provider value={sendContext}>\n <div\n className={className ? `qsl-chat-panel ${className}` : \"qsl-chat-panel\"}\n style={appearanceStyle(appearance)}\n ref={(element) => {\n wurzel.current = element;\n if (typeof nodeRef === \"function\") {\n nodeRef(element);\n } else if (nodeRef) {\n nodeRef.current = element;\n }\n }}\n >\n {children}\n {composer !== undefined && (\n <div className=\"qsl-chat-panel__composer\" ref={eingabe}>\n {composer}\n </div>\n )}\n </div>\n </ChatSendContext.Provider>\n );\n}\n", "import { ChatTexts, defaultTexts } from \"./texts\";\nimport { IconClock } from \"./icons\";\n\nexport function TimestampSwitch({\n showTimestamps,\n onChange,\n collapsible = true,\n texts,\n className,\n}: {\n showTimestamps: boolean;\n onChange: (showTimestamps: boolean) => void;\n collapsible?: boolean;\n texts?: Partial<ChatTexts>;\n className?: string;\n}) {\n const label = texts?.timestamps ?? defaultTexts.timestamps;\n const classes = showTimestamps ? \"qsl-icon-button qsl-icon-button--active\" : \"qsl-icon-button\";\n return (\n <button\n aria-label={label}\n aria-pressed={showTimestamps}\n className={className ? `${classes} ${className}` : classes}\n onClick={() => onChange(!showTimestamps)}\n title={label}\n type=\"button\"\n >\n <IconClock />\n <span className={collapsible ? \"qsl-collapsible\" : undefined}>{label}</span>\n </button>\n );\n}\n", "import { KeyboardEvent, ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\nimport { ChatTexts, defaultTexts } from \"./texts\";\nimport { isSendKey, useChatSubmit } from \"./ChatSendContext\";\nimport type { SendShortcut } from \"./options\";\nimport { IconSend, IconStop } from \"./icons\";\n\n// Unter dieser Panel-Breite klappen Beschriftungen mit .qsl-collapsible zu ihren Symbolen.\nconst COMPACT_WIDTH_PX = 480;\n\n/** Ein Toolbar-Knopf, deklarativ: Symbol, Text oder beides - plus Klick-Handler. */\nexport interface ToolbarAction {\n icon?: ReactNode;\n label?: string;\n title?: string;\n disabled?: boolean;\n active?: boolean;\n onClick: () => void;\n}\n\n/**\n * Die Eingabe-Karte: rahmenlose Textarea oben, Toolbar unter einer Haarlinie. Eigene\n * Kn\u00F6pfe kommen deklarativ \u00FCber `actions` oder frei \u00FCber die Slots links/rechts; im Lauf\n * bleibt der Stop-Knopf sichtbar, und Tippen zeigt daneben den Senden-Knopf, der zum\n * Dazwischenfunken wird. `rows` bestimmt die Starth\u00F6he; mit `maxRows` w\u00E4chst die Textarea\n * mit dem Inhalt bis zu dieser Zeilenzahl und scrollt danach.\n */\nexport function ChatInputToolbar({\n onSend,\n onStop,\n running = false,\n disabled = false,\n rows = 3,\n maxRows,\n actions,\n toolbarLeft,\n toolbarRight,\n texts,\n sendShortcut = \"enter\",\n}: {\n onSend: (text: string) => void | Promise<void>;\n onStop?: () => void;\n running?: boolean;\n disabled?: boolean;\n rows?: number;\n maxRows?: number;\n actions?: ToolbarAction[];\n toolbarLeft?: ReactNode;\n toolbarRight?: ReactNode;\n texts?: Partial<ChatTexts>;\n sendShortcut?: SendShortcut;\n}) {\n const alleTexte = { ...defaultTexts, ...texts };\n const [draft, setDraft] = useState(\"\");\n const { submit, sending, error } = useChatSubmit(onSend);\n const rootRef = useRef<HTMLDivElement>(null);\n const eingabeRef = useRef<HTMLTextAreaElement>(null);\n const [compact, setCompact] = useState(false);\n\n // Auto-Wachstum: Hoehe folgt dem Inhalt zwischen rows und maxRows, danach scrollt die Textarea.\n const applyAutoGrow = useCallback(() => {\n const element = eingabeRef.current;\n if (!element || maxRows === undefined) {\n return;\n }\n const stil = getComputedStyle(element);\n const zeilenhoehe = Number.parseFloat(stil.lineHeight) || Number.parseFloat(stil.fontSize) * 1.4;\n const polster = Number.parseFloat(stil.paddingTop) + Number.parseFloat(stil.paddingBottom);\n const maximum = zeilenhoehe * Math.max(maxRows, rows) + polster;\n element.style.height = \"auto\";\n const inhalt = element.scrollHeight;\n element.style.height = `${Math.min(inhalt, maximum)}px`;\n element.style.overflowY = inhalt > maximum ? \"auto\" : \"hidden\";\n }, [maxRows, rows]);\n\n useEffect(() => {\n applyAutoGrow();\n }, [draft, applyAutoGrow]);\n\n // Hosts may lay the composer out a frame later; re-measure once the width settles.\n useEffect(() => {\n const element = eingabeRef.current;\n if (!element || maxRows === undefined) {\n return;\n }\n let lastWidth = element.clientWidth;\n const observer = new ResizeObserver(() => {\n if (element.clientWidth !== lastWidth) {\n lastWidth = element.clientWidth;\n applyAutoGrow();\n }\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [maxRows, applyAutoGrow]);\n\n // Panel-Breite statt Viewport-Breite: die Chat-Spalte kann im Host beliebig schmal sein.\n useEffect(() => {\n const element = rootRef.current;\n if (!element) {\n return;\n }\n const update = () => setCompact(element.clientWidth < COMPACT_WIDTH_PX);\n update();\n const beobachter = new ResizeObserver(update);\n beobachter.observe(element);\n return () => beobachter.disconnect();\n }, []);\n\n const hatText = draft.trim().length > 0;\n\n const send = async () => {\n const text = draft.trim();\n if (!text || disabled || sending) {\n return;\n }\n if (await submit(text)) setDraft(current => current === draft ? \"\" : current);\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (isSendKey(event, sendShortcut)) {\n event.preventDefault();\n if (!event.repeat) void send();\n }\n };\n\n return (\n <div className={compact ? \"qsl-input-card qsl-input-card--compact\" : \"qsl-input-card\"} ref={rootRef}>\n {error && <p className=\"qsl-action-error\" role=\"alert\">{error}</p>}\n <textarea\n aria-label={alleTexte.placeholder}\n disabled={disabled}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={onKeyDown}\n placeholder={running ? alleTexte.steeringPlaceholder : alleTexte.placeholder}\n ref={eingabeRef}\n rows={rows}\n value={draft}\n />\n <div className=\"qsl-input-card__toolbar\">\n <div className=\"qsl-input-card__left\">\n {actions?.map((action, index) => (\n <button\n className={action.active ? \"qsl-icon-button qsl-icon-button--active\" : \"qsl-icon-button\"}\n disabled={action.disabled}\n key={index}\n onClick={action.onClick}\n title={action.title ?? action.label}\n type=\"button\"\n >\n {action.icon}\n {action.label && <span className={action.icon ? \"qsl-collapsible\" : undefined}>{action.label}</span>}\n </button>\n ))}\n {toolbarLeft}\n </div>\n <div className=\"qsl-input-card__right\">\n {toolbarRight}\n {running && onStop && (\n <button aria-label={alleTexte.stop} className=\"qsl-send qsl-send--stop\" onClick={onStop} title={alleTexte.stop} type=\"button\">\n <IconStop />\n </button>\n )}\n {(!running || !onStop || hatText) && (\n <button\n aria-label={alleTexte.send}\n className=\"qsl-send\"\n disabled={disabled || sending || !hatText}\n onClick={() => void send()}\n title={running ? alleTexte.sendIntoRun : alleTexte.send}\n type=\"button\"\n >\n <IconSend />\n </button>\n )}\n </div>\n </div>\n </div>\n );\n}\n", "import { DetailMode } from \"./types\";\nimport { ChatTexts, defaultTexts } from \"./texts\";\nimport { IconSpark } from \"./icons\";\n\nexport const DETAIL_MODES: readonly DetailMode[] = [\"off\", \"icons\", \"chips\", \"grouped\", \"compact\", \"full\"];\n\nconst TEXT_KEYS: Record<DetailMode, keyof ChatTexts> = {\n off: \"detailModeOff\",\n icons: \"detailModeIcons\",\n chips: \"detailModeChips\",\n grouped: \"detailModeGrouped\",\n compact: \"detailModeCompact\",\n full: \"detailModeFull\",\n};\n\nexport const detailModeLabel = (mode: DetailMode, texts?: Partial<ChatTexts>): string =>\n ({ ...defaultTexts, ...texts })[TEXT_KEYS[mode]];\n\n/**\n * Ein Knopf, der den Detailgrad der Denk- und Werkzeug-Schritte weiterschaltet. Die\n * Reihenfolge kommt aus `modes`, der aktuelle Wert steht als Beschriftung daneben.\n */\nexport function DetailModeSwitch({\n mode,\n onChange,\n modes = DETAIL_MODES,\n collapsible = true,\n texts,\n className,\n}: {\n mode: DetailMode;\n onChange: (mode: DetailMode) => void;\n /** Auswahl und Reihenfolge des Weiterschaltens; Default sind alle sechs Modi. */\n modes?: readonly DetailMode[];\n /** false = die Beschriftung bleibt auch in einer schmalen Eingabe-Karte stehen. */\n collapsible?: boolean;\n texts?: Partial<ChatTexts>;\n className?: string;\n}) {\n const alleTexte = { ...defaultTexts, ...texts };\n const aktuell = modes.indexOf(mode);\n const naechster = modes[(aktuell < 0 ? 0 : aktuell + 1) % modes.length];\n return (\n <button\n aria-label={`${alleTexte.detailModeTitle}: ${detailModeLabel(mode, texts)}`}\n className={className ? `qsl-icon-button ${className}` : \"qsl-icon-button\"}\n onClick={() => onChange(naechster)}\n title={`${alleTexte.detailModeTitle}: ${detailModeLabel(mode, texts)}`}\n type=\"button\"\n >\n <IconSpark size={14} />\n <span className={collapsible ? \"qsl-collapsible\" : undefined}>{detailModeLabel(mode, texts)}</span>\n </button>\n );\n}\n"],
5
- "mappings": "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",
6
- "names": ["useCallback", "useContext", "useEffect", "useLayoutEffect", "useRef", "useState", "useEffect", "useRef", "useState", "useRef", "useState", "createContext", "useContext", "jsx", "jsxs", "createContext", "useContext", "useEffect", "useLayoutEffect", "useRef", "useState", "jsx", "jsxs", "Fragment", "jsx", "jsxs", "useRef", "useState", "useLayoutEffect", "useEffect", "useState", "jsx", "jsxs", "useState", "useEffect", "useState", "jsx", "Fragment", "jsx", "jsxs", "announce", "useRef", "useState", "useContext", "useLayoutEffect", "useEffect", "useCallback", "useLayoutEffect", "useMemo", "useRef", "jsx", "jsxs", "useRef", "useLayoutEffect", "useMemo", "jsx", "jsxs", "useCallback", "useEffect", "useRef", "useState", "jsx", "jsxs", "useState", "useRef", "useCallback", "useEffect", "jsx", "jsxs"]
3
+ "sources": ["../src/types.ts", "../src/texts.ts", "../src/ui/cn.ts", "../src/ChatMessages.tsx", "../src/chat-scroll.ts", "../src/Markdown.tsx", "../src/QuasselProvider.tsx", "../src/ui/button.tsx", "../src/ui/card.tsx", "../src/ui/popover.tsx", "../src/ui/stop-button.tsx", "../src/ui/spinner.tsx", "../src/ui/toggle.tsx", "../src/useChatAction.ts", "../src/StepPopover.tsx", "../src/PendingActionCard.tsx", "../src/WorkingScenes.tsx", "../src/attachments.ts", "../src/options.ts", "../src/timestamps.ts", "../src/MessageActions.tsx", "../src/ChatSendContext.ts", "../src/announce.ts", "../src/ChatPanel.tsx", "../src/ChatInputToolbar.tsx", "../src/ui/useFileInput.ts", "../src/DetailModeSwitch.tsx", "../src/TimestampSwitch.tsx"],
4
+ "sourcesContent": ["import type { Message } from \"./events\";\n\nexport type { Role, ToolInfo, PendingAction, Message, ChatEvent, ChatTextCursor, ChatJournalCursor, ChatAttachment, ChatAttachmentInput, ChatAttachmentCapabilities, ChatStartupStatus } from \"./events\";\nexport { applyEvent, prettyJson, compactToolLine } from \"./events\";\n\n/**\n * current = nur der laufende Schritt, off = nur Antworten, icons = Schritte als reine Symbole nebeneinander,\n * chips = Schritte als Symbol + Kurztext nebeneinander (mit Umbruch),\n * grouped = aufeinanderfolgende Schritte als eine aufklappbare Zeile, dahinter einzeilig,\n * compact = Denken und Werkzeuge einzeilig, full = alles ausgeklappt.\n */\nexport type DetailMode = \"off\" | \"current\" | \"icons\" | \"chips\" | \"grouped\" | \"compact\" | \"full\";\n\n/** running = call still open, thinking = thought block still open, done = finished, error = failed. */\nexport type StepState = \"running\" | \"thinking\" | \"done\" | \"error\";\n\n/** The single derivation of a step state, so chips, hosts and tests read the same signal. */\nexport function stepState(message: Message): StepState {\n if (message.tool?.isError) {\n return \"error\";\n }\n if (message.role === \"thinking\") {\n return message.closed ? \"done\" : \"thinking\";\n }\n return message.tool !== undefined && message.tool.result === undefined ? \"running\" : \"done\";\n}\n\n/** A moment worth one screen reader announcement: a finished reply or a new pending action. */\nexport type ChatAnnouncement =\n | { kind: \"reply\"; message: Message }\n | { kind: \"action\"; message: Message };\n", "export interface ChatTexts {\n working: string;\n toolRunning: string;\n toolStillRunning: string;\n currentTool: string;\n thinkingChip: string;\n toolChip: string;\n stepGroupOne: string;\n stepGroupMany: string;\n stepGroupCollapse: string;\n thinkingTitle: string;\n toolTitle: string;\n argumentsLabel: string;\n resultLabel: string;\n close: string;\n jumpToEnd: string;\n send: string;\n sendIntoRun: string;\n stop: string;\n placeholder: string;\n steeringPlaceholder: string;\n steered: string;\n inputHint: string;\n detailModeTitle: string;\n detailModeOff: string;\n detailModeCurrent: string;\n detailModeIcons: string;\n detailModeChips: string;\n detailModeGrouped: string;\n detailModeCompact: string;\n detailModeFull: string;\n timestamps: string;\n showTimestamps: string;\n hideTimestamps: string;\n copyMessage: string;\n editMessage: string;\n retryMessage: string;\n copyCode: string;\n copied: string;\n pendingAction: string;\n dismissAction: string;\n actionDismissed: string;\n actionFailed: string;\n clipboardUnavailable: string;\n transcript: string;\n attachments: string;\n attachFiles: string;\n attachFilesHint: string;\n removeAttachment: string;\n attachmentPreparing: string;\n attachmentsPreparing: string;\n attachmentReadFailed: string;\n attachmentsWhileBusy: string;\n tooManyAttachments: string;\n attachmentsTooLarge: string;\n attachmentUnsupported: string;\n attachmentUnsupportedByModel: string;\n attachmentKindImage: string;\n attachmentKindVideo: string;\n attachmentKindPdf: string;\n notSent: string;\n notSentAttachments: string;\n insertUnsent: string;\n}\n\n\nexport const fillText = (text: string, values: Record<string, string | number>): string =>\n text.replace(/\\{(\\w+)\\}/g, (match, name: string) => name in values ? String(values[name]) : match);\n\nexport const defaultTexts: ChatTexts = {\n working: \"Arbeitet ...\",\n toolRunning: \"l\u00E4uft ...\",\n toolStillRunning: \"Werkzeug l\u00E4uft ...\",\n currentTool: \"Werkzeug l\u00E4uft\",\n thinkingChip: \"Denken\",\n toolChip: \"Werkzeug\",\n stepGroupOne: \"1 Schritt\",\n stepGroupMany: \"{count} Schritte\",\n stepGroupCollapse: \"Einklappen\",\n thinkingTitle: \"Thinking-Trace\",\n toolTitle: \"Tool-Call\",\n argumentsLabel: \"Argumente\",\n resultLabel: \"Ergebnis\",\n close: \"Schlie\u00DFen\",\n jumpToEnd: \"Zum Ende springen\",\n send: \"Senden\",\n sendIntoRun: \"In den laufenden Turn einspeisen\",\n stop: \"Arbeit stoppen\",\n placeholder: \"Nachricht schreiben ...\",\n steeringPlaceholder: \"Dazwischenfunken ...\",\n steered: \"In den laufenden Turn eingespeist\",\n inputHint: \"Enter zum Senden - Shift + Enter f\u00FCr eine neue Zeile\",\n detailModeTitle: \"Detailgrad der Schritte\",\n detailModeOff: \"nur Antworten\",\n detailModeCurrent: \"aktuell\",\n detailModeIcons: \"Symbole\",\n detailModeChips: \"kompakt\",\n detailModeGrouped: \"gruppiert\",\n detailModeCompact: \"einzeilig\",\n detailModeFull: \"alles\",\n timestamps: \"Zeitstempel\",\n showTimestamps: \"Zeitstempel anzeigen\",\n hideTimestamps: \"Zeitstempel ausblenden\",\n copyMessage: \"Nachricht kopieren\",\n editMessage: \"Nachricht bearbeiten\",\n retryMessage: \"Antwort erneut anfordern\",\n copyCode: \"Code kopieren\",\n copied: \"Kopiert\",\n pendingAction: \"wartet auf Eingabe\",\n dismissAction: \"Verwerfen\",\n actionDismissed: \"verworfen\",\n actionFailed: \"Aktion fehlgeschlagen\",\n clipboardUnavailable: \"Die Zwischenablage ist nicht verf\u00FCgbar\",\n transcript: \"Chatverlauf\",\n attachments: \"Anh\u00E4nge\",\n attachFiles: \"Dateien anh\u00E4ngen\",\n attachFilesHint: \"Dateien anh\u00E4ngen (bis zu {count} Dateien, insgesamt {size})\",\n removeAttachment: \"{name} entfernen\",\n attachmentPreparing: \"Wird vorbereitet ...\",\n attachmentsPreparing: \"Anh\u00E4nge werden vorbereitet ...\",\n attachmentReadFailed: \"Datei konnte nicht gelesen werden. Entferne sie und f\u00FCge sie erneut hinzu.\",\n attachmentsWhileBusy: \"Warte, bis die Eingabe wieder bereit ist, und f\u00FCge die Dateien dann erneut hinzu.\",\n tooManyAttachments: \"H\u00F6chstens {count} Anh\u00E4nge pro Nachricht. Entferne zuerst einen Anhang.\",\n attachmentsTooLarge: \"Anh\u00E4nge d\u00FCrfen zusammen h\u00F6chstens {size} gro\u00DF sein. W\u00E4hle kleinere Dateien.\",\n attachmentUnsupported: \"Dieser Chat unterst\u00FCtzt {name} nicht als {kind}. Entferne den Anhang.\",\n attachmentUnsupportedByModel: \"Das Modell {model} unterst\u00FCtzt {name} nicht als {kind}. W\u00E4hle ein passendes Modell oder entferne den Anhang.\",\n attachmentKindImage: \"Bild\",\n attachmentKindVideo: \"Video\",\n attachmentKindPdf: \"PDF\",\n notSent: \"Nicht gesendet:\",\n notSentAttachments: \"({count} Anh\u00E4nge)\",\n insertUnsent: \"Nicht gesendete Eingabe einf\u00FCgen\",\n};\n", "import type { CnFunction } from \"cn\";\nimport { createCn } from \"cn/config\";\n\nexport const cn: CnFunction = createCn({ prefix: \"qsl\" });\n", "import { cn } from \"./ui/cn\";\nimport { type CSSProperties, ReactNode, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { createChatScroll } from \"./chat-scroll\";\nimport { ChatAnnouncement, DetailMode, Message, PendingAction, prettyJson, stepState, ToolInfo } from \"./types\";\nimport { ChatTexts, defaultTexts } from \"./texts\";\nimport { Markdown, MarkdownCodeBlocks, MarkdownLinks, markdownPlainText, type LinkClickHandler } from \"./Markdown\";\nimport { StepPopover } from \"./StepPopover\";\nimport { PendingActionCard } from \"./PendingActionCard\";\nimport { WorkingScenes } from \"./WorkingScenes\";\nimport { attachmentDownloadUrl, formatAttachmentSize } from \"./attachments\";\nimport { CheckIcon, ChevronDownIcon, ChevronRightIcon, ChevronUpIcon, LayersIcon, SparklesIcon, WrenchIcon } from \"lucide-react\";\nimport { appearanceStyle, type ChatAppearance, type TimestampOptions, type CodeBlockOptions, type BubbleOptions, type MessageActionsOptions } from \"./options\";\nimport { messageDate, timestampDay, timestampLabel } from \"./timestamps\";\nimport { MessageActions } from \"./MessageActions\";\nimport { ChatSendContext } from \"./ChatSendContext\";\nimport { announce as ansagen } from \"./announce\";\nimport { useQuasselComponents } from \"./QuasselProvider\";\n\nconst stepClasses = \"qsl:mt-[var(--qsl-chat-message-gap,16px)]\";\nconst denseStepClasses = \"qsl:mt-[var(--qsl-chat-dense-message-gap,8px)]\";\n\nconst traceClasses = \"qsl:flex qsl:w-full qsl:gap-2 qsl:pl-6 qsl:text-left qsl:text-[11px] qsl:leading-[1.375] qsl:text-muted-foreground\";\nconst traceButtonClasses = \"qsl:cursor-pointer qsl:rounded-md qsl:py-1 qsl:pr-2 qsl:transition-colors qsl:hover:bg-secondary qsl:hover:text-foreground qsl:focus-visible:bg-secondary qsl:focus-visible:text-foreground qsl:focus-visible:outline-none\";\nconst traceIconClasses = \"qsl:mt-0.5 qsl:flex-none qsl:opacity-60\";\nconst traceErrorIconClasses = \"qsl:mt-0.5 qsl:flex-none qsl:text-destructive qsl:opacity-100\";\nconst traceLineClasses = \"qsl:min-w-0 qsl:self-baseline qsl:font-mono qsl:[overflow-wrap:anywhere]\";\nconst traceRunningClasses = \"qsl:ml-1.5 qsl:opacity-60\";\n\nconst chipClasses = cn(\n \"qsl:inline-flex qsl:max-w-[220px] qsl:items-center qsl:gap-[5px] qsl:rounded-full qsl:border qsl:border-border-soft qsl:px-2.5 qsl:py-0.5\",\n \"qsl:font-mono qsl:text-[10.5px] qsl:leading-[1.6] qsl:text-muted-foreground qsl:transition-colors\",\n \"qsl:data-[state=running]:border-[color-mix(in_srgb,var(--qsl-primary)_40%,var(--qsl-border-soft))]\",\n \"qsl:data-[state=thinking]:border-[color-mix(in_srgb,var(--qsl-primary)_40%,var(--qsl-border-soft))]\",\n \"qsl:data-[state=error]:border-[color-mix(in_srgb,var(--qsl-destructive)_45%,var(--qsl-border-soft))]\",\n \"qsl:data-[state=done]:opacity-85\",\n);\nconst chipInteractiveClasses = \"qsl:cursor-pointer qsl:hover:border-border qsl:hover:bg-secondary qsl:hover:text-foreground qsl:focus-visible:border-border qsl:focus-visible:bg-secondary qsl:focus-visible:text-foreground qsl:focus-visible:outline-none qsl:data-[state=done]:hover:opacity-100 qsl:data-[state=done]:focus-visible:opacity-100\";\n\nconst collapseAtBottomFrom = 11;\n\nconst hoechstensAnsagenAufEinmal = 2;\n\nconst bubbleBodyClasses = \"qsl:relative qsl:max-w-[86%] qsl:px-3 qsl:py-2 qsl:leading-[var(--qsl-chat-line-height,1.625)] qsl:[overflow-wrap:anywhere] qsl:@max-[620px]/chat:max-w-full\";\n\nfunction istSchritt(message?: Message): boolean {\n return !!message && (message.role === \"thinking\" || message.role === \"tool\");\n}\n\nfunction defaultArgumentsText(tool: ToolInfo): string {\n return prettyJson(tool.arguments);\n}\n\n/**\n * Der Verlauf: eigener Scroll-Container mit Autoscroll, solange man unten ist,\n * und einem Zum-Ende-Knopf, sobald man liest. Ohne Eingabe read-only nutzbar.\n */\nexport function ChatMessages({\n messages,\n owner,\n detailMode = \"current\",\n running = false,\n working,\n stepsExpandable = true,\n texts,\n toolArgumentsText = defaultArgumentsText,\n renderTool,\n renderAction,\n onDismissAction,\n onLinkClick,\n emptyState,\n className,\n showTimestamps = false,\n announce,\n scrollerRef,\n maxWidth,\n horizontalPadding,\n jumpToEndThreshold = 120,\n appearance,\n timestampOptions,\n codeBlockOptions,\n bubbleOptions,\n messageActions,\n}: {\n messages: Message[];\n /** Beitr\u00E4ge mit diesem Message.sender erscheinen ohne Sprechblase; null beh\u00E4lt die Nachrichtenvorgaben. */\n owner?: string | null;\n detailMode?: DetailMode;\n running?: boolean;\n working?: ReactNode;\n /** false = Denk- und Werkzeug-Schritte lassen sich nicht aufklappen (kein Popover). */\n stepsExpandable?: boolean;\n texts?: Partial<ChatTexts>;\n toolArgumentsText?: (tool: ToolInfo) => string;\n /** Eigene Darstellung fuer einzelne Werkzeuge; undefined = Standarddarstellung. */\n renderTool?: (tool: ToolInfo) => ReactNode | undefined;\n /** Darstellung einer wartenden Aktion durch ihren Eigent\u00FCmer; undefined = generische Karte. */\n renderAction?: (action: PendingAction, text: string) => ReactNode | undefined;\n onDismissAction?: (actionId: string) => void;\n /** Faengt Klicks auf Markdown-Links ab; true = behandelt, der Browser folgt nicht. */\n onLinkClick?: LinkClickHandler;\n emptyState?: ReactNode;\n className?: string;\n /** true = dezente HH:MM-Spalte links an jedem Block (Message.at). */\n showTimestamps?: boolean;\n /** Screenreader-Ansage fertiger Antworten und neuer Aktionen; false = der Host sagt selbst an. */\n announce?: false | ((announcement: ChatAnnouncement) => string | undefined);\n /** Exposes the scroll container so hosts can scroll without querying the DOM. */\n scrollerRef?: (element: HTMLDivElement | null) => void;\n maxWidth?: CSSProperties[\"maxWidth\"];\n horizontalPadding?: CSSProperties[\"paddingInline\"];\n jumpToEndThreshold?: number;\n appearance?: ChatAppearance;\n timestampOptions?: TimestampOptions;\n codeBlockOptions?: CodeBlockOptions;\n bubbleOptions?: BubbleOptions;\n messageActions?: MessageActionsOptions;\n}) {\n const alleTexte = { ...defaultTexts, ...texts };\n const { Button } = useQuasselComponents();\n const scrollBereich = useRef<HTMLDivElement>(null);\n const threadRef = useRef<HTMLDivElement>(null);\n const scrollbarDragging = useRef(false);\n const touchY = useRef<number | undefined>(undefined);\n const [showJumpToEnd, setShowJumpToEnd] = useState(false);\n const [scroll] = useState(() => createChatScroll());\n const sendScope = useContext(ChatSendContext);\n const [now, setNow] = useState(() => Date.now());\n useEffect(() => {\n if (!showTimestamps || timestampOptions?.format !== \"relative\") return;\n setNow(Date.now());\n const timer = window.setInterval(() => setNow(Date.now()), 15_000);\n return () => window.clearInterval(timer);\n }, [showTimestamps, timestampOptions?.format]);\n\n // Der Verlauf beim Einh\u00E4ngen und ganze Sch\u00FCbe (Reset mit Replay) gelten als bekannt, nicht als neu.\n const angesagt = useRef<ReadonlySet<string>>(new Set(messages.map((message) => message.key)));\n useEffect(() => {\n const faellig = messages.filter((message, index) => !angesagt.current.has(message.key) && (\n message.role === \"action\"\n ? message.action !== undefined && message.action.status === undefined\n : message.role === \"assistant\" && message.text.trim() !== \"\" && (message.closed === true || (!running && index === messages.length - 1))\n ));\n if (faellig.length === 0) {\n return;\n }\n angesagt.current = new Set([...angesagt.current, ...faellig.map((message) => message.key)]);\n if (announce === false || faellig.length > hoechstensAnsagenAufEinmal) {\n return;\n }\n faellig\n .map((message) => announce\n ? announce({ kind: message.role === \"action\" ? \"action\" : \"reply\", message })\n : markdownPlainText(message.text))\n .forEach((text) => text && ansagen(text));\n }, [messages, running, announce]);\n const updateJumpVisibility = useCallback((viewport: HTMLDivElement) => {\n if (viewport.clientHeight > 0) setShowJumpToEnd(viewport.scrollHeight - viewport.clientHeight - viewport.scrollTop > jumpToEndThreshold);\n }, [jumpToEndThreshold]);\n useLayoutEffect(() => sendScope?.subscribe(() => {\n const viewport = scrollBereich.current;\n if (!viewport) return;\n scroll.jump(viewport);\n updateJumpVisibility(viewport);\n }), [sendScope, scroll, updateJumpVisibility]);\n\n const pauseUp = (viewport: HTMLDivElement, target: EventTarget) => {\n let element = target instanceof Element ? target : null;\n while (element && element !== viewport) {\n if (element.scrollTop > 0 && /auto|scroll/.test(getComputedStyle(element).overflowY)) return;\n element = element.parentElement;\n }\n scroll.pause(viewport);\n };\n\n const pruefeEnde = useCallback(() => {\n const bereich = scrollBereich.current;\n if (bereich) {\n scroll.scroll(bereich, scrollbarDragging.current);\n updateJumpVisibility(bereich);\n }\n }, [scroll, updateJumpVisibility]);\n\n useEffect(() => {\n const finishDrag = () => {\n if (scrollbarDragging.current && scrollBereich.current) scroll.scroll(scrollBereich.current, true);\n scrollbarDragging.current = false;\n };\n window.addEventListener(\"pointerup\", finishDrag);\n window.addEventListener(\"pointercancel\", finishDrag);\n return () => {\n window.removeEventListener(\"pointerup\", finishDrag);\n window.removeEventListener(\"pointercancel\", finishDrag);\n };\n }, [scroll]);\n\n // Inhaltswachstum \u00E4ndert den Folgemodus nicht; auch nachgeladene Medien und die Eingabe z\u00E4hlen.\n useLayoutEffect(() => {\n const bereich = scrollBereich.current;\n if (!bereich) return;\n const align = () => {\n scroll.layout(bereich, scrollbarDragging.current);\n updateJumpVisibility(bereich);\n };\n align();\n const beobachter = new ResizeObserver(align);\n beobachter.observe(bereich);\n if (threadRef.current) beobachter.observe(threadRef.current, { box: \"border-box\" });\n return () => beobachter.disconnect();\n });\n\n const visible = useMemo(\n () => {\n // Eigene Eingaben hinter dem laufenden Schritt beenden ihn nicht; jede andere Nachricht schon.\n const letzterFremder = messages.reduce((last, message, index) => message.role === \"user\" ? last : index, -1);\n return messages.filter((message, index) => {\n if (detailMode === \"current\" && istSchritt(message)) {\n return running && index === letzterFremder\n && (message.role === \"thinking\" ? !message.closed : stepState(message) === \"running\");\n }\n if ((message.role === \"thinking\" || message.role === \"assistant\") && message.text.trim() === \"\" && !message.attachments?.length) {\n return false;\n }\n if (message.role === \"thinking\" || message.role === \"tool\") {\n return detailMode !== \"off\";\n }\n return true;\n });\n },\n [messages, detailMode, running],\n );\n\n const mitZeit = (inhalt: ReactNode, key: string, at: string | undefined, dicht = false): ReactNode =>\n showTimestamps\n ? (\n <div className={cn(\"qsl:flex qsl:items-baseline qsl:gap-2\", dicht ? denseStepClasses : stepClasses)} key={`zeit-${key}`}>\n <time dateTime={messageDate(at)?.toISOString()} className={cn(\"qsl:flex-none qsl:text-[10.5px] qsl:tabular-nums qsl:text-muted-foreground qsl:opacity-85\",\n timestampOptions?.format && timestampOptions.format !== \"time\" ? \"qsl:w-[clamp(60px,20%,120px)]\" : \"qsl:w-[34px]\")}>\n {messageDate(at) ? timestampLabel(messageDate(at)!, timestampOptions, now) : \"\"}\n </time>\n <div className=\"qsl:min-w-0 qsl:flex-1 qsl:[&>*:first-child]:mt-0\">{inhalt}</div>\n </div>\n )\n : inhalt;\n\n // In den Chip-Modi ruecken aufeinanderfolgende Schritte in eine umbrechende Zeile zusammen, gruppiert in eine aufklappbare Zeile.\n const chipModus = detailMode === \"current\" || detailMode === \"chips\" || detailMode === \"icons\";\n const gruppenModus = detailMode === \"grouped\";\n const bloecke: ReactNode[] = [];\n let lastDay: string | undefined;\n let gruppe: Message[] = [];\n const schliesseGruppe = () => {\n if (gruppe.length > 0) {\n const letzterZustand = stepState(gruppe[gruppe.length - 1]);\n bloecke.push(mitZeit(\n gruppenModus ? (\n <StepGroup\n aktiv={running && (letzterZustand === \"running\" || letzterZustand === \"thinking\")}\n expandierbar={stepsExpandable}\n key={gruppe[0].key}\n messages={gruppe}\n texts={alleTexte}\n toolArgumentsText={toolArgumentsText}\n />\n ) : (\n <StepRow\n expandierbar={stepsExpandable}\n key={gruppe[0].key}\n messages={gruppe}\n mitText={detailMode !== \"icons\"}\n texts={alleTexte}\n toolArgumentsText={toolArgumentsText}\n toolLabel={detailMode === \"current\" && !stepsExpandable ? alleTexte.currentTool : undefined}\n />\n ),\n gruppe[0].key,\n gruppe[0].at,\n ));\n gruppe = [];\n }\n };\n visible.forEach((message, index) => {\n const date = timestampOptions?.showDaySeparators ? messageDate(message.at) : undefined;\n if (date) {\n const day = timestampDay(date, timestampOptions);\n if (day.key !== lastDay) {\n schliesseGruppe();\n bloecke.push(<div className={cn(stepClasses, \"qsl:text-center qsl:text-xs qsl:text-muted-foreground\")} data-chat=\"day-separator\" data-day={day.key} key={`day-${message.key}`}>{day.label}</div>);\n lastDay = day.key;\n }\n }\n const eigeneDarstellung = message.role === \"tool\" && message.tool && detailMode !== \"current\" ? renderTool?.(message.tool) : undefined;\n if (eigeneDarstellung !== undefined) {\n schliesseGruppe();\n bloecke.push(mitZeit(\n <div className={stepClasses} key={message.key}>\n {eigeneDarstellung}\n </div>,\n message.key,\n message.at,\n ));\n return;\n }\n if ((chipModus || gruppenModus) && istSchritt(message)) {\n gruppe = [...gruppe, message];\n return;\n }\n schliesseGruppe();\n const dicht = istSchritt(message) && istSchritt(visible[index - 1]);\n bloecke.push(mitZeit(\n <Bubble\n detailMode={detailMode}\n dicht={dicht}\n expandierbar={stepsExpandable}\n key={message.key}\n message={message}\n plain={owner != null && message.sender === owner}\n texts={alleTexte}\n toolArgumentsText={toolArgumentsText}\n renderAction={renderAction}\n onDismissAction={onDismissAction}\n bubbleOptions={bubbleOptions}\n messageActions={messageActions}\n />,\n message.key,\n message.at,\n dicht,\n ));\n });\n schliesseGruppe();\n\n const verlauf = (\n <div className={cn(\"qsl:@container/chat qsl:relative qsl:flex qsl:min-h-0 qsl:flex-1 qsl:flex-col\", className)} data-quassel=\"\" style={{\n ...appearanceStyle(appearance),\n \"--qsl-chat-content-max-width\": typeof maxWidth === \"number\" ? `${maxWidth}px` : maxWidth,\n \"--qsl-chat-horizontal-padding\": typeof horizontalPadding === \"number\" ? `${horizontalPadding}px` : horizontalPadding,\n } as CSSProperties}>\n <div\n aria-label={alleTexte.transcript}\n className={cn(\n \"qsl:min-h-0 qsl:flex-1 qsl:cursor-default qsl:overflow-y-auto qsl:text-[length:var(--qsl-chat-font-size,13px)] qsl:text-foreground\",\n \"qsl:[--qsl-fade-edge:calc(100%_-_var(--qsl-composer-height,0px))]\",\n \"qsl:[-webkit-mask-image:linear-gradient(to_bottom,#000_calc(var(--qsl-fade-edge)_-_40px),transparent_calc(var(--qsl-fade-edge)_+_16px))]\",\n \"qsl:[mask-image:linear-gradient(to_bottom,#000_calc(var(--qsl-fade-edge)_-_40px),transparent_calc(var(--qsl-fade-edge)_+_16px))]\",\n \"qsl:in-data-[tone=material]:p-0\",\n )}\n onScroll={pruefeEnde}\n onWheel={(event) => { if (!event.ctrlKey && event.deltaY < 0) pauseUp(event.currentTarget, event.target); }}\n onKeyDown={(event) => {\n const editable = event.target instanceof Element && event.target.closest(\"input, textarea, select, [contenteditable=true]\");\n if (!editable && ([\"ArrowUp\", \"PageUp\", \"Home\"].includes(event.key) || event.target === event.currentTarget && event.key === \" \" && event.shiftKey)) pauseUp(event.currentTarget, event.target);\n }}\n onPointerDown={(event) => {\n const viewport = event.currentTarget;\n scrollbarDragging.current = event.clientX >= viewport.getBoundingClientRect().right - Math.max(16, viewport.offsetWidth - viewport.clientWidth);\n }}\n onTouchStart={(event) => { touchY.current = event.touches[0]?.clientY; }}\n onTouchMove={(event) => {\n const next = event.touches[0]?.clientY;\n if (next !== undefined && touchY.current !== undefined && next > touchY.current) pauseUp(event.currentTarget, event.target);\n touchY.current = next;\n }}\n role=\"region\"\n tabIndex={0}\n ref={(element) => {\n scrollBereich.current = element;\n scrollerRef?.(element);\n }}\n >\n {visible.length === 0 && !running ? (\n emptyState ?? null\n ) : (\n <div\n aria-busy={running || undefined}\n className={cn(\n \"qsl:mx-auto qsl:w-[calc(100%_-_2_*_var(--qsl-chat-horizontal-padding,24px))] qsl:max-w-[var(--qsl-chat-content-max-width,none)] qsl:pt-2\",\n \"qsl:pb-[calc(var(--qsl-composer-height,0px)_+_max(3.25em,40px))]\",\n \"qsl:in-data-[tone=material]:[&>*:first-child]:mt-0\",\n )}\n ref={threadRef}\n >\n {bloecke}\n {running && (working ?? <WorkingScenes label={alleTexte.working} />)}\n </div>\n )}\n </div>\n {showJumpToEnd && (\n <div className=\"qsl:pointer-events-none qsl:absolute qsl:inset-x-0 qsl:bottom-[calc(var(--qsl-composer-height,0px)_+_12px)] qsl:z-10 qsl:flex qsl:justify-center\">\n <Button aria-label={alleTexte.jumpToEnd} className=\"qsl:pointer-events-auto qsl:rounded-full qsl:border qsl:border-primary-foreground/20 qsl:shadow-md\" size=\"icon\" title={alleTexte.jumpToEnd} variant=\"default\" onClick={() => {\n if (scrollBereich.current) {\n scroll.jump(scrollBereich.current);\n updateJumpVisibility(scrollBereich.current);\n }\n }}>\n <ChevronDownIcon />\n </Button>\n </div>\n )}\n </div>\n );\n\n return <MarkdownLinks onLinkClick={onLinkClick}><MarkdownCodeBlocks options={codeBlockOptions} texts={alleTexte}>{verlauf}</MarkdownCodeBlocks></MarkdownLinks>;\n}\n\n/** Aufeinanderfolgende Schritte als Chips nebeneinander; bei Platzmangel bricht die Zeile um. */\nfunction StepRow({\n messages,\n mitText,\n expandierbar,\n texts,\n toolArgumentsText,\n toolLabel,\n}: {\n messages: Message[];\n mitText: boolean;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n toolLabel?: string;\n}) {\n const [detail, setDetail] = useState<{ key: string; position: { x: number; y: number } }>();\n const offen = expandierbar && detail && messages.find((message) => message.key === detail.key);\n\n return (\n <div className={cn(stepClasses, \"qsl:flex qsl:flex-wrap qsl:items-center qsl:gap-x-1.5 qsl:gap-y-1 qsl:pl-6\")} data-step=\"row\">\n {messages.map((message) => {\n const thinking = message.role === \"thinking\";\n const tool = message.tool;\n const state = stepState(message);\n const running = state === \"running\" || state === \"thinking\";\n const label = thinking ? texts.thinkingChip : toolLabel ?? (tool?.name || message.text || texts.toolChip);\n const content = (\n <>\n {thinking ? (\n <SparklesIcon size={11} />\n ) : (\n <WrenchIcon className={tool?.isError ? \"qsl:text-destructive\" : undefined} size={11} />\n )}\n {mitText && <span className=\"qsl:min-w-0 qsl:self-baseline qsl:overflow-hidden qsl:text-ellipsis qsl:whitespace-nowrap\">{label}</span>}\n {mitText && <span className=\"qsl:inline-flex qsl:w-2.5 qsl:flex-none qsl:items-center qsl:justify-center qsl:text-success\">{state === \"done\" && <CheckIcon size={10} />}</span>}\n </>\n );\n const classes = cn(chipClasses, !mitText && \"qsl:p-1\", running && \"qsl:animate-fade-pulse qsl:motion-reduce:animate-none\");\n if (!expandierbar) {\n return (\n <span className={classes} data-kind={thinking ? \"thinking\" : \"tool\"} data-state={state} data-step=\"chip\" key={message.key} title={label}>\n {content}\n </span>\n );\n }\n return (\n <button\n aria-haspopup=\"dialog\"\n className={cn(classes, chipInteractiveClasses)}\n data-kind={thinking ? \"thinking\" : \"tool\"}\n data-state={state}\n data-step=\"chip\"\n key={message.key}\n onClick={(event) => setDetail({ key: message.key, position: { x: event.clientX, y: event.clientY } })}\n title={label}\n type=\"button\"\n >\n {content}\n </button>\n );\n })}\n {offen && detail && (\n <StepPopover\n message={offen}\n position={detail.position}\n texts={texts}\n toolArgumentsText={toolArgumentsText}\n onClose={() => setDetail(undefined)}\n />\n )}\n </div>\n );\n}\n\n/** Aufeinanderfolgende Schritte hinter einer Kopfzeile; aufgeklappt stehen sie als einzeilige Zeilen darunter. */\nfunction StepGroup({\n messages,\n aktiv,\n expandierbar,\n texts,\n toolArgumentsText,\n}: {\n messages: Message[];\n aktiv: boolean;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n}) {\n const [offen, setOffen] = useState(false);\n const kopf = useRef<HTMLButtonElement>(null);\n const vonUntenEingeklappt = useRef(false);\n useLayoutEffect(() => {\n if (!offen && vonUntenEingeklappt.current) {\n vonUntenEingeklappt.current = false;\n kopf.current?.scrollIntoView({ block: \"nearest\" });\n }\n }, [offen]);\n const letzte = messages[messages.length - 1];\n const fehler = messages.some((message) => message.tool?.isError);\n const anzahl = messages.length === 1 ? texts.stepGroupOne : texts.stepGroupMany.replace(\"{count}\", String(messages.length));\n const laufend = aktiv ? (letzte.role === \"thinking\" ? texts.thinkingChip : letzte.tool?.name || letzte.text || texts.toolChip) : undefined;\n\n return (\n <div className={stepClasses} data-step=\"group\">\n <button\n aria-expanded={offen}\n className={cn(traceClasses, traceButtonClasses, \"qsl:items-center qsl:pl-1\", aktiv && \"qsl:animate-fade-pulse qsl:motion-reduce:animate-none\")}\n onClick={() => setOffen((wert) => !wert)}\n ref={kopf}\n type=\"button\"\n >\n <ChevronRightIcon className={cn(\"qsl:flex-none qsl:opacity-60 qsl:transition-transform\", offen && \"qsl:rotate-90\")} size={12} />\n <LayersIcon className={fehler ? traceErrorIconClasses : traceIconClasses} size={12} />\n <span className={cn(traceLineClasses, \"qsl:overflow-hidden qsl:text-ellipsis qsl:whitespace-nowrap\")}>\n {anzahl}\n {laufend && <span className={traceRunningClasses}>{laufend} {texts.toolRunning}</span>}\n </span>\n </button>\n {offen && (\n <div className=\"qsl:mt-0.5 qsl:flex qsl:flex-col qsl:gap-0.5 qsl:pl-3\">\n {messages.map((message) => (\n <TraceLine className=\"qsl:pl-3\" expandierbar={expandierbar} key={message.key} message={message} texts={texts} toolArgumentsText={toolArgumentsText} />\n ))}\n </div>\n )}\n {offen && messages.length >= collapseAtBottomFrom && (\n <button\n className={cn(traceClasses, traceButtonClasses, \"qsl:mt-0.5 qsl:items-center qsl:pl-1\")}\n data-step=\"group-collapse\"\n onClick={() => {\n vonUntenEingeklappt.current = true;\n setOffen(false);\n }}\n type=\"button\"\n >\n <ChevronUpIcon className=\"qsl:flex-none qsl:opacity-60\" size={12} />\n <span className={traceLineClasses}>{texts.stepGroupCollapse}</span>\n </button>\n )}\n </div>\n );\n}\n\n/** Ein Schritt als eine Zeile; mit Freigabe oeffnet ein Klick die Details im Popover. */\nfunction TraceLine({\n message,\n className,\n expandierbar,\n texts,\n toolArgumentsText,\n}: {\n message: Message;\n className: string;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n}) {\n const [detailPosition, setDetailPosition] = useState<{ x: number; y: number }>();\n const thinking = message.role === \"thinking\";\n const tool = message.tool;\n const classes = cn(traceClasses, className);\n const zeile = cn(traceLineClasses, thinking && \"qsl:font-sans qsl:italic qsl:whitespace-pre-wrap\", \"qsl:overflow-hidden qsl:text-ellipsis qsl:whitespace-nowrap\");\n const inhalt = (\n <>\n {thinking ? (\n <SparklesIcon className={traceIconClasses} size={12} />\n ) : (\n <WrenchIcon className={tool?.isError ? traceErrorIconClasses : traceIconClasses} size={12} />\n )}\n <span className={zeile}>\n {message.text}\n {tool && tool.result === undefined && <span className={traceRunningClasses}>{texts.toolRunning}</span>}\n </span>\n </>\n );\n const marks = { \"data-compact\": \"true\", \"data-kind\": thinking ? \"thinking\" : \"tool\", \"data-step\": \"line\" } as const;\n if (!expandierbar) {\n return <div className={classes} {...marks}>{inhalt}</div>;\n }\n return (\n <>\n <button\n aria-expanded={detailPosition !== undefined}\n aria-haspopup=\"dialog\"\n className={cn(classes, traceButtonClasses)}\n {...marks}\n onClick={(event) => setDetailPosition({ x: event.clientX, y: event.clientY })}\n type=\"button\"\n >\n {inhalt}\n </button>\n {detailPosition && (\n <StepPopover\n message={message}\n position={detailPosition}\n texts={texts}\n toolArgumentsText={toolArgumentsText}\n onClose={() => setDetailPosition(undefined)}\n />\n )}\n </>\n );\n}\n\nfunction Bubble({\n message,\n plain,\n detailMode,\n dicht,\n expandierbar,\n texts,\n toolArgumentsText,\n renderAction,\n onDismissAction,\n bubbleOptions,\n messageActions,\n}: {\n message: Message;\n plain: boolean;\n detailMode: DetailMode;\n dicht: boolean;\n expandierbar: boolean;\n texts: ChatTexts;\n toolArgumentsText: (tool: ToolInfo) => string;\n renderAction?: (action: PendingAction, text: string) => ReactNode | undefined;\n onDismissAction?: (actionId: string) => void;\n bubbleOptions?: BubbleOptions;\n messageActions?: MessageActionsOptions;\n}) {\n const schritt = dicht ? denseStepClasses : stepClasses;\n\n if (message.role === \"thinking\" || (message.role === \"tool\" && message.tool)) {\n if (detailMode === \"compact\") {\n return <TraceLine className={schritt} expandierbar={expandierbar} message={message} texts={texts} toolArgumentsText={toolArgumentsText} />;\n }\n const thinking = message.role === \"thinking\";\n const tool = message.tool;\n const icon = thinking ? (\n <SparklesIcon className={traceIconClasses} size={12} />\n ) : (\n <WrenchIcon className={tool?.isError ? traceErrorIconClasses : traceIconClasses} size={12} />\n );\n const zeile = (\n <>\n {message.text}\n {tool && tool.result === undefined && <span className={traceRunningClasses}>{texts.toolRunning}</span>}\n </>\n );\n return (\n <div className={cn(traceClasses, schritt)} data-kind={thinking ? \"thinking\" : \"tool\"} data-step=\"detail\">\n {icon}\n <div className=\"qsl:min-w-0 qsl:flex-1\">\n <div className={cn(traceLineClasses, thinking && \"qsl:font-sans qsl:italic qsl:whitespace-pre-wrap\")}>{zeile}</div>\n {tool && (\n <div className=\"qsl:mt-0.5 qsl:border-l-2 qsl:border-border-soft qsl:pl-2\">\n <pre className=\"qsl:mb-0.5 qsl:max-h-[208px] qsl:overflow-auto qsl:font-mono qsl:text-[10.5px] qsl:leading-[1.375] qsl:break-all qsl:whitespace-pre-wrap qsl:opacity-80\">{toolArgumentsText(tool)}</pre>\n {tool.result !== undefined && (\n <pre className={cn(\"qsl:mb-0.5 qsl:max-h-[208px] qsl:overflow-auto qsl:font-mono qsl:text-[10.5px] qsl:leading-[1.375] qsl:break-all qsl:whitespace-pre-wrap qsl:opacity-80\",\n tool.isError && \"qsl:text-destructive qsl:opacity-100\")}>{prettyJson(tool.result)}</pre>\n )}\n </div>\n )}\n </div>\n </div>\n );\n }\n\n if (message.role === \"action\" && message.action) {\n const action = message.action;\n return (\n <div className={schritt}>\n {renderAction?.(action, message.text) ?? (\n <PendingActionCard\n action={action}\n dismissedLabel={texts.actionDismissed}\n dismissLabel={texts.dismissAction}\n onDismiss={onDismissAction ? () => onDismissAction(action.actionId) : undefined}\n text={message.text}\n waitingLabel={texts.pendingAction}\n />\n )}\n </div>\n );\n }\n\n if (message.role === \"system\") {\n return (\n <div className={cn(schritt, \"qsl:border-l-2 qsl:border-destructive/50 qsl:pl-3 qsl:text-sm qsl:text-muted-foreground\")} data-message=\"system\">\n <Markdown text={message.text} />\n <MessageAttachments label={texts.attachments} message={message} />\n </div>\n );\n }\n\n if (!message.text.trim() && !message.attachments?.length) return null;\n\n const variant = bubbleOptions?.variant ?? \"default\";\n const useBubble = !plain && variant !== \"plain\" && (variant === \"bubbles\" || message.role === \"user\" || !!message.bubble);\n const side = (message.role === \"user\" ? bubbleOptions?.userSide : bubbleOptions?.assistantSide)\n ?? message.bubble?.side ?? (message.role === \"user\" ? \"end\" : \"start\");\n const sender = bubbleOptions?.senderLabel?.(message) ?? message.bubble?.label ?? message.sender;\n const showSender = bubbleOptions?.showSender ?? (!!message.bubble?.label && !plain);\n const content = <>\n {showSender && sender && <span className={cn(\"qsl:mb-[5px] qsl:table qsl:text-[0.72rem] qsl:leading-[1.45] qsl:font-semibold\",\n useBubble && message.bubble && \"qsl:rounded-full qsl:border qsl:border-white/30 qsl:bg-black/15 qsl:px-[7px] qsl:py-px qsl:tracking-[0.02em]\")} data-chat=\"sender\">{sender}</span>}\n <Markdown text={message.text} streaming={message.role === \"assistant\" && !message.closed} />\n <MessageAttachments label={texts.attachments} message={message} />\n {message.steered && <small className=\"qsl:mt-1 qsl:block qsl:text-[0.72rem] qsl:leading-[1.45] qsl:opacity-70\" data-chat=\"steered\">{texts.steered}</small>}\n <MessageActions message={message} options={messageActions} texts={texts} />\n </>;\n const cursor = message.role === \"assistant\" && message.textCursor ? JSON.stringify(message.textCursor) : undefined;\n if (!useBubble) return (\n <div data-chat-text-cursor={cursor} className={cn(schritt, \"qsl:group qsl:relative qsl:w-full qsl:leading-[var(--qsl-chat-line-height,1.625)] qsl:text-foreground\")} data-message=\"answer\">\n {content}\n </div>\n );\n return (\n <div data-chat-text-cursor={cursor} className={cn(schritt, \"qsl:flex\", side === \"end\" ? \"qsl:justify-end\" : \"qsl:justify-start\")}\n data-message={message.role === \"user\" && !message.bubble && variant === \"default\" ? \"user\" : \"bubble\"} data-side={side}>\n <div className={cn(bubbleBodyClasses, \"qsl:group\", message.bubble\n ? \"qsl:rounded-lg qsl:text-white qsl:[--qsl-scroll-cover:var(--qsl-primary)]\"\n : \"qsl:rounded-[10px_10px_4px_10px] qsl:border qsl:border-border qsl:bg-secondary qsl:text-foreground qsl:[--qsl-scroll-cover:var(--qsl-secondary)] qsl:in-data-[tone=material]:rounded-[9px] qsl:in-data-[tone=material]:border-glass-edge/20 qsl:in-data-[tone=material]:bg-primary/15 qsl:in-data-[tone=material]:text-foreground\")}\n data-tone={message.bubble ? \"on-color\" : undefined}\n style={{ background: message.bubble?.color, maxWidth: bubbleOptions?.maxWidth }}>\n {content}\n </div>\n </div>\n );\n}\n\nfunction MessageAttachments({ message, label }: { message: Message; label: string }) {\n if (!message.attachments?.length) return null;\n return (\n <ul className=\"qsl:mt-2.5 qsl:flex qsl:flex-wrap qsl:gap-2\" aria-label={label}>\n {message.attachments.map((attachment, index) => (\n <li className=\"qsl:relative qsl:flex qsl:w-[190px] qsl:max-w-full qsl:min-w-0 qsl:flex-col qsl:overflow-hidden qsl:rounded-lg qsl:border qsl:border-border qsl:text-sm\" key={`${attachment.url}-${index}`}>\n {attachment.mediaType.startsWith(\"image/\") && <a href={attachmentDownloadUrl(attachment.url)} download={attachment.name}><img className=\"qsl:block qsl:h-[112px] qsl:w-full qsl:bg-secondary qsl:object-contain\" src={attachment.url} alt={attachment.name} loading=\"lazy\" /></a>}\n {attachment.mediaType.startsWith(\"video/\") && <video className=\"qsl:block qsl:h-[112px] qsl:w-full qsl:bg-secondary qsl:object-contain\" src={attachment.url} controls preload=\"metadata\" aria-label={attachment.name} />}\n <div className=\"qsl:flex qsl:flex-col qsl:gap-1 qsl:p-2 qsl:[overflow-wrap:anywhere]\">\n <a className=\"qsl:font-medium\" href={attachmentDownloadUrl(attachment.url)} download={attachment.name}>{attachment.name}</a>\n <small>{formatAttachmentSize(attachment.size)}</small>\n </div>\n </li>\n ))}\n </ul>\n );\n}\n", "interface ScrollViewport {\n scrollTop: number;\n readonly scrollHeight: number;\n readonly clientHeight: number;\n}\n\nconst atEnd = (viewport: ScrollViewport) => viewport.scrollHeight - viewport.clientHeight - viewport.scrollTop <= 24;\n\nexport function createChatScroll(onFollowChange: (following: boolean) => void = () => {}) {\n let following = true;\n let lastTop = 0;\n\n const follow = (value: boolean) => {\n if (following === value) return;\n following = value;\n onFollowChange(value);\n };\n const layout = (viewport: ScrollViewport, dragging = false) => {\n if (viewport.clientHeight <= 0) return;\n if (dragging && viewport.scrollTop < lastTop && !atEnd(viewport)) follow(false);\n if (following) viewport.scrollTop = Math.max(0, viewport.scrollHeight - viewport.clientHeight);\n else if (viewport.scrollHeight <= viewport.clientHeight) follow(true);\n lastTop = viewport.scrollTop;\n };\n return {\n layout,\n pause(viewport: ScrollViewport) {\n if (viewport.scrollTop > 0) follow(false);\n },\n scroll(viewport: ScrollViewport, dragging = false) {\n if (viewport.clientHeight <= 0) return;\n if (atEnd(viewport)) follow(true);\n else if (dragging && viewport.scrollTop < lastTop) follow(false);\n lastTop = viewport.scrollTop;\n },\n jump(viewport: ScrollViewport) {\n follow(true);\n layout(viewport);\n },\n };\n}\n", "import { createContext, ReactNode, useCallback, useContext, useRef } from \"react\";\nimport { Streamdown, type Components } from \"streamdown\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport { cn } from \"./ui/cn\";\nimport { useAllowUrl, useQuasselComponents } from \"./QuasselProvider\";\nimport type { CodeBlockOptions } from \"./options\";\nimport { type ChatTexts, defaultTexts } from \"./texts\";\nimport { copyChatText, useChatAction } from \"./useChatAction\";\n\nexport type LinkClickHandler = (href: string, label: string) => boolean;\n\nconst LinkClickContext = createContext<LinkClickHandler | undefined>(undefined);\nconst CodeBlockContext = createContext<{ options?: CodeBlockOptions; texts: ChatTexts }>({ texts: defaultTexts });\n\nexport function MarkdownCodeBlocks({ children, options, texts }: { children: ReactNode; options?: CodeBlockOptions; texts: ChatTexts }) {\n return <CodeBlockContext.Provider value={{ options, texts }}>{children}</CodeBlockContext.Provider>;\n}\n\nfunction CodeBlock({ children }: { children?: ReactNode }) {\n const { options, texts } = useContext(CodeBlockContext);\n const { Button } = useQuasselComponents();\n const code = useRef<HTMLPreElement>(null);\n const action = useChatAction();\n const label = action.status === \"done\" ? texts.copied : texts.copyCode;\n const block = <pre ref={code} data-chat=\"code-block\"\n className={cn(scrollbar, \"qsl:my-2 qsl:overflow-auto qsl:rounded-lg qsl:bg-secondary qsl:px-3 qsl:py-2 qsl:font-mono qsl:text-sm qsl:leading-relaxed qsl:in-data-[tone=on-color]:bg-black/30 qsl:in-data-[tone=on-color]:text-inherit\")}\n style={{ maxHeight: options?.maxHeight, whiteSpace: options?.wrap ? \"pre-wrap\" : undefined, overflowWrap: options?.wrap ? \"anywhere\" : undefined }}>{children}</pre>;\n if (!options?.showCopyButton) return block;\n return <div className=\"qsl:relative\">\n {block}\n <Button aria-label={label} className=\"qsl:absolute qsl:top-1 qsl:right-1 qsl:bg-secondary\" disabled={action.status === \"pending\"} size=\"icon-sm\" title={label} variant=\"ghost\"\n onClick={() => { void action.invoke(() => copyChatText(code.current?.textContent ?? \"\", texts.clipboardUnavailable), texts.actionFailed); }}>\n {action.status === \"done\" ? <CheckIcon /> : <CopyIcon />}\n </Button>\n {action.error && <p className=\"qsl:text-sm qsl:text-destructive\" role=\"alert\">{action.error}</p>}\n </div>;\n}\n\nexport function MarkdownLinks({ children, onLinkClick }: { children: ReactNode; onLinkClick?: LinkClickHandler }) {\n return <LinkClickContext.Provider value={onLinkClick}>{children}</LinkClickContext.Provider>;\n}\n\nfunction MarkdownLink({ href, children }: { href?: string; children?: ReactNode }) {\n const onLinkClick = useContext(LinkClickContext);\n if (!href || href === \"streamdown:incomplete-link\") {\n return <span>{children}</span>;\n }\n return (\n <a\n className=\"qsl:text-primary qsl:[text-underline-offset:2px] qsl:in-data-[tone=on-color]:text-inherit qsl:in-data-[tone=on-color]:underline\"\n href={href}\n onClick={(event) => {\n if (href && onLinkClick?.(href, event.currentTarget.textContent ?? \"\")) {\n event.preventDefault();\n }\n }}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {children}\n </a>\n );\n}\n\n// Waagerechte Rollbalken bleiben sichtbar - sonst ist der Ueberlauf nicht auffindbar.\nconst scrollbar = \"qsl:[scrollbar-width:thin] qsl:[&::-webkit-scrollbar]:block qsl:[&::-webkit-scrollbar]:h-2 qsl:[&::-webkit-scrollbar-thumb]:rounded-full qsl:[&::-webkit-scrollbar-thumb]:bg-border\";\n\n// Die Deckstreifen verbergen den Umbruch am Rand; --qsl-scroll-cover kommt aus der umgebenden Blase.\nconst scrollCover = \"qsl:bg-[linear-gradient(to_right,var(--qsl-scroll-cover,var(--qsl-background))_50%,transparent)_left/20px_100%_no-repeat_local,linear-gradient(to_left,var(--qsl-scroll-cover,var(--qsl-background))_50%,transparent)_right/20px_100%_no-repeat_local,linear-gradient(to_right,#00000047,transparent)_left/14px_100%_no-repeat_scroll,linear-gradient(to_left,#00000047,transparent)_right/14px_100%_no-repeat_scroll]\";\n\nconst headingClasses = \"qsl:mt-3 qsl:mb-1 qsl:text-[15px] qsl:font-medium\";\nconst cellClasses = \"qsl:max-w-[44ch] qsl:border qsl:border-border qsl:px-2 qsl:py-1 qsl:text-left qsl:align-top qsl:in-data-[tone=on-color]:border-white/35\";\n\nconst components: Components = {\n h1: ({ children }) => <h1 className=\"qsl:mt-3 qsl:mb-1 qsl:text-lg qsl:font-semibold\">{children}</h1>,\n h2: ({ children }) => <h2 className={headingClasses}>{children}</h2>,\n h3: ({ children }) => <h3 className={headingClasses}>{children}</h3>,\n h4: ({ children }) => <h4 className=\"qsl:mt-2 qsl:mb-1 qsl:text-base qsl:font-medium\">{children}</h4>,\n h5: ({ children }) => <h5 className=\"qsl:mt-2 qsl:mb-1 qsl:text-base qsl:font-medium\">{children}</h5>,\n h6: ({ children }) => <h6 className=\"qsl:mt-2 qsl:mb-1 qsl:text-base qsl:font-medium\">{children}</h6>,\n p: ({ children }) => <p className=\"qsl:[p+&]:mt-2\">{children}</p>,\n ul: ({ children }) => <ul className=\"qsl:my-2 qsl:list-disc qsl:pl-6 qsl:[li>&]:my-0\">{children}</ul>,\n ol: ({ children }) => <ol className=\"qsl:my-2 qsl:list-decimal qsl:pl-6 qsl:[li>&]:my-0\">{children}</ol>,\n li: ({ children }) => <li className=\"qsl:marker:text-muted-foreground qsl:in-data-[tone=on-color]:marker:text-inherit\">{children}</li>,\n hr: () => <hr className=\"qsl:my-3 qsl:border-t qsl:border-border\" />,\n img: ({ src, alt }) => <img alt={alt} className=\"qsl:h-auto qsl:max-w-full\" src={typeof src === \"string\" ? src : undefined} />,\n blockquote: ({ children }) => (\n <blockquote className=\"qsl:my-1 qsl:border-l-2 qsl:border-border qsl:pl-3 qsl:text-muted-foreground qsl:in-data-[tone=on-color]:border-white/50 qsl:in-data-[tone=on-color]:text-inherit\">{children}</blockquote>\n ),\n strong: ({ children }) => <strong className=\"qsl:font-medium\">{children}</strong>,\n em: ({ children }) => <em>{children}</em>,\n a: ({ href, children }) => <MarkdownLink href={href}>{children}</MarkdownLink>,\n pre: ({ children }) => <CodeBlock>{children}</CodeBlock>,\n code: ({ children, className }) => (\n <code className={cn(className, \"qsl:rounded-sm qsl:bg-secondary qsl:px-1 qsl:py-0.5 qsl:font-mono qsl:text-sm qsl:[overflow-wrap:anywhere] qsl:in-data-[tone=on-color]:bg-white/20 qsl:in-data-[tone=on-color]:text-inherit\", \"qsl:[pre>&]:bg-transparent qsl:[pre>&]:p-0\")}>{children}</code>\n ),\n // Ohne max-content schrumpft die Tabelle auf den Container und stapelt Buchstaben.\n table: ({ children }) => (\n <div className={cn(scrollbar, scrollCover, \"qsl:my-2 qsl:overflow-x-auto\")}>\n <table className=\"qsl:w-max qsl:min-w-full qsl:border-collapse qsl:text-sm\">{children}</table>\n </div>\n ),\n thead: ({ children }) => <thead>{children}</thead>,\n tbody: ({ children }) => <tbody>{children}</tbody>,\n tr: ({ children }) => <tr>{children}</tr>,\n th: ({ children }) => <th className={cn(cellClasses, \"qsl:bg-secondary qsl:font-medium qsl:in-data-[tone=on-color]:bg-white/15 qsl:in-data-[tone=on-color]:text-inherit\")}>{children}</th>,\n td: ({ children }) => <td className={cellClasses}>{children}</td>,\n};\n\nfunction transformUrl(url: string, allowUrl?: (url: string) => boolean) {\n if (allowUrl?.(url)) return url;\n const scheme = /^[^/?#]*:/.exec(url);\n return !scheme || /^(https?|mailto|tel|ftp|irc|ircs|xmpp):$/i.test(scheme[0]) ? url : \"\";\n}\n\nexport function Markdown({ text, streaming = false }: { text: string; streaming?: boolean }) {\n const allowUrl = useAllowUrl();\n const urlTransform = useCallback((url: string) => transformUrl(url, allowUrl), [allowUrl]);\n return (\n <Streamdown\n className=\"space-y-0 text-inherit\"\n prefix=\"qsl\"\n mode={streaming ? \"streaming\" : \"static\"}\n isAnimating={streaming}\n parseIncompleteMarkdown={streaming}\n components={components}\n controls={false}\n rehypePlugins={[]}\n urlTransform={urlTransform}\n skipHtml\n >\n {text}\n </Streamdown>\n );\n}\n\n/** Dieselbe Syntax wie der Renderer, als Klartext ohne Markup, etwa f\u00FCr Screenreader-Ansagen. */\nexport function markdownPlainText(text: string): string {\n return text\n .split(\"\\n\")\n .filter((line) => !/^\\s*```\\w*\\s*$/.test(line) && !isTableDivider(line))\n .map((line) => (line.trim().startsWith(\"|\") ? splitTableRow(line).join(\", \") : line)\n .replace(/^(#{1,6})\\s+/, \"\")\n .replace(/^\\s*>\\s?/, \"\")\n .replace(/^\\s*([-*+]|\\d+[.)])\\s+/, \"\")\n .replace(/!?\\[([^\\]]*)\\]\\(([^)]+)\\)|\\*\\*([^*]+)\\*\\*|__([^_]+)__|\\*([^*]+)\\*|`([^`]+)`/g, (_, link, _href, fett, fettUnterstrich, kursiv, code) => link ?? fett ?? fettUnterstrich ?? kursiv ?? code)\n .trim())\n .filter((line) => line !== \"\")\n .join(\"\\n\");\n}\n\nfunction splitTableRow(line: string): string[] {\n let row = line.trim();\n if (row.startsWith(\"|\")) {\n row = row.slice(1);\n }\n if (row.endsWith(\"|\")) {\n row = row.slice(0, -1);\n }\n return row.split(\"|\").map((cell) => cell.trim());\n}\n\nfunction isTableDivider(line: string): boolean {\n return /^\\s*\\|?\\s*:?-{1,}:?\\s*(\\|\\s*:?-{1,}:?\\s*)*\\|?\\s*$/.test(line) && line.includes(\"-\");\n}\n", "import { createContext, useContext, useMemo, type ComponentType, type ReactNode } from \"react\";\nimport { Button } from \"./ui/button\";\nimport { Card } from \"./ui/card\";\nimport { Popover, PopoverContent } from \"./ui/popover\";\nimport { StopButton } from \"./ui/stop-button\";\nimport { Toggle } from \"./ui/toggle\";\n\nexport type QuasselButtonVariant = \"default\" | \"outline\" | \"secondary\" | \"ghost\" | \"destructive\" | \"link\";\nexport type QuasselButtonSize = \"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\";\n\nexport interface QuasselButtonProps {\n variant?: QuasselButtonVariant;\n size?: QuasselButtonSize;\n className?: string;\n disabled?: boolean;\n title?: string;\n \"aria-label\"?: string;\n \"aria-pressed\"?: boolean;\n onClick?: () => void;\n children?: ReactNode;\n}\n\nexport interface QuasselToggleProps {\n variant?: \"default\" | \"outline\";\n size?: \"default\" | \"sm\" | \"lg\";\n className?: string;\n disabled?: boolean;\n title?: string;\n pressed?: boolean;\n onPressedChange?: (pressed: boolean) => void;\n children?: ReactNode;\n}\n\nexport interface QuasselCardProps {\n size?: \"default\" | \"sm\";\n className?: string;\n children?: ReactNode;\n}\n\nexport interface QuasselStopButtonProps {\n label: string;\n busy?: boolean;\n size?: QuasselButtonSize;\n className?: string;\n disabled?: boolean;\n title?: string;\n onClick?: () => void;\n}\n\nexport interface QuasselPopoverProps {\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport interface QuasselPopoverAnchor {\n getBoundingClientRect: () => DOMRect;\n contextElement?: Element;\n}\n\nexport interface QuasselPopoverContentProps {\n anchor?: QuasselPopoverAnchor;\n align?: \"start\" | \"center\" | \"end\";\n side?: \"top\" | \"bottom\" | \"left\" | \"right\" | \"inline-start\" | \"inline-end\";\n sideOffset?: number;\n collisionPadding?: number;\n className?: string;\n \"aria-label\"?: string;\n children?: ReactNode;\n}\n\n/** The primitives quassel renders; a host replaces any of them through QuasselProvider. */\nexport interface QuasselComponents {\n Button: ComponentType<QuasselButtonProps>;\n Toggle: ComponentType<QuasselToggleProps>;\n Card: ComponentType<QuasselCardProps>;\n StopButton: ComponentType<QuasselStopButtonProps>;\n Popover: ComponentType<QuasselPopoverProps>;\n PopoverContent: ComponentType<QuasselPopoverContentProps>;\n}\n\nexport const defaultComponents: QuasselComponents = { Button, Toggle, Card, StopButton, Popover, PopoverContent };\n\ninterface QuasselSettings {\n components: QuasselComponents;\n allowUrl?: (url: string) => boolean;\n}\n\nconst QuasselContext = createContext<QuasselSettings>({ components: defaultComponents });\n\nexport function QuasselProvider({ components, allowUrl, children }: {\n /** Replaces single primitives; the rest stay the built-in ones or those of an outer provider. */\n components?: Partial<QuasselComponents>;\n /** Keeps Markdown link and image URLs that the default policy (http, https, mailto, tel, ftp, irc, xmpp, relative) would drop. */\n allowUrl?: (url: string) => boolean;\n children: ReactNode;\n}) {\n const outer = useContext(QuasselContext);\n const value = useMemo(() => ({\n components: { ...outer.components, ...components },\n allowUrl: allowUrl ?? outer.allowUrl,\n }), [outer, components, allowUrl]);\n return <QuasselContext.Provider value={value}>{children}</QuasselContext.Provider>;\n}\n\nexport const useQuasselComponents = (): QuasselComponents => useContext(QuasselContext).components;\n\nexport const useAllowUrl = (): ((url: string) => boolean) | undefined => useContext(QuasselContext).allowUrl;\n", "import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"./cn\"\n\nconst buttonVariants = cva(\n \"qsl:group/button qsl:inline-flex qsl:shrink-0 qsl:items-center qsl:justify-center qsl:rounded-lg qsl:border qsl:border-transparent qsl:bg-clip-padding qsl:text-sm qsl:font-medium qsl:whitespace-nowrap qsl:transition-all qsl:outline-none qsl:select-none qsl:focus-visible:border-ring qsl:focus-visible:ring-3 qsl:focus-visible:ring-ring/50 qsl:active:not-aria-[haspopup]:translate-y-px qsl:disabled:pointer-events-none qsl:disabled:opacity-50 qsl:aria-invalid:border-destructive qsl:aria-invalid:ring-3 qsl:aria-invalid:ring-destructive/20 qsl:dark:aria-invalid:border-destructive/50 qsl:dark:aria-invalid:ring-destructive/40 qsl:[&_svg]:pointer-events-none qsl:[&_svg]:shrink-0 qsl:[&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"qsl:bg-primary qsl:text-primary-foreground qsl:hover:bg-primary/80\",\n outline:\n \"qsl:border-border qsl:bg-background qsl:hover:bg-muted qsl:hover:text-foreground qsl:aria-expanded:bg-muted qsl:aria-expanded:text-foreground qsl:dark:border-input qsl:dark:bg-input/30 qsl:dark:hover:bg-input/50\",\n secondary:\n \"qsl:bg-secondary qsl:text-secondary-foreground qsl:hover:bg-[color-mix(in_oklch,var(--qsl-secondary),var(--qsl-foreground)_5%)] qsl:aria-expanded:bg-secondary qsl:aria-expanded:text-secondary-foreground\",\n ghost:\n \"qsl:hover:bg-muted qsl:hover:text-foreground qsl:aria-expanded:bg-muted qsl:aria-expanded:text-foreground qsl:dark:hover:bg-muted/50\",\n destructive:\n \"qsl:bg-destructive/10 qsl:text-destructive qsl:hover:bg-destructive/20 qsl:focus-visible:border-destructive/40 qsl:focus-visible:ring-destructive/20 qsl:dark:bg-destructive/20 qsl:dark:hover:bg-destructive/30 qsl:dark:focus-visible:ring-destructive/40\",\n link: \"qsl:text-primary qsl:underline-offset-4 qsl:hover:underline\",\n },\n size: {\n default:\n \"qsl:h-8 qsl:gap-1.5 qsl:px-2.5 qsl:has-data-[icon=inline-end]:pr-2 qsl:has-data-[icon=inline-start]:pl-2\",\n xs: \"qsl:h-6 qsl:gap-1 qsl:rounded-[min(var(--qsl-radius-md),10px)] qsl:px-2 qsl:text-xs qsl:in-data-[slot=button-group]:rounded-lg qsl:has-data-[icon=inline-end]:pr-1.5 qsl:has-data-[icon=inline-start]:pl-1.5 qsl:[&_svg:not([class*='size-'])]:size-3\",\n sm: \"qsl:h-7 qsl:gap-1 qsl:rounded-[min(var(--qsl-radius-md),12px)] qsl:px-2.5 qsl:text-[0.8rem] qsl:in-data-[slot=button-group]:rounded-lg qsl:has-data-[icon=inline-end]:pr-1.5 qsl:has-data-[icon=inline-start]:pl-1.5 qsl:[&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"qsl:h-9 qsl:gap-1.5 qsl:px-2.5 qsl:has-data-[icon=inline-end]:pr-2 qsl:has-data-[icon=inline-start]:pl-2\",\n icon: \"qsl:size-8\",\n \"icon-xs\":\n \"qsl:size-6 qsl:rounded-[min(var(--qsl-radius-md),10px)] qsl:in-data-[slot=button-group]:rounded-lg qsl:[&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"qsl:size-7 qsl:rounded-[min(var(--qsl-radius-md),12px)] qsl:in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"qsl:size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-quassel=\"\"\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n", "import * as React from \"react\"\nimport { cn } from \"./cn\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-quassel=\"\"\n data-slot=\"card\"\n data-size={size}\n className={cn(\n \"qsl:group/card qsl:flex qsl:flex-col qsl:gap-(--qsl-card-spacing) qsl:overflow-hidden qsl:rounded-panel qsl:border qsl:border-border qsl:bg-card qsl:py-(--qsl-card-spacing) qsl:text-sm qsl:text-card-foreground qsl:shadow-bar qsl:[--qsl-card-spacing:--spacing(4)] qsl:has-data-[slot=card-footer]:pb-0 qsl:has-[>img:first-child]:pt-0 qsl:data-[size=sm]:[--qsl-card-spacing:--spacing(3)] qsl:data-[size=sm]:has-data-[slot=card-footer]:pb-0 qsl:*:[img:first-child]:rounded-t-xl qsl:*:[img:last-child]:rounded-b-xl\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Card }\n", "import { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\nimport { cn } from \"./cn\"\n\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 8,\n anchor,\n collisionPadding,\n keepMounted,\n ...props\n}: PopoverPrimitive.Popup.Props &\n Pick<\n PopoverPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\" | \"anchor\" | \"collisionPadding\"\n > & Pick<PopoverPrimitive.Portal.Props, \"keepMounted\">) {\n return (\n <PopoverPrimitive.Portal keepMounted={keepMounted}>\n <PopoverPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n anchor={anchor}\n collisionPadding={collisionPadding}\n side={side}\n sideOffset={sideOffset}\n className=\"qsl:isolate qsl:z-[110]\"\n >\n <PopoverPrimitive.Popup\n data-quassel=\"\"\n data-slot=\"popover-content\"\n className={cn(\n \"qsl:z-[110] qsl:flex qsl:w-72 qsl:origin-(--transform-origin) qsl:flex-col qsl:gap-2.5 qsl:rounded-lg qsl:bg-popover qsl:p-2.5 qsl:text-sm qsl:text-popover-foreground qsl:shadow-md qsl:ring-1 qsl:ring-foreground/10 qsl:outline-hidden qsl:duration-100 qsl:data-[side=bottom]:slide-in-from-top-2 qsl:data-[side=inline-end]:slide-in-from-left-2 qsl:data-[side=inline-start]:slide-in-from-right-2 qsl:data-[side=left]:slide-in-from-right-2 qsl:data-[side=right]:slide-in-from-left-2 qsl:data-[side=top]:slide-in-from-bottom-2 qsl:data-open:animate-in qsl:data-open:fade-in-0 qsl:data-open:zoom-in-95 qsl:data-closed:animate-out qsl:data-closed:fade-out-0 qsl:data-closed:zoom-out-95\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverContent }\n", "import { SquareIcon } from \"lucide-react\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"./cn\";\nimport { Button } from \"./button\";\nimport { Spinner } from \"./spinner\";\n\n/** Die eine Stopp-Glyphe: ein gef\u00FClltes rotes Quadrat; ein Zustandssymbol tr\u00E4gt sie nie. */\nexport function StopGlyph({ className, ...props }: Omit<ComponentProps<typeof SquareIcon>, \"fill\">) {\n return <SquareIcon aria-hidden className={cn(\"qsl:text-destructive\", className)} fill=\"currentColor\" {...props} />;\n}\n\nconst stopButtonClass = \"qsl:text-destructive qsl:hover:bg-destructive/10 qsl:hover:text-destructive qsl:dark:hover:bg-destructive/20\";\n\n/** Jeder Stopp-Knopf sieht gleich aus: die Glyphe als Symbol, das Wort im Tooltip, rot in Ruhe und beim Hover. */\nexport function StopButton({ label, busy = false, className, title, ...props }: Omit<ComponentProps<typeof Button>, \"children\" | \"variant\"> & {\n label: string;\n busy?: boolean;\n}) {\n return <Button aria-busy={busy || undefined} aria-label={label} className={cn(stopButtonClass, className)} title={title ?? label} variant=\"ghost\" {...props}>\n {busy ? <Spinner /> : <StopGlyph />}\n </Button>;\n}\n", "import { cn } from \"./cn\"\nimport { Loader2Icon } from \"lucide-react\"\n\nfunction Spinner({ className, ...props }: React.ComponentProps<\"svg\">) {\n return (\n <Loader2Icon data-slot=\"spinner\" role=\"status\" aria-label=\"Loading\" className={cn(\"qsl:size-4 qsl:animate-spin\", className)} {...props} />\n )\n}\n\nexport { Spinner }\n", "import { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"./cn\"\n\nconst toggleVariants = cva(\n \"qsl:group/toggle qsl:inline-flex qsl:items-center qsl:justify-center qsl:gap-1 qsl:rounded-lg qsl:text-sm qsl:font-medium qsl:whitespace-nowrap qsl:transition-all qsl:outline-none qsl:hover:bg-muted qsl:hover:text-foreground qsl:focus-visible:border-ring qsl:focus-visible:ring-[3px] qsl:focus-visible:ring-ring/50 qsl:disabled:pointer-events-none qsl:disabled:opacity-50 qsl:aria-invalid:border-destructive qsl:aria-invalid:ring-destructive/20 qsl:aria-pressed:bg-muted qsl:data-[state=on]:bg-muted qsl:dark:aria-invalid:ring-destructive/40 qsl:[&_svg]:pointer-events-none qsl:[&_svg]:shrink-0 qsl:[&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"qsl:bg-transparent\",\n outline: \"qsl:border qsl:border-input qsl:bg-transparent qsl:hover:bg-muted\",\n },\n size: {\n default:\n \"qsl:h-8 qsl:min-w-8 qsl:px-2.5 qsl:has-data-[icon=inline-end]:pr-2 qsl:has-data-[icon=inline-start]:pl-2\",\n sm: \"qsl:h-7 qsl:min-w-7 qsl:rounded-[min(var(--qsl-radius-md),12px)] qsl:px-2.5 qsl:text-[0.8rem] qsl:has-data-[icon=inline-end]:pr-1.5 qsl:has-data-[icon=inline-start]:pl-1.5 qsl:[&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"qsl:h-9 qsl:min-w-9 qsl:px-2.5 qsl:has-data-[icon=inline-end]:pr-2 qsl:has-data-[icon=inline-start]:pl-2\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Toggle({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive\n data-quassel=\"\"\n data-slot=\"toggle\"\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Toggle, toggleVariants }\n", "import { useEffect, useRef, useState } from \"react\";\n\nexport function useChatAction() {\n const pending = useRef(false);\n const [status, setStatus] = useState<\"idle\" | \"pending\" | \"done\">(\"idle\");\n const [error, setError] = useState<string>();\n useEffect(() => {\n if (status !== \"done\") return;\n const timer = window.setTimeout(() => setStatus(\"idle\"), 1800);\n return () => window.clearTimeout(timer);\n }, [status]);\n const invoke = async (action: () => void | Promise<void>, failureLabel: string) => {\n if (pending.current) return;\n pending.current = true;\n setError(undefined);\n setStatus(\"pending\");\n try {\n await action();\n setStatus(\"done\");\n } catch (failure) {\n const detail = failure instanceof Error ? failure.message : String(failure);\n setError(`${failureLabel}: ${detail}`);\n setStatus(\"idle\");\n } finally {\n pending.current = false;\n }\n };\n return { status, error, invoke };\n}\n\nexport async function copyChatText(text: string, unavailable: string) {\n if (!navigator.clipboard) throw new Error(unavailable);\n await navigator.clipboard.writeText(text);\n}\n", "import { useMemo } from \"react\";\nimport { SparklesIcon, WrenchIcon, XIcon } from \"lucide-react\";\nimport { cn } from \"./ui/cn\";\nimport { useQuasselComponents } from \"./QuasselProvider\";\nimport { Message, prettyJson } from \"./types\";\nimport { ChatTexts } from \"./texts\";\n\nconst preClasses = \"qsl:rounded-lg qsl:bg-secondary qsl:p-3 qsl:font-mono qsl:text-[11px] qsl:leading-[1.625] qsl:break-all qsl:whitespace-pre-wrap\";\n\nexport function StepPopover({\n message,\n position,\n texts,\n toolArgumentsText,\n onClose,\n}: {\n message: Message;\n position: { x: number; y: number };\n texts: ChatTexts;\n toolArgumentsText: (tool: NonNullable<Message[\"tool\"]>) => string;\n onClose: () => void;\n}) {\n const anchor = useMemo(() => ({\n getBoundingClientRect: () => new DOMRect(position.x, position.y, 0, 0),\n contextElement: document.documentElement,\n }), [position]);\n const { Button, Popover, PopoverContent } = useQuasselComponents();\n const tool = message.tool;\n const thinking = message.role === \"thinking\";\n const title = thinking ? texts.thinkingTitle : texts.toolTitle;\n\n return (\n <Popover open onOpenChange={(open) => { if (!open) onClose(); }}>\n <PopoverContent\n align=\"start\"\n anchor={anchor}\n aria-label={title}\n className={cn(\n \"qsl:w-[min(680px,calc(100vw-32px))] qsl:gap-0 qsl:overflow-hidden qsl:p-0 qsl:text-[13px] qsl:shadow-pop\",\n thinking ? \"qsl:max-h-none\" : \"qsl:max-h-[min(70vh,620px)]\",\n )}\n collisionPadding={16}\n side=\"bottom\"\n sideOffset={10}\n >\n <div className=\"qsl:flex qsl:flex-none qsl:items-center qsl:gap-2 qsl:border-b qsl:border-border-soft qsl:px-4 qsl:py-2.5\">\n {thinking ? (\n <SparklesIcon className=\"qsl:text-muted-foreground\" size={14} />\n ) : (\n <WrenchIcon className={tool?.isError ? \"qsl:text-destructive\" : \"qsl:text-muted-foreground\"} size={14} />\n )}\n <span className=\"qsl:min-w-0 qsl:flex-1 qsl:overflow-hidden qsl:text-ellipsis qsl:whitespace-nowrap qsl:font-medium\">{title}</span>\n <Button aria-label={texts.close} className=\"qsl:flex-none\" onClick={onClose} size=\"icon-sm\" title={texts.close} variant=\"ghost\">\n <XIcon />\n </Button>\n </div>\n <div className={cn(\"qsl:min-h-0 qsl:p-4\", thinking ? \"qsl:overflow-visible\" : \"qsl:overflow-auto\")}>\n {thinking ? (\n <div className=\"qsl:text-sm qsl:leading-[1.625] qsl:whitespace-pre-wrap\">{message.text}</div>\n ) : tool ? (\n <div className=\"qsl:flex qsl:flex-col qsl:gap-4\">\n <div className=\"qsl:font-mono qsl:text-sm\">{message.text}</div>\n <PopoverSection label={texts.argumentsLabel} value={toolArgumentsText(tool)} />\n {tool.result === undefined ? (\n <div className=\"qsl:text-sm qsl:text-muted-foreground\">{texts.toolStillRunning}</div>\n ) : (\n <PopoverSection error={tool.isError} label={texts.resultLabel} value={prettyJson(tool.result)} />\n )}\n </div>\n ) : null}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction PopoverSection({ label, value, error = false }: { label: string; value: string; error?: boolean }) {\n return (\n <section>\n <h3 className=\"qsl:mb-1.5 qsl:text-[11px] qsl:font-semibold qsl:tracking-[0.04em] qsl:text-muted-foreground qsl:uppercase\">{label}</h3>\n <pre className={cn(preClasses, error && \"qsl:text-destructive\")}>{value}</pre>\n </section>\n );\n}\n", "import { CheckIcon } from \"lucide-react\";\nimport { useQuasselComponents } from \"./QuasselProvider\";\nimport type { PendingAction } from \"./types\";\n\nconst cardClasses = \"qsl:gap-2.5 qsl:bg-background qsl:px-3.5 qsl:text-sm\";\n\nconst resultText = (result: unknown): string =>\n typeof result === \"string\" ? result : result === null || result === undefined ? \"\" : JSON.stringify(result);\n\n/**\n * Die Darstellung einer wartenden Aktion ohne Beitrag ihres Eigent\u00FCmers: Titel, der Hinweis,\n * dass eine Eingabe erwartet wird, und das Verwerfen. Die Form kennt nur das Plugin.\n */\nexport function PendingActionCard({\n text,\n action,\n waitingLabel,\n dismissLabel,\n dismissedLabel,\n onDismiss,\n}: {\n text: string;\n action: PendingAction;\n waitingLabel: string;\n dismissLabel: string;\n dismissedLabel: string;\n onDismiss?: () => void;\n}) {\n const { Button, Card } = useQuasselComponents();\n if (action.status !== undefined) {\n return (\n <Card className={cardClasses} size=\"sm\">\n <div className=\"qsl:leading-normal\">{text}</div>\n <div className=\"qsl:flex qsl:items-center qsl:gap-1.5 qsl:text-sm qsl:text-muted-foreground\" data-action=\"resolved\">\n <CheckIcon className=\"qsl:text-success\" size={12} />\n {action.status === \"approved\" ? resultText(action.result) : dismissedLabel}\n </div>\n </Card>\n );\n }\n\n return (\n <Card className={cardClasses} size=\"sm\">\n <div className=\"qsl:leading-normal\">{text}</div>\n <div className=\"qsl:flex qsl:items-center qsl:justify-between qsl:gap-2\">\n <span className=\"qsl:text-sm qsl:text-muted-foreground\" data-action=\"waiting\">{waitingLabel}</span>\n {onDismiss && (\n <Button onClick={onDismiss} size=\"sm\" variant=\"outline\">{dismissLabel}</Button>\n )}\n </div>\n </Card>\n );\n}\n", "import { useEffect, useState } from \"react\";\nimport { cn } from \"./ui/cn\";\n\nconst SPUR = 13;\nconst GRUNDTAKT_MS = 90;\nconst SZENENWECHSEL_MS = 2600;\n\n/** Eine Zelle je Figur: Emoji und Satzzeichen teilen sich kein Raster, geschobener Text ruckelt. */\nfunction bahn(figuren: Record<number, string>, breite = SPUR): string[] {\n return Array.from({ length: breite }, (_, x) => figuren[x] ?? \" \");\n}\n\ninterface Szene {\n id: string;\n takt: number;\n laufend?: true;\n compact?: true;\n zeichne: (schritt: number) => string | string[];\n}\n\n/**\n * Kleine Szenen, in denen etwas Erkennbares passiert - der Zustand aendert sich sichtbar,\n * statt dass nur eine Figur vorbeilaeuft. Szenen mit Bewegung geben ihre Bahn als Zellen\n * zurueck, alle anderen als schlichten Text.\n */\nconst SZENEN: Szene[] = [\n {\n id: \"denken\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 10;\n if (takt >= 8) return \"\\u{1F929}\\u{1F4A1}\";\n return \"\\u{1F914}\" + \"\\u{1F4AD}\".repeat(Math.min(takt, 3));\n },\n },\n {\n // Fliegt nach rechts und zieht ihren Schweif hinterher.\n id: \"rakete\",\n takt: 2,\n laufend: true,\n zeichne: (schritt) => {\n const x = schritt % SPUR;\n return bahn({ [x - 2]: \"\u00B7\", [x - 1]: \"\\u{1F4A8}\", [x]: \"\\u{1F680}\" });\n },\n },\n {\n // Die Punkte bleiben stehen und werden einzeln gefressen.\n id: \"pacman\",\n takt: 2,\n laufend: true,\n zeichne: (schritt) => {\n const x = schritt % SPUR;\n const figuren: Record<number, string> = {};\n for (let i = x + 1; i < SPUR; i++) {\n figuren[i] = \"\u00B7\";\n }\n figuren[x] = schritt % 2 === 0 ? \"\\u{1F7E1}\" : \"\\u{1F315}\";\n return bahn(figuren);\n },\n },\n {\n // Aus einem Samen wird ein Baum, dann von vorn.\n id: \"wachsen\",\n compact: true,\n takt: 2,\n zeichne: (schritt) => {\n const stufen = [\"\\u{1F331}\", \"\\u{1F331}\", \"\\u{1F33F}\", \"\\u{1F33F}\", \"\\u{1F343}\", \"\\u{1F333}\", \"\\u{1F333}\", \"\\u{1F333}\"];\n return stufen[schritt % stufen.length];\n },\n },\n {\n // Das Ei bekommt Risse, das Kueken schluepft.\n id: \"schluepfen\",\n compact: true,\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 12;\n if (takt < 4) return \"\\u{1F95A}\";\n if (takt < 6) return \"\\u{1F95A}*\";\n if (takt < 9) return \"\\u{1F423}\";\n return \"\\u{1F425}\";\n },\n },\n {\n // Morse-artiges Signal, das sich zu einem OK aufloest.\n id: \"signal\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 14;\n if (takt >= 11) return \"\\u{1F4E1} OK\";\n const muster = [\"\u00B7\", \"\u00B7\u00B7\", \"\u00B7-\", \"-\u00B7\", \"\u00B7\u00B7-\", \"-\u00B7\u00B7\"];\n return \"\\u{1F4E1} \" + muster[takt % muster.length];\n },\n },\n {\n // Sanduhr: der Sand laeuft durch, dann wird gedreht.\n id: \"sanduhr\",\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 12;\n const koerner = \"\u00B7\".repeat(Math.max(0, 5 - Math.floor(takt / 2)));\n return (takt < 10 ? \"\u23F3\" : \"\u231B\") + \" \" + koerner;\n },\n },\n {\n // Ei, Kueken, Henne - und die legt das naechste Ei.\n id: \"huhn-kreislauf\",\n compact: true,\n takt: 3,\n zeichne: (schritt) => {\n const takt = schritt % 16;\n if (takt < 3) return \"\\u{1F95A}\";\n if (takt < 5) return \"\\u{1F95A}*\";\n if (takt < 8) return \"\\u{1F423}\";\n if (takt < 11) return \"\\u{1F424}\";\n if (takt < 14) return \"\\u{1F414}\";\n return \"\\u{1F414}\\u{1F95A}\";\n },\n },\n {\n // Hut, Funken - und das Kaninchen tuermt.\n id: \"zauberhut\",\n compact: true,\n takt: 3,\n zeichne: (schritt) => {\n const takt = schritt % 14;\n if (takt < 4) return \"\\u{1F3A9}\";\n if (takt < 7) return \"\\u{1F3A9}*\";\n if (takt < 11) return \"\\u{1F3A9}\\u{1F407}\";\n return \"\\u{1F407}\\u{1F4A8}\";\n },\n },\n {\n // Rot, Gelb, Gruen - und ab.\n id: \"ampel\",\n compact: true,\n takt: 3,\n zeichne: (schritt) => {\n const takt = schritt % 12;\n if (takt < 4) return \"\\u{1F534}\";\n if (takt < 6) return \"\\u{1F7E1}\";\n if (takt < 8) return \"\\u{1F7E2}\";\n return \"\\u{1F697}\\u{1F4A8}\";\n },\n },\n {\n // Klingeln, verschlafen, losrennen.\n id: \"wecker\",\n compact: true,\n takt: 2,\n zeichne: (schritt) => {\n const takt = schritt % 14;\n if (takt < 5) return takt % 2 === 0 ? \"\u23F0\" : \"\\u{1F514}\";\n if (takt < 8) return \"\\u{1F634}\";\n if (takt < 10) return \"\\u{1F633}\";\n return \"\\u{1F3C3}\\u{1F4A8}\";\n },\n },\n {\n // Schnecke kriecht zur Flagge - und feiert.\n id: \"schnecke\",\n takt: 4,\n zeichne: (schritt) => {\n const takt = schritt % 8;\n if (takt < 5) return bahn({ [takt]: \"\\u{1F40C}\", 4: \"\\u{1F3C1}\" }, 5);\n return bahn({ 4: \"\\u{1F389}\" }, 5);\n },\n },\n];\n\nconst COMPACT_SCENES = SZENEN.filter((scene) => scene.compact);\n\nexport interface WorkingScenesProps {\n /** Limits scenes to one or two visible characters for small status fields. */\n compact?: boolean;\n /** Text fuer Screenreader, Default \"Arbeitet ...\". */\n label?: string;\n}\n\n/**\n * Der Default-Working-Indikator: zufaellig rotierende Mini-Szenen. Zufaellige Reihenfolge\n * und Startphase, damit dieselben Szenen nie wie eine Schleife wirken. Ueber die\n * working-Prop von ChatMessages laesst er sich komplett ersetzen.\n */\nexport function WorkingScenes({ label = \"Arbeitet ...\", compact = false }: WorkingScenesProps) {\n const scenes = compact ? COMPACT_SCENES : SZENEN;\n const [sceneIndex, setSceneIndex] = useState(() => Math.floor(Math.random() * scenes.length));\n const [offset, setOffset] = useState(() => Math.floor(Math.random() * 20));\n const [frameTick, setFrameTick] = useState(0);\n const [reducedMotion, setReducedMotion] = useState(() => typeof window !== \"undefined\"\n && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches);\n const scene = scenes[sceneIndex % scenes.length];\n\n useEffect(() => {\n const preference = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const update = () => setReducedMotion(preference.matches);\n preference.addEventListener(\"change\", update);\n update();\n return () => preference.removeEventListener(\"change\", update);\n }, []);\n\n useEffect(() => {\n if (reducedMotion) return;\n const timer = window.setInterval(() => {\n setSceneIndex((previous) => (previous + 1 + Math.floor(Math.random() * (scenes.length - 1))) % scenes.length);\n setOffset(Math.floor(Math.random() * 20));\n setFrameTick(0);\n }, SZENENWECHSEL_MS);\n return () => window.clearInterval(timer);\n }, [reducedMotion, scenes]);\n\n useEffect(() => {\n if (reducedMotion) return;\n const timer = window.setInterval(() => setFrameTick((value) => value + 1), GRUNDTAKT_MS);\n return () => window.clearInterval(timer);\n }, [reducedMotion]);\n\n const frame = scene.zeichne(Math.floor(frameTick / scene.takt) + (scene.laufend ? offset : 0));\n return (\n <span aria-label={label} className={cn(\"qsl:flex qsl:items-center qsl:gap-2.5 qsl:text-[13px]\", compact ? \"qsl:text-inherit\" : \"qsl:mt-4 qsl:text-foreground\")} data-chat=\"working\" role=\"status\">\n {!compact && <span aria-hidden=\"true\" className=\"qsl:text-muted-foreground qsl:opacity-70\">&gt;</span>}\n <span aria-hidden=\"true\" className={cn(\"qsl:inline-block qsl:flex-none qsl:font-mono qsl:[font-variant-ligatures:none]\", compact ? \"qsl:w-[2.4em] qsl:text-center\" : \"qsl:w-[15rem]\")} key={scene.id}>\n <span className=\"qsl:tracking-[0.02em] qsl:whitespace-pre qsl:motion-reduce:opacity-60\">\n {typeof frame === \"string\"\n ? frame\n : frame.map((cell, index) => (\n <span className=\"qsl:inline-block qsl:w-[1.35em] qsl:text-center\" key={index}>\n {cell}\n </span>\n ))}\n </span>\n </span>\n </span>\n );\n}\n", "import type { ChatAttachmentInput } from \"./events\";\n\nimport { chatAttachmentMediaType, MAX_CHAT_ATTACHMENTS, MAX_CHAT_ATTACHMENT_BYTES } from \"./chat-attachments\";\nimport { defaultTexts, fillText, type ChatTexts } from \"./texts\";\n\nexport { MAX_CHAT_ATTACHMENTS, MAX_CHAT_ATTACHMENT_BYTES };\n\nexport const maxAttachmentSizeLabel = `${MAX_CHAT_ATTACHMENT_BYTES / (1024 * 1024)} MiB`;\n\nexport function attachmentMediaType(file: { name: string; type: string }): string {\n return chatAttachmentMediaType(file.name, file.type);\n}\n\nexport function attachmentCapabilityError(\n files: readonly { name: string; mediaType: string }[],\n capabilities: { input: readonly string[]; model: string },\n texts: ChatTexts = defaultTexts,\n): string | undefined {\n for (const file of files) {\n const required = file.mediaType.startsWith(\"image/\") ? \"image\"\n : file.mediaType.startsWith(\"video/\") ? \"video\" : file.mediaType === \"application/pdf\" ? \"file\" : undefined;\n if (required && !capabilities.input.includes(required)) {\n const kind = required === \"image\" ? texts.attachmentKindImage : required === \"video\" ? texts.attachmentKindVideo : texts.attachmentKindPdf;\n if (!capabilities.model) return fillText(texts.attachmentUnsupported, { name: file.name, kind });\n return fillText(texts.attachmentUnsupportedByModel, { model: capabilities.model, name: file.name, kind });\n }\n }\n}\n\nexport function validateAttachmentSelection(existing: readonly { size: number }[], incoming: readonly { size: number }[], texts: ChatTexts = defaultTexts): void {\n if (existing.length + incoming.length > MAX_CHAT_ATTACHMENTS) {\n throw new Error(fillText(texts.tooManyAttachments, { count: MAX_CHAT_ATTACHMENTS }));\n }\n if ([...existing, ...incoming].reduce((total, file) => total + file.size, 0) > MAX_CHAT_ATTACHMENT_BYTES) {\n throw new Error(fillText(texts.attachmentsTooLarge, { size: maxAttachmentSizeLabel }));\n }\n}\n\nexport async function encodeAttachment(file: File): Promise<ChatAttachmentInput> {\n const bytes = new Uint8Array(await file.arrayBuffer());\n const chunks: string[] = [];\n for (let offset = 0; offset < bytes.length; offset += 8192) {\n chunks.push(String.fromCharCode(...bytes.subarray(offset, offset + 8192)));\n }\n return { name: file.name, mediaType: attachmentMediaType(file), data: btoa(chunks.join(\"\")) };\n}\n\nexport function formatAttachmentSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;\n}\n\nexport function attachmentDownloadUrl(url: string): string {\n if (/^(data|blob):/i.test(url)) return url;\n const [resource, fragment] = url.split(/#(.*)/s);\n return `${resource}${resource.includes(\"?\") ? \"&\" : \"?\"}download=1${fragment === undefined ? \"\" : `#${fragment}`}`;\n}\n", "import type { CSSProperties, ReactNode } from \"react\";\nimport type { Message } from \"./types\";\n\nexport interface ChatAppearance {\n fontSize?: CSSProperties[\"fontSize\"];\n lineHeight?: CSSProperties[\"lineHeight\"];\n messageGap?: CSSProperties[\"marginTop\"];\n denseMessageGap?: CSSProperties[\"marginTop\"];\n}\n\nexport interface TimestampOptions {\n format?: \"time\" | \"date-time\" | \"relative\";\n locale?: string;\n timeZone?: string;\n showDaySeparators?: boolean;\n}\n\nexport interface CodeBlockOptions {\n wrap?: boolean;\n maxHeight?: CSSProperties[\"maxHeight\"];\n showCopyButton?: boolean;\n}\n\nexport interface BubbleOptions {\n variant?: \"default\" | \"plain\" | \"bubbles\";\n maxWidth?: CSSProperties[\"maxWidth\"];\n userSide?: \"start\" | \"end\";\n assistantSide?: \"start\" | \"end\";\n showSender?: boolean;\n senderLabel?: (message: Message) => string | undefined;\n}\n\nexport interface MessageAction {\n id: string;\n label: string;\n icon?: ReactNode;\n disabled?: boolean;\n onClick: (message: Message) => void | Promise<void>;\n}\n\nexport interface MessageActionsOptions {\n copy?: boolean | ((message: Message) => boolean);\n edit?: (message: Message) => void | Promise<void>;\n retry?: (message: Message) => void | Promise<void>;\n custom?: (message: Message) => readonly MessageAction[];\n}\n\nexport type SendShortcut = \"enter\" | \"mod-enter\";\n\nconst cssLength = (value: string | number | undefined) => typeof value === \"number\" ? `${value}px` : value;\n\nexport const appearanceStyle = (appearance?: ChatAppearance): CSSProperties => ({\n \"--qsl-chat-font-size\": cssLength(appearance?.fontSize),\n \"--qsl-chat-line-height\": appearance?.lineHeight,\n \"--qsl-chat-message-gap\": cssLength(appearance?.messageGap),\n \"--qsl-chat-dense-message-gap\": cssLength(appearance?.denseMessageGap),\n} as CSSProperties);\n", "import type { TimestampOptions } from \"./options\";\n\nexport function messageDate(at: string | undefined): Date | undefined {\n if (!at) return undefined;\n const date = new Date(at);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\nexport function timestampLabel(date: Date, options: TimestampOptions = {}, now = Date.now()): string {\n if ((!options.format || options.format === \"time\") && !options.locale && !options.timeZone) {\n return `${String(date.getHours()).padStart(2, \"0\")}:${String(date.getMinutes()).padStart(2, \"0\")}`;\n }\n if (options.format === \"relative\") {\n const seconds = (date.getTime() - now) / 1000;\n const units: readonly [Intl.RelativeTimeFormatUnit, number][] = [\n [\"year\", 365 * 86400], [\"month\", 30 * 86400], [\"day\", 86400], [\"hour\", 3600], [\"minute\", 60],\n ];\n const [unit, divisor] = units.find(([, value]) => Math.abs(seconds) >= value) ?? [\"second\", 1];\n return new Intl.RelativeTimeFormat(options.locale, { numeric: \"auto\" }).format(Math.round(seconds / divisor), unit);\n }\n return new Intl.DateTimeFormat(options.locale, {\n timeZone: options.timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hourCycle: \"h23\",\n ...(options.format === \"date-time\" ? { year: \"numeric\", month: \"2-digit\", day: \"2-digit\" } as const : {}),\n }).format(date);\n}\n\nexport function timestampDay(date: Date, options: TimestampOptions = {}): { key: string; label: string } {\n const key = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: options.timeZone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\",\n }).format(date);\n const label = new Intl.DateTimeFormat(options.locale, {\n timeZone: options.timeZone, dateStyle: \"long\",\n }).format(date);\n return { key, label };\n}\n", "import { CheckIcon, CopyIcon, PencilIcon, RotateCcwIcon } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { cn } from \"./ui/cn\";\nimport { useQuasselComponents } from \"./QuasselProvider\";\nimport type { MessageActionsOptions, MessageAction } from \"./options\";\nimport type { ChatTexts } from \"./texts\";\nimport type { Message } from \"./types\";\nimport { copyChatText, useChatAction } from \"./useChatAction\";\n\nconst actionClasses = cn(\n \"qsl:absolute qsl:top-1 qsl:right-1 qsl:z-[1] qsl:flex qsl:flex-wrap qsl:rounded-sm qsl:bg-secondary qsl:opacity-0\",\n \"qsl:shadow-[0_2px_6px_color-mix(in_srgb,var(--qsl-foreground)_15%,transparent)]\",\n \"qsl:pointer-events-none qsl:group-hover:pointer-events-auto qsl:group-hover:opacity-100 qsl:focus-within:pointer-events-auto qsl:focus-within:opacity-100\",\n \"qsl:[@media(hover:none)]:pointer-events-auto qsl:[@media(hover:none)]:opacity-100\",\n);\n\nexport function MessageActions({ message, options, texts }: { message: Message; options?: MessageActionsOptions; texts: ChatTexts }) {\n const action = useChatAction();\n const { Button } = useQuasselComponents();\n const [lastAction, setLastAction] = useState<string>();\n const copy = typeof options?.copy === \"function\" ? options.copy(message) : options?.copy ?? message.role === \"user\";\n const actions: MessageAction[] = [\n ...(copy && message.text.trim() ? [{ id: \"copy\", label: texts.copyMessage, icon: <CopyIcon />, onClick: () => copyChatText(message.text, texts.clipboardUnavailable) }] : []),\n ...(options?.edit && message.role === \"user\" ? [{ id: \"edit\", label: texts.editMessage, icon: <PencilIcon />, onClick: options.edit }] : []),\n ...(options?.retry && message.role === \"assistant\" ? [{ id: \"retry\", label: texts.retryMessage, icon: <RotateCcwIcon />, onClick: options.retry }] : []),\n ...options?.custom?.(message) ?? [],\n ];\n return <>\n {actions.length > 0 && <div className={actionClasses}>\n {actions.map((item) => {\n const copied = item.id === \"copy\" && lastAction === item.id && action.status === \"done\";\n const label = copied ? texts.copied : item.label;\n return <Button aria-label={label} className=\"qsl:text-inherit\" disabled={item.disabled || action.status === \"pending\"}\n key={item.id} size={item.icon ? \"icon-sm\" : \"sm\"} title={label} variant=\"ghost\"\n onClick={() => {\n setLastAction(item.id);\n void action.invoke(() => item.onClick(message), texts.actionFailed);\n }}>{copied ? <CheckIcon /> : item.icon ?? item.label}</Button>;\n })}\n </div>}\n {action.error && <p className=\"qsl:mt-2 qsl:text-sm qsl:text-destructive\" role=\"alert\">{action.error}</p>}\n </>;\n}\n", "import { createContext, type RefObject } from \"react\";\n\nexport interface ChatSendScope {\n notify: () => void;\n subscribe: (listener: () => void) => () => void;\n}\n\nexport const ChatSendContext = createContext<ChatSendScope | undefined>(undefined);\n\nexport function createChatSendScope(enabled: RefObject<boolean>): ChatSendScope {\n const listeners = new Set<() => void>();\n return {\n notify: () => { if (enabled.current) listeners.forEach((listener) => listener()); },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n };\n}\n", "const abstandMs = 400;\nconst hoechstensWartend = 5;\n\nlet region: HTMLElement | undefined;\nlet wartend: readonly string[] = [];\nlet laeuft = false;\n\nfunction ansageRegion(): HTMLElement {\n if (region?.isConnected) {\n return region;\n }\n const element = document.createElement(\"div\");\n element.setAttribute(\"role\", \"status\");\n element.setAttribute(\"aria-live\", \"polite\");\n element.setAttribute(\"aria-atomic\", \"true\");\n Object.assign(element.style, {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n margin: \"-1px\",\n padding: \"0\",\n border: \"0\",\n overflow: \"hidden\",\n clipPath: \"inset(50%)\",\n whiteSpace: \"nowrap\",\n });\n document.body.append(element);\n region = element;\n return element;\n}\n\nfunction naechste(): void {\n if (wartend.length === 0) {\n laeuft = false;\n return;\n }\n if (document.visibilityState === \"hidden\") {\n document.addEventListener(\"visibilitychange\", naechste, { once: true });\n return;\n }\n const [text, ...rest] = wartend;\n wartend = rest;\n const ziel = ansageRegion();\n ziel.textContent = ziel.textContent === text ? `${text}\\u00a0` : text;\n window.setTimeout(naechste, abstandMs);\n}\n\n/** Sagt Text \u00FCber eine gemeinsame, versteckte Live-Region an: gedrosselt, und bei verstecktem Tab angehalten. */\nexport function announce(text: string): void {\n const inhalt = text.trim();\n if (!inhalt || typeof document === \"undefined\") {\n return;\n }\n wartend = [...wartend, inhalt].slice(-hoechstensWartend);\n if (laeuft) {\n return;\n }\n laeuft = true;\n ansageRegion();\n window.setTimeout(naechste, abstandMs);\n}\n", "import { useEffect, useLayoutEffect, useRef, useState, type CSSProperties, type ReactNode, type Ref } from \"react\";\nimport { cn } from \"./ui/cn\";\nimport { ChatSendContext, createChatSendScope } from \"./ChatSendContext\";\nimport { appearanceStyle, type ChatAppearance } from \"./options\";\n\n/**\n * Verlauf mit ueberlagerter Eingabe. Der Rahmen misst die Eingabe selbst und\n * gibt dem Verlauf den noetigen Fussraum, damit kein Host Innenmasse setzen muss.\n */\nexport function ChatPanel({\n children,\n composer,\n className,\n nodeRef,\n maxWidth,\n horizontalPadding,\n appearance,\n scrollOnSend = false,\n}: {\n children: ReactNode;\n /** Die Eingabe; sie liegt ueber dem Verlauf, nicht darunter. */\n composer?: ReactNode;\n className?: string;\n nodeRef?: Ref<HTMLDivElement>;\n maxWidth?: CSSProperties[\"maxWidth\"];\n horizontalPadding?: CSSProperties[\"paddingInline\"];\n appearance?: ChatAppearance;\n scrollOnSend?: boolean;\n}) {\n const wurzel = useRef<HTMLDivElement>(null);\n const eingabe = useRef<HTMLDivElement>(null);\n const hasComposer = composer !== undefined;\n const scrollOnSendRef = useRef(scrollOnSend);\n const [sendScope] = useState(() => createChatSendScope(scrollOnSendRef));\n useLayoutEffect(() => { scrollOnSendRef.current = scrollOnSend; }, [scrollOnSend]);\n\n useEffect(() => {\n const element = eingabe.current;\n const rahmen = wurzel.current;\n if (!element || !rahmen) {\n return;\n }\n const messen = () => rahmen.style.setProperty(\"--qsl-composer-height\", `${element.offsetHeight}px`);\n const beobachter = new ResizeObserver(messen);\n beobachter.observe(element);\n messen();\n return () => {\n beobachter.disconnect();\n rahmen.style.removeProperty(\"--qsl-composer-height\");\n };\n }, [hasComposer]);\n\n return (\n <ChatSendContext.Provider value={sendScope}>\n <div\n className={cn(\"qsl:relative qsl:flex qsl:min-h-0 qsl:min-w-0 qsl:flex-col qsl:overflow-hidden\", className)}\n data-chat=\"panel\"\n data-quassel=\"\"\n style={{\n ...appearanceStyle(appearance),\n \"--qsl-chat-content-max-width\": typeof maxWidth === \"number\" ? `${maxWidth}px` : maxWidth,\n \"--qsl-chat-horizontal-padding\": typeof horizontalPadding === \"number\" ? `${horizontalPadding}px` : horizontalPadding,\n } as CSSProperties}\n ref={(element) => {\n wurzel.current = element;\n if (typeof nodeRef === \"function\") {\n nodeRef(element);\n } else if (nodeRef) {\n nodeRef.current = element;\n }\n }}\n >\n {children}\n {hasComposer && (\n <div className=\"qsl:absolute qsl:inset-x-0 qsl:bottom-0 qsl:z-[5] qsl:px-[var(--qsl-chat-horizontal-padding,24px)] qsl:pb-3.5 qsl:*:mx-auto qsl:*:max-w-[var(--qsl-chat-content-max-width,none)]\" data-chat=\"composer\" ref={eingabe}>\n {composer}\n </div>\n )}\n </div>\n </ChatSendContext.Provider>\n );\n}\n", "import { PaperclipIcon, SendIcon, XIcon } from \"lucide-react\";\nimport { cn } from \"./ui/cn\";\nimport { useFileInput } from \"./ui/useFileInput\";\nimport { useQuasselComponents } from \"./QuasselProvider\";\nimport { KeyboardEvent, ReactNode, Ref, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ChatTexts, defaultTexts, fillText } from \"./texts\";\nimport type { ChatAttachmentInput } from \"./events\";\nimport { attachmentCapabilityError, attachmentMediaType, encodeAttachment, formatAttachmentSize, MAX_CHAT_ATTACHMENTS, maxAttachmentSizeLabel, validateAttachmentSelection } from \"./attachments\";\nimport { ChatSendContext } from \"./ChatSendContext\";\nimport type { SendShortcut } from \"./options\";\n\ntype DraftAttachment = { id: number; file: File } & (\n | { status: \"reading\" }\n | { status: \"ready\"; input: ChatAttachmentInput }\n | { status: \"error\"; error: string }\n);\n\n// Unter dieser Panel-Breite klappen mitlaufende Beschriftungen zu ihren Symbolen.\nconst COMPACT_WIDTH_PX = 480;\n\nconst errorClasses = \"qsl:px-3 qsl:py-2 qsl:text-sm qsl:text-destructive\";\nconst attachmentItemClasses = \"qsl:relative qsl:flex qsl:w-[190px] qsl:max-w-full qsl:min-w-0 qsl:flex-col qsl:overflow-hidden qsl:rounded-lg qsl:border qsl:border-border qsl:text-sm\";\nconst attachmentMediaClasses = \"qsl:block qsl:h-[112px] qsl:w-full qsl:bg-secondary qsl:object-contain\";\n\n/** Ein Toolbar-Knopf, deklarativ: Symbol, Text oder beides - plus Klick-Handler. */\nexport interface ToolbarAction {\n icon?: ReactNode;\n label?: string;\n title?: string;\n disabled?: boolean;\n active?: boolean;\n onClick: () => void;\n}\n\n/** Hosts steuern den Entwurf von aussen, z.B. um eine Vorlage zum Bearbeiten einzusetzen. */\nexport interface ChatInputHandle {\n /** Ersetzt den Entwurf, fokussiert die Eingabe und stellt die Schreibmarke ans Ende. */\n insert: (text: string) => void;\n focus: () => void;\n reset: () => void;\n submit: (onSubmit?: (text: string, attachments?: ChatAttachmentInput[]) => void | Promise<void>, options?: { allowEmpty?: boolean }) => Promise<void>;\n}\n\n/**\n * Die Eingabe-Karte: rahmenlose Textarea oben, Toolbar unter einer Haarlinie. Eigene\n * Kn\u00F6pfe kommen deklarativ \u00FCber `actions` oder frei \u00FCber die Slots links/rechts; bei\n * laufender Arbeit bleibt der Stop-Knopf sichtbar, und Tippen zeigt daneben den Senden-Knopf,\n * der zum Dazwischenfunken wird. `rows` bestimmt die Starth\u00F6he; mit `maxRows` w\u00E4chst die Textarea\n * mit dem Inhalt bis zu dieser Zeilenzahl und scrollt danach.\n */\nexport function ChatInputToolbar({\n onSend,\n onStop,\n running = false,\n disabled = false,\n sendDisabled = false,\n layout = \"card\",\n detailsContainer,\n onErrorChange,\n inputAriaControls,\n rows = 3,\n maxRows,\n actions,\n toolbarLeft,\n toolbarRight,\n texts,\n handleRef,\n attachments: attachmentsEnabled = true,\n attachmentCapabilities,\n attachmentCapabilitiesError,\n onAttachmentsChange,\n initialValue = \"\",\n onDraftChange,\n sendShortcut = \"enter\",\n autoFocus = false,\n onAutoFocusSettled,\n}: {\n onSend: (text: string, attachments?: ChatAttachmentInput[]) => void | Promise<void>;\n onStop?: () => void;\n running?: boolean;\n disabled?: boolean;\n sendDisabled?: boolean;\n layout?: \"card\" | \"toolbar\" | \"inline\";\n detailsContainer?: HTMLElement | null;\n onErrorChange?: (error: string | undefined) => void;\n inputAriaControls?: string;\n rows?: number;\n maxRows?: number;\n actions?: ToolbarAction[];\n toolbarLeft?: ReactNode;\n toolbarRight?: ReactNode;\n texts?: Partial<ChatTexts>;\n handleRef?: Ref<ChatInputHandle>;\n /** false = kein Anh\u00E4ngen: weder Knopf noch Ablegen oder Einf\u00FCgen von Dateien. */\n attachments?: boolean;\n attachmentCapabilities?: { input: readonly string[]; model: string };\n attachmentCapabilitiesError?: string;\n onAttachmentsChange?: (hasAttachments: boolean) => void;\n initialValue?: string;\n onDraftChange?: (text: string) => void;\n sendShortcut?: SendShortcut;\n autoFocus?: boolean;\n onAutoFocusSettled?: () => void;\n}) {\n const sendScope = useContext(ChatSendContext);\n const alleTexte = { ...defaultTexts, ...texts };\n const { Button, StopButton, Toggle } = useQuasselComponents();\n const [draft, setDraft] = useState(initialValue);\n const [sending, setSending] = useState(false);\n const [sendError, setSendError] = useState<string>();\n const [failedSubmissions, setFailedSubmissions] = useState<{ id: number; draft: string; attachments: DraftAttachment[] }[]>([]);\n const nextFailedId = useRef(0);\n const pendingSend = useRef(false);\n const generation = useRef(0);\n useLayoutEffect(() => () => { generation.current += 1; }, []);\n const draftRevision = useRef(0);\n const [attachments, setAttachments] = useState<DraftAttachment[]>([]);\n const attachmentsRef = useRef<DraftAttachment[]>([]);\n const nextAttachmentId = useRef(0);\n const [attachmentError, setAttachmentError] = useState<string>();\n const updateAttachments = (update: (current: DraftAttachment[]) => DraftAttachment[]) => {\n attachmentsRef.current = update(attachmentsRef.current);\n setAttachments(attachmentsRef.current);\n };\n const addFiles = (files: File[]) => {\n if (!files.length) return;\n if (disabled || pendingSend.current) {\n setAttachmentError(alleTexte.attachmentsWhileBusy);\n return;\n }\n try {\n validateAttachmentSelection(attachmentsRef.current.map((entry) => entry.file), files, alleTexte);\n } catch (error) {\n setAttachmentError(error instanceof Error ? error.message : String(error));\n return;\n }\n setAttachmentError(undefined);\n const entries: DraftAttachment[] = files.map((file) => ({ id: ++nextAttachmentId.current, file, status: \"reading\" }));\n updateAttachments((current) => [...current, ...entries]);\n for (const entry of entries) {\n void encodeAttachment(entry.file).then(\n (input) => updateAttachments((current) => current.map((item) => item.id === entry.id ? { ...entry, status: \"ready\", input } : item)),\n () => updateAttachments((current) => current.map((item) => item.id === entry.id ? {\n ...entry, status: \"error\", error: alleTexte.attachmentReadFailed,\n } : item)),\n );\n }\n };\n const rootRef = useRef<HTMLDivElement>(null);\n const eingabeRef = useRef<HTMLTextAreaElement>(null);\n const autoFocusSettled = useRef(false);\n useEffect(() => {\n if (!autoFocus || autoFocusSettled.current) return;\n const input = eingabeRef.current;\n if (!input) return;\n let frame = 0;\n const settle = () => {\n if (autoFocusSettled.current) return;\n autoFocusSettled.current = true;\n window.cancelAnimationFrame(frame);\n onAutoFocusSettled?.();\n };\n const onFocus = (event: FocusEvent) => { if (event.target !== input) settle(); };\n const focusWhenVisible = () => {\n if (autoFocusSettled.current) return;\n const dialog = [...document.querySelectorAll<HTMLElement>('[role=\"dialog\"], dialog[open]')]\n .find((element) => element.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true }) && !element.contains(input));\n if (dialog) {\n settle();\n return;\n }\n const rect = input.getBoundingClientRect();\n const visible = input.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true }) && rect.width > 0 && rect.height > 0 && !input.closest('[inert], [hidden], [aria-hidden=\"true\"]')\n && document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2) === input;\n if (visible && !input.disabled && !input.readOnly && document.visibilityState === \"visible\") {\n input.focus({ preventScroll: true });\n if (document.activeElement === input) {\n settle();\n return;\n }\n }\n frame = window.requestAnimationFrame(focusWhenVisible);\n };\n window.addEventListener(\"pointerdown\", settle, true);\n window.addEventListener(\"keydown\", settle, true);\n window.addEventListener(\"focusin\", onFocus);\n window.addEventListener(\"blur\", settle);\n if (!disabled) frame = window.requestAnimationFrame(focusWhenVisible);\n return () => {\n window.cancelAnimationFrame(frame);\n window.removeEventListener(\"pointerdown\", settle, true);\n window.removeEventListener(\"keydown\", settle, true);\n window.removeEventListener(\"focusin\", onFocus);\n window.removeEventListener(\"blur\", settle);\n };\n }, [autoFocus, disabled, onAutoFocusSettled]);\n const [compact, setCompact] = useState(false);\n const pendingFocus = useRef(false);\n const fileInput = useFileInput({\n disabled: disabled || sending,\n onFiles: addFiles,\n onPasteText: (text) => {\n const input = eingabeRef.current;\n if (!input || disabled || pendingSend.current) return;\n const start = input.selectionStart;\n const end = input.selectionEnd;\n draftRevision.current += 1;\n setDraft((current) => current.slice(0, start) + text + current.slice(end));\n pendingFocus.current = true;\n },\n });\n const toolbar = layout === \"toolbar\";\n const inline = layout === \"inline\";\n const inputRows = inline || toolbar ? 1 : rows;\n const inputMaxRows = inline || toolbar ? 1 : maxRows;\n // Die Toolbar-Fassung pulsiert waehrend der Arbeit; der Host gibt nur den Radius vor.\n const rootClasses = cn(\n \"qsl:flex qsl:shrink-0 qsl:flex-col qsl:overflow-hidden qsl:rounded-[var(--qsl-input-card-radius,var(--qsl-radius-xl))] qsl:border qsl:border-border-strong qsl:bg-background qsl:shadow-bar qsl:transition-colors qsl:focus-within:border-primary\",\n \"qsl:in-data-[tone=material]:rounded-xl qsl:in-data-[tone=material]:border-glass-edge/50 qsl:in-data-[tone=material]:bg-background\",\n toolbar && \"qsl:h-full qsl:min-w-0 qsl:flex-row qsl:items-center qsl:rounded-lg qsl:data-[working=true]:animate-working-pulse qsl:data-[working=true]:border-primary qsl:motion-reduce:data-[working=true]:animate-none\",\n fileInput.dragging && \"qsl:outline-2 qsl:outline-offset-[3px] qsl:outline-dashed qsl:outline-primary\",\n );\n const textareaClasses = cn(\n \"qsl:resize-none qsl:border-0 qsl:bg-transparent qsl:text-[length:var(--qsl-chat-font-size,13px)] qsl:leading-[var(--qsl-chat-line-height,1.5)] qsl:text-foreground qsl:placeholder:text-muted-foreground qsl:focus:outline-none\",\n inline ? \"qsl:min-w-0 qsl:flex-1 qsl:px-2.5 qsl:py-2\" : toolbar ? \"qsl:w-full qsl:min-w-0 qsl:flex-auto qsl:px-2 qsl:py-[3px] qsl:leading-[1.3]\" : \"qsl:px-3 qsl:pt-3 qsl:pb-2\",\n );\n const toolbarRowClasses = cn(\n \"qsl:flex qsl:items-center qsl:gap-2 qsl:border-t qsl:border-border-soft qsl:px-2 qsl:py-1.5 qsl:in-data-[tone=overseer-details]:flex-nowrap\",\n inline && \"qsl:flex-none qsl:gap-1 qsl:border-t-0 qsl:p-1\",\n toolbar && \"qsl:flex-wrap qsl:border-t-0\",\n );\n const toolbarSideClasses = \"qsl:flex qsl:min-w-0 qsl:items-center qsl:gap-2 qsl:in-data-[tone=overseer-details]:flex-nowrap\";\n const changeDraft = useCallback((text: string) => {\n draftRevision.current += 1;\n setDraft(text);\n }, []);\n\n useImperativeHandle(handleRef, () => ({\n insert: (text: string) => {\n pendingFocus.current = true;\n changeDraft(text);\n const element = eingabeRef.current;\n element?.focus();\n if (element?.value === text) element.setSelectionRange(text.length, text.length);\n },\n focus: () => eingabeRef.current?.focus(),\n submit: (onSubmit, options) => send(onSubmit, options?.allowEmpty),\n reset: () => {\n generation.current += 1;\n pendingSend.current = false;\n pendingFocus.current = false;\n changeDraft(\"\");\n updateAttachments(() => []);\n setSendError(undefined);\n setFailedSubmissions([]);\n setAttachmentError(undefined);\n setSending(false);\n fileInput.clearDragging();\n },\n }));\n\n useEffect(() => { onDraftChange?.(draft); }, [draft, onDraftChange]);\n\n useEffect(() => {\n if (!pendingFocus.current) {\n return;\n }\n pendingFocus.current = false;\n const element = eingabeRef.current;\n if (element) {\n element.focus();\n element.setSelectionRange(element.value.length, element.value.length);\n }\n }, [draft, sending]);\n\n // Auto-Wachstum: Hoehe folgt dem Inhalt zwischen rows und maxRows, danach scrollt die Textarea.\n const applyAutoGrow = useCallback(() => {\n const element = eingabeRef.current;\n if (!element || inputMaxRows === undefined) {\n return;\n }\n const stil = getComputedStyle(element);\n const zeilenhoehe = Number.parseFloat(stil.lineHeight) || Number.parseFloat(stil.fontSize) * 1.4;\n const polster = Number.parseFloat(stil.paddingTop) + Number.parseFloat(stil.paddingBottom);\n const maximum = zeilenhoehe * Math.max(inputMaxRows, inputRows) + polster;\n element.style.height = \"auto\";\n const inhalt = element.scrollHeight;\n element.style.height = `${Math.min(inhalt, maximum)}px`;\n element.style.overflowY = inhalt > maximum ? \"auto\" : \"hidden\";\n }, [inputMaxRows, inputRows]);\n\n useEffect(() => {\n applyAutoGrow();\n }, [draft, applyAutoGrow]);\n\n // Hosts may lay the composer out a frame later; re-measure once the width settles.\n useEffect(() => {\n const element = eingabeRef.current;\n if (!element || inputMaxRows === undefined) {\n return;\n }\n let lastWidth = element.clientWidth;\n const observer = new ResizeObserver(() => {\n if (element.clientWidth !== lastWidth) {\n lastWidth = element.clientWidth;\n applyAutoGrow();\n }\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [inputMaxRows, applyAutoGrow]);\n\n // Panel-Breite statt Viewport-Breite: die Chat-Spalte kann im Host beliebig schmal sein.\n useEffect(() => {\n const element = rootRef.current;\n if (!element) {\n return;\n }\n const update = () => setCompact(element.clientWidth < COMPACT_WIDTH_PX);\n update();\n const beobachter = new ResizeObserver(update);\n beobachter.observe(element);\n return () => beobachter.disconnect();\n }, []);\n\n const hasAttachments = attachments.length > 0;\n useEffect(() => { onAttachmentsChange?.(hasAttachments); }, [hasAttachments, onAttachmentsChange]);\n const capabilityError = hasAttachments && attachmentCapabilitiesError ? attachmentCapabilitiesError : attachmentCapabilities ? attachmentCapabilityError(attachments.map((entry) => ({\n name: entry.file.name, mediaType: attachmentMediaType(entry.file),\n })), attachmentCapabilities, alleTexte) : undefined;\n const hasContent = draft.trim().length > 0 || attachments.length > 0;\n const preparing = attachments.some((entry) => entry.status === \"reading\");\n const attachmentBlocked = attachments.some((entry) => entry.status !== \"ready\");\n const currentError = sendError ?? attachmentError ?? capabilityError ?? attachments.find((entry) => entry.status === \"error\")?.error;\n useEffect(() => { onErrorChange?.(currentError); }, [currentError, onErrorChange]);\n\n const send = async (onSubmit = onSend, allowEmpty = false) => {\n const text = draft.trim();\n const snapshot = attachmentsRef.current;\n if ((!allowEmpty && !text && !snapshot.length) || disabled || sendDisabled || pendingSend.current || capabilityError || snapshot.some((entry) => entry.status !== \"ready\")) {\n return;\n }\n pendingSend.current = true;\n const sentGeneration = generation.current;\n const sentRevision = draftRevision.current;\n const sentDraft = draft;\n const focusOrigin = document.activeElement;\n const startedFocused = focusOrigin === eingabeRef.current || rootRef.current?.contains(focusOrigin);\n let leftComposer = false;\n const observeFocus = (event: Event) => {\n const target = event.target;\n if (target instanceof Node && !rootRef.current?.contains(target) && !detailsContainer?.contains(target)) leftComposer = true;\n };\n document.addEventListener(\"focusin\", observeFocus);\n document.addEventListener(\"pointerdown\", observeFocus);\n setSending(true);\n setSendError(undefined);\n setDraft(\"\");\n updateAttachments(() => []);\n try {\n const inputs = snapshot.flatMap((entry) => entry.status === \"ready\" ? [entry.input] : []);\n await onSubmit(text, inputs.length ? inputs : undefined);\n if (generation.current === sentGeneration && (text || inputs.length)) sendScope?.notify();\n } catch (error) {\n if (generation.current !== sentGeneration) return;\n if (draftRevision.current === sentRevision) {\n setDraft(sentDraft);\n updateAttachments((current) => [...snapshot, ...current]);\n } else if (sentDraft || snapshot.length) {\n const failed = { id: ++nextFailedId.current, draft: sentDraft, attachments: snapshot };\n setFailedSubmissions((current) => [...current, failed]);\n }\n setSendError(error instanceof Error ? error.message : String(error));\n } finally {\n document.removeEventListener(\"focusin\", observeFocus);\n document.removeEventListener(\"pointerdown\", observeFocus);\n if (generation.current === sentGeneration) {\n pendingSend.current = false;\n pendingFocus.current = !!startedFocused && !leftComposer && document.hasFocus()\n && (!toolbar || focusOrigin !== eingabeRef.current) && (document.activeElement === focusOrigin\n || (!toolbar && document.activeElement === document.body));\n setSending(false);\n }\n }\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing && event.nativeEvent.keyCode !== 229\n && (sendShortcut === \"enter\" || event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n if (!event.repeat) void send();\n }\n };\n\n const attachmentPreviews = (\n attachments.length > 0 && (\n <ul className=\"qsl:flex qsl:max-h-[240px] qsl:flex-wrap qsl:gap-2 qsl:overflow-y-auto qsl:px-3 qsl:pt-2.5 qsl:in-data-[tone=overseer-details]:max-h-40 qsl:in-data-[tone=overseer-details]:overflow-y-auto\" aria-label={alleTexte.attachments}>\n {attachments.map((entry) => (\n <li className={attachmentItemClasses} key={entry.id}>\n {entry.status === \"ready\" && entry.input.mediaType.startsWith(\"image/\") && (\n <img className={attachmentMediaClasses} src={`data:${entry.input.mediaType};base64,${entry.input.data}`} alt={entry.file.name} />\n )}\n {entry.status === \"ready\" && entry.input.mediaType.startsWith(\"video/\") && (\n <video className={attachmentMediaClasses} controls preload=\"metadata\" aria-label={entry.file.name} src={`data:${entry.input.mediaType};base64,${entry.input.data}`} />\n )}\n <div className=\"qsl:flex qsl:flex-col qsl:gap-1 qsl:p-2 qsl:pr-8 qsl:[overflow-wrap:anywhere]\">\n <span className=\"qsl:font-medium\" title={entry.file.name}>{entry.file.name}</span>\n <small>{formatAttachmentSize(entry.file.size)}</small>\n {entry.status === \"reading\" && <small role=\"status\">{alleTexte.attachmentPreparing}</small>}\n {entry.status === \"error\" && <small role=\"alert\">{entry.error}</small>}\n </div>\n <Button\n aria-label={fillText(alleTexte.removeAttachment, { name: entry.file.name })}\n className=\"qsl:absolute qsl:top-1 qsl:right-1\"\n disabled={disabled || sending}\n onClick={() => {\n updateAttachments((current) => current.filter((item) => item.id !== entry.id));\n setAttachmentError(undefined);\n eingabeRef.current?.focus();\n }}\n size=\"icon-sm\"\n title={fillText(alleTexte.removeAttachment, { name: entry.file.name })}\n variant=\"outline\"\n ><XIcon /></Button>\n </li>\n ))}\n </ul>\n )\n );\n const errors = <>\n {capabilityError && <p className={errorClasses} role=\"alert\">{capabilityError}</p>}\n {attachmentError && <p className={errorClasses} role=\"alert\">{attachmentError}</p>}\n {sendError && <p className={errorClasses} role=\"alert\">{sendError}</p>}\n {failedSubmissions.map((failed) => <div className={cn(errorClasses, \"qsl:flex qsl:flex-wrap qsl:items-center qsl:gap-2\")} key={failed.id} role=\"status\">\n <span>{alleTexte.notSent} {failed.draft.slice(0, 100)}{failed.draft.length > 100 ? \" ...\" : \"\"}{failed.attachments.length > 0 ? ` ${fillText(alleTexte.notSentAttachments, { count: failed.attachments.length })}` : \"\"} </span>\n <Button disabled={disabled || sending} size=\"sm\" variant=\"outline\" onClick={() => {\n try {\n validateAttachmentSelection(attachmentsRef.current.map((entry) => entry.file), failed.attachments.map((entry) => entry.file), alleTexte);\n } catch (error) {\n setAttachmentError(error instanceof Error ? error.message : String(error));\n return;\n }\n draftRevision.current += 1;\n setDraft((current) => [current, failed.draft].filter(Boolean).join(\"\\n\\n\"));\n updateAttachments((current) => [...current, ...failed.attachments]);\n setFailedSubmissions((current) => current.filter((entry) => entry.id !== failed.id));\n setAttachmentError(undefined);\n pendingFocus.current = true;\n }}>{alleTexte.insertUnsent}</Button>\n </div>)}\n </>;\n const sendButtons = <>\n {running && onStop && !hasContent && <StopButton className=\"qsl:flex-none\" label={alleTexte.stop} onClick={onStop} size=\"icon-sm\" />}\n {(!running || !onStop || hasContent) && (\n <Button\n aria-label={alleTexte.send}\n className=\"qsl:flex-none\"\n disabled={disabled || sendDisabled || sending || attachmentBlocked || !!capabilityError || !hasContent}\n onClick={() => { void send(); }}\n size=\"icon-sm\"\n title={running ? alleTexte.sendIntoRun : alleTexte.send}\n >\n <SendIcon size={14} />\n </Button>\n )}\n </>;\n const detailToolbar = (\n <div className={toolbarRowClasses} data-input=\"controls\">\n <div className={cn(toolbarSideClasses, \"qsl:in-data-[tone=overseer-details]:flex-none\", inline || toolbar ? \"qsl:flex-none\" : \"qsl:flex-auto\")}>\n {attachmentsEnabled && <Button\n aria-label={alleTexte.attachFiles}\n disabled={disabled || sending}\n onClick={() => fileInput.inputRef.current?.click()}\n size=\"icon-sm\"\n title={fillText(alleTexte.attachFilesHint, { count: MAX_CHAT_ATTACHMENTS, size: maxAttachmentSizeLabel })}\n variant=\"ghost\"\n >\n <PaperclipIcon />\n </Button>}\n {preparing && <span className={cn(\"qsl:text-xs qsl:text-muted-foreground\", inline && \"qsl:sr-only\")} role=\"status\">{alleTexte.attachmentsPreparing}</span>}\n {actions?.map((action, index) => action.active === undefined ? (\n <Button disabled={action.disabled} key={index} onClick={action.onClick} size=\"sm\" title={action.title ?? action.label} variant=\"ghost\">\n {action.icon}\n {action.label && <span className={action.icon ? \"qsl:in-data-[compact=true]:hidden\" : undefined}>{action.label}</span>}\n </Button>\n ) : (\n <Toggle disabled={action.disabled} key={index} onPressedChange={() => action.onClick()} pressed={action.active} size=\"sm\" title={action.title ?? action.label}>\n {action.icon}\n {action.label && <span className={action.icon ? \"qsl:in-data-[compact=true]:hidden\" : undefined}>{action.label}</span>}\n </Toggle>\n ))}\n {toolbarLeft}\n </div>\n <div className={cn(toolbarSideClasses, \"qsl:in-data-[tone=overseer-details]:flex-1\", inline || toolbar ? \"qsl:flex-none\" : \"qsl:flex-[0_1_auto]\")}>\n {toolbarRight}\n {!toolbar && sendButtons}\n </div>\n </div>\n );\n const details = <div className=\"qsl:min-w-0\" data-compact={compact} data-quassel=\"\">\n {attachmentPreviews}\n {errors}\n {detailToolbar}\n </div>;\n\n const input = (\n <textarea\n aria-controls={inputAriaControls}\n className={textareaClasses}\n aria-label={alleTexte.placeholder}\n disabled={!toolbar && disabled}\n readOnly={toolbar && disabled}\n onChange={(event) => changeDraft(event.target.value)}\n onKeyDown={onKeyDown}\n placeholder={running ? alleTexte.steeringPlaceholder : alleTexte.placeholder}\n ref={eingabeRef}\n rows={inputRows}\n value={draft}\n />\n );\n\n return (\n <div\n className={rootClasses}\n data-compact={compact}\n data-layout={layout}\n data-quassel=\"\"\n data-working={running || sending}\n ref={rootRef}\n {...(attachmentsEnabled ? fileInput.dropProps : {})}\n >\n {attachmentsEnabled && <input\n aria-label={alleTexte.attachFiles}\n hidden\n multiple\n type=\"file\"\n {...fileInput.inputProps}\n />}\n {!toolbar && attachmentPreviews}\n {inline ? <>{errors}<div className=\"qsl:flex qsl:min-w-0 qsl:items-center\">{input}{detailToolbar}</div></> : input}\n {toolbar ? <>\n <div className=\"qsl:flex qsl:flex-none qsl:items-center qsl:gap-1 qsl:p-1\">{sendButtons}</div>\n {detailsContainer && createPortal(details, detailsContainer)}\n </> : !inline && <>{errors}{detailToolbar}</>}\n\n </div>\n );\n}\n", "import { useRef, useState, type ChangeEvent, type ClipboardEvent, type DragEvent } from \"react\";\n\nexport function useFileInput({ disabled, onFiles, onPasteText }: {\n disabled?: boolean;\n onFiles: (files: File[]) => void | Promise<void>;\n onPasteText?: (text: string) => void;\n}) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [dragging, setDragging] = useState(false);\n const receive = (files: File[]) => { if (files.length) void onFiles(files); };\n\n return {\n inputRef,\n dragging,\n clearDragging: () => setDragging(false),\n inputProps: {\n ref: inputRef,\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n const files = Array.from(event.currentTarget.files ?? []);\n event.currentTarget.value = \"\";\n receive(files);\n },\n },\n dropProps: {\n onDragOver: (event: DragEvent<HTMLElement>) => {\n if (!event.dataTransfer.types.includes(\"Files\")) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = disabled ? \"none\" : \"copy\";\n setDragging(!disabled);\n },\n onDragLeave: (event: DragEvent<HTMLElement>) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) setDragging(false);\n },\n onDrop: (event: DragEvent<HTMLElement>) => {\n if (!event.dataTransfer.types.includes(\"Files\")) return;\n event.preventDefault();\n setDragging(false);\n receive(Array.from(event.dataTransfer.files));\n },\n onPaste: (event: ClipboardEvent<HTMLElement>) => {\n const files = Array.from(event.clipboardData.files);\n if (!files.length) return;\n event.preventDefault();\n receive(files);\n const text = event.clipboardData.getData(\"text/plain\");\n if (text) onPasteText?.(text);\n },\n },\n };\n}\n", "import { SparklesIcon } from \"lucide-react\";\nimport { useQuasselComponents } from \"./QuasselProvider\";\nimport { DetailMode } from \"./types\";\nimport { ChatTexts, defaultTexts } from \"./texts\";\n\nexport const DETAIL_MODES: readonly DetailMode[] = [\"off\", \"current\", \"icons\", \"chips\", \"grouped\", \"compact\", \"full\"];\n\nconst TEXT_KEYS: Record<DetailMode, keyof ChatTexts> = {\n off: \"detailModeOff\",\n current: \"detailModeCurrent\",\n icons: \"detailModeIcons\",\n chips: \"detailModeChips\",\n grouped: \"detailModeGrouped\",\n compact: \"detailModeCompact\",\n full: \"detailModeFull\",\n};\n\nexport const detailModeLabel = (mode: DetailMode, texts?: Partial<ChatTexts>): string =>\n ({ ...defaultTexts, ...texts })[TEXT_KEYS[mode]];\n\n/**\n * Ein Knopf, der den Detailgrad der Denk- und Werkzeug-Schritte weiterschaltet. Die\n * Reihenfolge kommt aus `modes`, der aktuelle Wert steht als Beschriftung daneben.\n */\nexport function DetailModeSwitch({\n mode,\n onChange,\n modes = DETAIL_MODES,\n collapsible = true,\n texts,\n className,\n}: {\n mode: DetailMode;\n onChange: (mode: DetailMode) => void;\n /** Auswahl und Reihenfolge des Weiterschaltens; Default sind alle Modi. */\n modes?: readonly DetailMode[];\n /** false = die Beschriftung bleibt auch in einer schmalen Eingabe-Karte stehen. */\n collapsible?: boolean;\n texts?: Partial<ChatTexts>;\n className?: string;\n}) {\n const alleTexte = { ...defaultTexts, ...texts };\n const { Button } = useQuasselComponents();\n const aktuell = modes.indexOf(mode);\n const naechster = modes[(aktuell < 0 ? 0 : aktuell + 1) % modes.length];\n return (\n <Button\n aria-label={`${alleTexte.detailModeTitle}: ${detailModeLabel(mode, texts)}`}\n className={className}\n onClick={() => onChange(naechster)}\n size=\"sm\"\n title={`${alleTexte.detailModeTitle}: ${detailModeLabel(mode, texts)}`}\n variant=\"ghost\"\n >\n <SparklesIcon />\n <span className={collapsible ? \"qsl:in-data-[compact=true]:hidden\" : undefined}>{detailModeLabel(mode, texts)}</span>\n </Button>\n );\n}\n", "import { ClockIcon } from \"lucide-react\";\nimport { useQuasselComponents } from \"./QuasselProvider\";\nimport { type ChatTexts, defaultTexts } from \"./texts\";\n\nexport function TimestampSwitch({ showTimestamps, onChange, collapsible = true, texts, className }: {\n showTimestamps: boolean;\n onChange: (showTimestamps: boolean) => void;\n collapsible?: boolean;\n texts?: Partial<ChatTexts>;\n className?: string;\n}) {\n const labels = { ...defaultTexts, ...texts };\n const { Button } = useQuasselComponents();\n const title = showTimestamps ? labels.hideTimestamps : labels.showTimestamps;\n return (\n <Button aria-label={title} aria-pressed={showTimestamps} className={className}\n onClick={() => onChange(!showTimestamps)} size=\"sm\" title={title} variant=\"ghost\">\n <ClockIcon />\n <span className={collapsible ? \"qsl:in-data-[compact=true]:hidden\" : undefined}>{labels.timestamps}</span>\n </Button>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["useCallback", "useContext", "useEffect", "useMemo", "useRef", "useState", "createContext", "useContext", "useRef", "jsx", "jsx", "jsx", "jsx", "cva", "jsx", "cva", "jsx", "components", "jsx", "createContext", "useContext", "Button", "useRef", "useMemo", "jsx", "jsxs", "useMemo", "Button", "Popover", "PopoverContent", "CheckIcon", "jsx", "jsxs", "Button", "Card", "CheckIcon", "useEffect", "useState", "jsx", "jsxs", "useState", "useEffect", "CheckIcon", "SparklesIcon", "WrenchIcon", "CheckIcon", "CopyIcon", "useState", "jsx", "jsxs", "Button", "useState", "CopyIcon", "CheckIcon", "createContext", "Fragment", "jsx", "jsxs", "announce", "Button", "useRef", "useState", "useContext", "useEffect", "useCallback", "useMemo", "SparklesIcon", "WrenchIcon", "CheckIcon", "useEffect", "useLayoutEffect", "useRef", "useState", "jsx", "jsxs", "useRef", "useState", "useLayoutEffect", "useEffect", "XIcon", "useRef", "useState", "useCallback", "useContext", "useEffect", "useLayoutEffect", "useRef", "useState", "Fragment", "jsx", "jsxs", "useContext", "Button", "StopButton", "Toggle", "useState", "useRef", "useLayoutEffect", "input", "useEffect", "useCallback", "XIcon", "SparklesIcon", "jsx", "jsxs", "Button", "SparklesIcon", "jsx", "jsxs", "Button"]
7
7
  }