@ahmetilhn/hanui 5.3.2 → 5.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"chat.cjs","sources":["../src/helpers/class-name.helper.ts","../src/helpers/component.helper.ts","../src/helpers/label.helper.ts","../src/chat/ChatThread/index.tsx","../src/chat/ChatMessage/index.tsx","../src/chat/PromptInput/index.tsx","../src/chat/PromptSuggestions/index.tsx","../src/chat/Prose/index.tsx","../src/chat/CodeBlock/index.tsx","../src/chat/ReasoningBlock/index.tsx","../src/chat/ReasoningText/index.tsx","../src/chat/ToolCall/index.tsx","../src/chat/TerminalOutput/index.tsx","../src/chat/SourceList/index.tsx","../src/chat/Citation/index.tsx","../src/chat/MessageActions/index.tsx","../src/chat/AppBar/index.tsx","../src/chat/ActionList/index.tsx","../src/chat/SegmentBar/index.tsx","../src/chat/Legend/index.tsx","../src/chat/DescriptionList/index.tsx"],"sourcesContent":["import { ClassValue } from '@/types/common-element-props.type';\n\n/** Sınıf adı birleştirici. */\nexport const cx = (...values: ClassValue[]): string => {\n let result = '';\n\n for (const value of values) {\n if (!value) continue;\n result = result === '' ? value : `${result} ${value}`;\n }\n\n return result;\n};\n","/**\n * DevTools adı — modül düzeyinde YAN ETKİ bırakmadan.\n *\n * ⚠ `X.displayName = 'X'` KULLANILMAZ: modül düzeyindeki özellik ataması\n * bundler için yan etkidir ve hedefinin tüm bağımlılık zincirini ayakta tutar.\n * Ölçüldü: yalnızca `Badge` import eden uygulama 20,7 kB indiriyordu (paketin\n * tamamı 21,8 kB). Atama çağrıya dönüşünce `#__PURE__` işaretlenebiliyor →\n * `Badge` 2,71 kB. Nöbetçi `.size-limit.json`.\n *\n * @example\n * export default memo(named(Button, 'Button')) as typeof Button;\n */\nexport const named = <TComponent extends object>(\n component: TComponent,\n displayName: string,\n): TComponent => Object.assign(component, { displayName });\n","/** Metin çözümlemesi: prop → sağlayıcı config'i → geliştirme uyarısı. */\n\nimport type { Formatter } from '@/types/theme.type';\n\n/* Uyari ANAHTAR BASINA bir kez verilir. */\nconst warned = new Set<string>();\n\n/** Uyarı durumu testler arasında sızmamalı; her test kendi durumundan başlar. */\nexport const resetLabelWarnings = (): void => warned.clear();\n\n/**\n * Verilen metni çözer.\n * @param key Uyarıda gösterilecek yol (`Modal.closeLabel`).\n * @param values Öncelik sırasına göre adaylar: prop önce, config sonra.\n */\nexport const resolveLabel = (key: string, ...values: (string | undefined)[]): string => {\n for (const value of values) if (value !== undefined) return value;\n\n if (process.env.NODE_ENV !== 'production' && !warned.has(key)) {\n warned.add(key);\n console.error(\n `[hanui] Eksik metin: ${key}. Prop olarak geçin ya da ` +\n '<HanuiProvider labels={…}> içinde bir kez tanımlayın. ' +\n 'Metinsiz bırakılan öğe ekran okuyucuda adsız kalır.',\n );\n }\n\n return '';\n};\n\n/** Biçimlendirici çözümü — değere bağlı metinler için. */\nexport const resolveFormatter = <TArgs extends unknown[]>(\n key: string,\n formatter: Formatter<TArgs> | undefined,\n ...args: TArgs\n): string => {\n if (formatter) return formatter(...args);\n\n return resolveLabel(key);\n};\n","'use client';\n\nimport { type FC, memo, type ReactNode, useEffect, useRef } from 'react';\n\nimport { ArrowDown } from 'react-bootstrap-icons';\n\nimport { IconButton, useAnnounce, useHanui, useStickToBottom } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Mesajlar (`ChatMessage`). */\n children: ReactNode;\n /** Alt dok — yazma alanı (`PromptInput`) ve ipucu satırı. */\n dock?: ReactNode;\n /** Yanıt akıyor. Akış bittiğinde \"yanıt hazır\" duyurulur. */\n isStreaming?: boolean;\n /** Bölgenin adı; verilmezse `labels.chat.thread`. */\n label?: string;\n className?: string;\n testId?: string;\n};\n\n/**\n * Sohbet iskeleti — kaydırma alanı, ortalanmış sütun ve alt dok.\n *\n * - Sona yapışık kalır; kullanıcı yukarı kaydırınca bırakır ve \"en yeniye in\" düğmesi belirir.\n * - ⚠ Akan belirteçler OKUNMAZ (`aria-live` yok, `role=\"log\"` değil): her belirteci duyuran bir bölge\n * ekran okuyucuyu kullanılamaz kılıyordu. Yanıt BİTTİĞİNDE tek bir cümle duyurulur.\n * - Dok sayfanın dibine yapışır ve `safe-area` payını taşır; iOS'ta klavye açıkken görünür kalır.\n */\nconst ChatThread: FC<Props> = ({ children, dock, isStreaming, label, className, testId }) => {\n const { labels } = useHanui();\n const announce = useAnnounce();\n const scrollRef = useRef<HTMLDivElement>(null);\n const { isAtEnd, scrollToEnd } = useStickToBottom(scrollRef);\n\n /* Akis bitti: `true` → `false` gecisinde bir kez duyurulur, ilk render'da degil. */\n const wasStreaming = useRef(isStreaming);\n useEffect(() => {\n if (wasStreaming.current && !isStreaming)\n announce(resolveLabel('ChatThread.replyReady', labels?.chat?.replyReady));\n wasStreaming.current = isStreaming;\n }, [announce, isStreaming, labels?.chat?.replyReady]);\n\n return (\n <div className={cx(styles.thread, className)} data-testid={testId}>\n <div\n ref={scrollRef}\n className={styles.thread__scroll}\n role=\"region\"\n aria-label={resolveLabel('ChatThread.label', label, labels?.chat?.thread)}\n /* Kaydirma bolgesi klavyeyle ulasilabilir (2.1.1). */\n tabIndex={0}\n >\n <div className={styles.thread__column}>{children}</div>\n </div>\n\n <div className={styles.thread__dock}>\n {!isAtEnd && (\n <IconButton\n className={styles.thread__latest}\n icon={<ArrowDown aria-hidden />}\n label={resolveLabel('ChatThread.scrollToLatest', labels?.chat?.scrollToLatest)}\n variant=\"outline\"\n shape=\"round\"\n size=\"sm\"\n onClick={scrollToEnd}\n />\n )}\n {dock !== undefined && <div className={styles.thread__column}>{dock}</div>}\n </div>\n </div>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ChatThread, 'ChatThread'),\n) as typeof ChatThread;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\nexport type ChatMessageAuthor = 'user' | 'assistant';\n\ntype Props = {\n author: ChatMessageAuthor;\n children: ReactNode;\n /** Asistan mesajının avatarı (`Avatar tone=\"brand\"`); ilk satır hizasında durur. */\n avatar?: ReactNode;\n /** Mesajın altındaki eylem çubuğu (`MessageActions`). */\n actions?: ReactNode;\n /** Yanıt hâlâ akıyor — `aria-busy`: ekran okuyucu yarım metni okumaz. */\n isStreaming?: boolean;\n className?: string;\n testId?: string;\n};\n\n/**\n * Sohbet mesajı. Kullanıcı mesajı sağa yaslı bir balon (`surface-2`, satır sonları korunur);\n * asistan mesajı tam genişlik, avatar sol üstte.\n *\n * ⚠ Eylemler hover'da VE `:focus-within`de belirginleşir: klavye kullanıcısı da görmeli. Gizlenmez,\n * yalnızca sessizleşir — `opacity` değil renk (soluklaştırma yasak).\n */\nconst ChatMessage: FC<Props> = ({\n author,\n children,\n avatar,\n actions,\n isStreaming,\n className,\n testId,\n}) => (\n <article\n className={cx(styles.message, styles[`message--${author}`], className)}\n aria-busy={isStreaming || undefined}\n data-testid={testId}\n >\n {author === 'assistant' && avatar !== undefined && (\n <div className={styles.message__avatar}>{avatar}</div>\n )}\n\n <div className={styles.message__main}>\n <div className={styles.message__body}>{children}</div>\n {actions !== undefined && <div className={styles.message__actions}>{actions}</div>}\n </div>\n </article>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ChatMessage, 'ChatMessage'),\n) as typeof ChatMessage;\n","'use client';\n\nimport { forwardRef, type KeyboardEvent, memo, type ReactNode, useEffect } from 'react';\n\nimport { ArrowUp, StopFill } from 'react-bootstrap-icons';\n\nimport { hasOpenSurface, IconButton, Textarea, useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n value: string;\n onChange: (value: string) => void;\n /** Enter ya da gönder düğmesi. Boş (yalnızca boşluk) metinde çağrılmaz. */\n onSubmit: () => void;\n /** Akışı durdurur — `isBusy` iken düğme ve `Escape`. */\n onStop?: () => void;\n /** Yanıt akıyor: gönder yerine durdur düğmesi. */\n isBusy?: boolean;\n /** Alanın tamamı pasif — yazılamaz. */\n isDisabled?: boolean;\n /**\n * Yazmaya izin var ama GÖNDERİM kapalı (bağlantı yok, oturum hazırlanıyor). Kullanıcı mesajını\n * yazabilir; gönder düğmesi ve `Enter` bekler.\n */\n isSubmitDisabled?: boolean;\n /** Yer tutucu — çağrı yerine ÖZGÜ metin, `labels`a girmez. */\n placeholder: string;\n /** Alanın erişilebilir adı; verilmezse yer tutucu. */\n label?: string;\n /** Otomatik büyümenin tavanı (satır). */\n maxRows?: number;\n /** Alanın altındaki ipucu satırı (`Kbd` ile kısayollar). */\n hint?: ReactNode;\n /** Alanın solunda (ek dosya, model seçici). */\n start?: ReactNode;\n /** Gönder düğmesinin solunda. */\n end?: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/**\n * Sohbet yazma alanı — çerçevesiz `Textarea` + yuvarlak gönder / durdur düğmesi.\n *\n * Klavye: `Enter` gönderir · `Shift+Enter` yeni satır · `Escape` (akış sürerken) durdurur.\n * - ⚠ IME yazımı sırasında (`isComposing`, Türkçe dışı klavyeler) `Enter` GÖNDERMEZ: harf seçimini\n * onaylıyor, mesajı değil.\n * - ⚠ `Escape` açık bir yüzey (modal, menü, bildirim) varken DOKUNMAZ (`hasOpenSurface`): kullanıcı\n * yalnızca o yüzeyi kapatmak istiyordu, arkadaki akış da duruyordu.\n * - Gönder düğmesi ekranın TEK birincil eylemi: çam dolgu, koyu temada mint sınır.\n * - Odak göstergesini çerçeve çizer (`:focus-within`); alan çerçevesiz (`variant=\"bare\"`).\n * - `ref` metin alanına iletilir: gönderimden ya da bir öneri seçildikten sonra odağı geri vermek için.\n */\nconst PromptInput = /*#__PURE__*/ forwardRef<HTMLTextAreaElement, Props>(\n (\n {\n value,\n onChange,\n onSubmit,\n onStop,\n isBusy,\n isDisabled,\n isSubmitDisabled,\n placeholder,\n label,\n maxRows = 8,\n hint,\n start,\n end,\n className,\n testId,\n },\n ref,\n ) => {\n const { labels } = useHanui();\n const isEmpty = value.trim() === '';\n\n /* `Escape` sayfa duzeyinde: odak alanda olmasa da (bir arac kartindayken) akis durdurulabilmeli. */\n useEffect(() => {\n if (!isBusy || !onStop) return;\n\n const handleKeyDown = (event: globalThis.KeyboardEvent) => {\n if (event.key !== 'Escape' || event.defaultPrevented || hasOpenSurface()) return;\n onStop();\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isBusy, onStop]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== 'Enter' || event.shiftKey || event.nativeEvent.isComposing) return;\n\n event.preventDefault();\n if (!isEmpty && !isBusy && !isDisabled && !isSubmitDisabled) onSubmit();\n };\n\n return (\n <div className={cx(styles.prompt, className)} data-testid={testId}>\n <div className={cx(styles.prompt__box, isDisabled && styles['prompt__box--disabled'])}>\n {start !== undefined && <div className={styles.prompt__start}>{start}</div>}\n\n <Textarea\n ref={ref}\n className={styles.prompt__field}\n variant=\"bare\"\n rows={1}\n isAutoSize\n maxRows={maxRows}\n value={value}\n placeholder={placeholder}\n aria-label={label ?? placeholder}\n disabled={isDisabled}\n onChange={event => onChange(event.target.value)}\n onKeyDown={handleKeyDown}\n />\n\n {end !== undefined && <div className={styles.prompt__end}>{end}</div>}\n\n {isBusy ? (\n <IconButton\n icon={<StopFill aria-hidden />}\n label={resolveLabel('PromptInput.stop', labels?.chat?.stop)}\n variant=\"outline\"\n shape=\"round\"\n onClick={onStop}\n disabled={!onStop}\n />\n ) : (\n <IconButton\n icon={<ArrowUp aria-hidden />}\n label={resolveLabel('PromptInput.send', labels?.chat?.send)}\n variant=\"solid\"\n shape=\"round\"\n onClick={onSubmit}\n disabled={isEmpty || isDisabled || isSubmitDisabled}\n />\n )}\n </div>\n\n {hint !== undefined && <div className={styles.prompt__hint}>{hint}</div>}\n </div>\n );\n },\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(PromptInput, 'PromptInput'),\n) as typeof PromptInput;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\nexport type PromptSuggestion = {\n id: string;\n /** Gönderilecek istem ya da kısa adı. */\n label: string;\n /** İkinci satır — neyi sorduğu. */\n description?: string;\n};\n\ntype Props = {\n /** Grubun erişilebilir adı (\"Örnek istemler\"). */\n label: string;\n items: PromptSuggestion[];\n onPick: (item: PromptSuggestion) => void;\n className?: string;\n testId?: string;\n};\n\n/**\n * Hazır istem önerileri — boş sohbetin başlangıç kartları.\n *\n * ⚠ Bunlar EYLEM, seçim değil: `ChipGroup` (seçim) yerine düğme ızgarası. Basmak bir şey seçmez,\n * istemi gönderir ya da yazma alanına koyar.\n */\nconst PromptSuggestions: FC<Props> = ({ label, items, onPick, className, testId }) => (\n <div role=\"group\" aria-label={label} className={cx(styles.grid, className)} data-testid={testId}>\n {items.map(item => (\n <button key={item.id} type=\"button\" className={styles.card} onClick={() => onPick(item)}>\n <span className={styles.card__label}>{item.label}</span>\n {item.description && <span className={styles.card__description}>{item.description}</span>}\n </button>\n ))}\n </div>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(PromptSuggestions, 'PromptSuggestions'),\n) as typeof PromptSuggestions;\n","import { type FC, type HTMLAttributes, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = HTMLAttributes<HTMLDivElement> & {\n testId?: string;\n};\n\n/**\n * Uzun metin kabı — markdown çıktısının (başlık, paragraf, liste, alıntı, tablo, satır içi kod,\n * bağlantı, formül) tipografisi.\n *\n * ⚠ AYRIŞTIRICI İÇERMEZ: `react-markdown`, `remark`/`rehype` eklentileri ve KaTeX tüketicide kalır;\n * hanui yalnızca çıktının nasıl göründüğünü verir (`linkComponent` ile aynı desen). Bir UI paketinin\n * markdown ayrıştırıcısı taşıması, sohbet kullanmayan tüketicinin hiç kullanmadığı yüzlerce kB demek.\n */\nconst Prose: FC<Props> = ({ className, testId, ...rest }) => (\n <div className={cx(styles.prose, className)} data-testid={testId} {...rest} />\n);\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(Prose, 'Prose')) as typeof Prose;\n","'use client';\n\nimport { type FC, memo, useEffect, useRef, useState } from 'react';\n\nimport { CheckLg, ClipboardFill } from 'react-bootstrap-icons';\n\nimport { IconButton, useAnnounce, useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveFormatter, resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Ham kod — kopyalanan ve `html` yokken çizilen metin. */\n code: string;\n /** Dil adı; başlık şeridinde ve kopyalama düğmesinin adında. */\n language?: string;\n /**\n * ÖNCEDEN VURGULANMIŞ HTML (Shiki çıktısı). Verilmezse düz `<pre>` çizilir.\n * ⚠ GÜVENLİK ÇAĞIRANIN: bu dize olduğu gibi DOM'a yazılır. Yalnızca kendi vurgulayıcınızın\n * ürettiği çıktıyı verin; kullanıcı girdisini asla doğrudan geçirmeyin.\n */\n html?: string;\n /** Gövdenin tavanı (px); uzun kod kendi içinde kayar. */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\n/** Kopyalandı işaretinin ekranda kaldığı süre (ms). */\nconst COPIED_FOR = 1600;\n\n/**\n * Kod bloğu — başlık şeridi (dil + kopyala) ve kod gövdesi.\n *\n * ⚠ Vurgulayıcı İÇERMEZ (Shiki tüketicide). Shiki'nin çift tema çıktısı (`--shiki-light` /\n * `--shiki-dark` değişkenleri) burada temaya bağlanır; vurgusuz kod da aynı kutuda okunur.\n * Kod satırları SARILMAZ: dar ekranda kutu yatay kayar (kodun girintisi anlamdır).\n */\nconst CodeBlock: FC<Props> = ({ code, language, html, maxHeight, className, testId }) => {\n const { labels } = useHanui();\n const announce = useAnnounce();\n const [isCopied, setIsCopied] = useState(false);\n const timer = useRef<number | undefined>(undefined);\n\n useEffect(() => () => window.clearTimeout(timer.current), []);\n\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(code);\n } catch {\n return;\n }\n\n setIsCopied(true);\n announce(resolveLabel('CodeBlock.copied', labels?.chat?.codeCopied));\n window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => setIsCopied(false), COPIED_FOR);\n };\n\n const languageName = language ?? '';\n\n return (\n <figure className={cx(styles.block, className)} data-testid={testId}>\n <figcaption className={styles.block__header}>\n <span className={styles.block__language}>{languageName}</span>\n <IconButton\n icon={isCopied ? <CheckLg aria-hidden /> : <ClipboardFill aria-hidden />}\n label={resolveFormatter('CodeBlock.copy', labels?.chat?.codeCopy, languageName)}\n size=\"sm\"\n onClick={copy}\n />\n </figcaption>\n\n <div\n className={styles.block__body}\n style={maxHeight === undefined ? undefined : { maxBlockSize: maxHeight }}\n /* Kayan kod klavyeyle ulaşılabilir (2.1.1). */\n tabIndex={0}\n /* Bölge ancak bir ADI varken bölge; adsız bir \"bölge\" ekran okuyucuda gürültü. */\n role={languageName ? 'region' : undefined}\n aria-label={languageName || undefined}\n >\n {html ? (\n <div className={styles.block__highlighted} dangerouslySetInnerHTML={{ __html: html }} />\n ) : (\n <pre className={styles.block__pre}>\n <code>{code}</code>\n </pre>\n )}\n </div>\n </figure>\n );\n};\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(CodeBlock, 'CodeBlock')) as typeof CodeBlock;\n","'use client';\n\nimport { type FC, memo, type ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Disclosure, Spinner } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Başlık — çağrı yerine ÖZGÜ (\"Düşündü · 3 araç · 2,4 sn\"), `labels`a girmez. */\n summary: ReactNode;\n /** Tur sürüyor: blok AÇIK durur ve gösterge döner. */\n isRunning?: boolean;\n /** Süren işin göstergesi; verilmezse `Spinner`. Marka yükleyicisi buraya geçer. */\n indicator?: ReactNode;\n /** Kapalı bir turda açılış durumu. */\n isDefaultOpen?: boolean;\n /** Gövde: `ReasoningText`, ara metinler, `ToolCall`lar. */\n children: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/**\n * \"Model ne yaptı\" bloğu — akıl yürütme, ara metinler, araç çağrıları.\n *\n * Tur sürerken AÇIK durur, bitince kapanır. ⚠ Kullanıcı bloğu elle açtıysa ya da kapattıysa o\n * tercihe DOKUNULMAZ: tur bittiğinde okuduğu bloğun elinden çekilmesi en sık şikâyetti.\n */\nconst ReasoningBlock: FC<Props> = ({\n summary,\n isRunning = false,\n indicator,\n isDefaultOpen = false,\n children,\n className,\n testId,\n}) => {\n const [isOpen, setIsOpen] = useState(isRunning || isDefaultOpen);\n const isTouched = useRef(false);\n\n useEffect(() => {\n if (!isTouched.current) setIsOpen(isRunning || isDefaultOpen);\n }, [isRunning, isDefaultOpen]);\n\n return (\n <Disclosure\n variant=\"plain\"\n className={cx(styles.block, className)}\n summary={\n <span className={styles.block__summary}>\n {isRunning && (\n <span className={styles.block__indicator}>{indicator ?? <Spinner size=\"sm\" />}</span>\n )}\n {summary}\n </span>\n }\n isOpen={isOpen}\n onOpenChange={next => {\n isTouched.current = true;\n setIsOpen(next);\n }}\n testId={testId}\n >\n <div className={styles.block__body}>{children}</div>\n </Disclosure>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ReasoningBlock, 'ReasoningBlock'),\n) as typeof ReasoningBlock;\n","import { type FC, memo } from 'react';\n\nimport { ScrollArea } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n text: string;\n /** Kaydırılabildiğinde bölgenin okunan adı (\"Akıl yürütme\"). */\n label: string;\n /** Kutunun tavanı (px); akan metin bu yükseklikte sona yapışık kayar. */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\n/** Akıl yürütme metni — yüksekliği sınırlı, akarken sona yapışık (`ScrollArea isFollowingEnd`). */\nconst ReasoningText: FC<Props> = ({ text, label, maxHeight = 180, className, testId }) => (\n <ScrollArea\n className={cx(styles.text, className)}\n label={label}\n maxHeight={maxHeight}\n hasFade\n isFollowingEnd\n testId={testId}\n >\n <p className={styles.text__body}>{text}</p>\n </ScrollArea>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ReasoningText, 'ReasoningText'),\n) as typeof ReasoningText;\n","'use client';\n\nimport { type FC, memo, type ReactNode } from 'react';\n\nimport { Disclosure, StatusDot, useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\nexport type ToolCallStatus = 'running' | 'ok' | 'error' | 'aborted' | 'interrupted';\n\ntype Props = {\n /** Aracın ikonu. */\n icon?: ReactNode;\n /** Aracın adı — çağrı yerine özgü (\"bash\", \"araştır\"). */\n name: string;\n /** Tek satırlık özet (komut, sorgu); teknik fontta, taşan kesilir. */\n summary?: string;\n status: ToolCallStatus;\n /** Sağdaki ikincil bilgi (süre). */\n meta?: ReactNode;\n isDefaultOpen?: boolean;\n /**\n * Kontrollü açılış — `onOpenChange` ile. Örn. çalışırken açık, bitince (kullanıcı dokunmadıysa)\n * kapalı bir terminal kartı.\n */\n isOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n /** Gövde — `ToolCallSection`lar. */\n children?: ReactNode;\n className?: string;\n testId?: string;\n};\n\nconst DOT_TONE = {\n running: 'neutral',\n ok: 'success',\n error: 'danger',\n aborted: 'warning',\n interrupted: 'danger',\n} as const;\n\n/**\n * Araç çağrısı kartı — ikon, ad, özet, durum noktası ve süre; açılınca bölümleri.\n *\n * Durum hem noktayla hem OKUNAN metinle bildirilir (`labels.chat.toolStatus`): renk tek başına\n * anlam taşımaz. Çalışan çağrının noktası nabız atar ve NÖTRDÜR — süren iş marka yüzeyi değil.\n */\nconst ToolCall: FC<Props> = ({\n icon,\n name,\n summary,\n status,\n meta,\n isDefaultOpen,\n isOpen,\n onOpenChange,\n children,\n className,\n testId,\n}) => {\n const { labels } = useHanui();\n const statusText = resolveLabel(`ToolCall.status.${status}`, labels?.chat?.toolStatus?.[status]);\n\n const header = (\n <span className={styles.call__header}>\n {icon !== undefined && (\n <span\n className={cx(styles.call__icon, status === 'running' && styles['call__icon--running'])}\n aria-hidden\n >\n {icon}\n </span>\n )}\n <span className={styles.call__name}>{name}</span>\n {summary !== undefined && <span className={styles.call__summary}>{summary}</span>}\n <StatusDot tone={DOT_TONE[status]} label={statusText} isPulsing={status === 'running'} />\n </span>\n );\n\n if (children === undefined)\n return (\n <div className={cx(styles.call, styles['call--static'], className)} data-testid={testId}>\n {header}\n {meta !== undefined && <span className={styles.call__meta}>{meta}</span>}\n </div>\n );\n\n return (\n <Disclosure\n className={cx(styles.call, className)}\n summary={header}\n meta={meta}\n isDefaultOpen={isDefaultOpen}\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n testId={testId}\n >\n <div className={styles.call__body}>{children}</div>\n </Disclosure>\n );\n};\n\ntype SectionProps = {\n /** Bölümün başlığı (\"Girdi\", \"Çıktı\", \"Hata\") — overline. */\n label: string;\n children: ReactNode;\n className?: string;\n};\n\n/** Araç çağrısının bir bölümü — başlık + gövde. */\nexport const ToolCallSection: FC<SectionProps> = ({ label, children, className }) => (\n /*\n * Başlık bir HEADING değil: sohbet akışında başlık düzeyi tüketicinin sayfasına bağlı ve sabit bir\n * `h4` hiyerarşiyi bozuyordu. Bölüm de bir landmark değil (her araç kartında bir \"bölge\" gürültü).\n */\n <div className={cx(styles.section, className)}>\n <span className={styles.section__label}>{label}</span>\n <div className={styles.section__body}>{children}</div>\n </div>\n);\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(ToolCall, 'ToolCall')) as typeof ToolCall;\n","'use client';\n\nimport { type FC, memo, useRef } from 'react';\n\nimport { useHanui, useStickToBottom } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\nexport type TerminalChunk = {\n stream: 'stdout' | 'stderr';\n text: string;\n};\n\ntype Props = {\n /** Çalıştırılan komut — `$` istemiyle ilk satırda. */\n command?: string;\n chunks: TerminalChunk[];\n /** Kaydırılabildiğinde bölgenin okunan adı (\"Komut çıktısı\"). */\n label: string;\n /** Gövdenin tavanı (px). */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\n/**\n * Terminal çıktısı — MÜREKKEP yüzey, iki temada da koyu (`shell*`). Akarken sona yapışık kalır.\n *\n * ⚠ stderr satırı renkten başka bir işaret de taşır: görsel olarak gizli bir önek\n * (`labels.chat.stderr`, \"hata çıktısı\"). Kırmızı tek başına anlam taşıyamaz (1.4.1).\n */\nconst TerminalOutput: FC<Props> = ({\n command,\n chunks,\n label,\n maxHeight = 300,\n className,\n testId,\n}) => {\n const { labels } = useHanui();\n const ref = useRef<HTMLPreElement>(null);\n useStickToBottom(ref);\n\n const stderrLabel = resolveLabel('TerminalOutput.stderr', labels?.chat?.stderr);\n\n return (\n <pre\n ref={ref}\n className={cx(styles.terminal, className)}\n style={{ maxBlockSize: maxHeight }}\n /* Kayan çıktı klavyeyle ulaşılabilir (2.1.1). */\n tabIndex={0}\n role=\"region\"\n aria-label={label}\n data-testid={testId}\n >\n {command !== undefined && (\n <span className={styles.terminal__command}>\n <span className={styles.terminal__prompt} aria-hidden>\n ${' '}\n </span>\n {command}\n {'\\n'}\n </span>\n )}\n {chunks.map((chunk, index) =>\n chunk.stream === 'stderr' ? (\n <span key={index} className={styles.terminal__stderr}>\n <span className={styles.terminal__srOnly}>{`${stderrLabel}: `}</span>\n {chunk.text}\n </span>\n ) : (\n <span key={index}>{chunk.text}</span>\n ),\n )}\n </pre>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(TerminalOutput, 'TerminalOutput'),\n) as typeof TerminalOutput;\n","'use client';\n\nimport { type FC, memo } from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\nexport type SourceItem = {\n id: string;\n title: string;\n /** Dış kaynak — yeni sekmede açılır. */\n url?: string;\n /** Kaynağın alan adı (\"tr.wikipedia.org\") — başlığın altında. */\n domain?: string;\n /** Uygulama içinde açılan kaynak (yan panel, kip pencere). `url` ile birlikte verilmez. */\n onSelect?: () => void;\n};\n\ntype Props = {\n items: SourceItem[];\n /** Listenin adı; verilmezse `labels.chat.sources`. */\n label?: string;\n className?: string;\n testId?: string;\n};\n\n/**\n * Yanıtın kaynakları — numaralı liste; numara yanıttaki `Citation` ile eşleşir.\n * Dış bağlantı yeni sekmede açılır ve `noopener` taşır; uygulama içi kaynak bir düğmedir.\n */\nconst SourceList: FC<Props> = ({ items, label, className, testId }) => {\n const { labels } = useHanui();\n\n return (\n <ol\n className={cx(styles.list, className)}\n aria-label={resolveLabel('SourceList.label', label, labels?.chat?.sources)}\n data-testid={testId}\n >\n {items.map((item, index) => (\n <li key={item.id} className={styles.list__item}>\n <span className={styles.list__index} aria-hidden>\n {index + 1}\n </span>\n <span className={styles.list__text}>\n {item.url ? (\n <a\n className={styles.list__title}\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {item.title}\n </a>\n ) : item.onSelect ? (\n <button type=\"button\" className={styles.list__title} onClick={item.onSelect}>\n {item.title}\n </button>\n ) : (\n <span className={styles.list__plain}>{item.title}</span>\n )}\n {item.domain && <span className={styles.list__domain}>{item.domain}</span>}\n </span>\n </li>\n ))}\n </ol>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(SourceList, 'SourceList'),\n) as typeof SourceList;\n","'use client';\n\nimport { type FC, memo } from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveFormatter } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Kaynağın numarası — `SourceList`teki sırayla eşleşir (1'den başlar). */\n index: number;\n href?: string;\n onClick?: () => void;\n className?: string;\n};\n\n/**\n * Metin içi atıf — \"[3]\". Okunan adı `labels.chat.citation(3)` (\"Kaynak 3\"): görünen rakam tek\n * başına ekran okuyucuda \"üç\" diye, bağlamsız okunuyordu.\n */\nconst Citation: FC<Props> = ({ index, href, onClick, className }) => {\n const { labels } = useHanui();\n const name = resolveFormatter('Citation.label', labels?.chat?.citation, index);\n\n if (href)\n return (\n <a className={cx(styles.citation, className)} href={href} aria-label={name}>\n {index}\n </a>\n );\n\n if (onClick)\n return (\n <button\n type=\"button\"\n className={cx(styles.citation, className)}\n onClick={onClick}\n aria-label={name}\n >\n {index}\n </button>\n );\n\n /* Etkileşimsiz: rolü olmayan öğeye `aria-label` verilemez — ad gizli metin, rakam görsel. */\n return (\n <span className={cx(styles.citation, styles['citation--static'], className)}>\n <span aria-hidden>{index}</span>\n <span className={styles.citation__srOnly}>{name}</span>\n </span>\n );\n};\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(Citation, 'Citation')) as typeof Citation;\n","'use client';\n\nimport { type FC, type KeyboardEvent, memo, type ReactNode, useRef } from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** `IconButton` / `Button size={UISize.XSMALL}` öğeleri. */\n children: ReactNode;\n /** Araç çubuğunun sonunda duran okunan bilgi (süre, belirteç, maliyet). */\n meta?: ReactNode;\n /** Araç çubuğunun adı; verilmezse `labels.chat.messageActions`. */\n label?: string;\n className?: string;\n testId?: string;\n};\n\nconst FOCUSABLE = 'button:not(:disabled), a[href]';\n\n/**\n * Mesajın eylem çubuğu — kopyala, yeniden dene, ayrıntı.\n *\n * Klavye (`role=\"toolbar\"`, tek sekme durağı değil — her düğme sekme sırasında kalır):\n * `ArrowRight` / `ArrowLeft` sonraki / önceki eylem · `Home` / `End` ilk / son.\n * ⚠ Satır içi araç çubuğu: ok tuşu yalnızca odak ÇUBUKTAYKEN çalışır, sayfayı kaydırmaz.\n */\nconst MessageActions: FC<Props> = ({ children, meta, label, className, testId }) => {\n const { labels } = useHanui();\n const ref = useRef<HTMLDivElement>(null);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const items = [...(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])];\n const index = items.indexOf(document.activeElement as HTMLElement);\n if (index < 0 || items.length === 0) return;\n\n const isRtl = getComputedStyle(event.currentTarget).direction === 'rtl';\n const next = isRtl ? 'ArrowLeft' : 'ArrowRight';\n const previous = isRtl ? 'ArrowRight' : 'ArrowLeft';\n\n const target =\n event.key === next\n ? items[(index + 1) % items.length]\n : event.key === previous\n ? items[(index - 1 + items.length) % items.length]\n : event.key === 'Home'\n ? items[0]\n : event.key === 'End'\n ? items[items.length - 1]\n : null;\n\n if (!target) return;\n event.preventDefault();\n target.focus();\n };\n\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n aria-label={resolveLabel('MessageActions.label', label, labels?.chat?.messageActions)}\n className={cx(styles.actions, className)}\n onKeyDown={handleKeyDown}\n data-testid={testId}\n >\n {children}\n {meta !== undefined && <span className={styles.actions__meta}>{meta}</span>}\n </div>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(MessageActions, 'MessageActions'),\n) as typeof MessageActions;\n","'use client';\n\nimport { type FC, memo, type ReactNode, useEffect, useRef } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Sol baştaki marka (logo + ad). */\n brand: ReactNode;\n /** Markanın yanında, esneyen orta bölge (model, bağlantı durumu). */\n start?: ReactNode;\n /** Sağdaki eylem kümesi. */\n end?: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/** Belgeye yazılan değişken — yapışkan bileşenler (`DirectoryGroup`, kapaklı `DataTable`) bunu okur. */\nconst HEIGHT_VARIABLE = '--hanui-header-height';\n\n/**\n * Uygulamanın üst bandı — sayfaya yapışık, sayfanın devamı (bant sayfayı ÖRTMEZ: `nav-*`).\n *\n * Kendi yüksekliğini ölçüp `--hanui-header-height`e yazar. README bu `ResizeObserver` kodunu her\n * tüketiciye elle yazdırıyordu; sabit bir sayı yazan da vardı ve bant mobilde iki satıra düştüğünde\n * yapışkan başlıklar altında kalıyordu.\n */\nconst AppBar: FC<Props> = ({ brand, start, end, className, testId }) => {\n const ref = useRef<HTMLElement>(null);\n\n useEffect(() => {\n const node = ref.current;\n if (!node || typeof ResizeObserver === 'undefined') return;\n\n const root = document.documentElement;\n const observer = new ResizeObserver(([entry]) =>\n root.style.setProperty(\n HEIGHT_VARIABLE,\n `${Math.round(entry.borderBoxSize?.[0]?.blockSize ?? node.offsetHeight)}px`,\n ),\n );\n observer.observe(node);\n\n return () => {\n observer.disconnect();\n root.style.removeProperty(HEIGHT_VARIABLE);\n };\n }, []);\n\n return (\n <header ref={ref} className={cx(styles.bar, className)} data-testid={testId}>\n <div className={styles.bar__brand}>{brand}</div>\n {start !== undefined && <div className={styles.bar__start}>{start}</div>}\n {end !== undefined && <div className={styles.bar__end}>{end}</div>}\n </header>\n );\n};\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(AppBar, 'AppBar')) as typeof AppBar;\n","'use client';\n\nimport {\n Children,\n cloneElement,\n type FC,\n isValidElement,\n memo,\n type ReactElement,\n type ReactNode,\n useState,\n} from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\n/** Sanal pencerenin üstüne ve altına fazladan çizilen satır sayısı — hızlı kaydırmada boşluk görünmesin. */\nconst OVERSCAN = 6;\n\ntype ListProps = {\n /** Listenin erişilebilir adı (\"Bağlam haritası\"). */\n label: string;\n /** `ActionListItem` öğeleri. */\n children: ReactNode;\n /**\n * Verilirse liste SANALLAŞTIRILIR: yalnızca görünen satırlar çizilir. Satır yüksekliği SABİT\n * olmalı (px).\n */\n rowHeight?: number;\n /** Sanal listede görünen alanın yüksekliği (px). */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\ntype ItemProps = {\n children: ReactNode;\n /** Satırın başında duran öğe (kimlik, ikon). */\n start?: ReactNode;\n /** Satırın sonunda duran öğe (tur numarası, süre). */\n end?: ReactNode;\n onClick?: () => void;\n href?: string;\n /** Verilirse satır bir SEÇİMDİR (`aria-pressed`); verilmezse düz bir eylem. */\n isSelected?: boolean;\n /** Geri planda kalan satır (gizlenmiş, eski) — renkle, saydamlıkla değil. */\n isMuted?: boolean;\n testId?: string;\n /** Sanal listenin kendisi yazar: satırın gerçek konumu ve listenin gerçek boyu. */\n 'aria-posinset'?: number;\n 'aria-setsize'?: number;\n};\n\n/**\n * Çerçeveli satır listesi — her satır bir EYLEM (açar, gider) ya da bir SEÇİM (ayrıntıyı gösterir).\n *\n * ⚠ Seçim mi eylem mi satır başına `isSelected` ile söylenir: verilirse satır bir aç/kapa düğmesidir\n * (`aria-pressed`), verilmezse düz bir eylem. Eylemi seçim gibi sunmak kalıcı bir durum vaat ediyordu.\n * ⚠ Sanal listede ekran okuyucu yalnızca çizilen satırları görür; gerçek konumu `aria-posinset` /\n * `aria-setsize` söyler.\n */\nconst ActionList: FC<ListProps> = ({\n label,\n children,\n rowHeight,\n maxHeight = 320,\n className,\n testId,\n}) => {\n const items = Children.toArray(children).filter(isValidElement) as ReactElement<ItemProps>[];\n const [scrollTop, setScrollTop] = useState(0);\n\n if (!rowHeight)\n return (\n <ul className={cx(styles.list, className)} aria-label={label} data-testid={testId}>\n {items}\n </ul>\n );\n\n const start = Math.max(0, Math.floor(scrollTop / rowHeight) - OVERSCAN);\n const end = Math.min(items.length, Math.ceil((scrollTop + maxHeight) / rowHeight) + OVERSCAN);\n\n return (\n <div\n className={cx(styles.list, styles['list--virtual'], className)}\n style={{ maxBlockSize: maxHeight, ['--hanui-row-height' as string]: `${rowHeight}px` }}\n onScroll={event => setScrollTop(event.currentTarget.scrollTop)}\n data-testid={testId}\n >\n <ul\n aria-label={label}\n className={styles.list__window}\n style={{\n blockSize: items.length * rowHeight,\n paddingBlockStart: start * rowHeight,\n }}\n >\n {items.slice(start, end).map((item, index) =>\n cloneElement(item, {\n 'aria-posinset': start + index + 1,\n 'aria-setsize': items.length,\n }),\n )}\n </ul>\n </div>\n );\n};\n\n/** `ActionList` satırı — kendi `li`sini taşır. */\nexport const ActionListItem: FC<ItemProps> = ({\n children,\n start,\n end,\n onClick,\n href,\n isSelected,\n isMuted,\n testId,\n 'aria-posinset': position,\n 'aria-setsize': setSize,\n}) => {\n const { linkComponent: LinkComponent } = useHanui();\n\n const className = cx(\n styles.item,\n isSelected && styles['item--selected'],\n isMuted && styles['item--muted'],\n );\n const content = (\n <>\n {start !== undefined && <span className={styles.item__start}>{start}</span>}\n <span className={styles.item__body}>{children}</span>\n {end !== undefined && <span className={styles.item__end}>{end}</span>}\n </>\n );\n\n const Anchor = LinkComponent ?? 'a';\n\n return (\n <li className={styles.list__slot} aria-posinset={position} aria-setsize={setSize}>\n {href ? (\n <Anchor href={href} className={className} data-testid={testId}>\n {content}\n </Anchor>\n ) : (\n <button\n type=\"button\"\n className={className}\n onClick={onClick}\n aria-pressed={isSelected}\n data-testid={testId}\n >\n {content}\n </button>\n )}\n </li>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ActionList, 'ActionList'),\n) as typeof ActionList;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport type { LegendTone } from '../Legend';\n\nimport styles from './index.module.scss';\n\nexport type SegmentBarSegment = {\n id: string;\n /** Parçanın okunan adı, değeriyle: \"Önek · 12,4 B\". Özet adın parçası olur. */\n label: string;\n tone: LegendTone;\n} & (\n | {\n /** Yığılmış çubukta parçanın büyüklüğü — parçalar sırayla dizilir. */\n value: number;\n from?: never;\n to?: never;\n }\n | {\n /** Zaman çizelgesinde parçanın başlangıcı ve bitişi (aynı ölçekte). */\n from: number;\n to: number;\n value?: never;\n }\n);\n\nexport type SegmentBarMarker = {\n id: string;\n /** Konum, `max` ile aynı ölçekte. */\n at: number;\n label: string;\n tone?: 'neutral' | 'danger';\n};\n\ntype Props = {\n /** Grafiğin adı (\"Bağlam bileşimi\"); parçaların ve işaretlerin adlarıyla birlikte okunur. */\n label: string;\n /** Ölçeğin tavanı. */\n max: number;\n segments: SegmentBarSegment[];\n /** Dikey çizgi işaretleri — bütçe sınırı, hedef. */\n markers?: SegmentBarMarker[];\n className?: string;\n testId?: string;\n};\n\nconst percent = (value: number, max: number): number =>\n max <= 0 ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n\nconst swatch = (tone: LegendTone): string =>\n tone === 'muted' ? 'var(--hanui-text-3)' : `var(--hanui-${tone})`;\n\n/**\n * Parçalı çubuk — yığılmış bileşim (`value`) ya da zaman çizelgesi (`from`/`to`).\n *\n * Erişilebilirlik: çubuk TEK bir görseldir (`role=\"img\"`); adı grafiğin adı + her parçanın ve\n * işaretin okunan adıdır. Parça başına odaklanılabilir öğe çizilmez — bir çubuğun içinde sekme\n * durağı dizmek, okunan özetten daha az bilgi verip daha çok tuş istiyordu.\n */\nconst SegmentBar: FC<Props> = ({ label, max, segments, markers = [], className, testId }) => {\n const summary = [\n ...segments.map(segment => segment.label),\n ...markers.map(marker => marker.label),\n ];\n let cursor = 0;\n\n return (\n <div\n role=\"img\"\n aria-label={`${label}: ${summary.join(', ')}`}\n className={cx(styles.bar, className)}\n data-testid={testId}\n >\n {segments.map(segment => {\n const start = segment.from ?? cursor;\n const end = segment.to ?? start + (segment.value ?? 0);\n cursor = end;\n\n return (\n <span\n key={segment.id}\n className={styles.bar__segment}\n title={segment.label}\n style={{\n insetInlineStart: `${percent(start, max)}%`,\n inlineSize: `${percent(end, max) - percent(start, max)}%`,\n backgroundColor: swatch(segment.tone),\n }}\n />\n );\n })}\n\n {markers.map(marker => (\n <span\n key={marker.id}\n className={cx(\n styles.bar__marker,\n marker.tone === 'danger' && styles['bar__marker--danger'],\n )}\n title={marker.label}\n style={{ insetInlineStart: `${percent(marker.at, max)}%` }}\n />\n ))}\n </div>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(SegmentBar, 'SegmentBar'),\n) as typeof SegmentBar;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\n/** Kategorik paletin adları (`cat-*`, `series-*`) + bekleme/boşluk için `muted`. */\nexport type LegendTone =\n 'cat-1' | 'cat-2' | 'cat-3' | 'cat-4' | 'cat-5' | 'series-1' | 'series-2' | 'muted';\n\nexport type LegendItem = {\n id: string;\n label: string;\n tone: LegendTone;\n};\n\ntype Props = {\n items: LegendItem[];\n className?: string;\n testId?: string;\n};\n\nconst swatchColor = (tone: LegendTone): string =>\n tone === 'muted' ? 'var(--hanui-text-3)' : `var(--hanui-${tone})`;\n\n/**\n * Grafik lejantı — renk karesi + ad. Renk yalnızca kategorik paletten gelir (iki temanın üç\n * yüzeyinde ≥3:1); ad her zaman metin olarak yazılır, renk tek başına anlam taşımaz.\n */\nconst Legend: FC<Props> = ({ items, className, testId }) => (\n <ul className={cx(styles.legend, className)} data-testid={testId}>\n {items.map(item => (\n <li key={item.id} className={styles.legend__item}>\n <span\n aria-hidden\n className={styles.legend__swatch}\n style={{ backgroundColor: swatchColor(item.tone) }}\n />\n {item.label}\n </li>\n ))}\n </ul>\n);\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(Legend, 'Legend')) as typeof Legend;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\nexport type DescriptionItem = {\n term: ReactNode;\n description: ReactNode;\n /** Değer teknik bir kimlik (kod, yol, karma): teknik fontta ve satır içinde bölünebilir. */\n isTechnical?: boolean;\n};\n\ntype Props = {\n items: DescriptionItem[];\n className?: string;\n testId?: string;\n};\n\n/** Terim–değer listesi — yerel `<dl>`; ekran okuyucu terimi değeriyle birlikte okur. */\nconst DescriptionList: FC<Props> = ({ items, className, testId }) => (\n <dl className={cx(styles.list, className)} data-testid={testId}>\n {items.map((item, index) => (\n <div key={index} className={styles.list__row}>\n <dt className={styles.list__term}>{item.term}</dt>\n <dd\n className={cx(styles.list__value, item.isTechnical && styles['list__value--technical'])}\n >\n {item.description}\n </dd>\n </div>\n ))}\n </dl>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(DescriptionList, 'DescriptionList'),\n) as typeof DescriptionList;\n"],"names":["cx","values","result","value","named","component","displayName","warned","resolveLabel","key","resolveFormatter","formatter","args","ChatThread","children","dock","isStreaming","label","className","testId","labels","useHanui","announce","useAnnounce","scrollRef","useRef","isAtEnd","scrollToEnd","useStickToBottom","wasStreaming","useEffect","_a","jsxs","styles","jsx","_b","IconButton","ArrowDown","_c","index$h","memo","ChatMessage","author","avatar","actions","index$g","PromptInput","forwardRef","onChange","onSubmit","onStop","isBusy","isDisabled","isSubmitDisabled","placeholder","maxRows","hint","start","end","ref","isEmpty","handleKeyDown","event","hasOpenSurface","Textarea","StopFill","ArrowUp","index$f","PromptSuggestions","items","onPick","item","index$e","Prose","rest","index$d","COPIED_FOR","CodeBlock","code","language","html","maxHeight","isCopied","setIsCopied","useState","timer","copy","languageName","CheckLg","ClipboardFill","index$c","ReasoningBlock","summary","isRunning","indicator","isDefaultOpen","isOpen","setIsOpen","isTouched","Disclosure","Spinner","next","index$b","ReasoningText","text","ScrollArea","index$a","DOT_TONE","ToolCall","icon","name","status","meta","onOpenChange","statusText","header","StatusDot","ToolCallSection","index$9","TerminalOutput","command","chunks","stderrLabel","chunk","index","index$8","SourceList","index$7","Citation","href","onClick","index$6","FOCUSABLE","MessageActions","isRtl","previous","target","index$5","HEIGHT_VARIABLE","AppBar","brand","node","root","observer","entry","index$4","OVERSCAN","ActionList","rowHeight","Children","isValidElement","scrollTop","setScrollTop","cloneElement","ActionListItem","isSelected","isMuted","position","setSize","LinkComponent","content","Fragment","Anchor","index$3","percent","max","swatch","tone","SegmentBar","segments","markers","segment","marker","cursor","index$2","swatchColor","Legend","index$1","DescriptionList"],"mappings":"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"}
1
+ {"version":3,"file":"chat.cjs","sources":["../src/helpers/class-name.helper.ts","../src/helpers/component.helper.ts","../src/helpers/label.helper.ts","../src/chat/ChatThread/index.tsx","../src/chat/ChatMessage/index.tsx","../src/chat/PromptInput/index.tsx","../src/chat/PromptSuggestions/index.tsx","../src/chat/Prose/index.tsx","../src/chat/CodeBlock/format.ts","../src/chat/CodeBlock/grammars.ts","../src/chat/CodeBlock/highlight.ts","../src/chat/CodeBlock/index.tsx","../src/chat/ReasoningBlock/index.tsx","../src/chat/ReasoningText/index.tsx","../src/chat/ToolCall/index.tsx","../src/chat/TerminalOutput/index.tsx","../src/chat/SourceList/index.tsx","../src/chat/Citation/index.tsx","../src/chat/MessageActions/index.tsx","../src/chat/AppBar/index.tsx","../src/chat/ActionList/index.tsx","../src/chat/SegmentBar/index.tsx","../src/chat/Legend/index.tsx","../src/chat/DescriptionList/index.tsx"],"sourcesContent":["import { ClassValue } from '@/types/common-element-props.type';\n\n/** Sınıf adı birleştirici. */\nexport const cx = (...values: ClassValue[]): string => {\n let result = '';\n\n for (const value of values) {\n if (!value) continue;\n result = result === '' ? value : `${result} ${value}`;\n }\n\n return result;\n};\n","/**\n * DevTools adı — modül düzeyinde YAN ETKİ bırakmadan.\n *\n * ⚠ `X.displayName = 'X'` KULLANILMAZ: modül düzeyindeki özellik ataması\n * bundler için yan etkidir ve hedefinin tüm bağımlılık zincirini ayakta tutar.\n * Ölçüldü: yalnızca `Badge` import eden uygulama 20,7 kB indiriyordu (paketin\n * tamamı 21,8 kB). Atama çağrıya dönüşünce `#__PURE__` işaretlenebiliyor →\n * `Badge` 2,71 kB. Nöbetçi `.size-limit.json`.\n *\n * @example\n * export default memo(named(Button, 'Button')) as typeof Button;\n */\nexport const named = <TComponent extends object>(\n component: TComponent,\n displayName: string,\n): TComponent => Object.assign(component, { displayName });\n","/** Metin çözümlemesi: prop → sağlayıcı config'i → geliştirme uyarısı. */\n\nimport type { Formatter } from '@/types/theme.type';\n\n/* Uyari ANAHTAR BASINA bir kez verilir. */\nconst warned = new Set<string>();\n\n/** Uyarı durumu testler arasında sızmamalı; her test kendi durumundan başlar. */\nexport const resetLabelWarnings = (): void => warned.clear();\n\n/**\n * Verilen metni çözer.\n * @param key Uyarıda gösterilecek yol (`Modal.closeLabel`).\n * @param values Öncelik sırasına göre adaylar: prop önce, config sonra.\n */\nexport const resolveLabel = (key: string, ...values: (string | undefined)[]): string => {\n for (const value of values) if (value !== undefined) return value;\n\n if (process.env.NODE_ENV !== 'production' && !warned.has(key)) {\n warned.add(key);\n console.error(\n `[hanui] Eksik metin: ${key}. Prop olarak geçin ya da ` +\n '<HanuiProvider labels={…}> içinde bir kez tanımlayın. ' +\n 'Metinsiz bırakılan öğe ekran okuyucuda adsız kalır.',\n );\n }\n\n return '';\n};\n\n/** Biçimlendirici çözümü — değere bağlı metinler için. */\nexport const resolveFormatter = <TArgs extends unknown[]>(\n key: string,\n formatter: Formatter<TArgs> | undefined,\n ...args: TArgs\n): string => {\n if (formatter) return formatter(...args);\n\n return resolveLabel(key);\n};\n","'use client';\n\nimport { type FC, memo, type ReactNode, useEffect, useRef } from 'react';\n\nimport { ArrowDown } from 'react-bootstrap-icons';\n\nimport { IconButton, useAnnounce, useHanui, useStickToBottom } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Mesajlar (`ChatMessage`). */\n children: ReactNode;\n /** Alt dok — yazma alanı (`PromptInput`) ve ipucu satırı. */\n dock?: ReactNode;\n /** Yanıt akıyor. Akış bittiğinde \"yanıt hazır\" duyurulur. */\n isStreaming?: boolean;\n /** Bölgenin adı; verilmezse `labels.chat.thread`. */\n label?: string;\n className?: string;\n testId?: string;\n};\n\n/**\n * Sohbet iskeleti — kaydırma alanı, ortalanmış sütun ve alt dok.\n *\n * - Sona yapışık kalır; kullanıcı yukarı kaydırınca bırakır ve \"en yeniye in\" düğmesi belirir.\n * - ⚠ Akan belirteçler OKUNMAZ (`aria-live` yok, `role=\"log\"` değil): her belirteci duyuran bir bölge\n * ekran okuyucuyu kullanılamaz kılıyordu. Yanıt BİTTİĞİNDE tek bir cümle duyurulur.\n * - Dok sayfanın dibine yapışır ve `safe-area` payını taşır; iOS'ta klavye açıkken görünür kalır.\n */\nconst ChatThread: FC<Props> = ({ children, dock, isStreaming, label, className, testId }) => {\n const { labels } = useHanui();\n const announce = useAnnounce();\n const scrollRef = useRef<HTMLDivElement>(null);\n const { isAtEnd, scrollToEnd } = useStickToBottom(scrollRef);\n\n /* Akis bitti: `true` → `false` gecisinde bir kez duyurulur, ilk render'da degil. */\n const wasStreaming = useRef(isStreaming);\n useEffect(() => {\n if (wasStreaming.current && !isStreaming)\n announce(resolveLabel('ChatThread.replyReady', labels?.chat?.replyReady));\n wasStreaming.current = isStreaming;\n }, [announce, isStreaming, labels?.chat?.replyReady]);\n\n return (\n <div className={cx(styles.thread, className)} data-testid={testId}>\n <div\n ref={scrollRef}\n className={styles.thread__scroll}\n role=\"region\"\n aria-label={resolveLabel('ChatThread.label', label, labels?.chat?.thread)}\n /* Kaydirma bolgesi klavyeyle ulasilabilir (2.1.1). */\n tabIndex={0}\n >\n <div className={styles.thread__column}>{children}</div>\n </div>\n\n <div className={styles.thread__dock}>\n {!isAtEnd && (\n <IconButton\n className={styles.thread__latest}\n icon={<ArrowDown aria-hidden />}\n label={resolveLabel('ChatThread.scrollToLatest', labels?.chat?.scrollToLatest)}\n variant=\"outline\"\n shape=\"round\"\n size=\"sm\"\n onClick={scrollToEnd}\n />\n )}\n {dock !== undefined && <div className={styles.thread__column}>{dock}</div>}\n </div>\n </div>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ChatThread, 'ChatThread'),\n) as typeof ChatThread;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\nexport type ChatMessageAuthor = 'user' | 'assistant';\n\ntype Props = {\n author: ChatMessageAuthor;\n children: ReactNode;\n /** Asistan mesajının avatarı (`Avatar tone=\"brand\"`); ilk satır hizasında durur. */\n avatar?: ReactNode;\n /** Mesajın altındaki eylem çubuğu (`MessageActions`). */\n actions?: ReactNode;\n /** Yanıt hâlâ akıyor — `aria-busy`: ekran okuyucu yarım metni okumaz. */\n isStreaming?: boolean;\n className?: string;\n testId?: string;\n};\n\n/**\n * Sohbet mesajı. Kullanıcı mesajı sağa yaslı bir balon (`surface-2`, satır sonları korunur);\n * asistan mesajı tam genişlik, avatar sol üstte.\n *\n * ⚠ Eylemler hover'da VE `:focus-within`de belirginleşir: klavye kullanıcısı da görmeli. Gizlenmez,\n * yalnızca sessizleşir — `opacity` değil renk (soluklaştırma yasak).\n */\nconst ChatMessage: FC<Props> = ({\n author,\n children,\n avatar,\n actions,\n isStreaming,\n className,\n testId,\n}) => (\n <article\n className={cx(styles.message, styles[`message--${author}`], className)}\n aria-busy={isStreaming || undefined}\n data-testid={testId}\n >\n {author === 'assistant' && avatar !== undefined && (\n <div className={styles.message__avatar}>{avatar}</div>\n )}\n\n <div className={styles.message__main}>\n <div className={styles.message__body}>{children}</div>\n {actions !== undefined && <div className={styles.message__actions}>{actions}</div>}\n </div>\n </article>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ChatMessage, 'ChatMessage'),\n) as typeof ChatMessage;\n","'use client';\n\nimport { forwardRef, type KeyboardEvent, memo, type ReactNode, useEffect } from 'react';\n\nimport { ArrowUp, StopFill } from 'react-bootstrap-icons';\n\nimport { hasOpenSurface, IconButton, Textarea, useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n value: string;\n onChange: (value: string) => void;\n /** Enter ya da gönder düğmesi. Boş (yalnızca boşluk) metinde çağrılmaz. */\n onSubmit: () => void;\n /** Akışı durdurur — `isBusy` iken düğme ve `Escape`. */\n onStop?: () => void;\n /** Yanıt akıyor: gönder yerine durdur düğmesi. */\n isBusy?: boolean;\n /** Alanın tamamı pasif — yazılamaz. */\n isDisabled?: boolean;\n /**\n * Yazmaya izin var ama GÖNDERİM kapalı (bağlantı yok, oturum hazırlanıyor). Kullanıcı mesajını\n * yazabilir; gönder düğmesi ve `Enter` bekler.\n */\n isSubmitDisabled?: boolean;\n /** Yer tutucu — çağrı yerine ÖZGÜ metin, `labels`a girmez. */\n placeholder: string;\n /** Alanın erişilebilir adı; verilmezse yer tutucu. */\n label?: string;\n /** Otomatik büyümenin tavanı (satır). */\n maxRows?: number;\n /** Alanın altındaki ipucu satırı (`Kbd` ile kısayollar). */\n hint?: ReactNode;\n /** Alanın solunda (ek dosya, model seçici). */\n start?: ReactNode;\n /** Gönder düğmesinin solunda. */\n end?: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/**\n * Sohbet yazma alanı — çerçevesiz `Textarea` + yuvarlak gönder / durdur düğmesi.\n *\n * Klavye: `Enter` gönderir · `Shift+Enter` yeni satır · `Escape` (akış sürerken) durdurur.\n * - ⚠ IME yazımı sırasında (`isComposing`, Türkçe dışı klavyeler) `Enter` GÖNDERMEZ: harf seçimini\n * onaylıyor, mesajı değil.\n * - ⚠ `Escape` açık bir yüzey (modal, menü, bildirim) varken DOKUNMAZ (`hasOpenSurface`): kullanıcı\n * yalnızca o yüzeyi kapatmak istiyordu, arkadaki akış da duruyordu.\n * - Gönder düğmesi ekranın TEK birincil eylemi: çam dolgu, koyu temada mint sınır.\n * - Odak göstergesini çerçeve çizer (`:focus-within`); alan çerçevesiz (`variant=\"bare\"`).\n * - `ref` metin alanına iletilir: gönderimden ya da bir öneri seçildikten sonra odağı geri vermek için.\n */\nconst PromptInput = /*#__PURE__*/ forwardRef<HTMLTextAreaElement, Props>(\n (\n {\n value,\n onChange,\n onSubmit,\n onStop,\n isBusy,\n isDisabled,\n isSubmitDisabled,\n placeholder,\n label,\n maxRows = 8,\n hint,\n start,\n end,\n className,\n testId,\n },\n ref,\n ) => {\n const { labels } = useHanui();\n const isEmpty = value.trim() === '';\n\n /* `Escape` sayfa duzeyinde: odak alanda olmasa da (bir arac kartindayken) akis durdurulabilmeli. */\n useEffect(() => {\n if (!isBusy || !onStop) return;\n\n const handleKeyDown = (event: globalThis.KeyboardEvent) => {\n if (event.key !== 'Escape' || event.defaultPrevented || hasOpenSurface()) return;\n onStop();\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isBusy, onStop]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== 'Enter' || event.shiftKey || event.nativeEvent.isComposing) return;\n\n event.preventDefault();\n if (!isEmpty && !isBusy && !isDisabled && !isSubmitDisabled) onSubmit();\n };\n\n return (\n <div className={cx(styles.prompt, className)} data-testid={testId}>\n <div className={cx(styles.prompt__box, isDisabled && styles['prompt__box--disabled'])}>\n {start !== undefined && <div className={styles.prompt__start}>{start}</div>}\n\n <Textarea\n ref={ref}\n className={styles.prompt__field}\n variant=\"bare\"\n rows={1}\n isAutoSize\n maxRows={maxRows}\n value={value}\n placeholder={placeholder}\n aria-label={label ?? placeholder}\n disabled={isDisabled}\n onChange={event => onChange(event.target.value)}\n onKeyDown={handleKeyDown}\n />\n\n {end !== undefined && <div className={styles.prompt__end}>{end}</div>}\n\n {isBusy ? (\n <IconButton\n icon={<StopFill aria-hidden />}\n label={resolveLabel('PromptInput.stop', labels?.chat?.stop)}\n variant=\"outline\"\n shape=\"round\"\n onClick={onStop}\n disabled={!onStop}\n />\n ) : (\n <IconButton\n icon={<ArrowUp aria-hidden />}\n label={resolveLabel('PromptInput.send', labels?.chat?.send)}\n variant=\"solid\"\n shape=\"round\"\n onClick={onSubmit}\n disabled={isEmpty || isDisabled || isSubmitDisabled}\n />\n )}\n </div>\n\n {hint !== undefined && <div className={styles.prompt__hint}>{hint}</div>}\n </div>\n );\n },\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(PromptInput, 'PromptInput'),\n) as typeof PromptInput;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\nexport type PromptSuggestion = {\n id: string;\n /** Gönderilecek istem ya da kısa adı. */\n label: string;\n /** İkinci satır — neyi sorduğu. */\n description?: string;\n};\n\ntype Props = {\n /** Grubun erişilebilir adı (\"Örnek istemler\"). */\n label: string;\n items: PromptSuggestion[];\n onPick: (item: PromptSuggestion) => void;\n className?: string;\n testId?: string;\n};\n\n/**\n * Hazır istem önerileri — boş sohbetin başlangıç kartları.\n *\n * ⚠ Bunlar EYLEM, seçim değil: `ChipGroup` (seçim) yerine düğme ızgarası. Basmak bir şey seçmez,\n * istemi gönderir ya da yazma alanına koyar.\n */\nconst PromptSuggestions: FC<Props> = ({ label, items, onPick, className, testId }) => (\n <div role=\"group\" aria-label={label} className={cx(styles.grid, className)} data-testid={testId}>\n {items.map(item => (\n <button key={item.id} type=\"button\" className={styles.card} onClick={() => onPick(item)}>\n <span className={styles.card__label}>{item.label}</span>\n {item.description && <span className={styles.card__description}>{item.description}</span>}\n </button>\n ))}\n </div>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(PromptSuggestions, 'PromptSuggestions'),\n) as typeof PromptSuggestions;\n","import { type FC, type HTMLAttributes, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = HTMLAttributes<HTMLDivElement> & {\n testId?: string;\n};\n\n/**\n * Uzun metin kabı — markdown çıktısının (başlık, paragraf, liste, alıntı, tablo, satır içi kod,\n * bağlantı, formül) tipografisi.\n *\n * ⚠ AYRIŞTIRICI İÇERMEZ: `react-markdown`, `remark`/`rehype` eklentileri ve KaTeX tüketicide kalır;\n * hanui yalnızca çıktının nasıl göründüğünü verir (`linkComponent` ile aynı desen). Bir UI paketinin\n * markdown ayrıştırıcısı taşıması, sohbet kullanmayan tüketicinin hiç kullanmadığı yüzlerce kB demek.\n */\nconst Prose: FC<Props> = ({ className, testId, ...rest }) => (\n <div className={cx(styles.prose, className)} data-testid={testId} {...rest} />\n);\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(Prose, 'Prose')) as typeof Prose;\n","/** Kodun başındaki boş satırlar (ilk dolu satırın girintisi korunur). */\nconst LEADING_BLANK_LINES = /^(?:[ \\t]*\\r?\\n)+/;\n\nconst INDENT = ' ';\n\nconst isJson = (language: string | undefined) => language?.trim().toLowerCase() === 'json';\n\n/** `\"` ile açılan dizenin kapanışından sonraki konum. */\nconst endOfString = (text: string, start: number): number => {\n let cursor = start + 1;\n while (cursor < text.length && text[cursor] !== '\"') cursor += text[cursor] === '\\\\' ? 2 : 1;\n\n return cursor + 1;\n};\n\nconst nextSignificant = (text: string, start: number): number => {\n let cursor = start;\n while (cursor < text.length && /\\s/.test(text[cursor])) cursor++;\n\n return cursor;\n};\n\n/**\n * Geçerli JSON'u iki boşlukla yeniden girintiler — `JSON.stringify(değer, null, 2)` çıktısının\n * aynısı, ama METİN üzerinden.\n * ⚠ Değer ayrıştırılıp yeniden yazılmaz: `JSON.parse` 2^53'ün üstündeki tamsayıyı yuvarlıyor\n * (`12345678901234567890` → `12345678901234567000`), kaçışları çözüyor ve yinelenen anahtarın\n * ilkini siliyordu — biçimlendirici GÖSTERDİĞİ veriyi değiştiriyordu. Ayrıştırma yalnızca\n * geçerliliği sınar; sayılar, kaçışlar ve anahtarlar karakteri karakterine korunur.\n * Geçersiz JSON (akan yanıtın yarım bloğu, yorumlu JSONC) olduğu gibi döner.\n */\nconst formatJson = (text: string): string => {\n try {\n JSON.parse(text);\n } catch {\n return text;\n }\n\n let output = '';\n let depth = 0;\n const newline = () => `\\n${INDENT.repeat(depth)}`;\n\n for (let cursor = 0; cursor < text.length; cursor++) {\n const character = text[cursor];\n\n if (character === '\"') {\n const end = endOfString(text, cursor);\n output += text.slice(cursor, end);\n cursor = end - 1;\n } else if (character === '{' || character === '[') {\n const next = nextSignificant(text, cursor + 1);\n /* Boş kap tek satırda kalır: `{}`, `[]`. */\n if (text[next] === (character === '{' ? '}' : ']')) {\n output += character + text[next];\n cursor = next;\n } else {\n depth++;\n output += character + newline();\n }\n } else if (character === '}' || character === ']') {\n depth--;\n output += newline() + character;\n } else if (character === ',') output += `,${newline()}`;\n else if (character === ':') output += ': ';\n else if (!/\\s/.test(character)) output += character;\n }\n\n return output;\n};\n\n/**\n * Kod bloğunun biçimlendiricisi. Her dilde başındaki ve sonundaki boş satırları atar (çitli\n * bloğun son `\\n`i gövdede boş bir satır çiziyordu); JSON'u yeniden girintiler.\n * ⚠ Girinti başka hiçbir dilde DEĞİŞTİRİLMEZ: bir dosyadan alınmış parçanın girintisi o dosyadaki\n * derinliği anlatıyor ve Python'da anlamın kendisi.\n */\nexport const formatCode = (code: string, language: string | undefined): string => {\n const trimmed = code.replace(LEADING_BLANK_LINES, '').trimEnd();\n\n return isJson(language) ? formatJson(trimmed) : trimmed;\n};\n","/**\n * DİL TANIMLARI — yerleşik vurgulayıcının (`highlight.ts`) kuralları.\n *\n * Her dil SIRALI bir kural listesidir: aynı konumda eşleşen İLK kural kazanır. Kurallar tek bir\n * düzenli ifadede birleşir (`gm` bayraklı), bu yüzden:\n * - kural ifadeleri bayrak TAŞIMAZ ve YAKALAYAN GRUP içermez (`(?:…)` yazılır) — eşleşen kuralı\n * grubun sırası söyler;\n * - geriye bakış (`(?<=…)`) KULLANILMAZ: Safari 16.4 öncesinde ifade kurulurken `SyntaxError`\n * atıyor ve kod bloğu çizilemiyordu. Önceki karaktere bağlı kurallar `reject` ile yazılır.\n *\n * ⚠ Kapanmamış yorum ve dize metnin SONUNA kadar uzanır (`(?![\\s\\S])`): akan yanıtta blok henüz\n * bitmemişken renk doğru tarafta kalır.\n *\n * Kurallar ve kelime kümeleri ilk kullanımda kurulur (fabrika): modül düzeyinde çağrı yok, sohbet\n * girişinden yalnızca başka bir bileşen alan uygulamaya vurgulayıcı inmez.\n */\n\n/** Vurgulanan parçanın türü; her biri bir renk token'ına bağlanır (`index.module.scss`). */\nexport type CodeTokenType =\n | 'comment'\n | 'keyword'\n | 'string'\n | 'number'\n | 'name'\n | 'type'\n | 'punctuation'\n | 'inserted'\n | 'deleted';\n\n/**\n * Kuralın türü. Bir `CodeTokenType` eşleşmeyi olduğu gibi boyar; ötekiler ek karar ister:\n * - `word` — tanıtıcı; anahtar kelime / sabit / tip / çağrı ayrımını `classify` yapar\n * - `tag` — `<ad` ya da `</ad`: ayraç noktalama, ad etiket (büyük harfle başlıyorsa bileşen → tip)\n * - `markup` — işaretleme etiketinin tamamı; içi `MARKUP_TAG` ile ayrıca vurgulanır\n * - `regex` — JS düzenli ifade değişmezi; `/` bölme işareti de olabildiği için bağlama bakılır\n */\nexport type RuleKind = CodeTokenType | 'word' | 'tag' | 'markup' | 'regex';\n\n/** `[tür, ifade, reject?]` — `reject` eşleşmeden ÖNCEKİ karaktere uyarsa eşleşme reddedilir. */\nexport type Rule = readonly [kind: RuleKind, pattern: RegExp, reject?: RegExp];\n\nexport type Grammar = {\n rules: readonly Rule[];\n keywords?: ReadonlySet<string>;\n /** Sabit değişmezler (`true`, `null`, `None`) — sayıyla aynı renk. */\n literals?: ReadonlySet<string>;\n /** Yerleşik tipler (`string`, `int`, `varchar`). */\n types?: ReadonlySet<string>;\n /** Büyük harfle başlayan ad tiptir (`Button`); TAMAMI büyük harf olan sabittir (`MAX_SIZE`). */\n hasCapitalTypes?: boolean;\n /** SQL: anahtar kelime ve tip kümesi küçük harfle yazılır, kelime küçültülerek aranır. */\n isCaseInsensitive?: boolean;\n};\n\nconst words = (list: string): ReadonlySet<string> => new Set(list.split(' '));\n\n/* --- Ortak parçalar ------------------------------------------------------ */\n\n/* Tek satırlık dize; kapanmamışsa satır sonunda biter (akış). */\nconst DQ = /\"(?:[^\"\\\\\\n]|\\\\.)*\"?/;\nconst SQ = /'(?:[^'\\\\\\n]|\\\\.)*'?/;\n/* Şablon dizesi satır aşar. */\nconst BACKTICK = /`(?:[^`\\\\]|\\\\[\\s\\S])*`?/;\nconst TRIPLE_DQ = /\"\"\"[\\s\\S]*?(?:\"\"\"|(?![\\s\\S]))/;\nconst TRIPLE_SQ = /'''[\\s\\S]*?(?:'''|(?![\\s\\S]))/;\n/*\n * Karakter değişmezi: tek karakter ya da kaçış ve HEMEN kapanış. Rust'ın yaşam süresi (`'a`)\n * kapanmadığı için eşleşmez — tek tırnağı dize sayan bir kural satırın geri kalanını boyuyordu.\n */\nconst CHAR = /'(?:\\\\[^\\n]{1,8}?|[^'\\\\\\n])'/;\nconst SLASH_COMMENT = /\\/\\/.*/;\nconst BLOCK_COMMENT = /\\/\\*[\\s\\S]*?(?:\\*\\/|(?![\\s\\S]))/;\nconst HASH_COMMENT = /#.*/;\nconst NUMBER =\n /\\b(?:0[xX][\\dA-Fa-f_]+|0[bB][01_]+|0[oO][0-7_]+|\\d[\\d_]*(?:\\.\\d[\\d_]*)?(?:[eE][+-]?\\d+)?)[A-Za-z]*\\b/;\nconst WORD = /[A-Za-z_]\\w*/;\nconst PUNCTUATION = /[{}[\\]();,.:]/;\n/* Dekoratör ve açıklama (`@Component`, `@Override`, `@dataclass`) — çağrı gibi boyanır. */\nconst DECORATOR = /@[A-Za-z_][\\w.]*/;\n/* Önceki karakter tanıtıcının parçasıysa (`a#b`, `foo<T>`) kural geçerli değil. */\nconst AFTER_WORD = /[\\w$)\\]]/;\nconst AFTER_NON_SPACE = /\\S/;\n\n/* --- Kelime kümeleri ----------------------------------------------------- */\n\nconst JS_KEYWORDS =\n 'break case catch class const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield async await of static get set as from';\nconst TS_KEYWORDS =\n 'type interface enum implements namespace declare abstract private protected public readonly keyof infer is satisfies override module asserts unique';\nconst JS_LITERALS = 'true false null undefined NaN Infinity';\nconst TS_TYPES = 'string number boolean any unknown never object symbol bigint';\n\n/* C ailesinin ortak tipleri ve sabitleri — dillerin birleşimi; yalnızca renk seçer. */\nconst C_TYPES =\n 'int long short char float double bool boolean byte void unsigned signed string str usize isize u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 rune uint uint8 uint16 uint32 uint64 int8 int16 int32 int64 float32 float64 error any decimal size_t';\nconst C_LITERALS = 'true false null nil nullptr NULL';\n\nconst C_KEYWORDS =\n 'auto break case const continue default do else enum extern for goto if inline register restrict return sizeof static struct switch typedef union volatile while';\nconst CPP_KEYWORDS = `${C_KEYWORDS} alignas alignof catch class constexpr consteval const_cast decltype delete dynamic_cast explicit export friend mutable namespace new noexcept operator private protected public reinterpret_cast static_assert static_cast template this thread_local throw try typeid typename using virtual override final concept requires co_await co_return co_yield`;\nconst CSHARP_KEYWORDS =\n 'abstract as async await base break case catch checked class const continue default delegate do dynamic else enum event explicit extern finally fixed for foreach get goto if implicit in init interface internal is lock namespace new operator out override params partial private protected public readonly record ref return sealed set sizeof stackalloc static struct switch this throw try typeof unchecked unsafe using var virtual volatile when where while yield';\nconst JAVA_KEYWORDS =\n 'abstract assert break case catch class const continue default do else enum extends final finally for goto if implements import instanceof interface native new package permits private protected public record return sealed static strictfp super switch synchronized this throw throws transient try var volatile while yield';\nconst KOTLIN_KEYWORDS =\n 'abstract annotation as break by catch class companion const constructor continue crossinline data do else enum external final finally for fun get if import in infix init inline inner interface internal is lateinit noinline object open operator out override package private protected public reified return sealed set super suspend this throw try typealias val var vararg when where while';\nconst SWIFT_KEYWORDS =\n 'actor as associatedtype async await break case catch class continue default defer deinit do else enum extension fallthrough fileprivate final for func guard if import in init inout internal is lazy let mutating open operator override private protocol public repeat rethrows return self Self some static struct subscript super switch throw throws try typealias var weak where while';\nconst GO_KEYWORDS =\n 'break case chan const continue default defer else fallthrough for func go goto if import interface map package range return select struct switch type var';\nconst RUST_KEYWORDS =\n 'as async await break const continue crate dyn else enum extern fn for if impl in let loop match mod move mut pub ref return self Self static struct super trait type unsafe use where while';\nconst PHP_KEYWORDS =\n 'abstract and array as break callable case catch class clone const continue declare default do echo else elseif empty extends final finally fn for foreach function global goto if implements include include_once instanceof insteadof interface isset list match namespace new or print private protected public readonly require require_once return static switch throw trait try unset use var while xor yield';\n\nconst BASH_KEYWORDS =\n 'if then else elif fi for while until do done case esac in function return local export select time break continue declare readonly unset shift source alias exit';\nconst DOCKER_KEYWORDS =\n 'FROM AS RUN CMD LABEL EXPOSE ENV ADD COPY ENTRYPOINT VOLUME USER WORKDIR ARG ONBUILD STOPSIGNAL HEALTHCHECK SHELL MAINTAINER';\n\n/* --- Diller -------------------------------------------------------------- */\n\nconst javascript = (isTyped: boolean, hasJsx: boolean): Grammar => ({\n rules: [\n ['comment', SLASH_COMMENT],\n ['comment', BLOCK_COMMENT],\n ['string', DQ],\n ['string', SQ],\n ['string', BACKTICK],\n /*\n * Düzenli ifade. Tamamı (kapanış `/` ve bayraklar) önce gelir; alternatifler AYRIK olduğu\n * için geri dönüş doğrusaldır.\n * ⚠ Karakter sınıfının kapanışı bu kuralda ZORUNLU. `\\]?` dıştaki tekrar ve sondaki `/` ile\n * birkaç bin `[`de üstel geri dönüş yapıp sayfayı kilitliyordu.\n * Kapanmamış ifade alttaki kural: sonda aranan bir `/` yok, bu yüzden başarısız olup geri\n * dönmez; gövde satır sonuna kadar boyanır.\n */\n ['regex', /\\/(?![*/])(?:\\\\.|\\[(?:\\\\.|[^\\]\\\\\\n])*\\]|[^/\\\\\\n[])+\\/[dgimsuvy]*/],\n ['regex', /\\/(?![*/])(?:\\\\.|\\[(?:\\\\.|[^\\]\\\\\\n])*\\]?|[^/\\\\\\n[])*/],\n /*\n * Bileşen etiketi yalnızca JSX'te; TS'te `<` bir tür parametresi ya da karşılaştırma. Açılış\n * etiketi addan sonra gelemez (`useState<string>`); kapanış gelebilir (`Kaydet</Button>`).\n */\n ...(hasJsx\n ? ([\n ['tag', /<\\/[A-Za-z][\\w.:-]*/],\n ['tag', /<[A-Za-z][\\w.:-]*/, AFTER_WORD],\n ] as const)\n : []),\n ['name', DECORATOR],\n ['number', NUMBER],\n ['word', /[A-Za-z_$][\\w$]*/],\n ['punctuation', PUNCTUATION],\n ],\n keywords: words(isTyped ? `${JS_KEYWORDS} ${TS_KEYWORDS}` : JS_KEYWORDS),\n literals: words(JS_LITERALS),\n types: isTyped ? words(TS_TYPES) : undefined,\n hasCapitalTypes: true,\n});\n\n/** C ailesi: ortak kurallar + dilin anahtar kelimeleri. `extra` ortak kurallardan ÖNCE gelir. */\nconst cFamily = (keywords: string, extra: readonly Rule[] = []): Grammar => ({\n rules: [\n ...extra,\n ['comment', SLASH_COMMENT],\n ['comment', BLOCK_COMMENT],\n /* Önişlemci (`#include`) ve Rust özniteliği (`#[derive(Debug)]`). */\n ['keyword', /^[ \\t]*#[ \\t]*[a-z]+|#!?\\[[^\\]\\n]*\\]/],\n ['string', TRIPLE_DQ],\n ['string', DQ],\n ['string', CHAR],\n /* Go'nun ham dizesi. */\n ['string', BACKTICK],\n ['name', DECORATOR],\n ['number', NUMBER],\n ['word', WORD],\n ['punctuation', PUNCTUATION],\n ],\n keywords: words(keywords),\n literals: words(C_LITERALS),\n types: words(C_TYPES),\n hasCapitalTypes: true,\n});\n\nconst python = (): Grammar => ({\n rules: [\n ['comment', HASH_COMMENT],\n [\n 'string',\n /(?:\\b[rRbBuUfF]{1,2})?(?:\"\"\"[\\s\\S]*?(?:\"\"\"|(?![\\s\\S]))|'''[\\s\\S]*?(?:'''|(?![\\s\\S])))/,\n ],\n ['string', /(?:\\b[rRbBuUfF]{1,2})?(?:\"(?:[^\"\\\\\\n]|\\\\.)*\"?|'(?:[^'\\\\\\n]|\\\\.)*'?)/],\n ['name', DECORATOR],\n ['number', NUMBER],\n ['word', WORD],\n ['punctuation', PUNCTUATION],\n ],\n keywords: words(\n 'and as assert async await break class continue def del elif else except finally for from global if import in is lambda nonlocal not or pass raise return try while with yield match case',\n ),\n literals: words('True False None'),\n types: words('int float str bool list dict set tuple bytes object'),\n hasCapitalTypes: true,\n});\n\nconst ruby = (): Grammar => ({\n rules: [\n ['comment', HASH_COMMENT],\n ['string', DQ],\n ['string', SQ],\n /* Sembol (`:ad`) sabittir; `Foo::Bar` içindeki `:Bar` değil. */\n ['number', /:[A-Za-z_]\\w*[?!]?/, /[\\w:]/],\n ['name', /@{1,2}[A-Za-z_]\\w*/],\n ['number', NUMBER],\n ['word', /[A-Za-z_]\\w*[?!]?/],\n ['punctuation', PUNCTUATION],\n ],\n keywords: words(\n 'alias and begin break case class def defined? do else elsif end ensure for if in module next not or redo rescue retry return self super then undef unless until when while yield require require_relative attr_accessor attr_reader attr_writer private protected public raise',\n ),\n literals: words('true false nil'),\n hasCapitalTypes: true,\n});\n\nconst bash = (keywords: string): Grammar => ({\n rules: [\n /* `#` yorum açar yalnızca kelime başında: `$#`, `a#b` yorum değil. */\n ['comment', HASH_COMMENT, /[^\\s;|&(]/],\n /* Kabukta çift tırnak satır aşar, tek tırnak kaçış tanımaz. */\n ['string', /\"(?:[^\"\\\\]|\\\\[\\s\\S])*\"?/],\n ['string', /'[^']*'?/],\n ['name', /\\$(?:\\{[^}\\n]*\\}?|[A-Za-z_]\\w*|[@#?$!*\\d-])/],\n ['number', /\\b\\d+\\b/],\n ['word', /[A-Za-z_][\\w-]*/],\n ['punctuation', /[{}[\\]();|&]/],\n ],\n keywords: words(keywords),\n});\n\nconst json = (): Grammar => ({\n rules: [\n ['comment', SLASH_COMMENT],\n ['comment', BLOCK_COMMENT],\n /* Anahtar: ardından `:` gelen dize. */\n ['name', /\"(?:[^\"\\\\\\n]|\\\\.)*\"(?=\\s*:)/],\n ['string', DQ],\n ['number', /-?\\b\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\b/],\n ['word', WORD],\n ['punctuation', /[{}[\\],:]/],\n ],\n literals: words('true false null'),\n});\n\nconst yaml = (): Grammar => ({\n rules: [\n ['comment', HASH_COMMENT, AFTER_NON_SPACE],\n /* Anahtar; ilk karakteri `-` olamaz (`- ad:` bir liste öğesi). */\n [\n 'name',\n /(?:\"(?:[^\"\\\\\\n]|\\\\.)*\"|'[^'\\n]*'|[\\w$./][\\w$./-]*(?:[ \\t]+[\\w$./-]+)*)(?=[ \\t]*:(?:[ \\t]|$))/,\n ],\n ['string', DQ],\n ['string', SQ],\n /* Çapa (`&ad`), takma ad (`*ad`), etiket (`!!str`). */\n ['type', /[&*][\\w-]+|!!?[\\w-]+/, AFTER_NON_SPACE],\n ['punctuation', /^[ \\t]*-(?=[ \\t]|$)|[{}[\\],]|[|>][-+]?(?=[ \\t]*$)/],\n ['number', /[-+]?\\b\\d[\\d_]*(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\b/],\n ['word', WORD],\n ],\n literals: words('true false null True False Null TRUE FALSE NULL'),\n});\n\nconst toml = (): Grammar => ({\n rules: [\n ['comment', HASH_COMMENT],\n ['type', /^[ \\t]*\\[\\[?[^\\]\\n]*\\]\\]?/],\n ['name', /(?:\"[^\"\\n]*\"|[\\w.-]+)(?=[ \\t]*=)/],\n ['string', TRIPLE_DQ],\n ['string', TRIPLE_SQ],\n ['string', DQ],\n ['string', /'[^'\\n]*'?/],\n [\n 'number',\n /\\b\\d{4}-\\d{2}-\\d{2}(?:[T ]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})?)?\\b|[-+]?\\b\\d[\\d_]*(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\b/,\n ],\n ['word', WORD],\n ['punctuation', /[{}[\\],=]/],\n ],\n literals: words('true false inf nan'),\n});\n\nconst css = (): Grammar => ({\n rules: [\n ['comment', BLOCK_COMMENT],\n /* SCSS/Less satır yorumu; `url(http://…)` içindeki `//` değil. */\n ['comment', SLASH_COMMENT, /:/],\n ['string', DQ],\n ['string', SQ],\n ['keyword', /@[\\w-]+|!important\\b/],\n /*\n * Özellik adı: ardındaki `:` bir bildirimi açıyorsa (`;` ya da `}` `{`dan önce geliyorsa).\n * `a:hover {` bir seçici — ardından önce `{` geliyor.\n */\n ['name', /-{0,2}[A-Za-z][\\w-]*(?=\\s*:[^;{}]*[;}])/],\n ['name', /\\$[\\w-]+/],\n ['number', /#[\\dA-Fa-f]{3,8}\\b|-?(?:\\b\\d+(?:\\.\\d+)?|\\.\\d+)(?:%|[A-Za-z]+\\b)?/],\n ['word', /-?[A-Za-z_][\\w-]*/],\n ['punctuation', /[{}();:,]/],\n ],\n});\n\nconst markup = (): Grammar => ({\n rules: [\n ['comment', /<!--[\\s\\S]*?(?:-->|(?![\\s\\S]))/],\n ['keyword', /<![A-Za-z][^>]*>?|<\\?[\\s\\S]*?(?:\\?>|(?![\\s\\S]))/],\n ['markup', /<\\/?[A-Za-z][\\w:.-]*(?:\"[^\"]*\"?|'[^']*'?|[^'\">])*>?/],\n /* Karakter başvurusu (`&amp;`). */\n ['number', /&#?\\w+;/],\n ],\n});\n\nconst markdown = (): Grammar => ({\n rules: [\n [\n 'string',\n /^[ \\t]*```[\\s\\S]*?(?:^[ \\t]*```|(?![\\s\\S]))|^[ \\t]*~~~[\\s\\S]*?(?:^[ \\t]*~~~|(?![\\s\\S]))/,\n ],\n ['keyword', /^#{1,6}[ \\t].*/],\n ['punctuation', /^[ \\t]*(?:[-*+]|\\d+[.)])(?=[ \\t])|^[ \\t]*>/],\n ['string', /`[^`\\n]+`/],\n ['name', /!?\\[[^\\]\\n]*\\]\\([^)\\n]*\\)/],\n ],\n});\n\nconst sql = (): Grammar => ({\n rules: [\n ['comment', /--.*/],\n ['comment', BLOCK_COMMENT],\n ['string', /'(?:[^']|'')*'?/],\n ['name', /\"[^\"\\n]*\"?|`[^`\\n]*`?/],\n ['number', NUMBER],\n ['word', WORD],\n ['punctuation', /[(),;.]/],\n ],\n keywords: words(\n 'select from where and or not insert into values update set delete create table alter drop index view join inner left right full outer cross on as group by order having limit offset union all distinct case when then else end is in exists between like ilike primary key foreign references default unique constraint returning with asc desc begin commit rollback transaction if replace check cascade grant revoke add column database schema trigger procedure function declare',\n ),\n literals: words('null true false'),\n types: words(\n 'int integer bigint smallint serial bigserial text varchar char boolean bool date time timestamp timestamptz interval numeric decimal real float double json jsonb uuid bytea',\n ),\n isCaseInsensitive: true,\n});\n\nconst diff = (): Grammar => ({\n rules: [\n ['keyword', /^(?:diff|index|\\+\\+\\+|---)(?: .*|$)/],\n ['name', /^@@.*/],\n ['inserted', /^\\+.*/],\n ['deleted', /^-.*/],\n ],\n});\n\nconst graphql = (): Grammar => ({\n rules: [\n ['comment', HASH_COMMENT],\n ['string', TRIPLE_DQ],\n ['string', DQ],\n ['name', /\\$\\w+/],\n ['name', /@\\w+/],\n ['number', NUMBER],\n ['word', WORD],\n ['punctuation', /[{}[\\]():,!=|]/],\n ],\n keywords: words(\n 'query mutation subscription fragment on type input enum interface union scalar schema extend directive implements',\n ),\n literals: words('true false null'),\n /* `ID` tamamı büyük harf ama sabit değil, yerleşik tip. */\n types: words('ID'),\n hasCapitalTypes: true,\n});\n\n/** İşaretleme etiketinin İÇİ (`markup` kuralının eşleşmesi): ad, öznitelik, değer. */\nexport const MARKUP_TAG = (): Grammar => ({\n rules: [\n ['tag', /<\\/?[A-Za-z][\\w:.-]*/],\n ['string', /\"[^\"]*\"?|'[^']*'?/],\n ['name', /[^\\s\"'<>/=]+/],\n ['punctuation', /\\/?>|=/],\n ],\n});\n\nconst JS = () => javascript(false, false);\nconst JSX = () => javascript(false, true);\nconst TS = () => javascript(true, false);\nconst TSX = () => javascript(true, true);\nconst BASH = () => bash(BASH_KEYWORDS);\nconst DOCKER = () => bash(DOCKER_KEYWORDS);\nconst C = () => cFamily(C_KEYWORDS);\nconst CPP = () => cFamily(CPP_KEYWORDS);\nconst CSHARP = () => cFamily(CSHARP_KEYWORDS);\nconst KOTLIN = () => cFamily(KOTLIN_KEYWORDS);\nconst GO = () => cFamily(GO_KEYWORDS);\nconst RUST = () => cFamily(RUST_KEYWORDS);\n/* PHP'de tek tırnak DİZE (karakter değil), `#` yorum ve değişken `$ad`. */\nconst PHP = () =>\n cFamily(PHP_KEYWORDS, [\n ['comment', HASH_COMMENT],\n ['name', /\\$[A-Za-z_]\\w*/],\n ['string', SQ],\n ]);\n\n/** Dil adı (küçük harf) → dil. Takma adlar aynı fabrikayı gösterir; önbellek fabrikaya bağlı. */\nexport const GRAMMARS: Readonly<Record<string, () => Grammar>> = {\n javascript: JS,\n js: JS,\n mjs: JS,\n cjs: JS,\n jsx: JSX,\n typescript: TS,\n ts: TS,\n mts: TS,\n cts: TS,\n tsx: TSX,\n json,\n jsonc: json,\n bash: BASH,\n sh: BASH,\n shell: BASH,\n zsh: BASH,\n console: BASH,\n dockerfile: DOCKER,\n docker: DOCKER,\n python,\n py: python,\n ruby,\n rb: ruby,\n yaml,\n yml: yaml,\n toml,\n css,\n scss: css,\n less: css,\n html: markup,\n xml: markup,\n svg: markup,\n vue: markup,\n markdown,\n md: markdown,\n sql,\n diff,\n patch: diff,\n graphql,\n gql: graphql,\n c: C,\n h: C,\n cpp: CPP,\n 'c++': CPP,\n hpp: CPP,\n csharp: CSHARP,\n cs: CSHARP,\n java: () => cFamily(JAVA_KEYWORDS),\n kotlin: KOTLIN,\n kt: KOTLIN,\n swift: () => cFamily(SWIFT_KEYWORDS),\n go: GO,\n golang: GO,\n rust: RUST,\n rs: RUST,\n php: PHP,\n};\n","import { type CodeTokenType, type Grammar, GRAMMARS, MARKUP_TAG, type Rule } from './grammars';\n\nexport type { CodeTokenType } from './grammars';\n\n/** Vurgulanmış bir parça; `type` yoksa düz metin. */\nexport type CodeToken = { text: string; type?: CodeTokenType };\n\n/**\n * Bu boyun üstündeki kod VURGULANMAZ, düz çizilir.\n * ⚠ Maliyet çözümlemede DEĞİL, `<span>` sayısında. Ölçüldü (chromium, galeri sunucusu, React\n * geliştirme kipi): 50 000 karakterlik TypeScript 8,5 ms'de 4 333 parçaya ayrılıyor, ama yalnızca\n * DOM kurulumu + yerleşim 66 ms, React'in ilk çizimi 590 ms ve akan yanıtta her güncelleme 173 ms.\n * 20 000 karakterde aynı ölçüm 3,8 ms · 1 555 parça · 17 ms · 139 ms · 78 ms. Sınırın altında renk,\n * üstünde akıcılık; ~500 satırdan uzun bir sohbet bloğu zaten istisna.\n */\nexport const HIGHLIGHT_LIMIT = 20_000;\n\ntype Compiled = { pattern: RegExp; grammar: Grammar };\n\n/* Ad ardından `(` (Rust/Ruby'de `!(`) — çağrı. Yapışkan: kodu dilimlemeden bakar. */\nconst CALL = /!?[ \\t]*\\(/y;\nconst CONSTANT = /^[A-Z][A-Z\\d_]+$/;\n/* Bu karakterlerden sonra gelen `/` bir düzenli ifade açar; `)`, `]` ve addan sonra bölmedir. */\nconst REGEX_AFTER = /[(,=:[!&|?{};~+\\-*%<>^]/;\nconst REGEX_AFTER_WORD = /*#__PURE__*/ new Set([\n 'return',\n 'typeof',\n 'case',\n 'do',\n 'else',\n 'in',\n 'of',\n 'new',\n 'delete',\n 'void',\n 'throw',\n 'yield',\n 'await',\n]);\n\nconst cache = /*#__PURE__*/ new Map<() => Grammar, Compiled>();\n\nconst compile = (factory: () => Grammar): Compiled => {\n const known = cache.get(factory);\n if (known) return known;\n\n const grammar = factory();\n const pattern = new RegExp(grammar.rules.map(([, rule]) => `(${rule.source})`).join('|'), 'gm');\n const compiled = { pattern, grammar };\n cache.set(factory, compiled);\n\n return compiled;\n};\n\n/**\n * Dil adı → dil; tanınmayan ya da verilmeyen dil `undefined` (düz metin).\n * ⚠ Yalnızca KENDİ anahtarları: `GRAMMARS.constructor` `Object`in kendisi — markdown'daki\n * ` ```constructor ` çiti onu dil sanıp bileşeni düşürürdü.\n */\nconst grammarOf = (language: string | undefined) => {\n const key = language?.trim().toLowerCase();\n\n return key && Object.hasOwn(GRAMMARS, key) ? GRAMMARS[key] : undefined;\n};\n\nconst isRegexStart = (code: string, index: number): boolean => {\n let cursor = index - 1;\n while (cursor >= 0 && /\\s/.test(code[cursor])) cursor--;\n if (cursor < 0 || REGEX_AFTER.test(code[cursor])) return true;\n\n const end = cursor + 1;\n while (cursor >= 0 && /[\\w$]/.test(code[cursor])) cursor--;\n\n return REGEX_AFTER_WORD.has(code.slice(cursor + 1, end));\n};\n\nconst classify = (\n grammar: Grammar,\n word: string,\n code: string,\n index: number,\n end: number,\n): CodeTokenType | undefined => {\n CALL.lastIndex = end;\n const isCall = CALL.test(code);\n\n /* Özellik erişimi (`map.get`, `obj.type`) anahtar kelime DEĞİL. */\n if (code[index - 1] === '.') return isCall ? 'name' : undefined;\n\n const key = grammar.isCaseInsensitive ? word.toLowerCase() : word;\n if (grammar.keywords?.has(key)) return 'keyword';\n if (grammar.literals?.has(key)) return 'number';\n if (grammar.types?.has(key)) return 'type';\n if (isCall) return 'name';\n if (grammar.hasCapitalTypes && /^[A-Z]/.test(word))\n return CONSTANT.test(word) ? 'number' : 'type';\n\n return undefined;\n};\n\nconst tokenize = ({ pattern, grammar }: Compiled, code: string): CodeToken[] => {\n const tokens: CodeToken[] = [];\n const push = (text: string, type?: CodeTokenType) => {\n if (!text) return;\n const last = tokens.at(-1);\n if (last && last.type === type) last.text += text;\n else tokens.push({ text, type });\n };\n\n let cursor = 0;\n pattern.lastIndex = 0;\n\n for (let match = pattern.exec(code); match; match = pattern.exec(code)) {\n const [text] = match;\n const { index } = match;\n const end = index + text.length;\n\n /* Boş eşleşme ilerlemez; kurallar boş eşleşmemeli, bu bir sigorta. */\n if (end === index) {\n pattern.lastIndex = index + 1;\n continue;\n }\n\n const [kind, , reject]: Rule = grammar.rules[match.indexOf(text, 1) - 1];\n\n const isRejected =\n (reject !== undefined && index > 0 && reject.test(code[index - 1])) ||\n (kind === 'regex' && !isRegexStart(code, index));\n\n /* Reddedilen eşleşmenin ilk karakteri düz metin kalır; arama bir sonrakinden sürer. */\n if (isRejected) {\n pattern.lastIndex = index + 1;\n continue;\n }\n\n push(code.slice(cursor, index));\n cursor = end;\n\n if (kind === 'word') push(text, classify(grammar, text, code, index, end));\n else if (kind === 'regex') push(text, 'string');\n else if (kind === 'tag') {\n const open = text[1] === '/' ? 2 : 1;\n const name = text.slice(open);\n push(text.slice(0, open), 'punctuation');\n push(name, /^[A-Z]/.test(name) || name.includes('.') ? 'type' : 'keyword');\n } else if (kind === 'markup')\n for (const token of tokenize(compile(MARKUP_TAG), text)) push(token.text, token.type);\n else push(text, kind);\n }\n\n push(code.slice(cursor));\n\n return tokens;\n};\n\n/**\n * Kodu renk parçalarına ayırır — bağımlılıksız, tek geçişlik bir sözcük çözümleyici.\n * Bir dilbilgisi ÇÖZÜMLEYİCİSİ değil: Shiki düzeyinde doğruluk gerekiyorsa vurgulanmış HTML\n * `CodeBlock`a `html` olarak verilir.\n */\nexport const highlight = (code: string, language: string | undefined): CodeToken[] => {\n const factory = grammarOf(language);\n\n return factory && code.length <= HIGHLIGHT_LIMIT\n ? tokenize(compile(factory), code)\n : [{ text: code }];\n};\n","'use client';\n\nimport { type FC, Fragment, memo, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { CheckLg, ClipboardFill } from 'react-bootstrap-icons';\n\nimport { IconButton, useAnnounce, useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveFormatter, resolveLabel } from '../../helpers/label.helper';\n\nimport { formatCode } from './format';\nimport { highlight } from './highlight';\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Ham kod. `html` yoksa biçimlendirilip vurgulanır; kopyalanan metin ekranda görünendir. */\n code: string;\n /**\n * Dil adı (`ts`, `json`, `bash`, `diff`…); başlık şeridinde, kopyalama düğmesinin adında ve\n * vurgulayıcının seçiminde. Tanınmayan dil düz çizilir.\n */\n language?: string;\n /**\n * ÖNCEDEN VURGULANMIŞ HTML (Shiki çıktısı) — yerleşik vurgulayıcının yerine geçer; `code`\n * biçimlendirilmez ve olduğu gibi kopyalanır.\n * ⚠ GÜVENLİK ÇAĞIRANIN: bu dize olduğu gibi DOM'a yazılır. Yalnızca kendi vurgulayıcınızın\n * ürettiği çıktıyı verin; kullanıcı girdisini asla doğrudan geçirmeyin.\n */\n html?: string;\n /** Gövdenin tavanı (px); uzun kod kendi içinde kayar. */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\n/** Kopyalandı işaretinin ekranda kaldığı süre (ms). */\nconst COPIED_FOR = 1600;\n\n/**\n * Kod bloğu — başlık şeridi (dil + kopyala) ve kod gövdesi.\n *\n * Yerleşik vurgulayıcı ve biçimlendirici (bağımlılıksız): renkler `syntax-*` token'larından,\n * yani temayla döner ve kontrastı derlemede ölçülür. JSON yeniden girintilenir, kenarlardaki boş\n * satırlar atılır. Shiki düzeyinde doğruluk gerekiyorsa `html` verilir; Shiki'nin çift tema\n * çıktısı (`--shiki-light` / `--shiki-dark`) burada temaya bağlanır.\n * Kod satırları SARILMAZ: dar ekranda kutu yatay kayar (kodun girintisi anlamdır).\n */\nconst CodeBlock: FC<Props> = ({ code, language, html, maxHeight, className, testId }) => {\n const { labels } = useHanui();\n const announce = useAnnounce();\n const [isCopied, setIsCopied] = useState(false);\n const timer = useRef<number | undefined>(undefined);\n\n /* Çağıranın HTML'i `code`dan üretildi; biçimlendirmek ikisini ayrıştırırdı. */\n const source = useMemo(() => (html ? code : formatCode(code, language)), [code, html, language]);\n const tokens = useMemo(() => (html ? [] : highlight(source, language)), [source, html, language]);\n\n useEffect(() => () => window.clearTimeout(timer.current), []);\n\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(source);\n } catch {\n return;\n }\n\n setIsCopied(true);\n announce(resolveLabel('CodeBlock.copied', labels?.chat?.codeCopied));\n window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => setIsCopied(false), COPIED_FOR);\n };\n\n const languageName = language ?? '';\n\n return (\n <figure className={cx(styles.block, className)} data-testid={testId}>\n <figcaption className={styles.block__header}>\n <span className={styles.block__language}>{languageName}</span>\n <IconButton\n icon={isCopied ? <CheckLg aria-hidden /> : <ClipboardFill aria-hidden />}\n label={resolveFormatter('CodeBlock.copy', labels?.chat?.codeCopy, languageName)}\n size=\"sm\"\n onClick={copy}\n />\n </figcaption>\n\n <div\n className={styles.block__body}\n style={maxHeight === undefined ? undefined : { maxBlockSize: maxHeight }}\n /* Kayan kod klavyeyle ulaşılabilir (2.1.1). */\n tabIndex={0}\n /* Bölge ancak bir ADI varken bölge; adsız bir \"bölge\" ekran okuyucuda gürültü. */\n role={languageName ? 'region' : undefined}\n aria-label={languageName || undefined}\n >\n {html ? (\n <div className={styles.block__highlighted} dangerouslySetInnerHTML={{ __html: html }} />\n ) : (\n <pre className={styles.block__pre}>\n <code>\n {/* Düz parça da anahtar taşır: dizideki yalın dize React'te key uyarısı basar. */}\n {tokens.map((token, index) =>\n token.type ? (\n <span key={index} className={styles[`block__token--${token.type}`]}>\n {token.text}\n </span>\n ) : (\n <Fragment key={index}>{token.text}</Fragment>\n ),\n )}\n </code>\n </pre>\n )}\n </div>\n </figure>\n );\n};\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(CodeBlock, 'CodeBlock')) as typeof CodeBlock;\n","'use client';\n\nimport { type FC, memo, type ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Disclosure, Spinner } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Başlık — çağrı yerine ÖZGÜ (\"Düşündü · 3 araç · 2,4 sn\"), `labels`a girmez. */\n summary: ReactNode;\n /** Tur sürüyor: blok AÇIK durur ve gösterge döner. */\n isRunning?: boolean;\n /** Süren işin göstergesi; verilmezse `Spinner`. Marka yükleyicisi buraya geçer. */\n indicator?: ReactNode;\n /** Kapalı bir turda açılış durumu. */\n isDefaultOpen?: boolean;\n /** Gövde: `ReasoningText`, ara metinler, `ToolCall`lar. */\n children: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/**\n * \"Model ne yaptı\" bloğu — akıl yürütme, ara metinler, araç çağrıları.\n *\n * Tur sürerken AÇIK durur, bitince kapanır. ⚠ Kullanıcı bloğu elle açtıysa ya da kapattıysa o\n * tercihe DOKUNULMAZ: tur bittiğinde okuduğu bloğun elinden çekilmesi en sık şikâyetti.\n */\nconst ReasoningBlock: FC<Props> = ({\n summary,\n isRunning = false,\n indicator,\n isDefaultOpen = false,\n children,\n className,\n testId,\n}) => {\n const [isOpen, setIsOpen] = useState(isRunning || isDefaultOpen);\n const isTouched = useRef(false);\n\n useEffect(() => {\n if (!isTouched.current) setIsOpen(isRunning || isDefaultOpen);\n }, [isRunning, isDefaultOpen]);\n\n return (\n <Disclosure\n variant=\"plain\"\n className={cx(styles.block, className)}\n summary={\n <span className={styles.block__summary}>\n {isRunning && (\n <span className={styles.block__indicator}>{indicator ?? <Spinner size=\"sm\" />}</span>\n )}\n {summary}\n </span>\n }\n isOpen={isOpen}\n onOpenChange={next => {\n isTouched.current = true;\n setIsOpen(next);\n }}\n testId={testId}\n >\n <div className={styles.block__body}>{children}</div>\n </Disclosure>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ReasoningBlock, 'ReasoningBlock'),\n) as typeof ReasoningBlock;\n","import { type FC, memo } from 'react';\n\nimport { ScrollArea } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n text: string;\n /** Kaydırılabildiğinde bölgenin okunan adı (\"Akıl yürütme\"). */\n label: string;\n /** Kutunun tavanı (px); akan metin bu yükseklikte sona yapışık kayar. */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\n/** Akıl yürütme metni — yüksekliği sınırlı, akarken sona yapışık (`ScrollArea isFollowingEnd`). */\nconst ReasoningText: FC<Props> = ({ text, label, maxHeight = 180, className, testId }) => (\n <ScrollArea\n className={cx(styles.text, className)}\n label={label}\n maxHeight={maxHeight}\n hasFade\n isFollowingEnd\n testId={testId}\n >\n <p className={styles.text__body}>{text}</p>\n </ScrollArea>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ReasoningText, 'ReasoningText'),\n) as typeof ReasoningText;\n","'use client';\n\nimport { type FC, memo, type ReactNode } from 'react';\n\nimport { Disclosure, StatusDot, useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\nexport type ToolCallStatus = 'running' | 'ok' | 'error' | 'aborted' | 'interrupted';\n\ntype Props = {\n /** Aracın ikonu. */\n icon?: ReactNode;\n /** Aracın adı — çağrı yerine özgü (\"bash\", \"araştır\"). */\n name: string;\n /** Tek satırlık özet (komut, sorgu); teknik fontta, taşan kesilir. */\n summary?: string;\n status: ToolCallStatus;\n /** Sağdaki ikincil bilgi (süre). */\n meta?: ReactNode;\n isDefaultOpen?: boolean;\n /**\n * Kontrollü açılış — `onOpenChange` ile. Örn. çalışırken açık, bitince (kullanıcı dokunmadıysa)\n * kapalı bir terminal kartı.\n */\n isOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n /** Gövde — `ToolCallSection`lar. */\n children?: ReactNode;\n className?: string;\n testId?: string;\n};\n\nconst DOT_TONE = {\n running: 'neutral',\n ok: 'success',\n error: 'danger',\n aborted: 'warning',\n interrupted: 'danger',\n} as const;\n\n/**\n * Araç çağrısı kartı — ikon, ad, özet, durum noktası ve süre; açılınca bölümleri.\n *\n * Durum hem noktayla hem OKUNAN metinle bildirilir (`labels.chat.toolStatus`): renk tek başına\n * anlam taşımaz. Çalışan çağrının noktası nabız atar ve NÖTRDÜR — süren iş marka yüzeyi değil.\n */\nconst ToolCall: FC<Props> = ({\n icon,\n name,\n summary,\n status,\n meta,\n isDefaultOpen,\n isOpen,\n onOpenChange,\n children,\n className,\n testId,\n}) => {\n const { labels } = useHanui();\n const statusText = resolveLabel(`ToolCall.status.${status}`, labels?.chat?.toolStatus?.[status]);\n\n const header = (\n <span className={styles.call__header}>\n {icon !== undefined && (\n <span\n className={cx(styles.call__icon, status === 'running' && styles['call__icon--running'])}\n aria-hidden\n >\n {icon}\n </span>\n )}\n <span className={styles.call__name}>{name}</span>\n {summary !== undefined && <span className={styles.call__summary}>{summary}</span>}\n <StatusDot tone={DOT_TONE[status]} label={statusText} isPulsing={status === 'running'} />\n </span>\n );\n\n if (children === undefined)\n return (\n <div className={cx(styles.call, styles['call--static'], className)} data-testid={testId}>\n {header}\n {meta !== undefined && <span className={styles.call__meta}>{meta}</span>}\n </div>\n );\n\n return (\n <Disclosure\n className={cx(styles.call, className)}\n summary={header}\n meta={meta}\n isDefaultOpen={isDefaultOpen}\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n testId={testId}\n >\n <div className={styles.call__body}>{children}</div>\n </Disclosure>\n );\n};\n\ntype SectionProps = {\n /** Bölümün başlığı (\"Girdi\", \"Çıktı\", \"Hata\") — overline. */\n label: string;\n children: ReactNode;\n className?: string;\n};\n\n/** Araç çağrısının bir bölümü — başlık + gövde. */\nexport const ToolCallSection: FC<SectionProps> = ({ label, children, className }) => (\n /*\n * Başlık bir HEADING değil: sohbet akışında başlık düzeyi tüketicinin sayfasına bağlı ve sabit bir\n * `h4` hiyerarşiyi bozuyordu. Bölüm de bir landmark değil (her araç kartında bir \"bölge\" gürültü).\n */\n <div className={cx(styles.section, className)}>\n <span className={styles.section__label}>{label}</span>\n <div className={styles.section__body}>{children}</div>\n </div>\n);\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(ToolCall, 'ToolCall')) as typeof ToolCall;\n","'use client';\n\nimport { type FC, memo, useRef } from 'react';\n\nimport { useHanui, useStickToBottom } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\nexport type TerminalChunk = {\n stream: 'stdout' | 'stderr';\n text: string;\n};\n\ntype Props = {\n /** Çalıştırılan komut — `$` istemiyle ilk satırda. */\n command?: string;\n chunks: TerminalChunk[];\n /** Kaydırılabildiğinde bölgenin okunan adı (\"Komut çıktısı\"). */\n label: string;\n /** Gövdenin tavanı (px). */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\n/**\n * Terminal çıktısı — MÜREKKEP yüzey, iki temada da koyu (`shell*`). Akarken sona yapışık kalır.\n *\n * ⚠ stderr satırı renkten başka bir işaret de taşır: görsel olarak gizli bir önek\n * (`labels.chat.stderr`, \"hata çıktısı\"). Kırmızı tek başına anlam taşıyamaz (1.4.1).\n */\nconst TerminalOutput: FC<Props> = ({\n command,\n chunks,\n label,\n maxHeight = 300,\n className,\n testId,\n}) => {\n const { labels } = useHanui();\n const ref = useRef<HTMLPreElement>(null);\n useStickToBottom(ref);\n\n const stderrLabel = resolveLabel('TerminalOutput.stderr', labels?.chat?.stderr);\n\n return (\n <pre\n ref={ref}\n className={cx(styles.terminal, className)}\n style={{ maxBlockSize: maxHeight }}\n /* Kayan çıktı klavyeyle ulaşılabilir (2.1.1). */\n tabIndex={0}\n role=\"region\"\n aria-label={label}\n data-testid={testId}\n >\n {command !== undefined && (\n <span className={styles.terminal__command}>\n <span className={styles.terminal__prompt} aria-hidden>\n ${' '}\n </span>\n {command}\n {'\\n'}\n </span>\n )}\n {chunks.map((chunk, index) =>\n chunk.stream === 'stderr' ? (\n <span key={index} className={styles.terminal__stderr}>\n <span className={styles.terminal__srOnly}>{`${stderrLabel}: `}</span>\n {chunk.text}\n </span>\n ) : (\n <span key={index}>{chunk.text}</span>\n ),\n )}\n </pre>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(TerminalOutput, 'TerminalOutput'),\n) as typeof TerminalOutput;\n","'use client';\n\nimport { type FC, memo } from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\nexport type SourceItem = {\n id: string;\n title: string;\n /** Dış kaynak — yeni sekmede açılır. */\n url?: string;\n /** Kaynağın alan adı (\"tr.wikipedia.org\") — başlığın altında. */\n domain?: string;\n /** Uygulama içinde açılan kaynak (yan panel, kip pencere). `url` ile birlikte verilmez. */\n onSelect?: () => void;\n};\n\ntype Props = {\n items: SourceItem[];\n /** Listenin adı; verilmezse `labels.chat.sources`. */\n label?: string;\n className?: string;\n testId?: string;\n};\n\n/**\n * Yanıtın kaynakları — numaralı liste; numara yanıttaki `Citation` ile eşleşir.\n * Dış bağlantı yeni sekmede açılır ve `noopener` taşır; uygulama içi kaynak bir düğmedir.\n */\nconst SourceList: FC<Props> = ({ items, label, className, testId }) => {\n const { labels } = useHanui();\n\n return (\n <ol\n className={cx(styles.list, className)}\n aria-label={resolveLabel('SourceList.label', label, labels?.chat?.sources)}\n data-testid={testId}\n >\n {items.map((item, index) => (\n <li key={item.id} className={styles.list__item}>\n <span className={styles.list__index} aria-hidden>\n {index + 1}\n </span>\n <span className={styles.list__text}>\n {item.url ? (\n <a\n className={styles.list__title}\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {item.title}\n </a>\n ) : item.onSelect ? (\n <button type=\"button\" className={styles.list__title} onClick={item.onSelect}>\n {item.title}\n </button>\n ) : (\n <span className={styles.list__plain}>{item.title}</span>\n )}\n {item.domain && <span className={styles.list__domain}>{item.domain}</span>}\n </span>\n </li>\n ))}\n </ol>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(SourceList, 'SourceList'),\n) as typeof SourceList;\n","'use client';\n\nimport { type FC, memo } from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveFormatter } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Kaynağın numarası — `SourceList`teki sırayla eşleşir (1'den başlar). */\n index: number;\n href?: string;\n onClick?: () => void;\n className?: string;\n};\n\n/**\n * Metin içi atıf — \"[3]\". Okunan adı `labels.chat.citation(3)` (\"Kaynak 3\"): görünen rakam tek\n * başına ekran okuyucuda \"üç\" diye, bağlamsız okunuyordu.\n */\nconst Citation: FC<Props> = ({ index, href, onClick, className }) => {\n const { labels } = useHanui();\n const name = resolveFormatter('Citation.label', labels?.chat?.citation, index);\n\n if (href)\n return (\n <a className={cx(styles.citation, className)} href={href} aria-label={name}>\n {index}\n </a>\n );\n\n if (onClick)\n return (\n <button\n type=\"button\"\n className={cx(styles.citation, className)}\n onClick={onClick}\n aria-label={name}\n >\n {index}\n </button>\n );\n\n /* Etkileşimsiz: rolü olmayan öğeye `aria-label` verilemez — ad gizli metin, rakam görsel. */\n return (\n <span className={cx(styles.citation, styles['citation--static'], className)}>\n <span aria-hidden>{index}</span>\n <span className={styles.citation__srOnly}>{name}</span>\n </span>\n );\n};\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(Citation, 'Citation')) as typeof Citation;\n","'use client';\n\nimport { type FC, type KeyboardEvent, memo, type ReactNode, useRef } from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport { resolveLabel } from '../../helpers/label.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** `IconButton` / `Button size={UISize.XSMALL}` öğeleri. */\n children: ReactNode;\n /** Araç çubuğunun sonunda duran okunan bilgi (süre, belirteç, maliyet). */\n meta?: ReactNode;\n /** Araç çubuğunun adı; verilmezse `labels.chat.messageActions`. */\n label?: string;\n className?: string;\n testId?: string;\n};\n\nconst FOCUSABLE = 'button:not(:disabled), a[href]';\n\n/**\n * Mesajın eylem çubuğu — kopyala, yeniden dene, ayrıntı.\n *\n * Klavye (`role=\"toolbar\"`, tek sekme durağı değil — her düğme sekme sırasında kalır):\n * `ArrowRight` / `ArrowLeft` sonraki / önceki eylem · `Home` / `End` ilk / son.\n * ⚠ Satır içi araç çubuğu: ok tuşu yalnızca odak ÇUBUKTAYKEN çalışır, sayfayı kaydırmaz.\n */\nconst MessageActions: FC<Props> = ({ children, meta, label, className, testId }) => {\n const { labels } = useHanui();\n const ref = useRef<HTMLDivElement>(null);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const items = [...(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])];\n const index = items.indexOf(document.activeElement as HTMLElement);\n if (index < 0 || items.length === 0) return;\n\n const isRtl = getComputedStyle(event.currentTarget).direction === 'rtl';\n const next = isRtl ? 'ArrowLeft' : 'ArrowRight';\n const previous = isRtl ? 'ArrowRight' : 'ArrowLeft';\n\n const target =\n event.key === next\n ? items[(index + 1) % items.length]\n : event.key === previous\n ? items[(index - 1 + items.length) % items.length]\n : event.key === 'Home'\n ? items[0]\n : event.key === 'End'\n ? items[items.length - 1]\n : null;\n\n if (!target) return;\n event.preventDefault();\n target.focus();\n };\n\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n aria-label={resolveLabel('MessageActions.label', label, labels?.chat?.messageActions)}\n className={cx(styles.actions, className)}\n onKeyDown={handleKeyDown}\n data-testid={testId}\n >\n {children}\n {meta !== undefined && <span className={styles.actions__meta}>{meta}</span>}\n </div>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(MessageActions, 'MessageActions'),\n) as typeof MessageActions;\n","'use client';\n\nimport { type FC, memo, type ReactNode, useEffect, useRef } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Sol baştaki marka (logo + ad). */\n brand: ReactNode;\n /** Markanın yanında, esneyen orta bölge (model, bağlantı durumu). */\n start?: ReactNode;\n /** Sağdaki eylem kümesi. */\n end?: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/** Belgeye yazılan değişken — yapışkan bileşenler (`DirectoryGroup`, kapaklı `DataTable`) bunu okur. */\nconst HEIGHT_VARIABLE = '--hanui-header-height';\n\n/**\n * Uygulamanın üst bandı — sayfaya yapışık, sayfanın devamı (bant sayfayı ÖRTMEZ: `nav-*`).\n *\n * Kendi yüksekliğini ölçüp `--hanui-header-height`e yazar. README bu `ResizeObserver` kodunu her\n * tüketiciye elle yazdırıyordu; sabit bir sayı yazan da vardı ve bant mobilde iki satıra düştüğünde\n * yapışkan başlıklar altında kalıyordu.\n */\nconst AppBar: FC<Props> = ({ brand, start, end, className, testId }) => {\n const ref = useRef<HTMLElement>(null);\n\n useEffect(() => {\n const node = ref.current;\n if (!node || typeof ResizeObserver === 'undefined') return;\n\n const root = document.documentElement;\n const observer = new ResizeObserver(([entry]) =>\n root.style.setProperty(\n HEIGHT_VARIABLE,\n `${Math.round(entry.borderBoxSize?.[0]?.blockSize ?? node.offsetHeight)}px`,\n ),\n );\n observer.observe(node);\n\n return () => {\n observer.disconnect();\n root.style.removeProperty(HEIGHT_VARIABLE);\n };\n }, []);\n\n return (\n <header ref={ref} className={cx(styles.bar, className)} data-testid={testId}>\n <div className={styles.bar__brand}>{brand}</div>\n {start !== undefined && <div className={styles.bar__start}>{start}</div>}\n {end !== undefined && <div className={styles.bar__end}>{end}</div>}\n </header>\n );\n};\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(AppBar, 'AppBar')) as typeof AppBar;\n","'use client';\n\nimport {\n Children,\n cloneElement,\n type FC,\n isValidElement,\n memo,\n type ReactElement,\n type ReactNode,\n useState,\n} from 'react';\n\nimport { useHanui } from '@ahmetilhn/hanui';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\n/** Sanal pencerenin üstüne ve altına fazladan çizilen satır sayısı — hızlı kaydırmada boşluk görünmesin. */\nconst OVERSCAN = 6;\n\ntype ListProps = {\n /** Listenin erişilebilir adı (\"Bağlam haritası\"). */\n label: string;\n /** `ActionListItem` öğeleri. */\n children: ReactNode;\n /**\n * Verilirse liste SANALLAŞTIRILIR: yalnızca görünen satırlar çizilir. Satır yüksekliği SABİT\n * olmalı (px).\n */\n rowHeight?: number;\n /** Sanal listede görünen alanın yüksekliği (px). */\n maxHeight?: number;\n className?: string;\n testId?: string;\n};\n\ntype ItemProps = {\n children: ReactNode;\n /** Satırın başında duran öğe (kimlik, ikon). */\n start?: ReactNode;\n /** Satırın sonunda duran öğe (tur numarası, süre). */\n end?: ReactNode;\n onClick?: () => void;\n href?: string;\n /** Verilirse satır bir SEÇİMDİR (`aria-pressed`); verilmezse düz bir eylem. */\n isSelected?: boolean;\n /** Geri planda kalan satır (gizlenmiş, eski) — renkle, saydamlıkla değil. */\n isMuted?: boolean;\n testId?: string;\n /** Sanal listenin kendisi yazar: satırın gerçek konumu ve listenin gerçek boyu. */\n 'aria-posinset'?: number;\n 'aria-setsize'?: number;\n};\n\n/**\n * Çerçeveli satır listesi — her satır bir EYLEM (açar, gider) ya da bir SEÇİM (ayrıntıyı gösterir).\n *\n * ⚠ Seçim mi eylem mi satır başına `isSelected` ile söylenir: verilirse satır bir aç/kapa düğmesidir\n * (`aria-pressed`), verilmezse düz bir eylem. Eylemi seçim gibi sunmak kalıcı bir durum vaat ediyordu.\n * ⚠ Sanal listede ekran okuyucu yalnızca çizilen satırları görür; gerçek konumu `aria-posinset` /\n * `aria-setsize` söyler.\n */\nconst ActionList: FC<ListProps> = ({\n label,\n children,\n rowHeight,\n maxHeight = 320,\n className,\n testId,\n}) => {\n const items = Children.toArray(children).filter(isValidElement) as ReactElement<ItemProps>[];\n const [scrollTop, setScrollTop] = useState(0);\n\n if (!rowHeight)\n return (\n <ul className={cx(styles.list, className)} aria-label={label} data-testid={testId}>\n {items}\n </ul>\n );\n\n const start = Math.max(0, Math.floor(scrollTop / rowHeight) - OVERSCAN);\n const end = Math.min(items.length, Math.ceil((scrollTop + maxHeight) / rowHeight) + OVERSCAN);\n\n return (\n <div\n className={cx(styles.list, styles['list--virtual'], className)}\n style={{ maxBlockSize: maxHeight, ['--hanui-row-height' as string]: `${rowHeight}px` }}\n onScroll={event => setScrollTop(event.currentTarget.scrollTop)}\n data-testid={testId}\n >\n <ul\n aria-label={label}\n className={styles.list__window}\n style={{\n blockSize: items.length * rowHeight,\n paddingBlockStart: start * rowHeight,\n }}\n >\n {items.slice(start, end).map((item, index) =>\n cloneElement(item, {\n 'aria-posinset': start + index + 1,\n 'aria-setsize': items.length,\n }),\n )}\n </ul>\n </div>\n );\n};\n\n/** `ActionList` satırı — kendi `li`sini taşır. */\nexport const ActionListItem: FC<ItemProps> = ({\n children,\n start,\n end,\n onClick,\n href,\n isSelected,\n isMuted,\n testId,\n 'aria-posinset': position,\n 'aria-setsize': setSize,\n}) => {\n const { linkComponent: LinkComponent } = useHanui();\n\n const className = cx(\n styles.item,\n isSelected && styles['item--selected'],\n isMuted && styles['item--muted'],\n );\n const content = (\n <>\n {start !== undefined && <span className={styles.item__start}>{start}</span>}\n <span className={styles.item__body}>{children}</span>\n {end !== undefined && <span className={styles.item__end}>{end}</span>}\n </>\n );\n\n const Anchor = LinkComponent ?? 'a';\n\n return (\n <li className={styles.list__slot} aria-posinset={position} aria-setsize={setSize}>\n {href ? (\n <Anchor href={href} className={className} data-testid={testId}>\n {content}\n </Anchor>\n ) : (\n <button\n type=\"button\"\n className={className}\n onClick={onClick}\n aria-pressed={isSelected}\n data-testid={testId}\n >\n {content}\n </button>\n )}\n </li>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(ActionList, 'ActionList'),\n) as typeof ActionList;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\nimport type { LegendTone } from '../Legend';\n\nimport styles from './index.module.scss';\n\nexport type SegmentBarSegment = {\n id: string;\n /** Parçanın okunan adı, değeriyle: \"Önek · 12,4 B\". Özet adın parçası olur. */\n label: string;\n tone: LegendTone;\n} & (\n | {\n /** Yığılmış çubukta parçanın büyüklüğü — parçalar sırayla dizilir. */\n value: number;\n from?: never;\n to?: never;\n }\n | {\n /** Zaman çizelgesinde parçanın başlangıcı ve bitişi (aynı ölçekte). */\n from: number;\n to: number;\n value?: never;\n }\n);\n\nexport type SegmentBarMarker = {\n id: string;\n /** Konum, `max` ile aynı ölçekte. */\n at: number;\n label: string;\n tone?: 'neutral' | 'danger';\n};\n\ntype Props = {\n /** Grafiğin adı (\"Bağlam bileşimi\"); parçaların ve işaretlerin adlarıyla birlikte okunur. */\n label: string;\n /** Ölçeğin tavanı. */\n max: number;\n segments: SegmentBarSegment[];\n /** Dikey çizgi işaretleri — bütçe sınırı, hedef. */\n markers?: SegmentBarMarker[];\n className?: string;\n testId?: string;\n};\n\nconst percent = (value: number, max: number): number =>\n max <= 0 ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n\nconst swatch = (tone: LegendTone): string =>\n tone === 'muted' ? 'var(--hanui-text-3)' : `var(--hanui-${tone})`;\n\n/**\n * Parçalı çubuk — yığılmış bileşim (`value`) ya da zaman çizelgesi (`from`/`to`).\n *\n * Erişilebilirlik: çubuk TEK bir görseldir (`role=\"img\"`); adı grafiğin adı + her parçanın ve\n * işaretin okunan adıdır. Parça başına odaklanılabilir öğe çizilmez — bir çubuğun içinde sekme\n * durağı dizmek, okunan özetten daha az bilgi verip daha çok tuş istiyordu.\n */\nconst SegmentBar: FC<Props> = ({ label, max, segments, markers = [], className, testId }) => {\n const summary = [\n ...segments.map(segment => segment.label),\n ...markers.map(marker => marker.label),\n ];\n let cursor = 0;\n\n return (\n <div\n role=\"img\"\n aria-label={`${label}: ${summary.join(', ')}`}\n className={cx(styles.bar, className)}\n data-testid={testId}\n >\n {segments.map(segment => {\n const start = segment.from ?? cursor;\n const end = segment.to ?? start + (segment.value ?? 0);\n cursor = end;\n\n return (\n <span\n key={segment.id}\n className={styles.bar__segment}\n title={segment.label}\n style={{\n insetInlineStart: `${percent(start, max)}%`,\n inlineSize: `${percent(end, max) - percent(start, max)}%`,\n backgroundColor: swatch(segment.tone),\n }}\n />\n );\n })}\n\n {markers.map(marker => (\n <span\n key={marker.id}\n className={cx(\n styles.bar__marker,\n marker.tone === 'danger' && styles['bar__marker--danger'],\n )}\n title={marker.label}\n style={{ insetInlineStart: `${percent(marker.at, max)}%` }}\n />\n ))}\n </div>\n );\n};\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(SegmentBar, 'SegmentBar'),\n) as typeof SegmentBar;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\n/** Kategorik paletin adları (`cat-*`, `series-*`) + bekleme/boşluk için `muted`. */\nexport type LegendTone =\n 'cat-1' | 'cat-2' | 'cat-3' | 'cat-4' | 'cat-5' | 'series-1' | 'series-2' | 'muted';\n\nexport type LegendItem = {\n id: string;\n label: string;\n tone: LegendTone;\n};\n\ntype Props = {\n items: LegendItem[];\n className?: string;\n testId?: string;\n};\n\nconst swatchColor = (tone: LegendTone): string =>\n tone === 'muted' ? 'var(--hanui-text-3)' : `var(--hanui-${tone})`;\n\n/**\n * Grafik lejantı — renk karesi + ad. Renk yalnızca kategorik paletten gelir (iki temanın üç\n * yüzeyinde ≥3:1); ad her zaman metin olarak yazılır, renk tek başına anlam taşımaz.\n */\nconst Legend: FC<Props> = ({ items, className, testId }) => (\n <ul className={cx(styles.legend, className)} data-testid={testId}>\n {items.map(item => (\n <li key={item.id} className={styles.legend__item}>\n <span\n aria-hidden\n className={styles.legend__swatch}\n style={{ backgroundColor: swatchColor(item.tone) }}\n />\n {item.label}\n </li>\n ))}\n </ul>\n);\n\nexport default /*#__PURE__*/ memo(/*#__PURE__*/ named(Legend, 'Legend')) as typeof Legend;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { named } from '../../helpers/component.helper';\n\nimport styles from './index.module.scss';\n\nexport type DescriptionItem = {\n term: ReactNode;\n description: ReactNode;\n /** Değer teknik bir kimlik (kod, yol, karma): teknik fontta ve satır içinde bölünebilir. */\n isTechnical?: boolean;\n};\n\ntype Props = {\n items: DescriptionItem[];\n className?: string;\n testId?: string;\n};\n\n/** Terim–değer listesi — yerel `<dl>`; ekran okuyucu terimi değeriyle birlikte okur. */\nconst DescriptionList: FC<Props> = ({ items, className, testId }) => (\n <dl className={cx(styles.list, className)} data-testid={testId}>\n {items.map((item, index) => (\n <div key={index} className={styles.list__row}>\n <dt className={styles.list__term}>{item.term}</dt>\n <dd\n className={cx(styles.list__value, item.isTechnical && styles['list__value--technical'])}\n >\n {item.description}\n </dd>\n </div>\n ))}\n </dl>\n);\n\nexport default /*#__PURE__*/ memo(\n /*#__PURE__*/ named(DescriptionList, 'DescriptionList'),\n) as typeof DescriptionList;\n"],"names":["cx","values","result","value","named","component","displayName","warned","resolveLabel","key","resolveFormatter","formatter","args","ChatThread","children","dock","isStreaming","label","className","testId","labels","useHanui","announce","useAnnounce","scrollRef","useRef","isAtEnd","scrollToEnd","useStickToBottom","wasStreaming","useEffect","_a","jsxs","styles","jsx","_b","IconButton","ArrowDown","_c","index$h","memo","ChatMessage","author","avatar","actions","index$g","PromptInput","forwardRef","onChange","onSubmit","onStop","isBusy","isDisabled","isSubmitDisabled","placeholder","maxRows","hint","start","end","ref","isEmpty","handleKeyDown","event","hasOpenSurface","Textarea","StopFill","ArrowUp","index$f","PromptSuggestions","items","onPick","item","index$e","Prose","rest","index$d","LEADING_BLANK_LINES","INDENT","isJson","language","endOfString","text","cursor","nextSignificant","formatJson","output","depth","newline","character","next","formatCode","code","trimmed","words","list","DQ","SQ","BACKTICK","TRIPLE_DQ","TRIPLE_SQ","CHAR","SLASH_COMMENT","BLOCK_COMMENT","HASH_COMMENT","NUMBER","WORD","PUNCTUATION","DECORATOR","AFTER_WORD","AFTER_NON_SPACE","JS_KEYWORDS","TS_KEYWORDS","JS_LITERALS","TS_TYPES","C_TYPES","C_LITERALS","C_KEYWORDS","CPP_KEYWORDS","CSHARP_KEYWORDS","JAVA_KEYWORDS","KOTLIN_KEYWORDS","SWIFT_KEYWORDS","GO_KEYWORDS","RUST_KEYWORDS","PHP_KEYWORDS","BASH_KEYWORDS","DOCKER_KEYWORDS","javascript","isTyped","hasJsx","cFamily","keywords","extra","python","ruby","bash","json","yaml","toml","css","markup","markdown","sql","diff","graphql","MARKUP_TAG","JS","JSX","TS","TSX","BASH","DOCKER","C","CPP","CSHARP","KOTLIN","GO","RUST","PHP","GRAMMARS","HIGHLIGHT_LIMIT","CALL","CONSTANT","REGEX_AFTER","REGEX_AFTER_WORD","cache","compile","factory","known","grammar","compiled","rule","grammarOf","isRegexStart","index","classify","word","isCall","tokenize","pattern","tokens","push","type","last","match","kind","reject","open","name","token","highlight","COPIED_FOR","CodeBlock","html","maxHeight","isCopied","setIsCopied","useState","timer","source","useMemo","copy","languageName","CheckLg","ClipboardFill","Fragment","index$c","ReasoningBlock","summary","isRunning","indicator","isDefaultOpen","isOpen","setIsOpen","isTouched","Disclosure","Spinner","index$b","ReasoningText","ScrollArea","index$a","DOT_TONE","ToolCall","icon","status","meta","onOpenChange","statusText","header","StatusDot","ToolCallSection","index$9","TerminalOutput","command","chunks","stderrLabel","chunk","index$8","SourceList","index$7","Citation","href","onClick","index$6","FOCUSABLE","MessageActions","isRtl","previous","target","index$5","HEIGHT_VARIABLE","AppBar","brand","node","root","observer","entry","index$4","OVERSCAN","ActionList","rowHeight","Children","isValidElement","scrollTop","setScrollTop","cloneElement","ActionListItem","isSelected","isMuted","position","setSize","LinkComponent","content","Anchor","index$3","percent","max","swatch","tone","SegmentBar","segments","markers","segment","marker","index$2","swatchColor","Legend","index$1","DescriptionList"],"mappings":"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"}
package/build/chat.css CHANGED
@@ -1 +1 @@
1
- @layer hanui{.hanui-thread-R1LCJ{position:relative;display:grid;grid-template-rows:minmax(0,1fr) auto;height:100%;min-height:0}.hanui-thread__scroll-37EaI{position:relative;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-thread__scroll-37EaI::-webkit-scrollbar{width:8px;height:8px}.hanui-thread__scroll-37EaI::-webkit-scrollbar-track{background:transparent}.hanui-thread__scroll-37EaI::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-thread__scroll-37EaI::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-thread__scroll-37EaI:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:-2px}.hanui-thread__column-57FQh{display:flex;flex-direction:column;gap:var(--hanui-space-6);width:100%;max-width:768px;margin-inline:auto;padding:var(--hanui-space-6) var(--hanui-space-5)}@media (max-width: 640px){.hanui-thread__column-57FQh{padding:var(--hanui-space-5) var(--hanui-space-4)}}.hanui-thread__dock-y0Tt9 .hanui-thread__column-57FQh{gap:var(--hanui-space-2);padding-block:0 calc(var(--hanui-space-4) + env(safe-area-inset-bottom,0px))}.hanui-thread__dock-y0Tt9{position:relative;padding-top:var(--hanui-space-3);background:linear-gradient(to bottom,transparent,var(--hanui-page) var(--hanui-space-5))}.hanui-thread__latest-ZNmqY{position:absolute;inset-block-start:calc(-1 * var(--hanui-space-8));inset-inline:0;margin-inline:auto;box-shadow:var(--hanui-shadow-md);background-color:var(--hanui-surface)}}@layer hanui{.hanui-message-z5uVx{display:flex;gap:var(--hanui-space-3);width:100%}.hanui-message--user-Mq6gb{justify-content:flex-end}.hanui-message__avatar-QzWck{flex-shrink:0;margin-top:2px}.hanui-message__main-1rh-A{display:flex;flex-direction:column;gap:var(--hanui-space-2);min-width:0}.hanui-message--assistant-ndkmH .hanui-message__main-1rh-A{flex:1}.hanui-message--user-Mq6gb .hanui-message__main-1rh-A{align-items:flex-end;max-width:min(85%,640px)}.hanui-message__body-Ngiqq{min-width:0}.hanui-message--user-Mq6gb .hanui-message__body-Ngiqq{padding:var(--hanui-space-3) var(--hanui-space-4);border-radius:var(--hanui-radius-xl);border-end-end-radius:var(--hanui-radius-sm);background-color:var(--hanui-surface-2);color:var(--hanui-text);font-size:var(--hanui-font-size-body);line-height:var(--hanui-leading-normal);white-space:pre-wrap;overflow-wrap:anywhere}.hanui-message__actions-dQ0Fn{color:var(--hanui-text-3);transition:color var(--hanui-duration-fast) var(--hanui-ease-out)}.hanui-message-z5uVx:hover .hanui-message__actions-dQ0Fn,.hanui-message-z5uVx:focus-within .hanui-message__actions-dQ0Fn{color:var(--hanui-text-2)}@media (prefers-reduced-motion: reduce){.hanui-message__actions-dQ0Fn{transition:none}}}@layer hanui{.hanui-prompt-qHV1e{display:flex;flex-direction:column;gap:var(--hanui-space-2);width:100%}.hanui-prompt__box-sUQDu{display:flex;align-items:flex-end;gap:var(--hanui-space-2);padding:var(--hanui-space-2) var(--hanui-space-2) var(--hanui-space-2) var(--hanui-space-4);border:1px solid var(--hanui-border-strong);border-radius:var(--hanui-radius-xl);background-color:var(--hanui-surface);box-shadow:var(--hanui-shadow-sm);transition:border-color var(--hanui-duration-fast) var(--hanui-ease-out),box-shadow var(--hanui-duration-fast) var(--hanui-ease-out)}.hanui-prompt__box-sUQDu:focus-within{border-color:var(--hanui-ring-color);box-shadow:var(--hanui-ring)}.hanui-prompt__box--disabled-xu-Yk{background-color:var(--hanui-surface-2);border-color:var(--hanui-border);cursor:not-allowed;color:var(--hanui-text-3)}@media (forced-colors: active){.hanui-prompt__box--disabled-xu-Yk{color:GrayText;border-color:GrayText}}.hanui-prompt__box--disabled-xu-Yk{box-shadow:none}@media (prefers-reduced-motion: reduce){.hanui-prompt__box-sUQDu{transition:none}}.hanui-prompt__field-EmvTZ{flex:1;min-width:0;padding-block:9px}.hanui-prompt__start-2tqre,.hanui-prompt__end-Zp7fi{display:flex;align-items:center;gap:var(--hanui-space-1);flex-shrink:0;min-height:40px}.hanui-prompt__hint-4TpeC{text-align:center;font-size:var(--hanui-font-size-2xs);color:var(--hanui-text-3)}}@layer hanui{.hanui-grid-4EfQ-{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(220px,100%),1fr));gap:var(--hanui-space-2);width:100%}.hanui-card-KTt0-{display:flex;flex-direction:column;gap:2px;min-height:44px;padding:var(--hanui-space-3) var(--hanui-space-4);border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-lg);color:var(--hanui-text);font:inherit;text-align:start;cursor:pointer;background-color:var(--hanui-surface);transition:background-color var(--hanui-duration-fast) var(--hanui-ease-out),translate var(--hanui-duration-instant) var(--hanui-ease-out)}.hanui-card-KTt0-:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-2)}.hanui-card-KTt0-:active:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-3);translate:0 1px}@media (prefers-reduced-motion: reduce){.hanui-card-KTt0-{transition:none}.hanui-card-KTt0-:active:not(:disabled):not([aria-disabled=true]){translate:none}}.hanui-card-KTt0-:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-card__label-LNLTF{font-size:var(--hanui-font-size-sm);font-weight:500}.hanui-card__description-eIx-0{font-size:var(--hanui-font-size-xs);color:var(--hanui-text-2)}}@layer hanui{.hanui-prose-kAp6f{font-size:var(--hanui-font-size-body);line-height:var(--hanui-leading-normal);color:var(--hanui-text);overflow-wrap:break-word}.hanui-prose-kAp6f>:first-child{margin-top:0}.hanui-prose-kAp6f>:last-child{margin-bottom:0}.hanui-prose-kAp6f h1,.hanui-prose-kAp6f h2,.hanui-prose-kAp6f h3,.hanui-prose-kAp6f h4{margin:1.4em 0 .5em;font-family:var(--hanui-font-heading);font-weight:600;line-height:var(--hanui-leading-snug);color:var(--hanui-text)}.hanui-prose-kAp6f h1{font-size:var(--hanui-font-size-xl);letter-spacing:-.011em}.hanui-prose-kAp6f h2{font-size:var(--hanui-font-size-lg)}.hanui-prose-kAp6f h3,.hanui-prose-kAp6f h4{font-size:var(--hanui-font-size-base)}.hanui-prose-kAp6f p{margin:.65em 0}.hanui-prose-kAp6f ul,.hanui-prose-kAp6f ol{margin:.65em 0;padding-inline-start:1.4em}.hanui-prose-kAp6f li+li{margin-top:.25em}.hanui-prose-kAp6f a{color:var(--hanui-link);text-decoration:underline;text-underline-offset:2px}.hanui-prose-kAp6f a:hover{color:var(--hanui-link-hover)}.hanui-prose-kAp6f a:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-prose-kAp6f blockquote{margin:.9em 0;padding-inline-start:var(--hanui-space-4);border-inline-start:3px solid var(--hanui-border-strong);color:var(--hanui-text-2)}.hanui-prose-kAp6f hr{margin:1.4em 0;border:0;border-top:1px solid var(--hanui-border)}.hanui-prose-kAp6f :not(pre)>code{font-family:var(--hanui-font-mono);font-size:.88em;letter-spacing:.02em;font-variant-numeric:tabular-nums;padding:1px 5px;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-xs);background-color:var(--hanui-surface-2)}.hanui-prose-kAp6f table{display:block;max-width:100%;margin:.9em 0;position:relative;overflow-x:auto;border-collapse:collapse;font-size:var(--hanui-font-size-sm)}.hanui-prose-kAp6f th,.hanui-prose-kAp6f td{padding:var(--hanui-space-2) var(--hanui-space-3);border:1px solid var(--hanui-border);text-align:start;vertical-align:top}.hanui-prose-kAp6f th{background-color:var(--hanui-surface-2);font-weight:600}.hanui-prose-kAp6f .katex-display{margin:.9em 0;position:relative;overflow-x:auto;overflow-y:hidden}}@layer hanui{.hanui-block-M1yL9{margin:.9em 0;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-lg);background-color:var(--hanui-surface-inset);overflow:hidden}.hanui-block__header-F2iBP{display:flex;align-items:center;justify-content:space-between;gap:var(--hanui-space-2);min-height:36px;padding-inline:var(--hanui-space-3) var(--hanui-space-1);border-bottom:1px solid var(--hanui-border);background-color:var(--hanui-surface-2)}.hanui-block__language-lmdS9{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-2xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;color:var(--hanui-text-2);text-transform:lowercase}.hanui-block__body-wDCJ2{position:relative;overflow:auto;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-block__body-wDCJ2::-webkit-scrollbar{width:8px;height:8px}.hanui-block__body-wDCJ2::-webkit-scrollbar-track{background:transparent}.hanui-block__body-wDCJ2::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-block__body-wDCJ2::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-block__body-wDCJ2:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:-2px}.hanui-block__pre--EERi,.hanui-block__highlighted-JK1Yj pre{margin:0;padding:var(--hanui-space-3) var(--hanui-space-4);background:transparent!important;font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);line-height:var(--hanui-leading-relaxed);white-space:pre;-moz-tab-size:2;tab-size:2}.hanui-block__highlighted-JK1Yj span{color:var(--shiki-light)}:root[data-hanui-theme=dark] .hanui-block__highlighted-JK1Yj span{color:var(--shiki-dark)}@media (prefers-color-scheme: dark){:root:not([data-hanui-theme]) .hanui-block__highlighted-JK1Yj span{color:var(--shiki-dark)}}}@layer hanui{.hanui-block-zqPjp summary{padding:var(--hanui-space-1) var(--hanui-space-2);margin-inline-start:calc(-1 * var(--hanui-space-2));border-radius:var(--hanui-radius-md);font-weight:500;color:var(--hanui-text-2)}.hanui-block__summary-Kkp-X{display:inline-flex;align-items:center;gap:var(--hanui-space-2)}.hanui-block__indicator-GuJMa{display:inline-flex;color:var(--hanui-text-2)}.hanui-block__body-mDvrV{display:flex;flex-direction:column;gap:var(--hanui-space-3);margin-top:var(--hanui-space-2);padding-inline-start:var(--hanui-space-4);border-inline-start:2px solid var(--hanui-border);color:var(--hanui-text-2)}}@layer hanui{.hanui-text-WKVxU{font-size:var(--hanui-font-size-sm);line-height:var(--hanui-leading-normal);color:var(--hanui-text-2)}.hanui-text__body--uP0k{margin:0;white-space:pre-wrap;overflow-wrap:anywhere}}@layer hanui{.hanui-call-tV2P8{border-radius:var(--hanui-radius-md);font-size:var(--hanui-font-size-sm)}.hanui-call-tV2P8 summary{padding:var(--hanui-space-2) var(--hanui-space-3);font-weight:400}.hanui-call--static-Nldru{display:flex;align-items:center;gap:var(--hanui-space-3);padding:var(--hanui-space-2) var(--hanui-space-3);border:1px solid var(--hanui-border);background-color:var(--hanui-surface)}.hanui-call__header-8Tw7m{display:flex;align-items:center;gap:var(--hanui-space-2);min-width:0}.hanui-call__icon-TLzwf{display:inline-flex;flex-shrink:0;font-size:var(--hanui-icon-sm);color:var(--hanui-text-3)}.hanui-call__icon--running-Mx1XK{color:var(--hanui-text)}.hanui-call__name-EHz6G{flex-shrink:0;font-weight:600;color:var(--hanui-text)}.hanui-call__summary-M4sLU{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;flex:1;min-width:0;color:var(--hanui-text-2)}.hanui-call__meta-bvpp7{flex-shrink:0;margin-inline-start:auto;font-size:var(--hanui-font-size-xs);color:var(--hanui-text-3);font-variant-numeric:tabular-nums}.hanui-call__body-nFK-C{display:flex;flex-direction:column;gap:var(--hanui-space-3)}.hanui-section-TjSGF{display:flex;flex-direction:column;gap:var(--hanui-space-1);min-width:0}.hanui-section__label-UrgqM{font-family:var(--hanui-font-body);font-size:var(--hanui-font-size-2xs);font-weight:600;letter-spacing:.045em;text-transform:uppercase;color:var(--hanui-text-2);margin:0}.hanui-section__body-Dy1PX{min-width:0;color:var(--hanui-text)}}@layer hanui{.hanui-terminal-D4Bz8{margin:0;padding:var(--hanui-space-3) var(--hanui-space-4);border:1px solid var(--hanui-shell-line);border-radius:var(--hanui-radius-md);background-color:var(--hanui-shell);color:var(--hanui-on-shell);font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);line-height:var(--hanui-leading-relaxed);white-space:pre-wrap;overflow-wrap:anywhere;position:relative;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-terminal-D4Bz8::-webkit-scrollbar{width:8px;height:8px}.hanui-terminal-D4Bz8::-webkit-scrollbar-track{background:transparent}.hanui-terminal-D4Bz8::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-terminal-D4Bz8::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-terminal-D4Bz8:focus-visible{outline:2px solid var(--hanui-on-shell);outline-offset:-2px}.hanui-terminal__command-A7PG2{color:var(--hanui-on-shell);font-weight:600}.hanui-terminal__prompt-9N1g2{color:var(--hanui-on-shell-2)}.hanui-terminal__stderr-qCNFe{color:var(--hanui-on-shell-danger)}.hanui-terminal__srOnly-2pmQA{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}}@layer hanui{.hanui-list-GC4NK{display:flex;flex-direction:column;gap:var(--hanui-space-2);margin:0;padding:0;list-style:none;font-size:var(--hanui-font-size-sm)}.hanui-list__item-N8DAn{display:flex;align-items:baseline;gap:var(--hanui-space-2)}.hanui-list__index-VrSMs{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-2xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;flex-shrink:0;min-width:18px;padding:1px 4px;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-xs);text-align:center;color:var(--hanui-text-2)}.hanui-list__text-4tll-{display:flex;flex-direction:column;min-width:0}.hanui-list__title-seHfJ{padding:0;border:0;background:none;color:var(--hanui-link);font:inherit;text-align:start;text-decoration:underline;text-underline-offset:2px;overflow-wrap:anywhere;cursor:pointer}.hanui-list__title-seHfJ:hover{color:var(--hanui-link-hover)}.hanui-list__title-seHfJ:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-list__plain-ZcCvx{color:var(--hanui-text);overflow-wrap:anywhere}.hanui-list__domain-sJLI7{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--hanui-font-size-xs);color:var(--hanui-text-3)}}@layer hanui{.hanui-citation-XrGMb{position:relative}.hanui-citation-XrGMb:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:max(100%,44px);height:max(100%,44px)}.hanui-citation-XrGMb{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-2xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;justify-content:center;min-width:18px;margin-inline:2px;padding:0 4px;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-xs);background-color:var(--hanui-surface-2);color:var(--hanui-link);line-height:1.5;vertical-align:super;text-decoration:none;cursor:pointer}.hanui-citation-XrGMb:hover{background-color:var(--hanui-surface-3)}.hanui-citation-XrGMb:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-citation__srOnly-GnMQp{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hanui-citation--static-8gXHs{color:var(--hanui-text-2);cursor:default}.hanui-citation--static-8gXHs:hover{background-color:var(--hanui-surface-2)}}@layer hanui{.hanui-actions-c8XlJ{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hanui-space-1);color:var(--hanui-text-3);font-size:var(--hanui-font-size-xs)}.hanui-actions__meta-j-X3I{margin-inline-start:var(--hanui-space-2);font-variant-numeric:tabular-nums}}@layer hanui{.hanui-bar-UJGDL{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:var(--hanui-space-3);min-height:56px;padding:var(--hanui-space-2) var(--hanui-space-5);border-bottom:1px solid var(--hanui-nav-line);background-color:var(--hanui-nav-bg);color:var(--hanui-nav-fg)}@media (max-width: 640px){.hanui-bar-UJGDL{flex-wrap:wrap;padding:var(--hanui-space-2) var(--hanui-space-4)}}.hanui-bar__brand-ZUcIw{display:inline-flex;align-items:center;gap:var(--hanui-space-2);flex-shrink:0;font-family:var(--hanui-font-heading);font-size:var(--hanui-font-size-base);font-weight:600;letter-spacing:-.011em}.hanui-bar__start-nvmHH{display:flex;align-items:center;gap:var(--hanui-space-2);flex:1;min-width:0}.hanui-bar__end-NNQve{display:flex;align-items:center;gap:var(--hanui-space-1);flex-shrink:0;margin-inline-start:auto}}@layer hanui{.hanui-list-e54gu{margin:0;padding:0;list-style:none;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-lg);background-color:var(--hanui-surface);position:relative;overflow:hidden}.hanui-list--virtual-zxqy5{overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-list--virtual-zxqy5::-webkit-scrollbar{width:8px;height:8px}.hanui-list--virtual-zxqy5::-webkit-scrollbar-track{background:transparent}.hanui-list--virtual-zxqy5::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-list--virtual-zxqy5::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-list__window-ESrZX{margin:0;padding-inline:0;padding-block-end:0;list-style:none}.hanui-list__slot-DxSnX{border-bottom:1px solid var(--hanui-border)}.hanui-list__slot-DxSnX:last-child{border-bottom:0}.hanui-list--virtual-zxqy5 .hanui-list__slot-DxSnX{block-size:var(--hanui-row-height);overflow:hidden}.hanui-item-DKEGh{display:flex;align-items:baseline;gap:var(--hanui-space-3);width:100%;height:100%;min-height:44px;padding:var(--hanui-space-2) var(--hanui-space-4);border:0;color:var(--hanui-text);font:inherit;font-size:var(--hanui-font-size-sm);text-align:start;text-decoration:none;cursor:pointer;background-color:transparent;transition:background-color var(--hanui-duration-fast) var(--hanui-ease-out),translate var(--hanui-duration-instant) var(--hanui-ease-out)}.hanui-item-DKEGh:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-2)}.hanui-item-DKEGh:active:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-3);translate:0 1px}@media (prefers-reduced-motion: reduce){.hanui-item-DKEGh{transition:none}.hanui-item-DKEGh:active:not(:disabled):not([aria-disabled=true]){translate:none}}.hanui-item-DKEGh:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:-2px}.hanui-item--selected-AMl3I{background-color:var(--hanui-selected-tint);box-shadow:inset 3px 0 0 var(--hanui-selected-line)}.hanui-item--muted-XBeA3{color:var(--hanui-text-3)}.hanui-item__start-Yb3xf{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;flex-shrink:0;color:var(--hanui-text-2)}.hanui-item--muted-XBeA3 .hanui-item__start-Yb3xf{color:var(--hanui-text-3)}.hanui-item__body-kD4Qk{flex:1;min-width:0;overflow-wrap:anywhere}.hanui-item__end-3SCT-{flex-shrink:0;font-size:var(--hanui-font-size-xs);color:var(--hanui-text-3);font-variant-numeric:tabular-nums}}@layer hanui{.hanui-bar-OZjXz{position:relative;height:10px;border-radius:var(--hanui-radius-pill);background-color:var(--hanui-surface-2);overflow:hidden}@media (forced-colors: active){.hanui-bar-OZjXz{border:1px solid CanvasText}}.hanui-bar__segment-hexbp{position:absolute;inset-block:0;box-shadow:inset -2px 0 0 var(--hanui-surface)}@media (forced-colors: active){.hanui-bar__segment-hexbp{background-color:CanvasText!important}}.hanui-bar__marker-E0FeF{position:absolute;inset-block:-2px;width:2px;margin-inline-start:-1px;background-color:var(--hanui-text)}.hanui-bar__marker--danger-245FK{background-color:var(--hanui-bad-fg)}}@layer hanui{.hanui-legend-zryov{display:flex;flex-wrap:wrap;gap:var(--hanui-space-1) var(--hanui-space-4);margin:0;padding:0;list-style:none}.hanui-legend__item-GGrR-{display:inline-flex;align-items:center;gap:var(--hanui-space-2);font-size:var(--hanui-font-size-xs);color:var(--hanui-text-2)}.hanui-legend__swatch-2MkAR{flex-shrink:0;width:10px;height:10px;border-radius:var(--hanui-radius-xs)}@media (forced-colors: active){.hanui-legend__swatch-2MkAR{border:1px solid CanvasText}}}@layer hanui{.hanui-list-KSLu5{display:grid;grid-template-columns:minmax(96px,max-content) minmax(0,1fr);gap:var(--hanui-space-2) var(--hanui-space-4);margin:0;font-size:var(--hanui-font-size-sm)}@media (max-width: 640px){.hanui-list-KSLu5{grid-template-columns:minmax(0,1fr);gap:var(--hanui-space-1)}}.hanui-list__row-k7aHp{display:contents}.hanui-list__term-vsD5B{color:var(--hanui-text-2)}@media (max-width: 640px){.hanui-list__term-vsD5B{margin-top:var(--hanui-space-2)}}.hanui-list__value-6GY6z{margin:0;color:var(--hanui-text);min-width:0}.hanui-list__value--technical-I-UYE{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}}
1
+ @layer hanui{.hanui-thread-R1LCJ{position:relative;display:grid;grid-template-rows:minmax(0,1fr) auto;height:100%;min-height:0}.hanui-thread__scroll-37EaI{position:relative;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-thread__scroll-37EaI::-webkit-scrollbar{width:8px;height:8px}.hanui-thread__scroll-37EaI::-webkit-scrollbar-track{background:transparent}.hanui-thread__scroll-37EaI::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-thread__scroll-37EaI::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-thread__scroll-37EaI:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:-2px}.hanui-thread__column-57FQh{display:flex;flex-direction:column;gap:var(--hanui-space-6);width:100%;max-width:768px;margin-inline:auto;padding:var(--hanui-space-6) var(--hanui-space-5)}@media (max-width: 640px){.hanui-thread__column-57FQh{padding:var(--hanui-space-5) var(--hanui-space-4)}}.hanui-thread__dock-y0Tt9 .hanui-thread__column-57FQh{gap:var(--hanui-space-2);padding-block:0 calc(var(--hanui-space-4) + env(safe-area-inset-bottom,0px))}.hanui-thread__dock-y0Tt9{position:relative;padding-top:var(--hanui-space-3);background:linear-gradient(to bottom,transparent,var(--hanui-page) var(--hanui-space-5))}.hanui-thread__latest-ZNmqY{position:absolute;inset-block-start:calc(-1 * var(--hanui-space-8));inset-inline:0;margin-inline:auto;box-shadow:var(--hanui-shadow-md);background-color:var(--hanui-surface)}}@layer hanui{.hanui-message-z5uVx{display:flex;gap:var(--hanui-space-3);width:100%}.hanui-message--user-Mq6gb{justify-content:flex-end}.hanui-message__avatar-QzWck{flex-shrink:0;margin-top:2px}.hanui-message__main-1rh-A{display:flex;flex-direction:column;gap:var(--hanui-space-2);min-width:0}.hanui-message--assistant-ndkmH .hanui-message__main-1rh-A{flex:1}.hanui-message--user-Mq6gb .hanui-message__main-1rh-A{align-items:flex-end;max-width:min(85%,640px)}.hanui-message__body-Ngiqq{min-width:0}.hanui-message--user-Mq6gb .hanui-message__body-Ngiqq{padding:var(--hanui-space-3) var(--hanui-space-4);border-radius:var(--hanui-radius-xl);border-end-end-radius:var(--hanui-radius-sm);background-color:var(--hanui-surface-2);color:var(--hanui-text);font-size:var(--hanui-font-size-body);line-height:var(--hanui-leading-normal);white-space:pre-wrap;overflow-wrap:anywhere}.hanui-message__actions-dQ0Fn{color:var(--hanui-text-3);transition:color var(--hanui-duration-fast) var(--hanui-ease-out)}.hanui-message-z5uVx:hover .hanui-message__actions-dQ0Fn,.hanui-message-z5uVx:focus-within .hanui-message__actions-dQ0Fn{color:var(--hanui-text-2)}@media (prefers-reduced-motion: reduce){.hanui-message__actions-dQ0Fn{transition:none}}}@layer hanui{.hanui-prompt-qHV1e{display:flex;flex-direction:column;gap:var(--hanui-space-2);width:100%}.hanui-prompt__box-sUQDu{display:flex;align-items:flex-end;gap:var(--hanui-space-2);padding:var(--hanui-space-2) var(--hanui-space-2) var(--hanui-space-2) var(--hanui-space-4);border:1px solid var(--hanui-border-strong);border-radius:var(--hanui-radius-xl);background-color:var(--hanui-surface);box-shadow:var(--hanui-shadow-sm);transition:border-color var(--hanui-duration-fast) var(--hanui-ease-out),box-shadow var(--hanui-duration-fast) var(--hanui-ease-out)}.hanui-prompt__box-sUQDu:focus-within{border-color:var(--hanui-ring-color);box-shadow:var(--hanui-ring)}.hanui-prompt__box--disabled-xu-Yk{background-color:var(--hanui-surface-2);border-color:var(--hanui-border);cursor:not-allowed;color:var(--hanui-text-3)}@media (forced-colors: active){.hanui-prompt__box--disabled-xu-Yk{color:GrayText;border-color:GrayText}}.hanui-prompt__box--disabled-xu-Yk{box-shadow:none}@media (prefers-reduced-motion: reduce){.hanui-prompt__box-sUQDu{transition:none}}.hanui-prompt__field-EmvTZ{flex:1;min-width:0;padding-block:9px}.hanui-prompt__start-2tqre,.hanui-prompt__end-Zp7fi{display:flex;align-items:center;gap:var(--hanui-space-1);flex-shrink:0;min-height:40px}.hanui-prompt__hint-4TpeC{text-align:center;font-size:var(--hanui-font-size-2xs);color:var(--hanui-text-3)}}@layer hanui{.hanui-grid-4EfQ-{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(220px,100%),1fr));gap:var(--hanui-space-2);width:100%}.hanui-card-KTt0-{display:flex;flex-direction:column;gap:2px;min-height:44px;padding:var(--hanui-space-3) var(--hanui-space-4);border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-lg);color:var(--hanui-text);font:inherit;text-align:start;cursor:pointer;background-color:var(--hanui-surface);transition:background-color var(--hanui-duration-fast) var(--hanui-ease-out),translate var(--hanui-duration-instant) var(--hanui-ease-out)}.hanui-card-KTt0-:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-2)}.hanui-card-KTt0-:active:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-3);translate:0 1px}@media (prefers-reduced-motion: reduce){.hanui-card-KTt0-{transition:none}.hanui-card-KTt0-:active:not(:disabled):not([aria-disabled=true]){translate:none}}.hanui-card-KTt0-:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-card__label-LNLTF{font-size:var(--hanui-font-size-sm);font-weight:500}.hanui-card__description-eIx-0{font-size:var(--hanui-font-size-xs);color:var(--hanui-text-2)}}@layer hanui{.hanui-prose-kAp6f{font-size:var(--hanui-font-size-body);line-height:var(--hanui-leading-normal);color:var(--hanui-text);overflow-wrap:break-word}.hanui-prose-kAp6f>:first-child{margin-top:0}.hanui-prose-kAp6f>:last-child{margin-bottom:0}.hanui-prose-kAp6f h1,.hanui-prose-kAp6f h2,.hanui-prose-kAp6f h3,.hanui-prose-kAp6f h4{margin:1.4em 0 .5em;font-family:var(--hanui-font-heading);font-weight:600;line-height:var(--hanui-leading-snug);color:var(--hanui-text)}.hanui-prose-kAp6f h1{font-size:var(--hanui-font-size-xl);letter-spacing:-.011em}.hanui-prose-kAp6f h2{font-size:var(--hanui-font-size-lg)}.hanui-prose-kAp6f h3,.hanui-prose-kAp6f h4{font-size:var(--hanui-font-size-base)}.hanui-prose-kAp6f p{margin:.65em 0}.hanui-prose-kAp6f ul,.hanui-prose-kAp6f ol{margin:.65em 0;padding-inline-start:1.4em}.hanui-prose-kAp6f li+li{margin-top:.25em}.hanui-prose-kAp6f a{color:var(--hanui-link);text-decoration:underline;text-underline-offset:2px}.hanui-prose-kAp6f a:hover{color:var(--hanui-link-hover)}.hanui-prose-kAp6f a:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-prose-kAp6f blockquote{margin:.9em 0;padding-inline-start:var(--hanui-space-4);border-inline-start:3px solid var(--hanui-border-strong);color:var(--hanui-text-2)}.hanui-prose-kAp6f hr{margin:1.4em 0;border:0;border-top:1px solid var(--hanui-border)}.hanui-prose-kAp6f :not(pre)>code{font-family:var(--hanui-font-mono);font-size:.88em;letter-spacing:.02em;font-variant-numeric:tabular-nums;padding:1px 5px;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-xs);background-color:var(--hanui-surface-2)}.hanui-prose-kAp6f table{display:block;max-width:100%;margin:.9em 0;position:relative;overflow-x:auto;border-collapse:collapse;font-size:var(--hanui-font-size-sm)}.hanui-prose-kAp6f th,.hanui-prose-kAp6f td{padding:var(--hanui-space-2) var(--hanui-space-3);border:1px solid var(--hanui-border);text-align:start;vertical-align:top}.hanui-prose-kAp6f th{background-color:var(--hanui-surface-2);font-weight:600}.hanui-prose-kAp6f .katex-display{margin:.9em 0;position:relative;overflow-x:auto;overflow-y:hidden}}@layer hanui{:root{--hanui-syntax-keyword: #a4277a;--hanui-syntax-string: #9d451f;--hanui-syntax-number: #7b2dcd;--hanui-syntax-name: #2063b0;--hanui-syntax-type: #76611f}@media (prefers-color-scheme: dark){:root:not([data-hanui-theme]){--hanui-syntax-keyword: #f691cc;--hanui-syntax-string: #f59e7c;--hanui-syntax-number: #c2a7f5;--hanui-syntax-name: #8dbaf5;--hanui-syntax-type: #d9b341}}:root[data-hanui-theme=dark]{--hanui-syntax-keyword: #f691cc;--hanui-syntax-string: #f59e7c;--hanui-syntax-number: #c2a7f5;--hanui-syntax-name: #8dbaf5;--hanui-syntax-type: #d9b341}:root[data-hanui-theme=light]{--hanui-syntax-keyword: #a4277a;--hanui-syntax-string: #9d451f;--hanui-syntax-number: #7b2dcd;--hanui-syntax-name: #2063b0;--hanui-syntax-type: #76611f}.hanui-block-M1yL9{margin:.9em 0;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-lg);background-color:var(--hanui-surface-inset);overflow:hidden}.hanui-block__header-F2iBP{display:flex;align-items:center;justify-content:space-between;gap:var(--hanui-space-2);min-height:36px;padding-inline:var(--hanui-space-3) var(--hanui-space-1);border-bottom:1px solid var(--hanui-border);background-color:var(--hanui-surface-2)}.hanui-block__language-lmdS9{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-2xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;color:var(--hanui-text-2);text-transform:lowercase}.hanui-block__body-wDCJ2{position:relative;overflow:auto;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-block__body-wDCJ2::-webkit-scrollbar{width:8px;height:8px}.hanui-block__body-wDCJ2::-webkit-scrollbar-track{background:transparent}.hanui-block__body-wDCJ2::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-block__body-wDCJ2::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-block__body-wDCJ2:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:-2px}.hanui-block__pre--EERi,.hanui-block__highlighted-JK1Yj pre{margin:0;padding:var(--hanui-space-3) var(--hanui-space-4);background:transparent!important;font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);line-height:var(--hanui-leading-relaxed);white-space:pre;-moz-tab-size:2;tab-size:2}.hanui-block__highlighted-JK1Yj span{color:var(--shiki-light)}:root[data-hanui-theme=dark] .hanui-block__highlighted-JK1Yj span{color:var(--shiki-dark)}@media (prefers-color-scheme: dark){:root:not([data-hanui-theme]) .hanui-block__highlighted-JK1Yj span{color:var(--shiki-dark)}}.hanui-block__token--comment-eFTyh{color:var(--hanui-text-3);font-style:italic}.hanui-block__token--keyword-qQpj9{color:var(--hanui-syntax-keyword)}.hanui-block__token--string-4onwX{color:var(--hanui-syntax-string)}.hanui-block__token--number-DThtL{color:var(--hanui-syntax-number)}.hanui-block__token--name-283C9{color:var(--hanui-syntax-name)}.hanui-block__token--type-cNUbM{color:var(--hanui-syntax-type)}.hanui-block__token--punctuation-Te2u8{color:var(--hanui-text-2)}.hanui-block__token--inserted-sUKnQ{color:var(--hanui-ok-fg)}.hanui-block__token--deleted-s74a-{color:var(--hanui-bad-fg)}}@layer hanui{.hanui-block-zqPjp summary{padding:var(--hanui-space-1) var(--hanui-space-2);margin-inline-start:calc(-1 * var(--hanui-space-2));border-radius:var(--hanui-radius-md);font-weight:500;color:var(--hanui-text-2)}.hanui-block__summary-Kkp-X{display:inline-flex;align-items:center;gap:var(--hanui-space-2)}.hanui-block__indicator-GuJMa{display:inline-flex;color:var(--hanui-text-2)}.hanui-block__body-mDvrV{display:flex;flex-direction:column;gap:var(--hanui-space-3);margin-top:var(--hanui-space-2);padding-inline-start:var(--hanui-space-4);border-inline-start:2px solid var(--hanui-border);color:var(--hanui-text-2)}}@layer hanui{.hanui-text-WKVxU{font-size:var(--hanui-font-size-sm);line-height:var(--hanui-leading-normal);color:var(--hanui-text-2)}.hanui-text__body--uP0k{margin:0;white-space:pre-wrap;overflow-wrap:anywhere}}@layer hanui{.hanui-call-tV2P8{border-radius:var(--hanui-radius-md);font-size:var(--hanui-font-size-sm)}.hanui-call-tV2P8 summary{padding:var(--hanui-space-2) var(--hanui-space-3);font-weight:400}.hanui-call--static-Nldru{display:flex;align-items:center;gap:var(--hanui-space-3);padding:var(--hanui-space-2) var(--hanui-space-3);border:1px solid var(--hanui-border);background-color:var(--hanui-surface)}.hanui-call__header-8Tw7m{display:flex;align-items:center;gap:var(--hanui-space-2);min-width:0}.hanui-call__icon-TLzwf{display:inline-flex;flex-shrink:0;font-size:var(--hanui-icon-sm);color:var(--hanui-text-3)}.hanui-call__icon--running-Mx1XK{color:var(--hanui-text)}.hanui-call__name-EHz6G{flex-shrink:0;font-weight:600;color:var(--hanui-text)}.hanui-call__summary-M4sLU{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;flex:1;min-width:0;color:var(--hanui-text-2)}.hanui-call__meta-bvpp7{flex-shrink:0;margin-inline-start:auto;font-size:var(--hanui-font-size-xs);color:var(--hanui-text-3);font-variant-numeric:tabular-nums}.hanui-call__body-nFK-C{display:flex;flex-direction:column;gap:var(--hanui-space-3)}.hanui-section-TjSGF{display:flex;flex-direction:column;gap:var(--hanui-space-1);min-width:0}.hanui-section__label-UrgqM{font-family:var(--hanui-font-body);font-size:var(--hanui-font-size-2xs);font-weight:600;letter-spacing:.045em;text-transform:uppercase;color:var(--hanui-text-2);margin:0}.hanui-section__body-Dy1PX{min-width:0;color:var(--hanui-text)}}@layer hanui{.hanui-terminal-D4Bz8{margin:0;padding:var(--hanui-space-3) var(--hanui-space-4);border:1px solid var(--hanui-shell-line);border-radius:var(--hanui-radius-md);background-color:var(--hanui-shell);color:var(--hanui-on-shell);font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);line-height:var(--hanui-leading-relaxed);white-space:pre-wrap;overflow-wrap:anywhere;position:relative;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-terminal-D4Bz8::-webkit-scrollbar{width:8px;height:8px}.hanui-terminal-D4Bz8::-webkit-scrollbar-track{background:transparent}.hanui-terminal-D4Bz8::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-terminal-D4Bz8::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-terminal-D4Bz8:focus-visible{outline:2px solid var(--hanui-on-shell);outline-offset:-2px}.hanui-terminal__command-A7PG2{color:var(--hanui-on-shell);font-weight:600}.hanui-terminal__prompt-9N1g2{color:var(--hanui-on-shell-2)}.hanui-terminal__stderr-qCNFe{color:var(--hanui-on-shell-danger)}.hanui-terminal__srOnly-2pmQA{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}}@layer hanui{.hanui-list-GC4NK{display:flex;flex-direction:column;gap:var(--hanui-space-2);margin:0;padding:0;list-style:none;font-size:var(--hanui-font-size-sm)}.hanui-list__item-N8DAn{display:flex;align-items:baseline;gap:var(--hanui-space-2)}.hanui-list__index-VrSMs{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-2xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;flex-shrink:0;min-width:18px;padding:1px 4px;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-xs);text-align:center;color:var(--hanui-text-2)}.hanui-list__text-4tll-{display:flex;flex-direction:column;min-width:0}.hanui-list__title-seHfJ{padding:0;border:0;background:none;color:var(--hanui-link);font:inherit;text-align:start;text-decoration:underline;text-underline-offset:2px;overflow-wrap:anywhere;cursor:pointer}.hanui-list__title-seHfJ:hover{color:var(--hanui-link-hover)}.hanui-list__title-seHfJ:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-list__plain-ZcCvx{color:var(--hanui-text);overflow-wrap:anywhere}.hanui-list__domain-sJLI7{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--hanui-font-size-xs);color:var(--hanui-text-3)}}@layer hanui{.hanui-citation-XrGMb{position:relative}.hanui-citation-XrGMb:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:max(100%,44px);height:max(100%,44px)}.hanui-citation-XrGMb{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-2xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;justify-content:center;min-width:18px;margin-inline:2px;padding:0 4px;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-xs);background-color:var(--hanui-surface-2);color:var(--hanui-link);line-height:1.5;vertical-align:super;text-decoration:none;cursor:pointer}.hanui-citation-XrGMb:hover{background-color:var(--hanui-surface-3)}.hanui-citation-XrGMb:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:2px}.hanui-citation__srOnly-GnMQp{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hanui-citation--static-8gXHs{color:var(--hanui-text-2);cursor:default}.hanui-citation--static-8gXHs:hover{background-color:var(--hanui-surface-2)}}@layer hanui{.hanui-actions-c8XlJ{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hanui-space-1);color:var(--hanui-text-3);font-size:var(--hanui-font-size-xs)}.hanui-actions__meta-j-X3I{margin-inline-start:var(--hanui-space-2);font-variant-numeric:tabular-nums}}@layer hanui{.hanui-bar-UJGDL{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:var(--hanui-space-3);min-height:56px;padding:var(--hanui-space-2) var(--hanui-space-5);border-bottom:1px solid var(--hanui-nav-line);background-color:var(--hanui-nav-bg);color:var(--hanui-nav-fg)}@media (max-width: 640px){.hanui-bar-UJGDL{flex-wrap:wrap;padding:var(--hanui-space-2) var(--hanui-space-4)}}.hanui-bar__brand-ZUcIw{display:inline-flex;align-items:center;gap:var(--hanui-space-2);flex-shrink:0;font-family:var(--hanui-font-heading);font-size:var(--hanui-font-size-base);font-weight:600;letter-spacing:-.011em}.hanui-bar__start-nvmHH{display:flex;align-items:center;gap:var(--hanui-space-2);flex:1;min-width:0}.hanui-bar__end-NNQve{display:flex;align-items:center;gap:var(--hanui-space-1);flex-shrink:0;margin-inline-start:auto}}@layer hanui{.hanui-list-e54gu{margin:0;padding:0;list-style:none;border:1px solid var(--hanui-border);border-radius:var(--hanui-radius-lg);background-color:var(--hanui-surface);position:relative;overflow:hidden}.hanui-list--virtual-zxqy5{overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--hanui-border-strong) transparent}.hanui-list--virtual-zxqy5::-webkit-scrollbar{width:8px;height:8px}.hanui-list--virtual-zxqy5::-webkit-scrollbar-track{background:transparent}.hanui-list--virtual-zxqy5::-webkit-scrollbar-thumb{background-color:var(--hanui-border-strong);border-radius:var(--hanui-radius-pill);border:2px solid transparent;background-clip:content-box}.hanui-list--virtual-zxqy5::-webkit-scrollbar-thumb:hover{background-color:var(--hanui-text-3)}.hanui-list__window-ESrZX{margin:0;padding-inline:0;padding-block-end:0;list-style:none}.hanui-list__slot-DxSnX{border-bottom:1px solid var(--hanui-border)}.hanui-list__slot-DxSnX:last-child{border-bottom:0}.hanui-list--virtual-zxqy5 .hanui-list__slot-DxSnX{block-size:var(--hanui-row-height);overflow:hidden}.hanui-item-DKEGh{display:flex;align-items:baseline;gap:var(--hanui-space-3);width:100%;height:100%;min-height:44px;padding:var(--hanui-space-2) var(--hanui-space-4);border:0;color:var(--hanui-text);font:inherit;font-size:var(--hanui-font-size-sm);text-align:start;text-decoration:none;cursor:pointer;background-color:transparent;transition:background-color var(--hanui-duration-fast) var(--hanui-ease-out),translate var(--hanui-duration-instant) var(--hanui-ease-out)}.hanui-item-DKEGh:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-2)}.hanui-item-DKEGh:active:not(:disabled):not([aria-disabled=true]){background-color:var(--hanui-surface-3);translate:0 1px}@media (prefers-reduced-motion: reduce){.hanui-item-DKEGh{transition:none}.hanui-item-DKEGh:active:not(:disabled):not([aria-disabled=true]){translate:none}}.hanui-item-DKEGh:focus-visible{outline:2px solid var(--hanui-ring-color);outline-offset:-2px}.hanui-item--selected-AMl3I{background-color:var(--hanui-selected-tint);box-shadow:inset 3px 0 0 var(--hanui-selected-line)}.hanui-item--muted-XBeA3{color:var(--hanui-text-3)}.hanui-item__start-Yb3xf{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;flex-shrink:0;color:var(--hanui-text-2)}.hanui-item--muted-XBeA3 .hanui-item__start-Yb3xf{color:var(--hanui-text-3)}.hanui-item__body-kD4Qk{flex:1;min-width:0;overflow-wrap:anywhere}.hanui-item__end-3SCT-{flex-shrink:0;font-size:var(--hanui-font-size-xs);color:var(--hanui-text-3);font-variant-numeric:tabular-nums}}@layer hanui{.hanui-bar-OZjXz{position:relative;height:10px;border-radius:var(--hanui-radius-pill);background-color:var(--hanui-surface-2);overflow:hidden}@media (forced-colors: active){.hanui-bar-OZjXz{border:1px solid CanvasText}}.hanui-bar__segment-hexbp{position:absolute;inset-block:0;box-shadow:inset -2px 0 0 var(--hanui-surface)}@media (forced-colors: active){.hanui-bar__segment-hexbp{background-color:CanvasText!important}}.hanui-bar__marker-E0FeF{position:absolute;inset-block:-2px;width:2px;margin-inline-start:-1px;background-color:var(--hanui-text)}.hanui-bar__marker--danger-245FK{background-color:var(--hanui-bad-fg)}}@layer hanui{.hanui-legend-zryov{display:flex;flex-wrap:wrap;gap:var(--hanui-space-1) var(--hanui-space-4);margin:0;padding:0;list-style:none}.hanui-legend__item-GGrR-{display:inline-flex;align-items:center;gap:var(--hanui-space-2);font-size:var(--hanui-font-size-xs);color:var(--hanui-text-2)}.hanui-legend__swatch-2MkAR{flex-shrink:0;width:10px;height:10px;border-radius:var(--hanui-radius-xs)}@media (forced-colors: active){.hanui-legend__swatch-2MkAR{border:1px solid CanvasText}}}@layer hanui{.hanui-list-KSLu5{display:grid;grid-template-columns:minmax(96px,max-content) minmax(0,1fr);gap:var(--hanui-space-2) var(--hanui-space-4);margin:0;font-size:var(--hanui-font-size-sm)}@media (max-width: 640px){.hanui-list-KSLu5{grid-template-columns:minmax(0,1fr);gap:var(--hanui-space-1)}}.hanui-list__row-k7aHp{display:contents}.hanui-list__term-vsD5B{color:var(--hanui-text-2)}@media (max-width: 640px){.hanui-list__term-vsD5B{margin-top:var(--hanui-space-2)}}.hanui-list__value-6GY6z{margin:0;color:var(--hanui-text);min-width:0}.hanui-list__value--technical-I-UYE{font-family:var(--hanui-font-mono);font-size:var(--hanui-font-size-xs);letter-spacing:.02em;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}}