@case-framework/survey-assistant 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{authoring-references-DYuOAdVx.mjs → authoring-references-ChDTVnms.mjs} +8 -2
- package/dist/authoring-references-ChDTVnms.mjs.map +1 -0
- package/dist/{capabilities-DlC1l6qy.d.mts → capabilities-CnsVuJ1k.d.mts} +12 -4
- package/dist/capabilities-CnsVuJ1k.d.mts.map +1 -0
- package/dist/capabilities-default.d.mts +1 -1
- package/dist/capabilities-default.d.mts.map +1 -1
- package/dist/capabilities-default.mjs +38 -4
- package/dist/capabilities-default.mjs.map +1 -1
- package/dist/{constants-D-5m_KGB.d.mts → constants-BK1-g6pR.d.mts} +12 -7
- package/dist/constants-BK1-g6pR.d.mts.map +1 -0
- package/dist/{controller-proxy-Hkuub9dt.d.mts → controller-proxy-CIDRd8Wu.d.mts} +2 -2
- package/dist/{controller-proxy-Hkuub9dt.d.mts.map → controller-proxy-CIDRd8Wu.d.mts.map} +1 -1
- package/dist/{controller-proxy-0WJZUZYx.mjs → controller-proxy-DY36XFV3.mjs} +2 -2
- package/dist/{controller-proxy-0WJZUZYx.mjs.map → controller-proxy-DY36XFV3.mjs.map} +1 -1
- package/dist/{digest-BvXpeWcR.d.mts → digest-Dyjch_sC.d.mts} +2 -2
- package/dist/{digest-BvXpeWcR.d.mts.map → digest-Dyjch_sC.d.mts.map} +1 -1
- package/dist/digest.d.mts +1 -1
- package/dist/{engine-0AJrv0hI.mjs → engine-CWTuN3o2.mjs} +866 -663
- package/dist/engine-CWTuN3o2.mjs.map +1 -0
- package/dist/engine.d.mts +3 -3
- package/dist/engine.mjs +3 -3
- package/dist/fair-guidance-CEdJYccK.mjs +21 -0
- package/dist/fair-guidance-CEdJYccK.mjs.map +1 -0
- package/dist/form-authoring-DCd9XfXf.mjs +155 -0
- package/dist/form-authoring-DCd9XfXf.mjs.map +1 -0
- package/dist/{index-BcyfBeDj.d.mts → index-Bp5W_oPa.d.mts} +25 -5
- package/dist/index-Bp5W_oPa.d.mts.map +1 -0
- package/dist/{index-JXH-t2EJ.d.mts → index-CPOQgkTN.d.mts} +67 -6
- package/dist/index-CPOQgkTN.d.mts.map +1 -0
- package/dist/{index-MEOL9_Gr.d.mts → index-EDL1V168.d.mts} +98 -4
- package/dist/{index-MEOL9_Gr.d.mts.map → index-EDL1V168.d.mts.map} +1 -1
- package/dist/{index-CneD8ibB.d.mts → index-SPHf3OoJ.d.mts} +9 -3
- package/dist/index-SPHf3OoJ.d.mts.map +1 -0
- package/dist/{memory-thread-repository-1ocPOda8.mjs → memory-thread-repository-acbz6HZJ.mjs} +181 -26
- package/dist/memory-thread-repository-acbz6HZJ.mjs.map +1 -0
- package/dist/{protocol-DpCYmCjr.mjs → protocol-DATvkr1S.mjs} +125 -6
- package/dist/protocol-DATvkr1S.mjs.map +1 -0
- package/dist/protocol.d.mts +3 -3
- package/dist/protocol.mjs +2 -2
- package/dist/{react-DXK5zWNo.mjs → react-3kSE6WtS.mjs} +127 -9
- package/dist/react-3kSE6WtS.mjs.map +1 -0
- package/dist/react-integration.d.mts +1 -1
- package/dist/react-integration.mjs +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.mjs +2 -2
- package/dist/references/assistant-operations.md +13 -18
- package/dist/references/embedded-forms.md +41 -2
- package/dist/references/expressions.md +17 -9
- package/dist/references/fair-by-design.md +80 -0
- package/dist/references/item-types.md +19 -3
- package/dist/references/localization.md +7 -4
- package/dist/references/source-material-surveys.md +6 -4
- package/dist/{request-context-BBzU3VdG.mjs → request-context-BEjnaaFr.mjs} +10 -5
- package/dist/request-context-BEjnaaFr.mjs.map +1 -0
- package/dist/server-agent.d.mts +26 -6
- package/dist/server-agent.d.mts.map +1 -1
- package/dist/server-agent.mjs +70 -13
- package/dist/server-agent.mjs.map +1 -1
- package/dist/server-runtime.d.mts +22 -11
- package/dist/server-runtime.d.mts.map +1 -1
- package/dist/server-runtime.mjs +47 -19
- package/dist/server-runtime.mjs.map +1 -1
- package/dist/server-tasks.d.mts +1 -1
- package/dist/server-tasks.mjs +4 -3
- package/dist/server-tasks.mjs.map +1 -1
- package/dist/server-tools.d.mts +1 -1
- package/dist/server-tools.mjs +1 -1
- package/dist/server.d.mts +16 -7
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +4 -4
- package/dist/storage-postgres.d.mts +1 -1
- package/dist/{tasks-DcfQNJwO.d.mts → tasks-DIZgr4nD.d.mts} +8 -4
- package/dist/tasks-DIZgr4nD.d.mts.map +1 -0
- package/dist/{thread-documents-BlxNjc7S.d.mts → thread-documents-C3kf0Vds.d.mts} +1 -1
- package/dist/{thread-documents-BlxNjc7S.d.mts.map → thread-documents-C3kf0Vds.d.mts.map} +1 -1
- package/dist/{thread-handlers-uddXwQjp.d.mts → thread-handlers-DZ1WsorO.d.mts} +9 -4
- package/dist/thread-handlers-DZ1WsorO.d.mts.map +1 -0
- package/dist/{tools-wgLen05n.mjs → tools-GDd5_GUh.mjs} +403 -77
- package/dist/tools-GDd5_GUh.mjs.map +1 -0
- package/dist/ui.css +1 -1
- package/dist/ui.d.mts +3 -3
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +152 -36
- package/dist/ui.mjs.map +1 -1
- package/docs/integration.md +73 -5
- package/package.json +3 -3
- package/dist/authoring-references-DYuOAdVx.mjs.map +0 -1
- package/dist/capabilities-DKbNCnBf.mjs +0 -66
- package/dist/capabilities-DKbNCnBf.mjs.map +0 -1
- package/dist/capabilities-DlC1l6qy.d.mts.map +0 -1
- package/dist/constants-D-5m_KGB.d.mts.map +0 -1
- package/dist/engine-0AJrv0hI.mjs.map +0 -1
- package/dist/index-BcyfBeDj.d.mts.map +0 -1
- package/dist/index-CneD8ibB.d.mts.map +0 -1
- package/dist/index-JXH-t2EJ.d.mts.map +0 -1
- package/dist/memory-thread-repository-1ocPOda8.mjs.map +0 -1
- package/dist/protocol-DpCYmCjr.mjs.map +0 -1
- package/dist/react-DXK5zWNo.mjs.map +0 -1
- package/dist/request-context-BBzU3VdG.mjs.map +0 -1
- package/dist/tasks-DcfQNJwO.d.mts.map +0 -1
- package/dist/thread-handlers-uddXwQjp.d.mts.map +0 -1
- package/dist/tools-wgLen05n.mjs.map +0 -1
package/dist/ui.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.mjs","names":["Collapsible","CollapsiblePrimitive","Collapsible","Select","SelectPrimitive","isRecord","Collapsible","Select"],"sources":["../src/ui/internal/collapsible.tsx","../src/ui/utils.ts","../src/ui/internal/shimmer.tsx","../src/ui/localizations/en.ts","../src/ui/localizations/nl.ts","../src/ui/localization.tsx","../src/ui/internal/chain-of-thought.tsx","../src/ui/internal/button.tsx","../src/ui/internal/conversation.tsx","../src/ui/internal/message.tsx","../src/ui/internal/prompt-input.tsx","../src/ui/internal/tool-technical-details.ts","../src/ui/internal/response.tsx","../src/ui/internal/select.tsx","../src/ui/internal/code-block.tsx","../src/ui/internal/message-timing.ts","../src/ui/survey-assistant-panel.tsx","../src/ui/connected-survey-assistant-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\";\n\nfunction Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return <CollapsiblePrimitive.CollapsibleTrigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return <CollapsiblePrimitive.CollapsibleContent data-slot=\"collapsible-content\" {...props} />;\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\n","\"use client\";\n\n/* eslint-disable react-hooks/static-components */\n\nimport { cn } from \"../utils\";\nimport type { MotionProps } from \"motion/react\";\nimport { motion } from \"motion/react\";\nimport type { CSSProperties, ElementType, JSX } from \"react\";\nimport { memo, useMemo } from \"react\";\n\ntype MotionHTMLProps = MotionProps & Record<string, unknown>;\n\n// Cache motion components at module level to avoid creating during render\nconst motionComponentCache = new Map<\n keyof JSX.IntrinsicElements,\n React.ComponentType<MotionHTMLProps>\n>();\n\nconst getMotionComponent = (element: keyof JSX.IntrinsicElements) => {\n let component = motionComponentCache.get(element);\n if (!component) {\n component = motion.create(element);\n motionComponentCache.set(element, component);\n }\n return component;\n};\n\nexport interface TextShimmerProps {\n children: string;\n as?: ElementType;\n className?: string;\n duration?: number;\n spread?: number;\n}\n\nconst ShimmerComponent = ({\n children,\n as: Component = \"p\",\n className,\n duration = 2,\n spread = 2,\n}: TextShimmerProps) => {\n const MotionComponent = getMotionComponent(Component as keyof JSX.IntrinsicElements);\n\n const dynamicSpread = useMemo(() => (children?.length ?? 0) * spread, [children, spread]);\n\n return (\n <MotionComponent\n animate={{ backgroundPosition: \"0% center\" }}\n className={cn(\n \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n \"[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]\",\n className,\n )}\n initial={{ backgroundPosition: \"100% center\" }}\n style={\n {\n \"--spread\": `${dynamicSpread}px`,\n backgroundImage:\n \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n } as CSSProperties\n }\n transition={{\n duration,\n ease: \"linear\",\n repeat: Number.POSITIVE_INFINITY,\n }}\n >\n {children}\n </MotionComponent>\n );\n};\n\nexport const Shimmer = memo(ShimmerComponent);\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantEnMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Survey assistant\",\n title: \"Assistant\",\n loadingChats: \"Loading chats\",\n controlsUnavailable: \"Assistant controls unavailable\",\n },\n empty: {\n title: \"What are you working on?\",\n description:\n \"Draft, inspect, or refine your survey - just describe what you need, or start with one of these.\",\n },\n quickActions: {\n review: {\n label: \"Review survey\",\n description: \"Spot issues and suggest improvements\",\n prompt: \"Review the current survey and suggest improvements.\",\n },\n create: {\n label: \"New question\",\n description: \"Draft a question to add\",\n prompt: \"Help me create a new survey question.\",\n },\n refine: {\n label: \"Refine wording\",\n description: \"Polish respondent-facing text\",\n prompt: \"Suggest improvements to the respondent-facing wording.\",\n },\n },\n input: {\n placeholder: \"Ask about the survey...\",\n attachFiles: \"Attach files\",\n dropFiles: \"Drop images or PDFs to attach\",\n unsupportedFiles: \"Unsupported file type: {filenames}\",\n removeFile: \"Remove {filename}\",\n send: \"Send message\",\n stop: \"Stop response\",\n model: \"Assistant model\",\n defaultModel: \"Default model\",\n },\n conversation: {\n noMessages: \"No messages yet\",\n startConversation: \"Start a conversation to see messages here\",\n scrollToLatest: \"Scroll to latest message\",\n working: \"Working...\",\n stopped: \"Stopped\",\n },\n status: {\n applying: \"Applying changes\",\n applied: \"Changes applied\",\n stopped: \"Stopped\",\n attention: \"Needs attention\",\n ready: \"Ready\",\n connecting: \"Connecting to the assistant\",\n thinking: \"Thinking through your request\",\n writing: \"Writing the response\",\n working: \"Working on your request\",\n },\n activity: {\n label: \"Activity\",\n working: \"Working...\",\n workedFor: \"Worked for {duration}\",\n technicalDetails: \"View technical details\",\n hideTechnicalDetails: \"Hide technical details\",\n waitingApproval: \"Waiting for approval\",\n approvalReceived: \"Approval received\",\n continuingApproval: \"Continuing after approval\",\n preparingStep: \"Preparing the next step\",\n usingResult: \"Using the result\",\n continuingWithoutStep: \"Continuing without that step\",\n recoveringToolError: \"Recovering from a tool error\",\n skipped: \"Skipped\",\n failed: \"Failed\",\n workingShort: \"Working\",\n done: \"Done\",\n stopped: \"Stopped\",\n expressionChange: \"Expression change\",\n surveyChange: \"Survey change\",\n genericActive: \"Working with survey\",\n genericComplete: \"Survey step complete\",\n failedSuffix: \"{name} failed\",\n skippedSuffix: \"{name} skipped\",\n tools: {\n survey_inspect: { active: \"Reviewing survey\", complete: \"Survey reviewed\" },\n survey_change: { active: \"Preparing change\", complete: \"Change prepared\" },\n survey_expression: { active: \"Preparing expression\", complete: \"Expression prepared\" },\n survey_authoring_reference: {\n active: \"Checking authoring guidance\",\n complete: \"Authoring guidance checked\",\n },\n survey_attachment: { active: \"Opening attachment\", complete: \"Attachment opened\" },\n recall: {\n active: \"Checking earlier conversation\",\n complete: \"Earlier conversation checked\",\n },\n },\n },\n changes: {\n applied: \"Change applied\",\n stale: \"Change not applied\",\n failed: \"Change could not be applied\",\n prepared: \"Change prepared\",\n rejected: \"Change could not be prepared\",\n operationCount: \"{count} operation\",\n operationCountPlural: \"{count} operations\",\n issueCount: \"{count} issue\",\n issueCountPlural: \"{count} issues\",\n warningCount: \"{count} warning\",\n warningCountPlural: \"{count} warnings\",\n incompleteTitle: \"The requested changes were not completed.\",\n blocked:\n \"No survey changes were applied because {count} rejected change proposal remains unresolved.\",\n blockedPlural:\n \"No survey changes were applied because {count} rejected change proposals remain unresolved.\",\n partial: \"{applied} change set was applied; {failed} could not be applied.\",\n partialPlural: \"{applied} change sets were applied; {failed} could not be applied.\",\n reviewBeforeRetry: \"Review the change steps above before retrying.\",\n },\n errors: {\n dismiss: \"Dismiss\",\n dismissAssistant: \"Dismiss assistant error\",\n retry: \"Try again\",\n fallbackDetail: \"The assistant hit an error on the previous turn.\",\n model_unavailable: {\n title: \"Model unavailable\",\n hint: \"Select a model available to this account, then send the message again.\",\n },\n rate_limited: {\n title: \"Assistant temporarily busy\",\n hint: \"Wait a moment, then send the message again.\",\n },\n authorization_failed: {\n title: \"Assistant unavailable\",\n hint: \"Check your access or sign in again before retrying.\",\n },\n attachment_unavailable: {\n title: \"Attachment unavailable\",\n hint: \"Attach the file again or continue without it.\",\n },\n request_failed: {\n title: \"Assistant could not complete request\",\n hint: \"You can continue with another message.\",\n },\n },\n threads: {\n newChat: \"New chat\",\n history: \"Chat history\",\n recent: \"Recent chats\",\n automaticTitle: \"Use automatic title\",\n automaticShort: \"Auto\",\n rename: \"Rename {title}\",\n renameTitle: \"Rename chat\",\n delete: \"Delete {title}\",\n deleteTitle: \"Delete chat\",\n deleteConfirm: 'Delete \"{title}\" and its attachments?',\n },\n};\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantNlMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Surveyassistent\",\n title: \"Assistent\",\n loadingChats: \"Chats laden\",\n controlsUnavailable: \"Bediening van de assistent niet beschikbaar\",\n },\n empty: {\n title: \"Waar werk je aan?\",\n description:\n \"Maak, controleer of verbeter je survey. Beschrijf wat je nodig hebt of kies een van deze opties.\",\n },\n quickActions: {\n review: {\n label: \"Survey controleren\",\n description: \"Problemen vinden en verbeteringen voorstellen\",\n prompt: \"Controleer de huidige survey en stel verbeteringen voor.\",\n },\n create: {\n label: \"Nieuwe vraag\",\n description: \"Een vraag opstellen en toevoegen\",\n prompt: \"Help me een nieuwe surveyvraag te maken.\",\n },\n refine: {\n label: \"Formulering verbeteren\",\n description: \"Tekst voor respondenten aanscherpen\",\n prompt: \"Stel verbeteringen voor voor de tekst die respondenten zien.\",\n },\n },\n input: {\n placeholder: \"Vraag iets over de survey...\",\n attachFiles: \"Bestanden toevoegen\",\n dropFiles: \"Sleep afbeeldingen of pdf's hierheen om ze toe te voegen\",\n unsupportedFiles: \"Niet-ondersteund bestandstype: {filenames}\",\n removeFile: \"{filename} verwijderen\",\n send: \"Bericht verzenden\",\n stop: \"Antwoord stoppen\",\n model: \"Assistentmodel\",\n defaultModel: \"Standaardmodel\",\n },\n conversation: {\n noMessages: \"Nog geen berichten\",\n startConversation: \"Start een gesprek om hier berichten te zien\",\n scrollToLatest: \"Naar het nieuwste bericht scrollen\",\n working: \"Bezig...\",\n stopped: \"Gestopt\",\n },\n status: {\n applying: \"Wijzigingen toepassen\",\n applied: \"Wijzigingen toegepast\",\n stopped: \"Gestopt\",\n attention: \"Aandacht nodig\",\n ready: \"Gereed\",\n connecting: \"Verbinding maken met de assistent\",\n thinking: \"Verzoek doordenken\",\n writing: \"Antwoord schrijven\",\n working: \"Aan je verzoek werken\",\n },\n activity: {\n label: \"Activiteit\",\n working: \"Bezig...\",\n workedFor: \"{duration} gewerkt\",\n technicalDetails: \"Technische details tonen\",\n hideTechnicalDetails: \"Technische details verbergen\",\n waitingApproval: \"Wachten op goedkeuring\",\n approvalReceived: \"Goedkeuring ontvangen\",\n continuingApproval: \"Doorgaan na goedkeuring\",\n preparingStep: \"Volgende stap voorbereiden\",\n usingResult: \"Resultaat gebruiken\",\n continuingWithoutStep: \"Doorgaan zonder die stap\",\n recoveringToolError: \"Herstellen van een fout in een hulpmiddel\",\n skipped: \"Overgeslagen\",\n failed: \"Mislukt\",\n workingShort: \"Bezig\",\n done: \"Gereed\",\n stopped: \"Gestopt\",\n expressionChange: \"Expressiewijziging\",\n surveyChange: \"Surveywijziging\",\n genericActive: \"Werken met de survey\",\n genericComplete: \"Surveystap voltooid\",\n failedSuffix: \"{name} mislukt\",\n skippedSuffix: \"{name} overgeslagen\",\n tools: {\n survey_inspect: { active: \"Survey controleren\", complete: \"Survey gecontroleerd\" },\n survey_change: { active: \"Wijziging voorbereiden\", complete: \"Wijziging voorbereid\" },\n survey_expression: {\n active: \"Expressie voorbereiden\",\n complete: \"Expressie voorbereid\",\n },\n survey_authoring_reference: {\n active: \"Auteursrichtlijnen controleren\",\n complete: \"Auteursrichtlijnen gecontroleerd\",\n },\n survey_attachment: { active: \"Bijlage openen\", complete: \"Bijlage geopend\" },\n recall: {\n active: \"Eerder gesprek controleren\",\n complete: \"Eerder gesprek gecontroleerd\",\n },\n },\n },\n changes: {\n applied: \"Wijziging toegepast\",\n stale: \"Wijziging niet toegepast\",\n failed: \"Wijziging kon niet worden toegepast\",\n prepared: \"Wijziging voorbereid\",\n rejected: \"Wijziging kon niet worden voorbereid\",\n operationCount: \"{count} bewerking\",\n operationCountPlural: \"{count} bewerkingen\",\n issueCount: \"{count} probleem\",\n issueCountPlural: \"{count} problemen\",\n warningCount: \"{count} waarschuwing\",\n warningCountPlural: \"{count} waarschuwingen\",\n incompleteTitle: \"De gevraagde wijzigingen zijn niet voltooid.\",\n blocked:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstel nog niet is opgelost.\",\n blockedPlural:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstellen nog niet zijn opgelost.\",\n partial: \"{applied} wijzigingsset is toegepast; {failed} kon niet worden toegepast.\",\n partialPlural:\n \"{applied} wijzigingssets zijn toegepast; {failed} konden niet worden toegepast.\",\n reviewBeforeRetry:\n \"Controleer de bovenstaande wijzigingsstappen voordat je het opnieuw probeert.\",\n },\n errors: {\n dismiss: \"Sluiten\",\n dismissAssistant: \"Assistentfout sluiten\",\n retry: \"Opnieuw proberen\",\n fallbackDetail: \"Er is tijdens de vorige beurt een fout opgetreden.\",\n model_unavailable: {\n title: \"Model niet beschikbaar\",\n hint: \"Selecteer een model dat beschikbaar is voor dit account en verzend het bericht opnieuw.\",\n },\n rate_limited: {\n title: \"Assistent tijdelijk bezet\",\n hint: \"Wacht even en verzend het bericht daarna opnieuw.\",\n },\n authorization_failed: {\n title: \"Assistent niet beschikbaar\",\n hint: \"Controleer je toegang of meld je opnieuw aan voordat je het opnieuw probeert.\",\n },\n attachment_unavailable: {\n title: \"Bijlage niet beschikbaar\",\n hint: \"Voeg het bestand opnieuw toe of ga verder zonder het bestand.\",\n },\n request_failed: {\n title: \"Assistent kon het verzoek niet voltooien\",\n hint: \"Je kunt doorgaan met een nieuw bericht.\",\n },\n },\n threads: {\n newChat: \"Nieuwe chat\",\n history: \"Chatgeschiedenis\",\n recent: \"Recente chats\",\n automaticTitle: \"Automatische titel gebruiken\",\n automaticShort: \"Automatisch\",\n rename: \"{title} hernoemen\",\n renameTitle: \"Chat hernoemen\",\n delete: \"{title} verwijderen\",\n deleteTitle: \"Chat verwijderen\",\n deleteConfirm: '\"{title}\" en de bijlagen verwijderen?',\n },\n};\n","\"use client\";\n\nimport {\n createLocalizationTranslator,\n mergeLocalizationCatalogs,\n type LocalizationCatalog,\n type LocalizationTranslate,\n} from \"@case-framework/ui-localization\";\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport { surveyAssistantEnMessages } from \"./localizations/en\";\nimport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport { surveyAssistantEnMessages } from \"./localizations/en\";\nexport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport const defaultSurveyAssistantLocalizations: LocalizationCatalog = {\n en: surveyAssistantEnMessages,\n nl: surveyAssistantNlMessages,\n};\n\nconst SurveyAssistantLocalizationContext = createContext<LocalizationTranslate | null>(null);\n\nexport interface SurveyAssistantLocalizationProviderProps {\n children: ReactNode;\n language?: string;\n localizations?: LocalizationCatalog;\n}\n\nexport const SurveyAssistantLocalizationProvider = ({\n children,\n language = \"en\",\n localizations,\n}: SurveyAssistantLocalizationProviderProps) => {\n const translate = useMemo(\n () =>\n createLocalizationTranslator({\n fallbackLocale: \"en\",\n locale: language,\n localizations: mergeLocalizationCatalogs(\n defaultSurveyAssistantLocalizations,\n localizations,\n ),\n onMissing: (key, locale) =>\n console.log(\n `[SurveyAssistant] Missing localization for key \"${key}\" in language \"${locale}\".`,\n ),\n }),\n [language, localizations],\n );\n\n return (\n <SurveyAssistantLocalizationContext.Provider value={translate}>\n {children}\n </SurveyAssistantLocalizationContext.Provider>\n );\n};\n\nexport const useSurveyAssistantTranslation = (): LocalizationTranslate => {\n const translate = useContext(SurveyAssistantLocalizationContext);\n if (!translate) {\n throw new Error(\n \"useSurveyAssistantTranslation must be used within SurveyAssistantLocalizationProvider.\",\n );\n }\n return translate;\n};\n","\"use client\";\n\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { cn } from \"../utils\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { BrainIcon, ChevronDownIcon, DotIcon, type LucideIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Shimmer } from \"./shimmer\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\ninterface ChainOfThoughtContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n isStreaming: boolean;\n duration: number | undefined;\n}\n\nconst ChainOfThoughtContext = createContext<ChainOfThoughtContextValue | null>(null);\n\nexport const useChainOfThought = () => {\n const context = useContext(ChainOfThoughtContext);\n if (!context) {\n throw new Error(\"ChainOfThought components must be used within ChainOfThought\");\n }\n return context;\n};\n\nexport type ChainOfThoughtProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n defaultOpen?: boolean;\n defaultDuration?: number;\n duration?: number;\n autoClose?: boolean;\n};\n\nconst AUTO_CLOSE_DELAY = 1000;\nconst MS_IN_S = 1000;\n\nconst formatDuration = (durationSeconds: number) => {\n const hours = Math.floor(durationSeconds / 3600);\n const minutes = Math.floor((durationSeconds % 3600) / 60);\n const seconds = durationSeconds % 60;\n\n if (hours > 0) return `${hours}h ${minutes}m`;\n if (minutes > 0) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;\n return `${seconds}s`;\n};\n\nexport const ChainOfThought = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n defaultDuration,\n onOpenChange,\n duration: durationProp,\n autoClose = true,\n children,\n ...props\n }: ChainOfThoughtProps) => {\n const resolvedDefaultOpen = defaultOpen ?? isStreaming;\n // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n const isExplicitlyClosed = defaultOpen === false;\n\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: resolvedDefaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: defaultDuration,\n prop: durationProp,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n const startTimeRef = useRef<number | null>(null);\n\n // Track when streaming starts and compute duration\n useEffect(() => {\n if (isStreaming) {\n hasEverStreamedRef.current = true;\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));\n startTimeRef.current = null;\n }\n }, [isStreaming, setDuration]);\n\n // Auto-open when streaming starts (unless explicitly closed)\n useEffect(() => {\n if (isStreaming && !isOpen && !isExplicitlyClosed) {\n setIsOpen(true);\n }\n }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);\n\n // Auto-close when streaming ends (once only, and only if it ever streamed)\n useEffect(() => {\n if (autoClose && hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n\n return () => clearTimeout(timer);\n }\n }, [autoClose, isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n },\n [setIsOpen],\n );\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen],\n );\n\n return (\n <ChainOfThoughtContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose w-full\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ChainOfThoughtContext.Provider>\n );\n },\n);\n\nexport type ChainOfThoughtHeaderProps = ComponentProps<typeof CollapsibleTrigger> & {\n getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode;\n};\n\nexport const ChainOfThoughtHeader = memo(\n ({ className, children, getThinkingMessage, ...props }: ChainOfThoughtHeaderProps) => {\n const { isOpen, isStreaming, duration } = useChainOfThought();\n const t = useSurveyAssistantTranslation();\n const defaultThinkingMessage = isStreaming ? (\n <Shimmer duration={1}>{t(\"activity.working\")}</Shimmer>\n ) : duration === undefined ? (\n <span>{t(\"activity.label\")}</span>\n ) : (\n <span>{t(\"activity.workedFor\", { duration: formatDuration(duration) })}</span>\n );\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center gap-1.5 text-muted-foreground text-sm transition-colors hover:text-foreground\",\n className,\n )}\n {...props}\n >\n <BrainIcon className=\"size-3.5 shrink-0\" />\n <span className=\"flex-1 text-left\">\n {children ?? getThinkingMessage?.(isStreaming, duration) ?? defaultThinkingMessage}\n </span>\n <ChevronDownIcon\n className={cn(\n \"size-3.5 shrink-0 transition-transform\",\n isOpen ? \"rotate-180\" : \"rotate-0\",\n )}\n />\n </CollapsibleTrigger>\n );\n },\n);\n\nexport type ChainOfThoughtContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ChainOfThoughtContent = memo(({ className, ...props }: ChainOfThoughtContentProps) => (\n <CollapsibleContent\n className={cn(\n \"mt-2\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className,\n )}\n {...props}\n />\n));\n\nexport type ChainOfThoughtStepProps = ComponentProps<\"div\"> & {\n icon?: LucideIcon;\n label: ReactNode;\n description?: ReactNode;\n result?: ReactNode;\n status?: \"complete\" | \"active\" | \"pending\";\n isLast?: boolean;\n};\n\nconst stepStatusStyles = {\n complete: \"text-muted-foreground\",\n active: \"text-foreground\",\n pending: \"text-muted-foreground/50\",\n} as const;\n\nexport const ChainOfThoughtStep = memo(\n ({\n className,\n icon: Icon = DotIcon,\n label,\n description,\n result,\n status = \"complete\",\n isLast = false,\n children,\n ...props\n }: ChainOfThoughtStepProps) => (\n <div\n className={cn(\n \"fade-in-0 slide-in-from-top-2 relative animate-in text-xs\",\n isLast ? \"pb-0\" : \"pb-2.5\",\n stepStatusStyles[status],\n className,\n )}\n {...props}\n >\n <div className=\"flex gap-2\">\n <div className=\"relative z-10 mt-0.5 shrink-0 bg-background\">\n <Icon className=\"size-3.5\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"wrap-break-word\">{label}</div>\n {description && <div className=\"mt-1.5 text-muted-foreground text-xs\">{description}</div>}\n </div>\n </div>\n {result && <div className=\"relative mt-1.5 ml-[22px]\">{result}</div>}\n {children && <div className=\"mt-1.5 ml-[22px] space-y-1.5\">{children}</div>}\n </div>\n ),\n);\n\nChainOfThought.displayName = \"ChainOfThought\";\nChainOfThoughtHeader.displayName = \"ChainOfThoughtHeader\";\nChainOfThoughtContent.displayName = \"ChainOfThoughtContent\";\nChainOfThoughtStep.displayName = \"ChainOfThoughtStep\";\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-muted hover:text-foreground\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n },\n },\n defaultVariants: { variant: \"default\", size: \"default\" },\n },\n);\n\nexport const Button = ({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) => {\n const Component = asChild ? Slot.Root : \"button\";\n return <Component className={cn(buttonVariants({ variant, size, className }))} {...props} />;\n};\n","\"use client\";\n\nimport { Button } from \"./button\";\nimport { cn } from \"../utils\";\nimport { ArrowDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { useCallback } from \"react\";\nimport { StickToBottom, useStickToBottomContext } from \"use-stick-to-bottom\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\nexport type ConversationProps = ComponentProps<typeof StickToBottom>;\n\nexport const Conversation = ({ className, ...props }: ConversationProps) => (\n <StickToBottom\n className={cn(\"relative min-h-0 flex-1 overflow-y-hidden\", className)}\n initial=\"smooth\"\n role=\"log\"\n resize=\"smooth\"\n {...props}\n />\n);\n\nexport type ConversationContentProps = ComponentProps<typeof StickToBottom.Content>;\n\nexport const ConversationContent = ({ className, ...props }: ConversationContentProps) => (\n <StickToBottom.Content className={cn(\"flex flex-col gap-8 p-4\", className)} {...props} />\n);\n\nexport type ConversationEmptyStateProps = ComponentProps<\"div\"> & {\n title?: string;\n description?: string;\n icon?: ReactNode;\n};\n\nexport const ConversationEmptyState = ({\n className,\n title,\n description,\n icon,\n children,\n ...props\n}: ConversationEmptyStateProps) => {\n const t = useSurveyAssistantTranslation();\n const resolvedTitle = title ?? t(\"conversation.noMessages\");\n const resolvedDescription = description ?? t(\"conversation.startConversation\");\n\n return (\n <div\n className={cn(\n \"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <>\n {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n <div className=\"space-y-1\">\n <h3 className=\"font-medium text-sm\">{resolvedTitle}</h3>\n {resolvedDescription && (\n <p className=\"text-muted-foreground text-sm\">{resolvedDescription}</p>\n )}\n </div>\n </>\n )}\n </div>\n );\n};\n\nexport type ConversationScrollButtonProps = ComponentProps<typeof Button>;\n\nexport const ConversationScrollButton = ({\n className,\n ...props\n}: ConversationScrollButtonProps) => {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext();\n const t = useSurveyAssistantTranslation();\n\n const handleScrollToBottom = useCallback(() => {\n scrollToBottom();\n }, [scrollToBottom]);\n\n return (\n !isAtBottom && (\n <Button\n className={cn(\n \"absolute left-1/2 z-10 size-8 -translate-x-1/2 rounded-full border border-background/60 bg-foreground text-background shadow-lg ring-1 ring-border/50 hover:bg-foreground/85 hover:text-background\",\n className,\n )}\n aria-label={t(\"conversation.scrollToLatest\")}\n onClick={handleScrollToBottom}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"secondary\"\n {...props}\n >\n <ArrowDownIcon className=\"size-4\" />\n </Button>\n )\n );\n};\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport type { UIMessage } from \"ai\";\nimport type { HTMLAttributes } from \"react\";\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n from: UIMessage[\"role\"];\n};\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n from === \"user\" ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n data-role={from}\n {...props}\n />\n);\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageContent = ({ children, className, ...props }: MessageContentProps) => (\n <div\n className={cn(\n \"w-fit min-w-0 max-w-full break-words text-sm\",\n \"group-data-[role=user]:whitespace-pre-wrap group-data-[role=user]:rounded-xl group-data-[role=user]:border group-data-[role=user]:border-blue-200/70 group-data-[role=user]:bg-blue-50 group-data-[role=user]:px-3 group-data-[role=user]:py-2 group-data-[role=user]:text-foreground group-data-[role=user]:shadow-xs dark:group-data-[role=user]:border-blue-800/60 dark:group-data-[role=user]:bg-blue-950/50\",\n \"group-data-[role=assistant]:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type MessageResponseProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageResponse = ({ className, ...props }: MessageResponseProps) => (\n <div className={cn(\"leading-6\", className)} {...props} />\n);\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport type { ChatStatus, FileUIPart } from \"ai\";\nimport { ArrowUpIcon, FileIcon, PaperclipIcon, SquareIcon, XIcon } from \"lucide-react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type ClipboardEvent,\n type ComponentProps,\n type DragEvent,\n type FormEvent,\n type HTMLAttributes,\n} from \"react\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\nconst SUPPORTED_FILE_ACCEPT = \"image/*,application/pdf\";\nconst isSupportedFile = (file: File) =>\n file.type.startsWith(\"image/\") || file.type === \"application/pdf\";\n\nconst formatFileSize = (size: number) => {\n if (size < 1024 * 1024) {\n return `${Math.max(1, Math.round(size / 1024))} KB`;\n }\n\n return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`;\n};\n\nconst fileToUIPart = async (file: File): Promise<FileUIPart> => {\n const mediaType = file.type || \"application/octet-stream\";\n const bytes = new Uint8Array(await file.arrayBuffer());\n const chunkSize = 0x8000;\n let binary = \"\";\n\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n\n return {\n type: \"file\",\n mediaType,\n filename: file.name,\n url: `data:${mediaType};base64,${btoa(binary)}`,\n };\n};\n\nexport interface PromptInputMessage {\n text: string;\n files: FileUIPart[];\n}\n\ntype PromptInputContextValue = {\n value: string;\n setValue: (value: string) => void;\n files: File[];\n addFiles: (files: FileList | null) => void;\n removeFile: (index: number) => void;\n unsupportedFileNames: string[];\n};\n\nconst PromptInputContext = createContext<PromptInputContextValue | null>(null);\n\nconst usePromptInput = () => {\n const context = useContext(PromptInputContext);\n if (!context) {\n throw new Error(\"PromptInput components must be used within PromptInput.\");\n }\n return context;\n};\n\nexport type PromptInputProps = Omit<ComponentProps<\"form\">, \"onSubmit\"> & {\n attachmentsDisabled?: boolean;\n onSubmit: (\n message: PromptInputMessage,\n event: FormEvent<HTMLFormElement>,\n ) => boolean | void | Promise<boolean | void>;\n};\n\nexport const PromptInput = ({\n attachmentsDisabled = false,\n children,\n className,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onPaste,\n onSubmit,\n ...props\n}: PromptInputProps) => {\n const [value, setValue] = useState(\"\");\n const [files, setFiles] = useState<File[]>([]);\n const [isDraggingFiles, setIsDraggingFiles] = useState(false);\n const [unsupportedFileNames, setUnsupportedFileNames] = useState<string[]>([]);\n const fileDragDepthRef = useRef(0);\n const t = useSurveyAssistantTranslation();\n\n const addFiles = useCallback((fileList: FileList | null) => {\n const nextFiles = Array.from(fileList ?? []);\n const supportedFiles = nextFiles.filter(isSupportedFile);\n const unsupportedFiles = nextFiles.filter((file) => !isSupportedFile(file));\n\n setFiles((currentFiles) => [...currentFiles, ...supportedFiles]);\n setUnsupportedFileNames(unsupportedFiles.map((file) => file.name));\n }, []);\n\n const removeFile = useCallback((index: number) => {\n setFiles((currentFiles) => currentFiles.filter((_, fileIndex) => fileIndex !== index));\n }, []);\n\n const contextValue = useMemo(\n () => ({\n value,\n setValue,\n files,\n addFiles,\n removeFile,\n unsupportedFileNames,\n }),\n [addFiles, files, removeFile, unsupportedFileNames, value],\n );\n\n const handleSubmit = useCallback(\n async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const text = value.trim();\n if (!text && files.length === 0) {\n return;\n }\n\n const fileUIParts = await Promise.all(files.map(fileToUIPart));\n const accepted = await onSubmit({ text, files: fileUIParts }, event);\n if (accepted === false) return;\n setValue(\"\");\n setFiles([]);\n setUnsupportedFileNames([]);\n },\n [files, onSubmit, value],\n );\n\n const isFileDrag = (event: DragEvent<HTMLFormElement>) =>\n event.dataTransfer.types.includes(\"Files\");\n\n const handleDragEnter = (event: DragEvent<HTMLFormElement>) => {\n onDragEnter?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n fileDragDepthRef.current += 1;\n if (!attachmentsDisabled) setIsDraggingFiles(true);\n };\n\n const handleDragLeave = (event: DragEvent<HTMLFormElement>) => {\n onDragLeave?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = Math.max(0, fileDragDepthRef.current - 1);\n if (fileDragDepthRef.current === 0) setIsDraggingFiles(false);\n };\n\n const handleDragOver = (event: DragEvent<HTMLFormElement>) => {\n onDragOver?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n event.dataTransfer.dropEffect = attachmentsDisabled ? \"none\" : \"copy\";\n };\n\n const handleDrop = (event: DragEvent<HTMLFormElement>) => {\n onDrop?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = 0;\n setIsDraggingFiles(false);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n if (!attachmentsDisabled) addFiles(event.dataTransfer.files);\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLFormElement>) => {\n onPaste?.(event);\n if (event.defaultPrevented || attachmentsDisabled || event.clipboardData.files.length === 0) {\n return;\n }\n\n event.preventDefault();\n addFiles(event.clipboardData.files);\n };\n\n return (\n <PromptInputContext.Provider value={contextValue}>\n <form\n className={cn(\"relative rounded-xl border border-input bg-background\", className)}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onPaste={handlePaste}\n onSubmit={handleSubmit}\n {...props}\n >\n {children}\n {isDraggingFiles && (\n <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-[inherit] border-2 border-primary bg-background/90 px-4 text-center font-medium text-sm text-foreground\">\n {t(\"input.dropFiles\")}\n </div>\n )}\n </form>\n </PromptInputContext.Provider>\n );\n};\n\nexport type PromptInputBodyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputBody = ({ children, className, ...props }: PromptInputBodyProps) => {\n const { files, removeFile, unsupportedFileNames } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n\n return (\n <div className={cn(\"contents\", className)} {...props}>\n {children}\n {(files.length > 0 || unsupportedFileNames.length > 0) && (\n <div className=\"flex flex-wrap gap-2 px-3 pb-2\">\n {files.map((file, index) => (\n <div\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={`${file.name}-${file.lastModified}-${index}`}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{file.name}</span>\n <span className=\"shrink-0 text-muted-foreground\">{formatFileSize(file.size)}</span>\n <button\n className=\"shrink-0 rounded-sm text-muted-foreground hover:text-foreground\"\n onClick={() => removeFile(index)}\n type=\"button\"\n >\n <XIcon className=\"size-3.5\" />\n <span className=\"sr-only\">{t(\"input.removeFile\", { filename: file.name })}</span>\n </button>\n </div>\n ))}\n {unsupportedFileNames.length > 0 && (\n <div className=\"text-destructive text-xs\">\n {t(\"input.unsupportedFiles\", { filenames: unsupportedFileNames.join(\", \") })}\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport type PromptInputTextareaProps = ComponentProps<\"textarea\">;\n\nexport const PromptInputTextarea = ({\n className,\n onChange,\n onKeyDown,\n ...props\n}: PromptInputTextareaProps) => {\n const { value, setValue } = usePromptInput();\n\n return (\n <textarea\n className={cn(\n \"max-h-40 min-h-20 w-full resize-none bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground\",\n className,\n )}\n onChange={(event) => {\n setValue(event.target.value);\n onChange?.(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || event.shiftKey || event.key !== \"Enter\") {\n return;\n }\n event.preventDefault();\n event.currentTarget.form?.requestSubmit();\n }}\n value={value}\n {...props}\n />\n );\n};\n\nexport type PromptInputFooterProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputFooter = ({ className, ...props }: PromptInputFooterProps) => (\n <div\n className={cn(\"flex items-center gap-2 border-t border-border px-2 py-2\", className)}\n {...props}\n />\n);\n\nexport type PromptInputAttachmentButtonProps = Omit<ComponentProps<\"input\">, \"type\">;\n\nexport const PromptInputAttachmentButton = ({\n accept = SUPPORTED_FILE_ACCEPT,\n className,\n disabled,\n onChange,\n ...props\n}: PromptInputAttachmentButtonProps) => {\n const { addFiles } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n\n return (\n <label\n className={cn(\n \"inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n disabled && \"pointer-events-none cursor-default opacity-50\",\n className,\n )}\n >\n <PaperclipIcon className=\"size-4\" />\n <span className=\"sr-only\">{t(\"input.attachFiles\")}</span>\n <input\n accept={accept}\n className=\"sr-only\"\n disabled={disabled}\n multiple\n onChange={(event) => {\n addFiles(event.currentTarget.files);\n onChange?.(event);\n event.currentTarget.value = \"\";\n }}\n type=\"file\"\n {...props}\n />\n </label>\n );\n};\n\nexport type PromptInputSubmitProps = ComponentProps<\"button\"> & {\n status?: ChatStatus;\n onStop?: () => void;\n};\n\nexport const PromptInputSubmit = ({\n className,\n status,\n onStop,\n onClick,\n ...props\n}: PromptInputSubmitProps) => {\n const isGenerating = status === \"submitted\" || status === \"streaming\";\n const t = useSurveyAssistantTranslation();\n\n return (\n <button\n className={cn(\n \"inline-flex size-8 items-center justify-center rounded-full bg-foreground text-background transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\",\n className,\n )}\n onClick={(event) => {\n if (isGenerating && onStop) {\n event.preventDefault();\n onStop();\n return;\n }\n onClick?.(event);\n }}\n type=\"submit\"\n {...props}\n >\n {isGenerating ? <SquareIcon className=\"size-3.5\" /> : <ArrowUpIcon className=\"size-4\" />}\n <span className=\"sr-only\">{isGenerating ? t(\"input.stop\") : t(\"input.send\")}</span>\n </button>\n );\n};\n","const formatOmittedLength = (length: number) => length.toLocaleString(\"en-US\");\n\nexport const stringifyToolTechnicalDetails = (value: unknown): string =>\n JSON.stringify(\n value,\n function redactEmbeddedBinary(this: unknown, key, currentValue) {\n const parent =\n this && typeof this === \"object\" ? (this as Record<string, unknown>) : undefined;\n if (\n key === \"data\" &&\n typeof currentValue === \"string\" &&\n parent?.type === \"embedded\" &&\n parent.encoding === \"base64\"\n ) {\n return `[embedded base64 omitted: ${formatOmittedLength(currentValue.length)} characters]`;\n }\n\n if (\n typeof currentValue === \"string\" &&\n currentValue.length > 512 &&\n /^data:[^;,]+;base64,/.test(currentValue)\n ) {\n return `[base64 data URL omitted: ${formatOmittedLength(currentValue.length)} characters]`;\n }\n\n return currentValue;\n },\n 2,\n );\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport { Streamdown, type StreamdownProps } from \"streamdown\";\n\nexport type ResponseProps = Omit<StreamdownProps, \"children\"> & {\n children: string;\n};\n\nexport const Response = ({ children, className, controls = false, ...props }: ResponseProps) => (\n <Streamdown\n className={cn(\n \"leading-6\",\n \"[&>:first-child]:mt-0 [&>:last-child]:mb-0\",\n \"[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2\",\n \"[&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground\",\n \"[&_code]:rounded-md [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.85em]\",\n \"[&_h1]:mb-2 [&_h1]:mt-4 [&_h1]:text-base [&_h1]:font-semibold\",\n \"[&_h2]:mb-2 [&_h2]:mt-4 [&_h2]:text-sm [&_h2]:font-semibold\",\n \"[&_h3]:mb-1.5 [&_h3]:mt-3 [&_h3]:text-sm [&_h3]:font-semibold\",\n \"[&_li]:my-1 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5\",\n \"[&_p]:my-2\",\n \"[&_pre]:my-3 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:border [&_pre]:bg-muted [&_pre]:p-3\",\n \"[&_pre_code]:bg-transparent [&_pre_code]:p-0\",\n \"[&_strong]:font-semibold\",\n \"[&_table]:my-3 [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_th]:font-semibold\",\n className,\n )}\n controls={controls}\n {...props}\n >\n {children}\n </Streamdown>\n);\n","\"use client\";\n\nimport * as React from \"react\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { Select as SelectPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../utils\";\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <div className=\"case-survey-assistant case-survey-assistant-portal\">\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </div>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className,\n )}\n {...props}\n >\n <span\n data-slot=\"select-item-indicator\"\n className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n >\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","\"use client\";\n\n/* eslint-disable react-hooks/refs */\n\nimport { Button } from \"./button\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./select\";\nimport { cn } from \"../utils\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { BundledLanguage, BundledTheme, HighlighterGeneric, ThemedToken } from \"shiki\";\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1;\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2;\nconst isUnderline = (fontStyle: number | undefined) =>\n // oxlint-disable-next-line eslint(no-bitwise)\n fontStyle && fontStyle & 4;\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n token: ThemedToken;\n key: string;\n}\ninterface KeyedLine {\n tokens: KeyedToken[];\n key: string;\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n lines.map((line, lineIdx) => ({\n key: `line-${lineIdx}`,\n tokens: line.map((token, tokenIdx) => ({\n key: `line-${lineIdx}-${tokenIdx}`,\n token,\n })),\n }));\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n <span\n className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n style={\n {\n backgroundColor: token.bgColor,\n color: token.color,\n fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n ...token.htmlStyle,\n } as CSSProperties\n }\n >\n {token.content}\n </span>\n);\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n \"block\",\n \"before:content-[counter(line)]\",\n \"before:inline-block\",\n \"before:[counter-increment:line]\",\n \"before:w-8\",\n \"before:mr-4\",\n \"before:text-right\",\n \"before:text-muted-foreground/50\",\n \"before:font-mono\",\n \"before:select-none\",\n);\n\n// Line rendering component\nconst LineSpan = ({\n keyedLine,\n showLineNumbers,\n}: {\n keyedLine: KeyedLine;\n showLineNumbers: boolean;\n}) => (\n <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n {keyedLine.tokens.length === 0\n ? \"\\n\"\n : keyedLine.tokens.map(({ token, key }) => <TokenSpan key={key} token={token} />)}\n </span>\n);\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n};\n\ninterface TokenizedCode {\n tokens: ThemedToken[][];\n fg: string;\n bg: string;\n}\n\ninterface CodeBlockContextType {\n code: string;\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n code: \"\",\n});\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n string,\n Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>();\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>();\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>();\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n const start = code.slice(0, 100);\n const end = code.length > 100 ? code.slice(-100) : \"\";\n return `${language}:${code.length}:${start}:${end}`;\n};\n\nconst getHighlighter = (\n language: BundledLanguage,\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n const cached = highlighterCache.get(language);\n if (cached) {\n return cached;\n }\n\n const highlighterPromise = import(\"shiki\").then(({ createHighlighter }) =>\n createHighlighter({\n langs: [language],\n themes: [\"github-light\", \"github-dark\"],\n }),\n );\n\n highlighterCache.set(language, highlighterPromise);\n return highlighterPromise;\n};\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n bg: \"transparent\",\n fg: \"inherit\",\n tokens: code.split(\"\\n\").map((line) =>\n line === \"\"\n ? []\n : [\n {\n color: \"inherit\",\n content: line,\n } as ThemedToken,\n ],\n ),\n});\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n code: string,\n language: BundledLanguage,\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n callback?: (result: TokenizedCode) => void,\n): TokenizedCode | null => {\n const tokensCacheKey = getTokensCacheKey(code, language);\n\n // Return cached result if available\n const cached = tokensCache.get(tokensCacheKey);\n if (cached) {\n return cached;\n }\n\n // Subscribe callback if provided\n if (callback) {\n if (!subscribers.has(tokensCacheKey)) {\n subscribers.set(tokensCacheKey, new Set());\n }\n subscribers.get(tokensCacheKey)?.add(callback);\n }\n\n // Start highlighting in background - fire-and-forget async pattern\n getHighlighter(language)\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n .then((highlighter) => {\n const availableLangs = highlighter.getLoadedLanguages();\n const langToUse = availableLangs.includes(language) ? language : \"text\";\n\n const result = highlighter.codeToTokens(code, {\n lang: langToUse,\n themes: {\n dark: \"github-dark\",\n light: \"github-light\",\n },\n });\n\n const tokenized: TokenizedCode = {\n bg: result.bg ?? \"transparent\",\n fg: result.fg ?? \"inherit\",\n tokens: result.tokens,\n };\n\n // Cache the result\n tokensCache.set(tokensCacheKey, tokenized);\n\n // Notify all subscribers\n const subs = subscribers.get(tokensCacheKey);\n if (subs) {\n for (const sub of subs) {\n sub(tokenized);\n }\n subscribers.delete(tokensCacheKey);\n }\n })\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n .catch((error) => {\n console.error(\"Failed to highlight code:\", error);\n subscribers.delete(tokensCacheKey);\n });\n\n return null;\n};\n\nconst CodeBlockBody = memo(\n ({\n tokenized,\n showLineNumbers,\n className,\n }: {\n tokenized: TokenizedCode;\n showLineNumbers: boolean;\n className?: string;\n }) => {\n const preStyle = useMemo(\n () => ({\n backgroundColor: tokenized.bg,\n color: tokenized.fg,\n }),\n [tokenized.bg, tokenized.fg],\n );\n\n const keyedLines = useMemo(() => addKeysToTokens(tokenized.tokens), [tokenized.tokens]);\n\n return (\n <pre\n className={cn(\n \"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)] m-0 p-4 text-sm\",\n className,\n )}\n style={preStyle}\n >\n <code\n className={cn(\n \"font-mono text-sm\",\n showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\",\n )}\n >\n {keyedLines.map((keyedLine) => (\n <LineSpan key={keyedLine.key} keyedLine={keyedLine} showLineNumbers={showLineNumbers} />\n ))}\n </code>\n </pre>\n );\n },\n (prevProps, nextProps) =>\n prevProps.tokenized === nextProps.tokenized &&\n prevProps.showLineNumbers === nextProps.showLineNumbers &&\n prevProps.className === nextProps.className,\n);\n\nCodeBlockBody.displayName = \"CodeBlockBody\";\n\nexport const CodeBlockContainer = ({\n className,\n language,\n style,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n <div\n className={cn(\n \"group relative w-full overflow-hidden rounded-md border bg-background text-foreground\",\n className,\n )}\n data-language={language}\n style={{\n containIntrinsicSize: \"auto 200px\",\n contentVisibility: \"auto\",\n ...style,\n }}\n {...props}\n />\n);\n\nexport const CodeBlockHeader = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex items-center justify-between border-b bg-muted/80 px-3 py-2 text-muted-foreground text-xs\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport const CodeBlockTitle = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockFilename = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n <span className={cn(\"font-mono\", className)} {...props}>\n {children}\n </span>\n);\n\nexport const CodeBlockActions = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockContent = ({\n code,\n language,\n showLineNumbers = false,\n}: {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n}) => {\n // Memoized raw tokens for immediate display\n const rawTokens = useMemo(() => createRawTokens(code), [code]);\n\n // Synchronous cache lookup — avoids setState in effect for cached results\n const syncTokens = useMemo(\n () => highlightCode(code, language) ?? rawTokens,\n [code, language, rawTokens],\n );\n\n // Async highlighting result (populated after shiki loads)\n const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null);\n const asyncKeyRef = useRef({ code, language });\n\n // Invalidate stale async tokens synchronously during render\n if (asyncKeyRef.current.code !== code || asyncKeyRef.current.language !== language) {\n asyncKeyRef.current = { code, language };\n setAsyncTokens(null);\n }\n\n useEffect(() => {\n let cancelled = false;\n\n highlightCode(code, language, (result) => {\n if (!cancelled) {\n setAsyncTokens(result);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, language]);\n\n const tokenized = asyncTokens ?? syncTokens;\n\n return (\n <div className=\"relative overflow-auto\">\n <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n </div>\n );\n};\n\nexport const CodeBlock = ({\n code,\n language,\n showLineNumbers = false,\n className,\n children,\n ...props\n}: CodeBlockProps) => {\n const contextValue = useMemo(() => ({ code }), [code]);\n\n return (\n <CodeBlockContext.Provider value={contextValue}>\n <CodeBlockContainer className={className} language={language} {...props}>\n {children}\n <CodeBlockContent code={code} language={language} showLineNumbers={showLineNumbers} />\n </CodeBlockContainer>\n </CodeBlockContext.Provider>\n );\n};\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n onCopy?: () => void;\n onError?: (error: Error) => void;\n timeout?: number;\n};\n\nexport const CodeBlockCopyButton = ({\n onCopy,\n onError,\n timeout = 2000,\n children,\n className,\n ...props\n}: CodeBlockCopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number>(0);\n const { code } = useContext(CodeBlockContext);\n\n const copyToClipboard = useCallback(async () => {\n if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n onError?.(new Error(\"Clipboard API not available\"));\n return;\n }\n\n try {\n if (!isCopied) {\n await navigator.clipboard.writeText(code);\n setIsCopied(true);\n onCopy?.();\n timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout);\n }\n } catch (error) {\n onError?.(error as Error);\n }\n }, [code, onCopy, onError, timeout, isCopied]);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current);\n },\n [],\n );\n\n const Icon = isCopied ? CheckIcon : CopyIcon;\n\n return (\n <Button\n className={cn(\"shrink-0\", className)}\n onClick={copyToClipboard}\n size=\"icon\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <Icon size={14} />}\n </Button>\n );\n};\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>;\n\nexport const CodeBlockLanguageSelector = (props: CodeBlockLanguageSelectorProps) => (\n <Select {...props} />\n);\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<typeof SelectTrigger>;\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n className,\n ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n <SelectTrigger\n className={cn(\"h-7 border-none bg-transparent px-2 text-xs shadow-none\", className)}\n size=\"sm\"\n {...props}\n />\n);\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<typeof SelectValue>;\n\nexport const CodeBlockLanguageSelectorValue = (props: CodeBlockLanguageSelectorValueProps) => (\n <SelectValue {...props} />\n);\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<typeof SelectContent>;\n\nexport const CodeBlockLanguageSelectorContent = ({\n align = \"end\",\n ...props\n}: CodeBlockLanguageSelectorContentProps) => <SelectContent align={align} {...props} />;\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<typeof SelectItem>;\n\nexport const CodeBlockLanguageSelectorItem = (props: CodeBlockLanguageSelectorItemProps) => (\n <SelectItem {...props} />\n);\n","import type { UIMessage } from \"ai\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst asTimestamp = (value: unknown): number | undefined => {\n if (value instanceof Date) return Number.isFinite(value.getTime()) ? value.getTime() : undefined;\n if (typeof value === \"number\") return Number.isFinite(value) ? value : undefined;\n if (typeof value !== \"string\") return undefined;\n\n const timestamp = Date.parse(value);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n};\n\nconst getMastraCreatedAt = (value: unknown): number | undefined => {\n if (!isRecord(value) || !isRecord(value.mastra)) return undefined;\n return asTimestamp(value.mastra.createdAt);\n};\n\nconst getPartTimestamps = (part: UIMessage[\"parts\"][number]): number[] => {\n const value = part as unknown as Record<string, unknown>;\n return [\n getMastraCreatedAt(value.providerMetadata),\n getMastraCreatedAt(value.callProviderMetadata),\n getMastraCreatedAt(value.resultProviderMetadata),\n ].filter((timestamp): timestamp is number => timestamp !== undefined);\n};\n\n/**\n * Mastra persists message and part timestamps already. Reconstructing elapsed\n * time here keeps restored chats informative without a second timing store.\n */\nexport const getPersistedMessageDurationSeconds = (message: UIMessage): number | undefined => {\n if (!isRecord(message.metadata)) return undefined;\n\n const startedAt = asTimestamp(message.metadata.createdAt);\n if (startedAt === undefined) return undefined;\n\n const completedAt = Math.max(...message.parts.flatMap(getPartTimestamps));\n if (!Number.isFinite(completedAt) || completedAt < startedAt) return undefined;\n\n return Math.max(1, Math.ceil((completedAt - startedAt) / 1000));\n};\n","\"use client\";\n\nimport {\n ChainOfThought,\n ChainOfThoughtContent,\n ChainOfThoughtHeader,\n ChainOfThoughtStep,\n} from \"./internal/chain-of-thought\";\nimport {\n Conversation,\n ConversationContent,\n ConversationEmptyState,\n ConversationScrollButton,\n} from \"./internal/conversation\";\nimport { Message, MessageContent } from \"./internal/message\";\nimport {\n PromptInput,\n PromptInputAttachmentButton,\n PromptInputBody,\n PromptInputFooter,\n PromptInputSubmit,\n PromptInputTextarea,\n type PromptInputMessage,\n} from \"./internal/prompt-input\";\nimport { stringifyToolTechnicalDetails } from \"./internal/tool-technical-details\";\nimport { Response } from \"./internal/response\";\nimport { CodeBlock } from \"./internal/code-block\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./internal/collapsible\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./internal/select\";\nimport { cn } from \"./utils\";\nimport { parseSurveyAssistantError, SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE } from \"../protocol\";\nimport type {\n SurveyApplyResult,\n SurveyAssistantAttachmentReference,\n SurveyAssistantModelOption,\n SurveyAssistantThread,\n SurveyChangeSet,\n} from \"../protocol\";\nimport {\n createSurveyAssistantThreadClient,\n isSurveyAssistantTurnActive,\n parseSurveyChangeSet,\n type SurveyAssistantThreadClient,\n type SurveyAssistantSessionOptions,\n type SurveyTurnOutcome,\n unwrapSurveyAssistantToolOutput,\n useSurveyAssistantSession,\n} from \"../react\";\nimport {\n connectSurveyAssistantThreadLauncher,\n type SurveyAssistantThreadLaunch,\n type SurveyAssistantThreadLauncher,\n} from \"../react/thread-launcher\";\nimport type { LocalizationCatalog, LocalizationTranslate } from \"@case-framework/ui-localization\";\nimport {\n getToolName,\n isFileUIPart,\n isReasoningUIPart,\n isToolUIPart,\n type DynamicToolUIPart,\n type FileUIPart,\n type ToolUIPart,\n type UIMessage,\n} from \"ai\";\nimport {\n CheckCircleIcon,\n ChevronRightIcon,\n ClockIcon,\n FileIcon,\n HistoryIcon,\n ListChecksIcon,\n LoaderCircleIcon,\n BotIcon,\n MessageSquarePlusIcon,\n PencilIcon,\n PlusIcon,\n SparklesIcon,\n Trash2Icon,\n WandSparklesIcon,\n WrenchIcon,\n XCircleIcon,\n} from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { SurveyAssistantLocalizationProvider, useSurveyAssistantTranslation } from \"./localization\";\nimport { getPersistedMessageDurationSeconds } from \"./internal/message-timing\";\n\ntype ToolPart = ToolUIPart | DynamicToolUIPart;\n\nconst getAssistantQuickPrompts = (t: LocalizationTranslate) => [\n {\n label: t(\"quickActions.review.label\"),\n description: t(\"quickActions.review.description\"),\n icon: ListChecksIcon,\n prompt: t(\"quickActions.review.prompt\"),\n },\n {\n label: t(\"quickActions.create.label\"),\n description: t(\"quickActions.create.description\"),\n icon: MessageSquarePlusIcon,\n prompt: t(\"quickActions.create.prompt\"),\n },\n {\n label: t(\"quickActions.refine.label\"),\n description: t(\"quickActions.refine.description\"),\n icon: WandSparklesIcon,\n prompt: t(\"quickActions.refine.prompt\"),\n },\n];\n\nconst isSurveyAssistantAttachmentReferencePart = (\n part: UIMessage[\"parts\"][number],\n): part is {\n type: typeof SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE;\n data: SurveyAssistantAttachmentReference;\n} => {\n if (\n part.type !== SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE ||\n typeof part.data !== \"object\" ||\n part.data === null\n ) {\n return false;\n }\n const data = part.data as Partial<SurveyAssistantAttachmentReference>;\n return (\n typeof data.filename === \"string\" &&\n typeof data.mediaType === \"string\" &&\n typeof data.bytes === \"number\"\n );\n};\n\nconst hasRenderableParts = (message: UIMessage) => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" && part.text.length > 0) ||\n isFileUIPart(part) ||\n isSurveyAssistantAttachmentReferencePart(part) ||\n (isReasoningUIPart(part) && part.text.trim().length > 0) ||\n isToolUIPart(part),\n );\n};\n\nconst getFilePartLabel = (part: FileUIPart) => part.filename ?? part.mediaType;\n\nconst getToolOutput = (part: ToolPart) =>\n part.state === \"output-available\" ? part.output : undefined;\n\nconst getToolErrorText = (part: ToolPart) =>\n part.state === \"output-error\" ? part.errorText : undefined;\n\nconst localizedToolNames = new Set([\n \"survey_inspect\",\n \"survey_change\",\n \"survey_expression\",\n \"survey_authoring_reference\",\n \"survey_attachment\",\n \"recall\",\n]);\n\nconst getToolDisplayName = (\n t: LocalizationTranslate,\n toolName: string,\n phase: \"active\" | \"complete\" = \"complete\",\n) =>\n localizedToolNames.has(toolName)\n ? t(`activity.tools.${toolName}.${phase}`)\n : t(phase === \"active\" ? \"activity.genericActive\" : \"activity.genericComplete\");\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst unwrapOutput = unwrapSurveyAssistantToolOutput;\n\ntype AssistantErrorPresentation = {\n description: string;\n hint: string;\n title: string;\n tone: \"warning\" | \"error\";\n};\n\nconst getAssistantErrorPresentation = (\n error: unknown,\n t: LocalizationTranslate,\n): AssistantErrorPresentation => {\n const parsed = parseSurveyAssistantError(error);\n return {\n title: t(`errors.${parsed.code}.title`),\n description: parsed.detail ?? t(\"errors.fallbackDetail\"),\n hint: t(`errors.${parsed.code}.hint`),\n tone:\n parsed.code === \"model_unavailable\" || parsed.code === \"rate_limited\" ? \"warning\" : \"error\",\n };\n};\n\nconst getChangeSet = parseSurveyChangeSet;\n\nconst isChangeSet = (output: unknown): output is SurveyChangeSet => {\n return getChangeSet(output) !== null;\n};\n\nconst getValidationCounts = (validation: unknown) => {\n if (!isRecord(validation)) {\n return { issueCount: 0, warningCount: 0 };\n }\n\n return {\n issueCount: Array.isArray(validation.issues) ? validation.issues.length : 0,\n warningCount: Array.isArray(validation.warnings) ? validation.warnings.length : 0,\n };\n};\n\nconst SurveyAssistantToolOutputSummary = ({\n applyResult,\n output,\n}: {\n applyResult?: SurveyApplyResult;\n output: unknown;\n}) => {\n const t = useSurveyAssistantTranslation();\n const unwrappedOutput = unwrapOutput(output);\n\n if (isChangeSet(unwrappedOutput)) {\n const { issueCount, warningCount } = getValidationCounts(unwrappedOutput.validation);\n const isValid = unwrappedOutput.status === \"validated\";\n const status = applyResult?.status ?? (isValid ? \"validated\" : \"rejected\");\n const isPositiveStatus = status === \"applied\" || status === \"validated\";\n const statusLabel =\n status === \"applied\"\n ? t(\"changes.applied\")\n : status === \"stale\"\n ? t(\"changes.stale\")\n : status === \"failed\"\n ? t(\"changes.failed\")\n : isValid\n ? t(\"changes.prepared\")\n : t(\"changes.rejected\");\n const statusMessage = applyResult?.message ?? unwrappedOutput.summary;\n\n return (\n <div\n className={cn(\n \"relative rounded-md border px-2.5 py-2 text-xs\",\n isPositiveStatus\n ? \"border-emerald-200/80 bg-emerald-50/60 text-emerald-950\"\n : status === \"stale\"\n ? \"border-amber-200 bg-amber-50 text-amber-900\"\n : \"border-red-200 bg-red-50 text-red-900\",\n )}\n >\n <div className=\"flex items-center gap-2 font-medium\">\n {isPositiveStatus ? (\n <CheckCircleIcon className=\"size-3.5 shrink-0\" />\n ) : (\n <XCircleIcon className=\"size-3.5 shrink-0\" />\n )}\n <span>{statusLabel}</span>\n </div>\n <div className=\"mt-1 text-xs\">\n {statusMessage}\n {unwrappedOutput.operations.length > 0 && (\n <span className=\"text-current/70\">\n {\" \"}\n (\n {t(\n unwrappedOutput.operations.length === 1\n ? \"changes.operationCount\"\n : \"changes.operationCountPlural\",\n { count: unwrappedOutput.operations.length },\n )}\n )\n </span>\n )}\n </div>\n {(issueCount > 0 || warningCount > 0) && (\n <div className=\"mt-1 text-current/70\">\n {issueCount > 0 &&\n t(issueCount === 1 ? \"changes.issueCount\" : \"changes.issueCountPlural\", {\n count: issueCount,\n })}\n {issueCount > 0 && warningCount > 0 && \", \"}\n {warningCount > 0 &&\n t(warningCount === 1 ? \"changes.warningCount\" : \"changes.warningCountPlural\", {\n count: warningCount,\n })}\n </div>\n )}\n </div>\n );\n }\n\n return null;\n};\n\nconst getToolTitle = (t: LocalizationTranslate, toolName: string, state: ToolPart[\"state\"]) => {\n if (state === \"output-available\") {\n return getToolDisplayName(t, toolName, \"complete\");\n }\n if (state === \"output-error\") {\n return t(\"activity.failedSuffix\", { name: getToolDisplayName(t, toolName, \"complete\") });\n }\n if (state === \"output-denied\") {\n return t(\"activity.skippedSuffix\", { name: getToolDisplayName(t, toolName, \"active\") });\n }\n\n return getToolDisplayName(t, toolName, \"active\");\n};\n\nconst getToolProgressLabel = (t: LocalizationTranslate, part: ToolPart) => {\n switch (part.state) {\n case \"approval-requested\":\n return t(\"activity.waitingApproval\");\n case \"approval-responded\":\n return t(\"activity.continuingApproval\");\n case \"input-streaming\":\n return t(\"activity.preparingStep\");\n case \"input-available\":\n return getToolDisplayName(t, getToolName(part), \"active\");\n case \"output-available\":\n return t(\"activity.usingResult\");\n case \"output-denied\":\n return t(\"activity.continuingWithoutStep\");\n case \"output-error\":\n return t(\"activity.recoveringToolError\");\n }\n};\n\nconst getToolStatusMeta = (\n t: LocalizationTranslate,\n): Record<\n ToolPart[\"state\"],\n { icon: ReactNode; label: string | null; stepStatus: \"active\" | \"complete\" }\n> => ({\n \"approval-requested\": {\n icon: <ClockIcon className=\"size-3 text-amber-600\" />,\n label: t(\"activity.waitingApproval\"),\n stepStatus: \"active\",\n },\n \"approval-responded\": {\n icon: <CheckCircleIcon className=\"size-3 text-blue-600\" />,\n label: t(\"activity.approvalReceived\"),\n stepStatus: \"complete\",\n },\n \"input-available\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"input-streaming\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"output-available\": {\n icon: <CheckCircleIcon className=\"size-3 text-emerald-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-denied\": {\n icon: <XCircleIcon className=\"size-3 text-orange-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-error\": {\n icon: <XCircleIcon className=\"size-3 text-red-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n});\n\nconst getStoppedToolStatusMeta = (t: LocalizationTranslate) => ({\n icon: <XCircleIcon className=\"size-3 text-muted-foreground\" />,\n label: t(\"activity.stopped\"),\n stepStatus: \"complete\" as const,\n});\n\nconst SurveyAssistantToolStep = ({\n applyResultsByChangeId,\n isAborted,\n part,\n isLast,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n isAborted: boolean;\n part: ToolPart;\n isLast: boolean;\n}) => {\n const t = useSurveyAssistantTranslation();\n const toolStatusMeta = getToolStatusMeta(t);\n const toolName = getToolName(part);\n const output = getToolOutput(part);\n const errorText = getToolErrorText(part);\n const changeSet = output === undefined ? null : getChangeSet(output);\n const applyResult = changeSet ? applyResultsByChangeId[changeSet.id] : undefined;\n const title = changeSet\n ? toolName === \"survey_expression\"\n ? t(\"activity.expressionChange\")\n : t(\"activity.surveyChange\")\n : getToolTitle(t, toolName, part.state);\n const meta =\n isAborted && toolStatusMeta[part.state].stepStatus === \"active\"\n ? getStoppedToolStatusMeta(t)\n : toolStatusMeta[part.state];\n const metaTitle =\n meta.label ??\n (part.state === \"output-denied\"\n ? t(\"activity.skipped\")\n : part.state === \"output-error\"\n ? t(\"activity.failed\")\n : meta.stepStatus === \"active\"\n ? t(\"activity.workingShort\")\n : t(\"activity.done\"));\n const [detailsOpen, setDetailsOpen] = useState(part.state === \"output-error\");\n const hasDetails = part.input !== undefined || output !== undefined || Boolean(errorText);\n\n return (\n <ChainOfThoughtStep\n icon={WrenchIcon}\n isLast={isLast}\n label={\n <span className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span>{title}</span>\n <span\n className={cn(\n \"inline-flex shrink-0 items-center gap-1 text-[11px] font-normal\",\n meta.stepStatus === \"active\" ? \"text-blue-700\" : \"text-muted-foreground\",\n )}\n title={metaTitle}\n >\n {meta.icon}\n {meta.label && <span>{meta.label}</span>}\n {!meta.label && <span className=\"sr-only\">{metaTitle}</span>}\n </span>\n </span>\n }\n result={\n output !== undefined ? (\n <SurveyAssistantToolOutputSummary applyResult={applyResult} output={output} />\n ) : undefined\n }\n status={meta.stepStatus}\n >\n {hasDetails && (\n <Collapsible onOpenChange={setDetailsOpen} open={detailsOpen}>\n <CollapsibleTrigger className=\"flex items-center gap-1 text-muted-foreground text-xs hover:text-foreground\">\n <ChevronRightIcon\n className={cn(\"size-3 transition-transform\", detailsOpen && \"rotate-90\")}\n />\n {t(detailsOpen ? \"activity.hideTechnicalDetails\" : \"activity.technicalDetails\")}\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-2 space-y-2\">\n {part.input !== undefined && (\n <CodeBlock\n className=\"border-border/50 bg-muted/30\"\n code={stringifyToolTechnicalDetails(part.input)}\n language=\"json\"\n />\n )}\n {(output !== undefined || errorText) && (\n <CodeBlock\n className={cn(\n \"bg-muted/30\",\n errorText ? \"border-destructive/30\" : \"border-border/50\",\n )}\n code={errorText ?? stringifyToolTechnicalDetails(output)}\n language=\"json\"\n />\n )}\n </CollapsibleContent>\n </Collapsible>\n )}\n </ChainOfThoughtStep>\n );\n};\n\nconst getStreamingProgressLabel = (t: LocalizationTranslate, message?: UIMessage) => {\n if (!message || message.role !== \"assistant\") {\n return t(\"status.connecting\");\n }\n\n const lastPart = message.parts.at(-1);\n if (!lastPart) {\n return t(\"status.thinking\");\n }\n\n if (isReasoningUIPart(lastPart)) {\n return t(\"status.thinking\");\n }\n\n if (isToolUIPart(lastPart)) {\n return getToolProgressLabel(t, lastPart);\n }\n\n if (lastPart.type === \"text\") {\n return t(\"status.writing\");\n }\n\n return t(\"status.working\");\n};\n\nconst SurveyAssistantProgressIndicator = ({ message }: { message?: UIMessage }) => {\n const t = useSurveyAssistantTranslation();\n return (\n <div\n aria-live=\"polite\"\n className=\"mt-2 flex items-center gap-2 px-1 text-muted-foreground text-xs\"\n role=\"status\"\n >\n <LoaderCircleIcon className=\"size-3.5 animate-spin text-blue-600\" />\n <span>{getStreamingProgressLabel(t, message)}</span>\n </div>\n );\n};\n\ntype ChainOfThoughtEntry =\n | { type: \"reasoning\"; key: string; text: string }\n | { type: \"tool\"; key: string; part: ToolPart };\n\ntype MessageBlock =\n | {\n type: \"attachment-reference\";\n key: string;\n attachment: SurveyAssistantAttachmentReference;\n }\n | { type: \"chain\"; key: string; entries: ChainOfThoughtEntry[] }\n | { type: \"file\"; key: string; part: FileUIPart }\n | { type: \"text\"; key: string; text: string };\n\n// Group the message's parts into ordered blocks, keeping text interleaved\n// with reasoning/tool-call chains in the exact order they were emitted,\n// instead of hoisting all reasoning/tool calls above all text output.\nconst buildMessageBlocks = (parts: UIMessage[\"parts\"]): MessageBlock[] => {\n const blocks: MessageBlock[] = [];\n let pendingEntries: ChainOfThoughtEntry[] = [];\n\n const flushChain = () => {\n if (pendingEntries.length > 0) {\n blocks.push({\n type: \"chain\",\n key: `chain-${pendingEntries[0].key}`,\n entries: pendingEntries,\n });\n pendingEntries = [];\n }\n };\n\n parts.forEach((part, index) => {\n if (isReasoningUIPart(part)) {\n if (part.text) {\n pendingEntries.push({ type: \"reasoning\", key: `reasoning-${index}`, text: part.text });\n }\n return;\n }\n\n if (isToolUIPart(part)) {\n pendingEntries.push({ type: \"tool\", key: `tool-${part.toolCallId}`, part });\n return;\n }\n\n if (part.type === \"text\") {\n flushChain();\n blocks.push({ type: \"text\", key: `text-${index}`, text: part.text });\n return;\n }\n\n if (isFileUIPart(part)) {\n flushChain();\n blocks.push({ type: \"file\", key: `file-${index}`, part });\n return;\n }\n\n if (isSurveyAssistantAttachmentReferencePart(part)) {\n flushChain();\n blocks.push({\n type: \"attachment-reference\",\n key: `attachment-reference-${index}`,\n attachment: part.data,\n });\n }\n });\n\n flushChain();\n\n return blocks;\n};\n\nconst SurveyAssistantMessageParts = ({\n applyResultsByChangeId,\n isAborted,\n isLastMessage,\n isStreaming,\n message,\n showProgress,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n isAborted: boolean;\n isLastMessage: boolean;\n isStreaming: boolean;\n message: UIMessage;\n showProgress?: boolean;\n}) => {\n const blocks = useMemo(() => buildMessageBlocks(message.parts), [message.parts]);\n const persistedDuration = useMemo(() => getPersistedMessageDurationSeconds(message), [message]);\n const lastPart = message.parts.at(-1);\n const hasActiveToolMessage =\n lastPart !== undefined &&\n isToolUIPart(lastPart) &&\n (lastPart.state === \"input-streaming\" || lastPart.state === \"input-available\");\n\n return (\n <>\n {blocks.map((block, blockIndex) => {\n const isLastBlock = blockIndex === blocks.length - 1;\n\n if (block.type === \"text\") {\n if (message.role === \"assistant\") {\n return (\n <Response\n className=\"leading-5 [&_li]:my-0.5 [&_p]:my-1.5 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\"\n key={block.key}\n >\n {block.text}\n </Response>\n );\n }\n\n return <span key={block.key}>{block.text}</span>;\n }\n\n if (block.type === \"file\") {\n return (\n <a\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs hover:bg-muted/80\"\n href={block.part.url}\n key={block.key}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{getFilePartLabel(block.part)}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.part.mediaType}</span>\n </a>\n );\n }\n\n if (block.type === \"attachment-reference\") {\n return (\n <span\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={block.key}\n title={block.attachment.filename}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{block.attachment.filename}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.attachment.mediaType}</span>\n </span>\n );\n }\n\n const isChainActive = isLastMessage && isStreaming && isLastBlock;\n\n return (\n <ChainOfThought\n autoClose\n className=\"w-full rounded-md bg-muted/35 px-2 py-1.5\"\n defaultDuration={persistedDuration}\n defaultOpen={isChainActive}\n isStreaming={isChainActive}\n key={block.key}\n >\n <ChainOfThoughtHeader className=\"text-xs font-medium\" />\n <ChainOfThoughtContent className=\"relative mt-2\">\n <div\n aria-hidden=\"true\"\n className=\"absolute top-0 bottom-0 left-1.75 w-px bg-border\"\n />\n {block.entries.map((entry, index) => {\n const isLastEntry = index === block.entries.length - 1;\n\n if (entry.type === \"reasoning\") {\n return (\n <Response\n className={cn(\n \"pr-1 pl-5 text-muted-foreground text-xs leading-5 [&_p]:my-1 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\",\n !isLastEntry && \"mb-2\",\n )}\n key={entry.key}\n >\n {entry.text}\n </Response>\n );\n }\n\n return (\n <SurveyAssistantToolStep\n applyResultsByChangeId={applyResultsByChangeId}\n isAborted={isAborted}\n isLast={isLastEntry}\n key={entry.key}\n part={entry.part}\n />\n );\n })}\n </ChainOfThoughtContent>\n </ChainOfThought>\n );\n })}\n {showProgress &&\n !hasActiveToolMessage &&\n (lastPart === undefined || !isReasoningUIPart(lastPart)) && (\n <SurveyAssistantProgressIndicator message={message} />\n )}\n </>\n );\n};\n\nexport type SurveyAssistantPanelProps = Omit<\n SurveyAssistantSessionOptions,\n \"initialMessages\" | \"modelId\" | \"resourceId\" | \"threadId\"\n> & {\n embedded?: boolean;\n language?: string;\n localizations?: LocalizationCatalog;\n modelId?: string;\n models?: SurveyAssistantModelOption[];\n onConfirmDeleteThread?: (thread: SurveyAssistantThread) => boolean | Promise<boolean>;\n onModelChange?(modelId: string): void;\n resourceId: string;\n selectedThreadStorageKey?: string | false;\n threadApi?: string;\n threadClient?: SurveyAssistantThreadClient;\n /** Allows host UI outside the panel to create a new thread and execute its first prompt. */\n threadLauncher?: SurveyAssistantThreadLauncher;\n};\n\ntype SurveyAssistantChatPanelProps = SurveyAssistantSessionOptions & {\n embedded?: boolean;\n initialLaunch?: SurveyAssistantThreadLaunch;\n models: SurveyAssistantModelOption[];\n onInitialLaunchHandled(): void;\n onModelChange(modelId: string): void;\n onFirstSubmit(text: string): void;\n onTurnSettled(): void;\n threadControls: ReactNode;\n threadTitle: string;\n};\n\nconst SurveyAssistantTurnOutcomeNotice = (outcome: SurveyTurnOutcome) => {\n const t = useSurveyAssistantTranslation();\n const description =\n outcome.status === \"blocked\"\n ? t(outcome.blockedChangeSetCount === 1 ? \"changes.blocked\" : \"changes.blockedPlural\", {\n count: outcome.blockedChangeSetCount,\n })\n : t(outcome.appliedChangeSetCount === 1 ? \"changes.partial\" : \"changes.partialPlural\", {\n applied: outcome.appliedChangeSetCount,\n failed: outcome.failedChangeSetCount,\n });\n\n return (\n <div className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-amber-950 text-xs\">\n <div className=\"font-medium\">{t(\"changes.incompleteTitle\")}</div>\n <div className=\"mt-1\">\n {description} {t(\"changes.reviewBeforeRetry\")}\n </div>\n </div>\n );\n};\n\nconst SurveyAssistantHeaderIdentity = ({\n indicatorClassName,\n status,\n title,\n}: {\n indicatorClassName: string;\n status: string;\n title: string;\n}) => (\n <div className=\"flex min-w-0 items-center gap-2\">\n <div className=\"relative flex size-6 shrink-0 items-center justify-center rounded-md bg-foreground text-background shadow-sm\">\n <SparklesIcon className=\"size-3.5\" />\n <span\n aria-hidden=\"true\"\n className={cn(\n \"absolute -right-px -bottom-px size-1.5 rounded-full border border-background\",\n indicatorClassName,\n )}\n />\n </div>\n <div className=\"min-w-0\">\n <h2 className=\"truncate font-semibold text-[13px] leading-4\">{title}</h2>\n <span\n aria-live=\"polite\"\n className=\"block truncate text-[10px] text-muted-foreground leading-3\"\n role=\"status\"\n >\n {status}\n </span>\n </div>\n </div>\n);\n\nconst SurveyAssistantChatPanel = ({\n api,\n applyPolicy,\n controller,\n embedded = false,\n initialLaunch,\n initialMessages,\n modelId,\n models,\n onInitialLaunchHandled,\n onModelChange,\n onFirstSubmit,\n onTurnSettled,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadControls,\n threadId,\n threadTitle,\n}: SurveyAssistantChatPanelProps) => {\n const t = useSurveyAssistantTranslation();\n const assistantQuickPrompts = getAssistantQuickPrompts(t);\n const {\n applyResultsByChangeId,\n authorizationError,\n dismissError,\n error,\n isStreaming,\n latestTurnOutcome,\n messages,\n state,\n status,\n stop,\n submit,\n retry,\n } = useSurveyAssistantSession({\n api,\n applyPolicy,\n controller,\n initialMessages,\n modelId,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadId,\n });\n const showAssistantError = Boolean(authorizationError) || Boolean(error);\n const assistantErrorPresentation = getAssistantErrorPresentation(authorizationError ?? error, t);\n const selectedModelLabel =\n models.find((model) => model.id === modelId)?.label ?? modelId ?? t(\"input.defaultModel\");\n const lastMessage = messages.at(-1);\n const isAssistantTurnActive = isSurveyAssistantTurnActive({ isStreaming, state });\n const promptTextareaRef = useRef<HTMLTextAreaElement>(null);\n const shouldRestorePromptFocusRef = useRef(false);\n const turnWasActiveRef = useRef(false);\n const isAssistantTurnSettled =\n !isStreaming &&\n (state === \"completed\" || state === \"failed\" || state === \"aborted\" || state === \"applied\");\n\n useEffect(() => {\n if (!isAssistantTurnActive) {\n if (shouldRestorePromptFocusRef.current) {\n shouldRestorePromptFocusRef.current = false;\n promptTextareaRef.current?.focus();\n }\n return;\n }\n\n const cancelFocusRestoreOnPointerDown = (event: PointerEvent) => {\n if (event.target !== promptTextareaRef.current) {\n shouldRestorePromptFocusRef.current = false;\n }\n };\n const cancelFocusRestore = () => {\n shouldRestorePromptFocusRef.current = false;\n };\n\n document.addEventListener(\"focusin\", cancelFocusRestore, true);\n document.addEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.addEventListener(\"blur\", cancelFocusRestore);\n\n return () => {\n document.removeEventListener(\"focusin\", cancelFocusRestore, true);\n document.removeEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.removeEventListener(\"blur\", cancelFocusRestore);\n };\n }, [isAssistantTurnActive]);\n\n useEffect(() => {\n if (isAssistantTurnActive) {\n turnWasActiveRef.current = true;\n return;\n }\n if (!turnWasActiveRef.current || !isAssistantTurnSettled) return;\n\n turnWasActiveRef.current = false;\n onTurnSettled();\n }, [isAssistantTurnActive, isAssistantTurnSettled, onTurnSettled]);\n\n const showPendingAssistantRow =\n isAssistantTurnActive && (!lastMessage || lastMessage.role !== \"assistant\");\n const sessionStatusLabel =\n state === \"applying\"\n ? t(\"status.applying\")\n : state === \"applied\"\n ? t(\"status.applied\")\n : state === \"aborted\"\n ? t(\"status.stopped\")\n : isAssistantTurnActive\n ? getStreamingProgressLabel(t, lastMessage)\n : showAssistantError\n ? t(\"status.attention\")\n : t(\"status.ready\");\n\n const handleSubmit = useCallback(\n (message: PromptInputMessage) => {\n if (isAssistantTurnActive) return false;\n const submittedFromFocusedPrompt = document.activeElement === promptTextareaRef.current;\n const accepted = submit({ files: message.files, text: message.text });\n if (accepted) {\n shouldRestorePromptFocusRef.current = submittedFromFocusedPrompt;\n onFirstSubmit(message.text);\n }\n return accepted;\n },\n [isAssistantTurnActive, onFirstSubmit, submit],\n );\n\n const handleQuickPrompt = useCallback(\n (prompt: string) => handleSubmit({ files: [], text: prompt }),\n [handleSubmit],\n );\n\n useEffect(() => {\n if (!initialLaunch) return;\n const accepted = submit({\n files: initialLaunch.files ?? [],\n text: initialLaunch.prompt,\n uiContext: initialLaunch.uiContext,\n });\n if (accepted) {\n onFirstSubmit(initialLaunch.prompt);\n onInitialLaunchHandled();\n }\n }, [initialLaunch, onFirstSubmit, onInitialLaunchHandled, submit]);\n\n return (\n <aside\n aria-label={t(\"panel.ariaLabel\")}\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center justify-between gap-2 border-b border-border bg-muted/20 px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName={\n showAssistantError\n ? \"bg-destructive\"\n : isAssistantTurnActive\n ? \"animate-pulse bg-blue-500\"\n : state === \"aborted\"\n ? \"bg-muted-foreground\"\n : \"bg-emerald-500\"\n }\n status={sessionStatusLabel}\n title={threadTitle}\n />\n {threadControls}\n </header>\n\n <Conversation className=\"min-h-0\">\n <ConversationContent className=\"gap-3 px-3 py-2.5\">\n {messages.length === 0 ? (\n <ConversationEmptyState className=\"min-h-full items-stretch justify-center gap-0 px-1 py-6 text-left\">\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-3 flex size-10 items-center justify-center rounded-xl bg-foreground text-background shadow-sm\">\n <SparklesIcon className=\"size-5\" />\n </div>\n <h3 className=\"font-semibold text-foreground text-base tracking-tight\">\n {t(\"empty.title\")}\n </h3>\n <p className=\"mt-1 text-muted-foreground text-xs leading-relaxed\">\n {t(\"empty.description\")}\n </p>\n <div className=\"mt-4 flex flex-col gap-1.5\">\n {assistantQuickPrompts.map(({ label, description, icon: Icon, prompt }) => (\n <button\n className=\"group flex w-full items-center gap-2.5 rounded-lg border border-border bg-background px-2.5 py-2 text-left transition-colors hover:border-foreground/20 hover:bg-muted/50\"\n key={label}\n onClick={() => handleQuickPrompt(prompt)}\n type=\"button\"\n >\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground transition-colors group-hover:bg-background group-hover:text-foreground\">\n <Icon className=\"size-3.5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium text-foreground text-xs\">\n {label}\n </span>\n <span className=\"block truncate text-[11px] text-muted-foreground\">\n {description}\n </span>\n </span>\n <ChevronRightIcon className=\"size-3.5 shrink-0 text-muted-foreground/40 transition-transform group-hover:translate-x-0.5 group-hover:text-muted-foreground\" />\n </button>\n ))}\n </div>\n </div>\n </ConversationEmptyState>\n ) : (\n <>\n {messages.map((message, index) => {\n const isLastMessage = index === messages.length - 1;\n const shouldShowProgress =\n isAssistantTurnActive && isLastMessage && message.role === \"assistant\";\n\n return (\n <Message className=\"max-w-[96%] gap-1\" from={message.role} key={message.id}>\n <MessageContent\n className={cn(message.role === \"assistant\" && \"w-full space-y-2\")}\n >\n {hasRenderableParts(message) ? (\n <>\n <SurveyAssistantMessageParts\n applyResultsByChangeId={applyResultsByChangeId}\n isAborted={state === \"aborted\"}\n isLastMessage={isLastMessage}\n isStreaming={isAssistantTurnActive}\n message={message}\n showProgress={shouldShowProgress}\n />\n {isLastMessage && latestTurnOutcome && (\n <SurveyAssistantTurnOutcomeNotice {...latestTurnOutcome} />\n )}\n </>\n ) : shouldShowProgress ? (\n <SurveyAssistantProgressIndicator message={message} />\n ) : state === \"aborted\" ? (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.stopped\")}\n </span>\n ) : (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.working\")}\n </span>\n )}\n </MessageContent>\n </Message>\n );\n })}\n {showPendingAssistantRow && (\n <Message className=\"max-w-[96%] gap-1\" from=\"assistant\">\n <MessageContent className=\"w-full\">\n <SurveyAssistantProgressIndicator />\n </MessageContent>\n </Message>\n )}\n </>\n )}\n </ConversationContent>\n <ConversationScrollButton className=\"bottom-2.5\" />\n </Conversation>\n\n {showAssistantError && (\n <div\n className={cn(\n \"flex items-start justify-between gap-3 border-t px-3 py-2.5 text-sm\",\n assistantErrorPresentation.tone === \"warning\"\n ? \"border-amber-200 bg-amber-50/60\"\n : \"border-destructive/20 bg-destructive/5\",\n )}\n role=\"alert\"\n >\n <div className=\"flex min-w-0 gap-2.5\">\n {assistantErrorPresentation.tone === \"warning\" ? (\n <WrenchIcon className=\"mt-0.5 size-4 shrink-0 text-amber-700\" />\n ) : (\n <XCircleIcon className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n )}\n <div className=\"min-w-0\">\n <div className=\"font-medium text-foreground\">{assistantErrorPresentation.title}</div>\n <p className=\"mt-0.5 wrap-break-word text-muted-foreground\">\n {assistantErrorPresentation.description}\n </p>\n <p className=\"mt-1 text-muted-foreground/80\">{assistantErrorPresentation.hint}</p>\n <button\n className=\"mt-1.5 font-medium text-foreground text-xs hover:underline\"\n onClick={retry}\n type=\"button\"\n >\n {t(\"errors.retry\")}\n </button>\n </div>\n </div>\n <button\n aria-label={t(\"errors.dismissAssistant\")}\n className=\"shrink-0 text-muted-foreground text-xs hover:text-foreground\"\n onClick={dismissError}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n\n <div className=\"shrink-0 border-t border-border bg-muted/20 p-2\">\n <PromptInput\n aria-busy={isAssistantTurnActive}\n attachmentsDisabled={isAssistantTurnActive}\n className={cn(\n \"rounded-xl border-border bg-background shadow-sm transition-colors\",\n isAssistantTurnActive && \"border-border/60 bg-muted/50 shadow-none\",\n )}\n onSubmit={handleSubmit}\n >\n <PromptInputBody>\n <PromptInputTextarea\n className=\"min-h-11 max-h-28 px-3 pt-2.5 pb-1.5 transition-colors disabled:cursor-not-allowed disabled:text-muted-foreground disabled:placeholder:text-muted-foreground/60\"\n disabled={isAssistantTurnActive}\n placeholder={t(\"input.placeholder\")}\n ref={promptTextareaRef}\n />\n </PromptInputBody>\n <PromptInputFooter\n className={cn(\n \"justify-between border-0 px-1.5 pt-0 pb-1.5 transition-colors\",\n isAssistantTurnActive && \"bg-muted/30\",\n )}\n >\n <PromptInputAttachmentButton className=\"size-8\" disabled={isAssistantTurnActive} />\n <div className=\"flex min-w-0 items-center justify-end gap-1\">\n {models.length > 1 && modelId ? (\n <Select\n disabled={isAssistantTurnActive}\n onValueChange={onModelChange}\n value={modelId}\n >\n <SelectTrigger\n aria-label={t(\"input.model\")}\n className=\"h-8 min-w-0 max-w-48 gap-1.5 border-0 bg-transparent px-2 text-xs shadow-none hover:bg-muted hover:text-foreground focus-visible:ring-1\"\n size=\"sm\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5\" />\n <SelectValue />\n </SelectTrigger>\n <SelectContent\n align=\"end\"\n className=\"min-w-52 rounded-lg border-border p-0 shadow-lg\"\n position=\"popper\"\n >\n {models.map((model) => (\n <SelectItem\n className=\"min-h-9 rounded-md px-2 py-2 text-xs focus:bg-muted\"\n key={model.id}\n title={model.id}\n value={model.id}\n >\n {model.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <div\n className=\"flex h-8 min-w-0 max-w-48 items-center gap-1.5 px-2 text-muted-foreground text-xs\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{selectedModelLabel}</span>\n </div>\n )}\n <PromptInputSubmit onStop={stop} status={status} />\n </div>\n </PromptInputFooter>\n </PromptInput>\n </div>\n </aside>\n );\n};\n\nconst SELECTED_THREAD_STORAGE_KEY = \"survey-assistant-selected-thread\";\n\nconst createThreadTitle = (text: string, fallback: string) => {\n const normalized = text.replace(/\\s+/g, \" \").trim();\n if (!normalized) return fallback;\n const words = normalized.split(\" \").slice(0, 8).join(\" \");\n return words.length > 64 ? `${words.slice(0, 61).trimEnd()}...` : words;\n};\n\ntype SurveyAssistantPanelContentProps = Omit<\n SurveyAssistantPanelProps,\n \"language\" | \"localizations\"\n>;\n\ninterface PendingInitialLaunch {\n input: SurveyAssistantThreadLaunch;\n onSubmitted(): void;\n}\n\nconst SurveyAssistantPanelContent = ({\n embedded = false,\n modelId,\n models = [],\n onConfirmDeleteThread,\n onModelChange = () => {},\n resourceId,\n selectedThreadStorageKey,\n surveyId,\n threadApi,\n threadClient: providedThreadClient,\n threadLauncher,\n ...sessionProps\n}: SurveyAssistantPanelContentProps) => {\n const t = useSurveyAssistantTranslation();\n const threadClient = useMemo(\n () => providedThreadClient ?? createSurveyAssistantThreadClient(threadApi),\n [providedThreadClient, threadApi],\n );\n const storageKey =\n selectedThreadStorageKey === false\n ? null\n : (selectedThreadStorageKey ??\n `${SELECTED_THREAD_STORAGE_KEY}:${encodeURIComponent(resourceId)}${\n surveyId ? `:${encodeURIComponent(surveyId)}` : \"\"\n }`);\n const [threads, setThreads] = useState<SurveyAssistantThread[]>([]);\n const [selectedThread, setSelectedThread] = useState<SurveyAssistantThread | null>(null);\n const [initialMessages, setInitialMessages] = useState<UIMessage[]>([]);\n const [historyOpen, setHistoryOpen] = useState(false);\n const [editingThreadId, setEditingThreadId] = useState<string | null>(null);\n const [editingTitle, setEditingTitle] = useState(\"\");\n const [threadError, setThreadError] = useState<string | null>(null);\n const [loadingThread, setLoadingThread] = useState(true);\n const [initialLaunch, setInitialLaunch] = useState<PendingInitialLaunch>();\n const historyControlsRef = useRef<HTMLDivElement>(null);\n\n const selectModel = useCallback(\n (modelId: string) => {\n if (!models.some((model) => model.id === modelId)) return;\n onModelChange(modelId);\n },\n [models, onModelChange],\n );\n\n const selectThread = useCallback(\n async (thread: SurveyAssistantThread) => {\n setLoadingThread(true);\n setThreadError(null);\n try {\n const transcript = await threadClient.read(thread.id);\n setSelectedThread(transcript.thread);\n setInitialMessages(transcript.messages as UIMessage[]);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n const createThread = useCallback(\n async (launch?: SurveyAssistantThreadLaunch) => {\n setLoadingThread(true);\n setThreadError(null);\n try {\n const thread = await threadClient.create(launch?.title);\n setThreads((current) => [thread, ...current]);\n setSelectedThread(thread);\n setInitialMessages([]);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n return thread;\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n if (launch) throw error;\n return null;\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n useEffect(() => {\n let cancelled = false;\n void threadClient\n .list()\n .then(async (availableThreads) => {\n if (cancelled) return;\n setThreads(availableThreads);\n const rememberedId = storageKey ? window.localStorage.getItem(storageKey) : null;\n const initialThread =\n availableThreads.find((thread) => thread.id === rememberedId) ?? availableThreads[0];\n if (initialThread) {\n await selectThread(initialThread);\n } else {\n await createThread();\n }\n })\n .catch((error) => {\n if (!cancelled) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n setLoadingThread(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [createThread, selectThread, storageKey, t, threadClient]);\n\n useEffect(() => {\n if (!threadLauncher || loadingThread) return;\n return connectSurveyAssistantThreadLauncher(threadLauncher, async (launch) => {\n const thread = await createThread(launch);\n if (!thread) throw new Error(\"The survey assistant thread could not be created.\");\n return new Promise<SurveyAssistantThread>((resolve) => {\n setInitialLaunch({\n input: launch,\n onSubmitted: () => resolve(thread),\n });\n });\n });\n }, [createThread, loadingThread, threadLauncher]);\n\n const renameThread = useCallback(\n async (thread: SurveyAssistantThread, title: string) => {\n const normalized = title.trim();\n if (!normalized || normalized === thread.title) {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n return;\n }\n try {\n const updated = await threadClient.rename(thread.id, normalized);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const setAutomaticTitle = useCallback(\n async (thread: SurveyAssistantThread, title?: string) => {\n try {\n const updated = await threadClient.setAutomaticTitle(thread.id, title);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const beginEditingThread = useCallback((thread: SurveyAssistantThread) => {\n setEditingThreadId(thread.id);\n setEditingTitle(thread.title);\n }, []);\n\n const cancelEditingThread = useCallback(() => {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n }, []);\n\n const commitEditingThread = useCallback(async () => {\n if (!editingThreadId) return;\n const thread = threads.find((item) => item.id === editingThreadId);\n const title = editingTitle;\n if (thread) await renameThread(thread, title);\n }, [editingThreadId, editingTitle, renameThread, threads]);\n\n const deleteThread = useCallback(\n async (thread: SurveyAssistantThread) => {\n const confirmed = onConfirmDeleteThread\n ? await onConfirmDeleteThread(thread)\n : window.confirm(t(\"threads.deleteConfirm\", { title: thread.title }));\n if (!confirmed) return;\n try {\n await threadClient.delete(thread.id);\n const remaining = threads.filter((item) => item.id !== thread.id);\n setThreads(remaining);\n if (selectedThread?.id === thread.id) {\n if (remaining[0]) await selectThread(remaining[0]);\n else await createThread();\n }\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [createThread, onConfirmDeleteThread, selectThread, selectedThread, t, threadClient, threads],\n );\n\n const handleFirstSubmit = useCallback(\n (text: string) => {\n if (!selectedThread || initialMessages.length > 0) {\n return;\n }\n void setAutomaticTitle(selectedThread, createThreadTitle(text, t(\"threads.newChat\")));\n },\n [initialMessages.length, selectedThread, setAutomaticTitle, t],\n );\n\n const handleInitialLaunchHandled = useCallback(() => {\n if (!initialLaunch) return;\n setInitialLaunch(undefined);\n initialLaunch.onSubmitted();\n }, [initialLaunch]);\n\n const refreshThreadList = useCallback(\n async (reportError: boolean) => {\n try {\n const availableThreads = await threadClient.list();\n setThreads(availableThreads);\n const current = availableThreads.find((thread) => thread.id === selectedThread?.id);\n if (current && !editingThreadId) {\n setSelectedThread((selected) => {\n if (!selected || selected.id !== current.id) return selected;\n return selected.title === current.title &&\n selected.titleMode === current.titleMode &&\n selected.updatedAt === current.updatedAt\n ? selected\n : current;\n });\n }\n } catch (error) {\n if (reportError) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n }\n },\n [editingThreadId, selectedThread?.id, t, threadClient],\n );\n\n const toggleHistory = useCallback(() => {\n if (historyOpen) {\n void commitEditingThread();\n setHistoryOpen(false);\n return;\n }\n\n setHistoryOpen(true);\n void refreshThreadList(true);\n }, [commitEditingThread, historyOpen, refreshThreadList]);\n\n const handleTurnSettled = useCallback(() => {\n void refreshThreadList(false);\n }, [refreshThreadList]);\n\n useEffect(() => {\n if (!historyOpen) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n if (!historyControlsRef.current?.contains(event.target as Node)) {\n void commitEditingThread();\n setHistoryOpen(false);\n }\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n cancelEditingThread();\n setHistoryOpen(false);\n }\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [cancelEditingThread, commitEditingThread, historyOpen]);\n\n useEffect(() => {\n const handleFocus = () => {\n void refreshThreadList(false);\n };\n\n window.addEventListener(\"focus\", handleFocus);\n return () => window.removeEventListener(\"focus\", handleFocus);\n }, [refreshThreadList]);\n\n if (loadingThread || !selectedThread) {\n return (\n <aside\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center border-b border-border bg-muted/20 px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName=\"animate-pulse bg-blue-500\"\n status={t(\"panel.loadingChats\")}\n title={t(\"panel.title\")}\n />\n </header>\n <div className=\"flex min-h-0 flex-1 items-center justify-center text-muted-foreground text-sm\">\n <LoaderCircleIcon className=\"mr-2 size-4 animate-spin\" />\n {t(\"panel.loadingChats\")}\n </div>\n </aside>\n );\n }\n\n const threadControls = (\n <div className=\"relative flex shrink-0 items-center gap-1\" ref={historyControlsRef}>\n <button\n aria-label={t(\"threads.newChat\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground\"\n onClick={() => void createThread()}\n title={t(\"threads.newChat\")}\n type=\"button\"\n >\n <PlusIcon className=\"size-4\" />\n </button>\n <button\n aria-expanded={historyOpen}\n aria-label={t(\"threads.history\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground\"\n onClick={toggleHistory}\n title={t(\"threads.history\")}\n type=\"button\"\n >\n <HistoryIcon className=\"size-4\" />\n </button>\n {historyOpen && (\n <div className=\"absolute top-10 right-0 z-30 w-72 overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\">\n <div className=\"border-b border-border px-3 py-2 font-medium text-xs\">\n {t(\"threads.recent\")}\n </div>\n <div className=\"max-h-72 overflow-y-auto p-1\">\n {threads.map((thread) => (\n <div\n className={cn(\n \"group flex min-h-10 items-center gap-1 rounded-md px-2\",\n thread.id === selectedThread.id ? \"bg-muted\" : \"hover:bg-muted/60\",\n )}\n key={thread.id}\n >\n {editingThreadId === thread.id ? (\n <>\n <input\n autoFocus\n className=\"min-w-0 flex-1 rounded border border-input bg-background px-1.5 py-1 text-xs outline-none focus:ring-1 focus:ring-ring\"\n onBlur={() => void commitEditingThread()}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n void commitEditingThread();\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n cancelEditingThread();\n setHistoryOpen(false);\n }\n }}\n value={editingTitle}\n />\n {thread.titleMode === \"manual\" && (\n <button\n aria-label={t(\"threads.automaticTitle\")}\n className=\"flex h-7 shrink-0 items-center gap-1 rounded px-1.5 text-muted-foreground text-xs hover:bg-background hover:text-foreground\"\n onClick={() => void setAutomaticTitle(thread)}\n onMouseDown={(event) => event.preventDefault()}\n title={t(\"threads.automaticTitle\")}\n type=\"button\"\n >\n <SparklesIcon className=\"size-3\" />\n <span>{t(\"threads.automaticShort\")}</span>\n </button>\n )}\n </>\n ) : (\n <button\n className=\"min-w-0 flex-1 truncate py-2 text-left text-xs\"\n onClick={() => void selectThread(thread)}\n type=\"button\"\n >\n {thread.title}\n </button>\n )}\n <button\n aria-label={t(\"threads.rename\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => beginEditingThread(thread)}\n title={t(\"threads.renameTitle\")}\n type=\"button\"\n >\n <PencilIcon className=\"size-3.5\" />\n </button>\n <button\n aria-label={t(\"threads.delete\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => void deleteThread(thread)}\n title={t(\"threads.deleteTitle\")}\n type=\"button\"\n >\n <Trash2Icon className=\"size-3.5\" />\n </button>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n\n return (\n <div className=\"relative h-full min-h-0\">\n <SurveyAssistantChatPanel\n {...sessionProps}\n embedded={embedded}\n initialLaunch={initialLaunch?.input}\n initialMessages={initialMessages}\n key={selectedThread.id}\n modelId={modelId}\n models={models}\n onInitialLaunchHandled={handleInitialLaunchHandled}\n onModelChange={selectModel}\n onFirstSubmit={handleFirstSubmit}\n onTurnSettled={handleTurnSettled}\n resourceId={resourceId}\n surveyId={surveyId}\n threadControls={threadControls}\n threadId={selectedThread.id}\n threadTitle={selectedThread.title}\n />\n {threadError && (\n <div className=\"absolute right-3 bottom-3 left-3 z-40 rounded-lg border border-destructive/20 bg-background px-3 py-2 text-xs shadow-lg\">\n <div className=\"font-medium\">{t(\"panel.controlsUnavailable\")}</div>\n <div className=\"mt-0.5 text-muted-foreground\">{threadError}</div>\n <button\n className=\"mt-1 font-medium hover:underline\"\n onClick={() => setThreadError(null)}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n </div>\n );\n};\n\nexport const SurveyAssistantPanel = ({\n language,\n localizations,\n ...props\n}: SurveyAssistantPanelProps) => (\n <div className=\"case-survey-assistant\">\n <SurveyAssistantLocalizationProvider language={language} localizations={localizations}>\n <SurveyAssistantPanelContent\n {...props}\n key={JSON.stringify([props.resourceId, props.surveyId])}\n />\n </SurveyAssistantLocalizationProvider>\n </div>\n);\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useSurveyAssistantModelCatalog } from \"../react\";\nimport { SurveyAssistantPanel, type SurveyAssistantPanelProps } from \"./survey-assistant-panel\";\n\nexport type ConnectedSurveyAssistantPanelProps = Omit<\n SurveyAssistantPanelProps,\n \"modelId\" | \"models\" | \"onModelChange\"\n> & {\n modelCatalogApi?: string;\n modelStorageKey?: string | false;\n onModelCatalogError?(error: Error): void;\n onModelChange?(modelId: string): void;\n};\n\nexport const ConnectedSurveyAssistantPanel = ({\n modelCatalogApi,\n modelStorageKey,\n onModelCatalogError,\n onModelChange,\n ...props\n}: ConnectedSurveyAssistantPanelProps) => {\n const catalog = useSurveyAssistantModelCatalog({\n api: modelCatalogApi,\n onModelChange,\n storageKey: modelStorageKey,\n });\n\n useEffect(() => {\n if (catalog.error) onModelCatalogError?.(catalog.error);\n }, [catalog.error, onModelCatalogError]);\n\n return (\n <SurveyAssistantPanel\n {...props}\n modelId={catalog.modelId}\n models={catalog.models}\n onModelChange={catalog.selectModel}\n />\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ui.mjs","names":["Collapsible","CollapsiblePrimitive","Collapsible","Select","SelectPrimitive","isRecord","Collapsible","Select"],"sources":["../src/ui/internal/collapsible.tsx","../src/ui/utils.ts","../src/ui/internal/shimmer.tsx","../src/ui/localizations/en.ts","../src/ui/localizations/nl.ts","../src/ui/localization.tsx","../src/ui/internal/chain-of-thought.tsx","../src/ui/internal/button.tsx","../src/ui/internal/conversation.tsx","../src/ui/internal/message.tsx","../src/ui/internal/prompt-input.tsx","../src/ui/internal/tool-technical-details.ts","../src/ui/internal/select.tsx","../src/ui/internal/code-block.tsx","../src/ui/internal/response.tsx","../src/ui/internal/message-timing.ts","../src/ui/internal/message-turn-status.ts","../src/ui/survey-assistant-panel.tsx","../src/ui/connected-survey-assistant-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\";\n\nfunction Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return <CollapsiblePrimitive.CollapsibleTrigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return <CollapsiblePrimitive.CollapsibleContent data-slot=\"collapsible-content\" {...props} />;\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\n","\"use client\";\n\n/* eslint-disable react-hooks/static-components */\n\nimport { cn } from \"../utils\";\nimport type { MotionProps } from \"motion/react\";\nimport { motion } from \"motion/react\";\nimport type { CSSProperties, ElementType, JSX } from \"react\";\nimport { memo, useMemo } from \"react\";\n\ntype MotionHTMLProps = MotionProps & Record<string, unknown>;\n\n// Cache motion components at module level to avoid creating during render\nconst motionComponentCache = new Map<\n keyof JSX.IntrinsicElements,\n React.ComponentType<MotionHTMLProps>\n>();\n\nconst getMotionComponent = (element: keyof JSX.IntrinsicElements) => {\n let component = motionComponentCache.get(element);\n if (!component) {\n component = motion.create(element);\n motionComponentCache.set(element, component);\n }\n return component;\n};\n\nexport interface TextShimmerProps {\n children: string;\n as?: ElementType;\n className?: string;\n duration?: number;\n spread?: number;\n}\n\nconst ShimmerComponent = ({\n children,\n as: Component = \"p\",\n className,\n duration = 2,\n spread = 2,\n}: TextShimmerProps) => {\n const MotionComponent = getMotionComponent(Component as keyof JSX.IntrinsicElements);\n\n const dynamicSpread = useMemo(() => (children?.length ?? 0) * spread, [children, spread]);\n\n return (\n <MotionComponent\n animate={{ backgroundPosition: \"0% center\" }}\n className={cn(\n \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n \"[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]\",\n className,\n )}\n initial={{ backgroundPosition: \"100% center\" }}\n style={\n {\n \"--spread\": `${dynamicSpread}px`,\n backgroundImage:\n \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n } as CSSProperties\n }\n transition={{\n duration,\n ease: \"linear\",\n repeat: Number.POSITIVE_INFINITY,\n }}\n >\n {children}\n </MotionComponent>\n );\n};\n\nexport const Shimmer = memo(ShimmerComponent);\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantEnMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Survey assistant\",\n title: \"Assistant\",\n loadingChats: \"Loading chats\",\n controlsUnavailable: \"Assistant controls unavailable\",\n },\n empty: {\n title: \"What are you working on?\",\n description:\n \"Draft, inspect, or refine your survey - just describe what you need, or start with one of these.\",\n },\n quickActions: {\n review: {\n label: \"Review survey\",\n description: \"Spot issues and suggest improvements\",\n prompt: \"Review the current survey and suggest improvements.\",\n },\n create: {\n label: \"New question\",\n description: \"Draft a question to add\",\n prompt: \"Help me create a new survey question.\",\n },\n refine: {\n label: \"Refine wording\",\n description: \"Polish respondent-facing text\",\n prompt: \"Suggest improvements to the respondent-facing wording.\",\n },\n },\n input: {\n placeholder: \"Ask about the survey...\",\n attachFiles: \"Attach files\",\n dropFiles: \"Drop images or PDFs to attach\",\n unsupportedFiles: \"Unsupported file type: {filenames}\",\n removeFile: \"Remove {filename}\",\n send: \"Send message\",\n stop: \"Stop response\",\n model: \"Assistant model\",\n defaultModel: \"Default model\",\n },\n conversation: {\n noMessages: \"No messages yet\",\n startConversation: \"Start a conversation to see messages here\",\n scrollToLatest: \"Scroll to latest message\",\n working: \"Working...\",\n stopped: \"Stopped\",\n incomplete: \"Response interrupted\",\n },\n turn: {\n failedTitle: \"The assistant did not complete this turn.\",\n abortedTitle: \"The turn was stopped.\",\n reasons: {\n clientAbort: \"The request was stopped by the client.\",\n firstResponseTimeout: \"No meaningful response arrived before the initial deadline.\",\n idleTimeout: \"The assistant stopped producing activity.\",\n maxDuration: \"The one-hour execution ceiling was reached.\",\n maxSteps: \"The assistant reached its tool-step limit before finishing.\",\n lengthLimit: \"The model reached its output-length limit.\",\n contentFilter: \"The provider stopped the response because of its content policy.\",\n providerError: \"The model provider reported an error.\",\n streamError: \"The response stream ended with an error.\",\n incompleteResponse: \"The response ended without a normal completion.\",\n unknown: \"The response ended before completion.\",\n },\n },\n status: {\n applying: \"Applying changes\",\n applied: \"Changes applied\",\n stopped: \"Stopped\",\n attention: \"Needs attention\",\n ready: \"Ready\",\n connecting: \"Connecting to the assistant\",\n thinking: \"Thinking through your request\",\n writing: \"Writing the response\",\n working: \"Working on your request\",\n },\n activity: {\n label: \"Activity\",\n working: \"Working...\",\n workedFor: \"Worked for {duration}\",\n technicalDetails: \"View technical details\",\n hideTechnicalDetails: \"Hide technical details\",\n waitingApproval: \"Waiting for approval\",\n approvalReceived: \"Approval received\",\n continuingApproval: \"Continuing after approval\",\n preparingStep: \"Preparing the next step\",\n usingResult: \"Using the result\",\n continuingWithoutStep: \"Continuing without that step\",\n recoveringToolError: \"Recovering from a tool error\",\n skipped: \"Skipped\",\n failed: \"Failed\",\n workingShort: \"Working\",\n done: \"Done\",\n stopped: \"Stopped\",\n expressionChange: \"Expression change\",\n surveyChange: \"Survey change\",\n genericActive: \"Working with survey\",\n genericComplete: \"Survey step complete\",\n failedSuffix: \"{name} failed\",\n skippedSuffix: \"{name} skipped\",\n tools: {\n survey_inspect: { active: \"Reviewing survey\", complete: \"Survey reviewed\" },\n survey_change: { active: \"Preparing change\", complete: \"Change prepared\" },\n survey_expression: { active: \"Preparing expression\", complete: \"Expression prepared\" },\n survey_authoring_reference: {\n active: \"Checking authoring guidance\",\n complete: \"Authoring guidance checked\",\n },\n survey_attachment: { active: \"Opening attachment\", complete: \"Attachment opened\" },\n recall: {\n active: \"Checking earlier conversation\",\n complete: \"Earlier conversation checked\",\n },\n },\n },\n changes: {\n applied: \"Change applied\",\n stale: \"Change not applied\",\n failed: \"Change could not be applied\",\n prepared: \"Change prepared\",\n rejected: \"Change could not be prepared\",\n operationCount: \"{count} operation\",\n operationCountPlural: \"{count} operations\",\n issueCount: \"{count} issue\",\n issueCountPlural: \"{count} issues\",\n warningCount: \"{count} warning\",\n warningCountPlural: \"{count} warnings\",\n incompleteTitle: \"The requested changes were not completed.\",\n blocked:\n \"No survey changes were applied because {count} rejected change proposal remains unresolved.\",\n blockedPlural:\n \"No survey changes were applied because {count} rejected change proposals remain unresolved.\",\n partial: \"{applied} change set was applied; {failed} could not be applied.\",\n partialPlural: \"{applied} change sets were applied; {failed} could not be applied.\",\n reviewBeforeRetry: \"Review the change steps above before retrying.\",\n },\n errors: {\n dismiss: \"Dismiss\",\n dismissAssistant: \"Dismiss assistant error\",\n retry: \"Try again\",\n fallbackDetail: \"The assistant hit an error on the previous turn.\",\n model_unavailable: {\n title: \"Model unavailable\",\n hint: \"Select a model available to this account, then send the message again.\",\n },\n rate_limited: {\n title: \"Assistant temporarily busy\",\n hint: \"Wait a moment, then send the message again.\",\n },\n authorization_failed: {\n title: \"Assistant unavailable\",\n hint: \"Check your access or sign in again before retrying.\",\n },\n attachment_unavailable: {\n title: \"Attachment unavailable\",\n hint: \"Attach the file again or continue without it.\",\n },\n request_failed: {\n title: \"Assistant could not complete request\",\n hint: \"You can continue with another message.\",\n },\n },\n threads: {\n newChat: \"New chat\",\n history: \"Chat history\",\n recent: \"Recent chats\",\n automaticTitle: \"Use automatic title\",\n automaticShort: \"Auto\",\n rename: \"Rename {title}\",\n renameTitle: \"Rename chat\",\n delete: \"Delete {title}\",\n deleteTitle: \"Delete chat\",\n deleteConfirm: 'Delete \"{title}\" and its attachments?',\n },\n};\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantNlMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Surveyassistent\",\n title: \"Assistent\",\n loadingChats: \"Chats laden\",\n controlsUnavailable: \"Bediening van de assistent niet beschikbaar\",\n },\n empty: {\n title: \"Waar werk je aan?\",\n description:\n \"Maak, controleer of verbeter je survey. Beschrijf wat je nodig hebt of kies een van deze opties.\",\n },\n quickActions: {\n review: {\n label: \"Survey controleren\",\n description: \"Problemen vinden en verbeteringen voorstellen\",\n prompt: \"Controleer de huidige survey en stel verbeteringen voor.\",\n },\n create: {\n label: \"Nieuwe vraag\",\n description: \"Een vraag opstellen en toevoegen\",\n prompt: \"Help me een nieuwe surveyvraag te maken.\",\n },\n refine: {\n label: \"Formulering verbeteren\",\n description: \"Tekst voor respondenten aanscherpen\",\n prompt: \"Stel verbeteringen voor voor de tekst die respondenten zien.\",\n },\n },\n input: {\n placeholder: \"Vraag iets over de survey...\",\n attachFiles: \"Bestanden toevoegen\",\n dropFiles: \"Sleep afbeeldingen of pdf's hierheen om ze toe te voegen\",\n unsupportedFiles: \"Niet-ondersteund bestandstype: {filenames}\",\n removeFile: \"{filename} verwijderen\",\n send: \"Bericht verzenden\",\n stop: \"Antwoord stoppen\",\n model: \"Assistentmodel\",\n defaultModel: \"Standaardmodel\",\n },\n conversation: {\n noMessages: \"Nog geen berichten\",\n startConversation: \"Start een gesprek om hier berichten te zien\",\n scrollToLatest: \"Naar het nieuwste bericht scrollen\",\n working: \"Bezig...\",\n stopped: \"Gestopt\",\n incomplete: \"Antwoord onderbroken\",\n },\n turn: {\n failedTitle: \"De assistent heeft deze beurt niet voltooid.\",\n abortedTitle: \"De beurt is gestopt.\",\n reasons: {\n clientAbort: \"Het verzoek is door de client gestopt.\",\n firstResponseTimeout: \"Er kwam geen betekenisvol antwoord vóór de eerste tijdslimiet.\",\n idleTimeout: \"De assistent produceerde geen activiteit meer.\",\n maxDuration: \"De maximale uitvoertijd van één uur is bereikt.\",\n maxSteps: \"De assistent bereikte de limiet voor hulpmiddelstappen voordat hij klaar was.\",\n lengthLimit: \"Het model bereikte de maximale antwoordlengte.\",\n contentFilter: \"De provider stopte het antwoord vanwege het inhoudsbeleid.\",\n providerError: \"De modelprovider meldde een fout.\",\n streamError: \"De antwoordstream eindigde met een fout.\",\n incompleteResponse: \"Het antwoord eindigde zonder normale voltooiing.\",\n unknown: \"Het antwoord eindigde voordat het voltooid was.\",\n },\n },\n status: {\n applying: \"Wijzigingen toepassen\",\n applied: \"Wijzigingen toegepast\",\n stopped: \"Gestopt\",\n attention: \"Aandacht nodig\",\n ready: \"Gereed\",\n connecting: \"Verbinding maken met de assistent\",\n thinking: \"Verzoek doordenken\",\n writing: \"Antwoord schrijven\",\n working: \"Aan je verzoek werken\",\n },\n activity: {\n label: \"Activiteit\",\n working: \"Bezig...\",\n workedFor: \"{duration} gewerkt\",\n technicalDetails: \"Technische details tonen\",\n hideTechnicalDetails: \"Technische details verbergen\",\n waitingApproval: \"Wachten op goedkeuring\",\n approvalReceived: \"Goedkeuring ontvangen\",\n continuingApproval: \"Doorgaan na goedkeuring\",\n preparingStep: \"Volgende stap voorbereiden\",\n usingResult: \"Resultaat gebruiken\",\n continuingWithoutStep: \"Doorgaan zonder die stap\",\n recoveringToolError: \"Herstellen van een fout in een hulpmiddel\",\n skipped: \"Overgeslagen\",\n failed: \"Mislukt\",\n workingShort: \"Bezig\",\n done: \"Gereed\",\n stopped: \"Gestopt\",\n expressionChange: \"Expressiewijziging\",\n surveyChange: \"Surveywijziging\",\n genericActive: \"Werken met de survey\",\n genericComplete: \"Surveystap voltooid\",\n failedSuffix: \"{name} mislukt\",\n skippedSuffix: \"{name} overgeslagen\",\n tools: {\n survey_inspect: { active: \"Survey controleren\", complete: \"Survey gecontroleerd\" },\n survey_change: { active: \"Wijziging voorbereiden\", complete: \"Wijziging voorbereid\" },\n survey_expression: {\n active: \"Expressie voorbereiden\",\n complete: \"Expressie voorbereid\",\n },\n survey_authoring_reference: {\n active: \"Auteursrichtlijnen controleren\",\n complete: \"Auteursrichtlijnen gecontroleerd\",\n },\n survey_attachment: { active: \"Bijlage openen\", complete: \"Bijlage geopend\" },\n recall: {\n active: \"Eerder gesprek controleren\",\n complete: \"Eerder gesprek gecontroleerd\",\n },\n },\n },\n changes: {\n applied: \"Wijziging toegepast\",\n stale: \"Wijziging niet toegepast\",\n failed: \"Wijziging kon niet worden toegepast\",\n prepared: \"Wijziging voorbereid\",\n rejected: \"Wijziging kon niet worden voorbereid\",\n operationCount: \"{count} bewerking\",\n operationCountPlural: \"{count} bewerkingen\",\n issueCount: \"{count} probleem\",\n issueCountPlural: \"{count} problemen\",\n warningCount: \"{count} waarschuwing\",\n warningCountPlural: \"{count} waarschuwingen\",\n incompleteTitle: \"De gevraagde wijzigingen zijn niet voltooid.\",\n blocked:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstel nog niet is opgelost.\",\n blockedPlural:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstellen nog niet zijn opgelost.\",\n partial: \"{applied} wijzigingsset is toegepast; {failed} kon niet worden toegepast.\",\n partialPlural:\n \"{applied} wijzigingssets zijn toegepast; {failed} konden niet worden toegepast.\",\n reviewBeforeRetry:\n \"Controleer de bovenstaande wijzigingsstappen voordat je het opnieuw probeert.\",\n },\n errors: {\n dismiss: \"Sluiten\",\n dismissAssistant: \"Assistentfout sluiten\",\n retry: \"Opnieuw proberen\",\n fallbackDetail: \"Er is tijdens de vorige beurt een fout opgetreden.\",\n model_unavailable: {\n title: \"Model niet beschikbaar\",\n hint: \"Selecteer een model dat beschikbaar is voor dit account en verzend het bericht opnieuw.\",\n },\n rate_limited: {\n title: \"Assistent tijdelijk bezet\",\n hint: \"Wacht even en verzend het bericht daarna opnieuw.\",\n },\n authorization_failed: {\n title: \"Assistent niet beschikbaar\",\n hint: \"Controleer je toegang of meld je opnieuw aan voordat je het opnieuw probeert.\",\n },\n attachment_unavailable: {\n title: \"Bijlage niet beschikbaar\",\n hint: \"Voeg het bestand opnieuw toe of ga verder zonder het bestand.\",\n },\n request_failed: {\n title: \"Assistent kon het verzoek niet voltooien\",\n hint: \"Je kunt doorgaan met een nieuw bericht.\",\n },\n },\n threads: {\n newChat: \"Nieuwe chat\",\n history: \"Chatgeschiedenis\",\n recent: \"Recente chats\",\n automaticTitle: \"Automatische titel gebruiken\",\n automaticShort: \"Automatisch\",\n rename: \"{title} hernoemen\",\n renameTitle: \"Chat hernoemen\",\n delete: \"{title} verwijderen\",\n deleteTitle: \"Chat verwijderen\",\n deleteConfirm: '\"{title}\" en de bijlagen verwijderen?',\n },\n};\n","\"use client\";\n\nimport {\n createLocalizationTranslator,\n mergeLocalizationCatalogs,\n type LocalizationCatalog,\n type LocalizationTranslate,\n} from \"@case-framework/ui-localization\";\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport { surveyAssistantEnMessages } from \"./localizations/en\";\nimport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport { surveyAssistantEnMessages } from \"./localizations/en\";\nexport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport const defaultSurveyAssistantLocalizations: LocalizationCatalog = {\n en: surveyAssistantEnMessages,\n nl: surveyAssistantNlMessages,\n};\n\nconst SurveyAssistantLocalizationContext = createContext<LocalizationTranslate | null>(null);\n\nexport interface SurveyAssistantLocalizationProviderProps {\n children: ReactNode;\n language?: string;\n localizations?: LocalizationCatalog;\n}\n\nexport const SurveyAssistantLocalizationProvider = ({\n children,\n language = \"en\",\n localizations,\n}: SurveyAssistantLocalizationProviderProps) => {\n const translate = useMemo(\n () =>\n createLocalizationTranslator({\n fallbackLocale: \"en\",\n locale: language,\n localizations: mergeLocalizationCatalogs(\n defaultSurveyAssistantLocalizations,\n localizations,\n ),\n onMissing: (key, locale) =>\n console.log(\n `[SurveyAssistant] Missing localization for key \"${key}\" in language \"${locale}\".`,\n ),\n }),\n [language, localizations],\n );\n\n return (\n <SurveyAssistantLocalizationContext.Provider value={translate}>\n {children}\n </SurveyAssistantLocalizationContext.Provider>\n );\n};\n\nexport const useSurveyAssistantTranslation = (): LocalizationTranslate => {\n const translate = useContext(SurveyAssistantLocalizationContext);\n if (!translate) {\n throw new Error(\n \"useSurveyAssistantTranslation must be used within SurveyAssistantLocalizationProvider.\",\n );\n }\n return translate;\n};\n","\"use client\";\n\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { cn } from \"../utils\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { BrainIcon, ChevronDownIcon, DotIcon, type LucideIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Shimmer } from \"./shimmer\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\ninterface ChainOfThoughtContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n isStreaming: boolean;\n duration: number | undefined;\n}\n\nconst ChainOfThoughtContext = createContext<ChainOfThoughtContextValue | null>(null);\n\nexport const useChainOfThought = () => {\n const context = useContext(ChainOfThoughtContext);\n if (!context) {\n throw new Error(\"ChainOfThought components must be used within ChainOfThought\");\n }\n return context;\n};\n\nexport type ChainOfThoughtProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n defaultOpen?: boolean;\n defaultDuration?: number;\n duration?: number;\n autoClose?: boolean;\n};\n\nconst AUTO_CLOSE_DELAY = 1000;\nconst MS_IN_S = 1000;\n\nconst formatDuration = (durationSeconds: number) => {\n const hours = Math.floor(durationSeconds / 3600);\n const minutes = Math.floor((durationSeconds % 3600) / 60);\n const seconds = durationSeconds % 60;\n\n if (hours > 0) return `${hours}h ${minutes}m`;\n if (minutes > 0) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;\n return `${seconds}s`;\n};\n\nexport const ChainOfThought = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n defaultDuration,\n onOpenChange,\n duration: durationProp,\n autoClose = true,\n children,\n ...props\n }: ChainOfThoughtProps) => {\n const resolvedDefaultOpen = defaultOpen ?? isStreaming;\n // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n const isExplicitlyClosed = defaultOpen === false;\n\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: resolvedDefaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: defaultDuration,\n prop: durationProp,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n const startTimeRef = useRef<number | null>(null);\n\n // Track when streaming starts and compute duration\n useEffect(() => {\n if (isStreaming) {\n hasEverStreamedRef.current = true;\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));\n startTimeRef.current = null;\n }\n }, [isStreaming, setDuration]);\n\n // Auto-open when streaming starts (unless explicitly closed)\n useEffect(() => {\n if (isStreaming && !isOpen && !isExplicitlyClosed) {\n setIsOpen(true);\n }\n }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);\n\n // Auto-close when streaming ends (once only, and only if it ever streamed)\n useEffect(() => {\n if (autoClose && hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n\n return () => clearTimeout(timer);\n }\n }, [autoClose, isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n },\n [setIsOpen],\n );\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen],\n );\n\n return (\n <ChainOfThoughtContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose w-full\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ChainOfThoughtContext.Provider>\n );\n },\n);\n\nexport type ChainOfThoughtHeaderProps = ComponentProps<typeof CollapsibleTrigger> & {\n getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode;\n};\n\nexport const ChainOfThoughtHeader = memo(\n ({ className, children, getThinkingMessage, ...props }: ChainOfThoughtHeaderProps) => {\n const { isOpen, isStreaming, duration } = useChainOfThought();\n const t = useSurveyAssistantTranslation();\n const defaultThinkingMessage = isStreaming ? (\n <Shimmer duration={1}>{t(\"activity.working\")}</Shimmer>\n ) : duration === undefined ? (\n <span>{t(\"activity.label\")}</span>\n ) : (\n <span>{t(\"activity.workedFor\", { duration: formatDuration(duration) })}</span>\n );\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center gap-1.5 text-muted-foreground text-sm transition-colors hover:text-foreground\",\n className,\n )}\n {...props}\n >\n <BrainIcon className=\"size-3.5 shrink-0\" />\n <span className=\"flex-1 text-left\">\n {children ?? getThinkingMessage?.(isStreaming, duration) ?? defaultThinkingMessage}\n </span>\n <ChevronDownIcon\n className={cn(\n \"size-3.5 shrink-0 transition-transform\",\n isOpen ? \"rotate-180\" : \"rotate-0\",\n )}\n />\n </CollapsibleTrigger>\n );\n },\n);\n\nexport type ChainOfThoughtContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ChainOfThoughtContent = memo(({ className, ...props }: ChainOfThoughtContentProps) => (\n <CollapsibleContent\n className={cn(\n \"mt-2\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className,\n )}\n {...props}\n />\n));\n\nexport type ChainOfThoughtStepProps = ComponentProps<\"div\"> & {\n icon?: LucideIcon;\n label: ReactNode;\n description?: ReactNode;\n result?: ReactNode;\n status?: \"complete\" | \"active\" | \"pending\";\n isLast?: boolean;\n};\n\nconst stepStatusStyles = {\n complete: \"text-muted-foreground\",\n active: \"text-foreground\",\n pending: \"text-muted-foreground/50\",\n} as const;\n\nexport const ChainOfThoughtStep = memo(\n ({\n className,\n icon: Icon = DotIcon,\n label,\n description,\n result,\n status = \"complete\",\n isLast = false,\n children,\n ...props\n }: ChainOfThoughtStepProps) => (\n <div\n className={cn(\n \"fade-in-0 slide-in-from-top-2 relative animate-in text-xs\",\n isLast ? \"pb-0\" : \"pb-2.5\",\n stepStatusStyles[status],\n className,\n )}\n {...props}\n >\n <div className=\"flex gap-2\">\n <div className=\"relative z-10 mt-0.5 shrink-0 bg-background\">\n <Icon className=\"size-3.5\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"wrap-break-word\">{label}</div>\n {description && <div className=\"mt-1.5 text-muted-foreground text-xs\">{description}</div>}\n </div>\n </div>\n {result && <div className=\"relative mt-1.5 ml-[22px]\">{result}</div>}\n {children && <div className=\"mt-1.5 ml-[22px] space-y-1.5\">{children}</div>}\n </div>\n ),\n);\n\nChainOfThought.displayName = \"ChainOfThought\";\nChainOfThoughtHeader.displayName = \"ChainOfThoughtHeader\";\nChainOfThoughtContent.displayName = \"ChainOfThoughtContent\";\nChainOfThoughtStep.displayName = \"ChainOfThoughtStep\";\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-muted hover:text-foreground\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n },\n },\n defaultVariants: { variant: \"default\", size: \"default\" },\n },\n);\n\nexport const Button = ({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) => {\n const Component = asChild ? Slot.Root : \"button\";\n return <Component className={cn(buttonVariants({ variant, size, className }))} {...props} />;\n};\n","\"use client\";\n\nimport { Button } from \"./button\";\nimport { cn } from \"../utils\";\nimport { ArrowDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { useCallback } from \"react\";\nimport { StickToBottom, useStickToBottomContext } from \"use-stick-to-bottom\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\nexport type ConversationProps = ComponentProps<typeof StickToBottom>;\n\nexport const Conversation = ({ className, ...props }: ConversationProps) => (\n <StickToBottom\n className={cn(\"relative min-h-0 flex-1 overflow-y-hidden\", className)}\n initial=\"smooth\"\n role=\"log\"\n resize=\"smooth\"\n {...props}\n />\n);\n\nexport type ConversationContentProps = ComponentProps<typeof StickToBottom.Content>;\n\nexport const ConversationContent = ({ className, ...props }: ConversationContentProps) => (\n <StickToBottom.Content className={cn(\"flex flex-col gap-8 p-4\", className)} {...props} />\n);\n\nexport type ConversationEmptyStateProps = ComponentProps<\"div\"> & {\n title?: string;\n description?: string;\n icon?: ReactNode;\n};\n\nexport const ConversationEmptyState = ({\n className,\n title,\n description,\n icon,\n children,\n ...props\n}: ConversationEmptyStateProps) => {\n const t = useSurveyAssistantTranslation();\n const resolvedTitle = title ?? t(\"conversation.noMessages\");\n const resolvedDescription = description ?? t(\"conversation.startConversation\");\n\n return (\n <div\n className={cn(\n \"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <>\n {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n <div className=\"space-y-1\">\n <h3 className=\"font-medium text-sm\">{resolvedTitle}</h3>\n {resolvedDescription && (\n <p className=\"text-muted-foreground text-sm\">{resolvedDescription}</p>\n )}\n </div>\n </>\n )}\n </div>\n );\n};\n\nexport type ConversationScrollButtonProps = ComponentProps<typeof Button>;\n\nexport const ConversationScrollButton = ({\n className,\n ...props\n}: ConversationScrollButtonProps) => {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext();\n const t = useSurveyAssistantTranslation();\n\n const handleScrollToBottom = useCallback(() => {\n scrollToBottom();\n }, [scrollToBottom]);\n\n return (\n !isAtBottom && (\n <Button\n className={cn(\n \"absolute left-1/2 z-10 size-8 -translate-x-1/2 rounded-full border border-background/60 bg-foreground text-background shadow-lg ring-1 ring-border/50 hover:bg-foreground/85 hover:text-background\",\n className,\n )}\n aria-label={t(\"conversation.scrollToLatest\")}\n onClick={handleScrollToBottom}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"secondary\"\n {...props}\n >\n <ArrowDownIcon className=\"size-4\" />\n </Button>\n )\n );\n};\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport type { UIMessage } from \"ai\";\nimport type { HTMLAttributes } from \"react\";\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n from: UIMessage[\"role\"];\n};\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n from === \"user\" ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n data-role={from}\n {...props}\n />\n);\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageContent = ({ children, className, ...props }: MessageContentProps) => (\n <div\n className={cn(\n \"w-fit min-w-0 max-w-full break-words text-sm\",\n \"group-data-[role=user]:whitespace-pre-wrap group-data-[role=user]:rounded-xl group-data-[role=user]:border group-data-[role=user]:border-blue-200/70 group-data-[role=user]:bg-blue-50 group-data-[role=user]:px-3 group-data-[role=user]:py-2 group-data-[role=user]:text-foreground group-data-[role=user]:shadow-xs dark:group-data-[role=user]:border-blue-800/60 dark:group-data-[role=user]:bg-blue-950/50\",\n \"group-data-[role=assistant]:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type MessageResponseProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageResponse = ({ className, ...props }: MessageResponseProps) => (\n <div className={cn(\"leading-6\", className)} {...props} />\n);\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport type { ChatStatus, FileUIPart } from \"ai\";\nimport { ArrowUpIcon, FileIcon, PaperclipIcon, SquareIcon, XIcon } from \"lucide-react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type ClipboardEvent,\n type ComponentProps,\n type DragEvent,\n type FormEvent,\n type HTMLAttributes,\n} from \"react\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\nconst SUPPORTED_FILE_ACCEPT = \"image/*,application/pdf\";\nconst isSupportedFile = (file: File) =>\n file.type.startsWith(\"image/\") || file.type === \"application/pdf\";\n\nconst formatFileSize = (size: number) => {\n if (size < 1024 * 1024) {\n return `${Math.max(1, Math.round(size / 1024))} KB`;\n }\n\n return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`;\n};\n\nconst fileToUIPart = async (file: File): Promise<FileUIPart> => {\n const mediaType = file.type || \"application/octet-stream\";\n const bytes = new Uint8Array(await file.arrayBuffer());\n const chunkSize = 0x8000;\n let binary = \"\";\n\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n\n return {\n type: \"file\",\n mediaType,\n filename: file.name,\n url: `data:${mediaType};base64,${btoa(binary)}`,\n };\n};\n\nexport interface PromptInputMessage {\n text: string;\n files: FileUIPart[];\n}\n\ntype PromptInputContextValue = {\n value: string;\n setValue: (value: string) => void;\n files: File[];\n addFiles: (files: FileList | null) => void;\n removeFile: (index: number) => void;\n unsupportedFileNames: string[];\n};\n\nconst PromptInputContext = createContext<PromptInputContextValue | null>(null);\n\nconst usePromptInput = () => {\n const context = useContext(PromptInputContext);\n if (!context) {\n throw new Error(\"PromptInput components must be used within PromptInput.\");\n }\n return context;\n};\n\nexport type PromptInputProps = Omit<ComponentProps<\"form\">, \"onSubmit\"> & {\n attachmentsDisabled?: boolean;\n onSubmit: (\n message: PromptInputMessage,\n event: FormEvent<HTMLFormElement>,\n ) => boolean | void | Promise<boolean | void>;\n};\n\nexport const PromptInput = ({\n attachmentsDisabled = false,\n children,\n className,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onPaste,\n onSubmit,\n ...props\n}: PromptInputProps) => {\n const [value, setValue] = useState(\"\");\n const [files, setFiles] = useState<File[]>([]);\n const [isDraggingFiles, setIsDraggingFiles] = useState(false);\n const [unsupportedFileNames, setUnsupportedFileNames] = useState<string[]>([]);\n const fileDragDepthRef = useRef(0);\n const t = useSurveyAssistantTranslation();\n\n const addFiles = useCallback((fileList: FileList | null) => {\n const nextFiles = Array.from(fileList ?? []);\n const supportedFiles = nextFiles.filter(isSupportedFile);\n const unsupportedFiles = nextFiles.filter((file) => !isSupportedFile(file));\n\n setFiles((currentFiles) => [...currentFiles, ...supportedFiles]);\n setUnsupportedFileNames(unsupportedFiles.map((file) => file.name));\n }, []);\n\n const removeFile = useCallback((index: number) => {\n setFiles((currentFiles) => currentFiles.filter((_, fileIndex) => fileIndex !== index));\n }, []);\n\n const contextValue = useMemo(\n () => ({\n value,\n setValue,\n files,\n addFiles,\n removeFile,\n unsupportedFileNames,\n }),\n [addFiles, files, removeFile, unsupportedFileNames, value],\n );\n\n const handleSubmit = useCallback(\n async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const text = value.trim();\n if (!text && files.length === 0) {\n return;\n }\n\n const fileUIParts = await Promise.all(files.map(fileToUIPart));\n const accepted = await onSubmit({ text, files: fileUIParts }, event);\n if (accepted === false) return;\n setValue(\"\");\n setFiles([]);\n setUnsupportedFileNames([]);\n },\n [files, onSubmit, value],\n );\n\n const isFileDrag = (event: DragEvent<HTMLFormElement>) =>\n event.dataTransfer.types.includes(\"Files\");\n\n const handleDragEnter = (event: DragEvent<HTMLFormElement>) => {\n onDragEnter?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n fileDragDepthRef.current += 1;\n if (!attachmentsDisabled) setIsDraggingFiles(true);\n };\n\n const handleDragLeave = (event: DragEvent<HTMLFormElement>) => {\n onDragLeave?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = Math.max(0, fileDragDepthRef.current - 1);\n if (fileDragDepthRef.current === 0) setIsDraggingFiles(false);\n };\n\n const handleDragOver = (event: DragEvent<HTMLFormElement>) => {\n onDragOver?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n event.dataTransfer.dropEffect = attachmentsDisabled ? \"none\" : \"copy\";\n };\n\n const handleDrop = (event: DragEvent<HTMLFormElement>) => {\n onDrop?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = 0;\n setIsDraggingFiles(false);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n if (!attachmentsDisabled) addFiles(event.dataTransfer.files);\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLFormElement>) => {\n onPaste?.(event);\n if (event.defaultPrevented || attachmentsDisabled || event.clipboardData.files.length === 0) {\n return;\n }\n\n event.preventDefault();\n addFiles(event.clipboardData.files);\n };\n\n return (\n <PromptInputContext.Provider value={contextValue}>\n <form\n className={cn(\"relative rounded-xl border border-input bg-background\", className)}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onPaste={handlePaste}\n onSubmit={handleSubmit}\n {...props}\n >\n {children}\n {isDraggingFiles && (\n <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-[inherit] border-2 border-primary bg-background/90 px-4 text-center font-medium text-sm text-foreground\">\n {t(\"input.dropFiles\")}\n </div>\n )}\n </form>\n </PromptInputContext.Provider>\n );\n};\n\nexport type PromptInputBodyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputBody = ({ children, className, ...props }: PromptInputBodyProps) => {\n const { files, removeFile, unsupportedFileNames } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n\n return (\n <div className={cn(\"contents\", className)} {...props}>\n {children}\n {(files.length > 0 || unsupportedFileNames.length > 0) && (\n <div className=\"flex flex-wrap gap-2 px-3 pb-2\">\n {files.map((file, index) => (\n <div\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={`${file.name}-${file.lastModified}-${index}`}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{file.name}</span>\n <span className=\"shrink-0 text-muted-foreground\">{formatFileSize(file.size)}</span>\n <button\n className=\"shrink-0 rounded-sm text-muted-foreground hover:text-foreground\"\n onClick={() => removeFile(index)}\n type=\"button\"\n >\n <XIcon className=\"size-3.5\" />\n <span className=\"sr-only\">{t(\"input.removeFile\", { filename: file.name })}</span>\n </button>\n </div>\n ))}\n {unsupportedFileNames.length > 0 && (\n <div className=\"text-destructive text-xs\">\n {t(\"input.unsupportedFiles\", { filenames: unsupportedFileNames.join(\", \") })}\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport type PromptInputTextareaProps = ComponentProps<\"textarea\">;\n\nexport const PromptInputTextarea = ({\n className,\n onChange,\n onKeyDown,\n ...props\n}: PromptInputTextareaProps) => {\n const { value, setValue } = usePromptInput();\n\n return (\n <textarea\n className={cn(\n \"max-h-40 min-h-20 w-full resize-none bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground\",\n className,\n )}\n onChange={(event) => {\n setValue(event.target.value);\n onChange?.(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || event.shiftKey || event.key !== \"Enter\") {\n return;\n }\n event.preventDefault();\n event.currentTarget.form?.requestSubmit();\n }}\n value={value}\n {...props}\n />\n );\n};\n\nexport type PromptInputFooterProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputFooter = ({ className, ...props }: PromptInputFooterProps) => (\n <div\n className={cn(\"flex items-center gap-2 border-t border-border px-2 py-2\", className)}\n {...props}\n />\n);\n\nexport type PromptInputAttachmentButtonProps = Omit<ComponentProps<\"input\">, \"type\">;\n\nexport const PromptInputAttachmentButton = ({\n accept = SUPPORTED_FILE_ACCEPT,\n className,\n disabled,\n onChange,\n ...props\n}: PromptInputAttachmentButtonProps) => {\n const { addFiles } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n\n return (\n <label\n className={cn(\n \"inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n disabled && \"pointer-events-none cursor-default opacity-50\",\n className,\n )}\n >\n <PaperclipIcon className=\"size-4\" />\n <span className=\"sr-only\">{t(\"input.attachFiles\")}</span>\n <input\n accept={accept}\n className=\"sr-only\"\n disabled={disabled}\n multiple\n onChange={(event) => {\n addFiles(event.currentTarget.files);\n onChange?.(event);\n event.currentTarget.value = \"\";\n }}\n type=\"file\"\n {...props}\n />\n </label>\n );\n};\n\nexport type PromptInputSubmitProps = ComponentProps<\"button\"> & {\n status?: ChatStatus;\n onStop?: () => void;\n};\n\nexport const PromptInputSubmit = ({\n className,\n status,\n onStop,\n onClick,\n ...props\n}: PromptInputSubmitProps) => {\n const isGenerating = status === \"submitted\" || status === \"streaming\";\n const t = useSurveyAssistantTranslation();\n\n return (\n <button\n className={cn(\n \"inline-flex size-8 items-center justify-center rounded-full bg-foreground text-background transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\",\n className,\n )}\n onClick={(event) => {\n if (isGenerating && onStop) {\n event.preventDefault();\n onStop();\n return;\n }\n onClick?.(event);\n }}\n type=\"submit\"\n {...props}\n >\n {isGenerating ? <SquareIcon className=\"size-3.5\" /> : <ArrowUpIcon className=\"size-4\" />}\n <span className=\"sr-only\">{isGenerating ? t(\"input.stop\") : t(\"input.send\")}</span>\n </button>\n );\n};\n","const formatOmittedLength = (length: number) => length.toLocaleString(\"en-US\");\n\nexport const stringifyToolTechnicalDetails = (value: unknown): string =>\n JSON.stringify(\n value,\n function redactEmbeddedBinary(this: unknown, key, currentValue) {\n const parent =\n this && typeof this === \"object\" ? (this as Record<string, unknown>) : undefined;\n if (\n key === \"data\" &&\n typeof currentValue === \"string\" &&\n parent?.type === \"embedded\" &&\n parent.encoding === \"base64\"\n ) {\n return `[embedded base64 omitted: ${formatOmittedLength(currentValue.length)} characters]`;\n }\n\n if (\n typeof currentValue === \"string\" &&\n currentValue.length > 512 &&\n /^data:[^;,]+;base64,/.test(currentValue)\n ) {\n return `[base64 data URL omitted: ${formatOmittedLength(currentValue.length)} characters]`;\n }\n\n return currentValue;\n },\n 2,\n );\n","\"use client\";\n\nimport * as React from \"react\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { Select as SelectPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../utils\";\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <div className=\"case-survey-assistant case-survey-assistant-portal\">\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </div>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className,\n )}\n {...props}\n >\n <span\n data-slot=\"select-item-indicator\"\n className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n >\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","\"use client\";\n\n/* eslint-disable react-hooks/refs */\n\nimport { Button } from \"./button\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./select\";\nimport { cn } from \"../utils\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { BundledLanguage, BundledTheme, HighlighterGeneric, ThemedToken } from \"shiki\";\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1;\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2;\nconst isUnderline = (fontStyle: number | undefined) =>\n // oxlint-disable-next-line eslint(no-bitwise)\n fontStyle && fontStyle & 4;\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n token: ThemedToken;\n key: string;\n}\ninterface KeyedLine {\n tokens: KeyedToken[];\n key: string;\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n lines.map((line, lineIdx) => ({\n key: `line-${lineIdx}`,\n tokens: line.map((token, tokenIdx) => ({\n key: `line-${lineIdx}-${tokenIdx}`,\n token,\n })),\n }));\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n <span\n className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n style={\n {\n backgroundColor: token.bgColor,\n color: token.color,\n fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n ...token.htmlStyle,\n } as CSSProperties\n }\n >\n {token.content}\n </span>\n);\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n \"block\",\n \"before:content-[counter(line)]\",\n \"before:inline-block\",\n \"before:[counter-increment:line]\",\n \"before:w-8\",\n \"before:mr-4\",\n \"before:text-right\",\n \"before:text-muted-foreground/50\",\n \"before:font-mono\",\n \"before:select-none\",\n);\n\n// Line rendering component\nconst LineSpan = ({\n keyedLine,\n showLineNumbers,\n}: {\n keyedLine: KeyedLine;\n showLineNumbers: boolean;\n}) => (\n <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n {keyedLine.tokens.length === 0\n ? \"\\n\"\n : keyedLine.tokens.map(({ token, key }) => <TokenSpan key={key} token={token} />)}\n </span>\n);\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n};\n\ninterface TokenizedCode {\n tokens: ThemedToken[][];\n fg: string;\n bg: string;\n}\n\ninterface CodeBlockContextType {\n code: string;\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n code: \"\",\n});\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n string,\n Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>();\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>();\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>();\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n const start = code.slice(0, 100);\n const end = code.length > 100 ? code.slice(-100) : \"\";\n return `${language}:${code.length}:${start}:${end}`;\n};\n\nconst getHighlighter = (\n language: BundledLanguage,\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n const cached = highlighterCache.get(language);\n if (cached) {\n return cached;\n }\n\n const highlighterPromise = import(\"shiki\").then(({ createHighlighter }) =>\n createHighlighter({\n langs: [language],\n themes: [\"github-light\", \"github-dark\"],\n }),\n );\n\n highlighterCache.set(language, highlighterPromise);\n return highlighterPromise;\n};\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n bg: \"transparent\",\n fg: \"inherit\",\n tokens: code.split(\"\\n\").map((line) =>\n line === \"\"\n ? []\n : [\n {\n color: \"inherit\",\n content: line,\n } as ThemedToken,\n ],\n ),\n});\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n code: string,\n language: BundledLanguage,\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n callback?: (result: TokenizedCode) => void,\n): TokenizedCode | null => {\n const tokensCacheKey = getTokensCacheKey(code, language);\n\n // Return cached result if available\n const cached = tokensCache.get(tokensCacheKey);\n if (cached) {\n return cached;\n }\n\n // Subscribe callback if provided\n if (callback) {\n if (!subscribers.has(tokensCacheKey)) {\n subscribers.set(tokensCacheKey, new Set());\n }\n subscribers.get(tokensCacheKey)?.add(callback);\n }\n\n // Start highlighting in background - fire-and-forget async pattern\n getHighlighter(language)\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n .then((highlighter) => {\n const availableLangs = highlighter.getLoadedLanguages();\n const langToUse = availableLangs.includes(language) ? language : \"text\";\n\n const result = highlighter.codeToTokens(code, {\n lang: langToUse,\n themes: {\n dark: \"github-dark\",\n light: \"github-light\",\n },\n });\n\n const tokenized: TokenizedCode = {\n bg: result.bg ?? \"transparent\",\n fg: result.fg ?? \"inherit\",\n tokens: result.tokens,\n };\n\n // Cache the result\n tokensCache.set(tokensCacheKey, tokenized);\n\n // Notify all subscribers\n const subs = subscribers.get(tokensCacheKey);\n if (subs) {\n for (const sub of subs) {\n sub(tokenized);\n }\n subscribers.delete(tokensCacheKey);\n }\n })\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n .catch((error) => {\n console.error(\"Failed to highlight code:\", error);\n subscribers.delete(tokensCacheKey);\n });\n\n return null;\n};\n\nconst CodeBlockBody = memo(\n ({\n tokenized,\n showLineNumbers,\n className,\n }: {\n tokenized: TokenizedCode;\n showLineNumbers: boolean;\n className?: string;\n }) => {\n const preStyle = useMemo(\n () => ({\n backgroundColor: tokenized.bg,\n color: tokenized.fg,\n }),\n [tokenized.bg, tokenized.fg],\n );\n\n const keyedLines = useMemo(() => addKeysToTokens(tokenized.tokens), [tokenized.tokens]);\n\n return (\n <pre\n className={cn(\n \"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)] m-0 p-4 text-sm\",\n className,\n )}\n style={preStyle}\n >\n <code\n className={cn(\n \"font-mono text-sm\",\n showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\",\n )}\n >\n {keyedLines.map((keyedLine) => (\n <LineSpan key={keyedLine.key} keyedLine={keyedLine} showLineNumbers={showLineNumbers} />\n ))}\n </code>\n </pre>\n );\n },\n (prevProps, nextProps) =>\n prevProps.tokenized === nextProps.tokenized &&\n prevProps.showLineNumbers === nextProps.showLineNumbers &&\n prevProps.className === nextProps.className,\n);\n\nCodeBlockBody.displayName = \"CodeBlockBody\";\n\nexport const CodeBlockContainer = ({\n className,\n language,\n style,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n <div\n className={cn(\n \"group relative w-full overflow-hidden rounded-md border bg-background text-foreground\",\n className,\n )}\n data-language={language}\n style={{\n containIntrinsicSize: \"auto 200px\",\n contentVisibility: \"auto\",\n ...style,\n }}\n {...props}\n />\n);\n\nexport const CodeBlockHeader = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex items-center justify-between border-b bg-muted/80 px-3 py-2 text-muted-foreground text-xs\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport const CodeBlockTitle = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockFilename = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n <span className={cn(\"font-mono\", className)} {...props}>\n {children}\n </span>\n);\n\nexport const CodeBlockActions = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockContent = ({\n code,\n language,\n showLineNumbers = false,\n}: {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n}) => {\n // Memoized raw tokens for immediate display\n const rawTokens = useMemo(() => createRawTokens(code), [code]);\n\n // Synchronous cache lookup — avoids setState in effect for cached results\n const syncTokens = useMemo(\n () => highlightCode(code, language) ?? rawTokens,\n [code, language, rawTokens],\n );\n\n // Async highlighting result (populated after shiki loads)\n const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null);\n const asyncKeyRef = useRef({ code, language });\n\n // Invalidate stale async tokens synchronously during render\n if (asyncKeyRef.current.code !== code || asyncKeyRef.current.language !== language) {\n asyncKeyRef.current = { code, language };\n setAsyncTokens(null);\n }\n\n useEffect(() => {\n let cancelled = false;\n\n highlightCode(code, language, (result) => {\n if (!cancelled) {\n setAsyncTokens(result);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, language]);\n\n const tokenized = asyncTokens ?? syncTokens;\n\n return (\n <div className=\"relative overflow-auto\">\n <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n </div>\n );\n};\n\nexport const CodeBlock = ({\n code,\n language,\n showLineNumbers = false,\n className,\n children,\n ...props\n}: CodeBlockProps) => {\n const contextValue = useMemo(() => ({ code }), [code]);\n\n return (\n <CodeBlockContext.Provider value={contextValue}>\n <CodeBlockContainer className={className} language={language} {...props}>\n {children}\n <CodeBlockContent code={code} language={language} showLineNumbers={showLineNumbers} />\n </CodeBlockContainer>\n </CodeBlockContext.Provider>\n );\n};\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n onCopy?: () => void;\n onError?: (error: Error) => void;\n timeout?: number;\n};\n\nexport const CodeBlockCopyButton = ({\n onCopy,\n onError,\n timeout = 2000,\n children,\n className,\n ...props\n}: CodeBlockCopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number>(0);\n const { code } = useContext(CodeBlockContext);\n\n const copyToClipboard = useCallback(async () => {\n if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n onError?.(new Error(\"Clipboard API not available\"));\n return;\n }\n\n try {\n if (!isCopied) {\n await navigator.clipboard.writeText(code);\n setIsCopied(true);\n onCopy?.();\n timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout);\n }\n } catch (error) {\n onError?.(error as Error);\n }\n }, [code, onCopy, onError, timeout, isCopied]);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current);\n },\n [],\n );\n\n const Icon = isCopied ? CheckIcon : CopyIcon;\n\n return (\n <Button\n className={cn(\"shrink-0\", className)}\n onClick={copyToClipboard}\n size=\"icon\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <Icon size={14} />}\n </Button>\n );\n};\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>;\n\nexport const CodeBlockLanguageSelector = (props: CodeBlockLanguageSelectorProps) => (\n <Select {...props} />\n);\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<typeof SelectTrigger>;\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n className,\n ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n <SelectTrigger\n className={cn(\"h-7 border-none bg-transparent px-2 text-xs shadow-none\", className)}\n size=\"sm\"\n {...props}\n />\n);\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<typeof SelectValue>;\n\nexport const CodeBlockLanguageSelectorValue = (props: CodeBlockLanguageSelectorValueProps) => (\n <SelectValue {...props} />\n);\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<typeof SelectContent>;\n\nexport const CodeBlockLanguageSelectorContent = ({\n align = \"end\",\n ...props\n}: CodeBlockLanguageSelectorContentProps) => <SelectContent align={align} {...props} />;\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<typeof SelectItem>;\n\nexport const CodeBlockLanguageSelectorItem = (props: CodeBlockLanguageSelectorItemProps) => (\n <SelectItem {...props} />\n);\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport { highlightCode } from \"./code-block\";\nimport { Streamdown, type CodeHighlighterPlugin, type StreamdownProps } from \"streamdown\";\nimport { useMemo } from \"react\";\nimport { bundledLanguages } from \"shiki/langs\";\nimport type { BundledLanguage } from \"shiki\";\n\nconst highlightedLanguages = Object.keys(bundledLanguages) as BundledLanguage[];\n\nconst codeHighlighter = {\n getSupportedLanguages: () => highlightedLanguages,\n getThemes: () => [\"github-light\", \"github-dark\"],\n highlight: ({ code, language }, callback) => highlightCode(code, language, callback),\n name: \"shiki\",\n supportsLanguage: (language) => language in bundledLanguages,\n type: \"code-highlighter\",\n} satisfies CodeHighlighterPlugin;\n\nexport type ResponseProps = Omit<StreamdownProps, \"children\"> & {\n children: string;\n};\n\nexport const Response = ({\n children,\n className,\n controls = false,\n plugins,\n ...props\n}: ResponseProps) => {\n const responsePlugins = useMemo(\n () => ({ ...plugins, code: plugins?.code ?? codeHighlighter }),\n [plugins],\n );\n\n return (\n <Streamdown\n className={cn(\n \"leading-6\",\n \"*:first:mt-0 *:last:mb-0\",\n \"[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2\",\n \"[&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground\",\n \"[&_h1]:mb-2 [&_h1]:mt-4 [&_h1]:text-base [&_h1]:font-semibold\",\n \"[&_h2]:mb-2 [&_h2]:mt-4 [&_h2]:text-sm [&_h2]:font-semibold\",\n \"[&_h3]:mb-1.5 [&_h3]:mt-3 [&_h3]:text-sm [&_h3]:font-semibold\",\n \"[&_li]:my-1 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5\",\n \"[&_p]:my-2\",\n \"**:data-[streamdown=code-block]:my-3 **:data-[streamdown=code-block]:gap-0 **:data-[streamdown=code-block]:overflow-hidden **:data-[streamdown=code-block]:rounded-lg **:data-[streamdown=code-block]:bg-muted/40 **:data-[streamdown=code-block]:p-0\",\n \"**:data-[streamdown=code-block-header]:px-2\",\n \"**:data-[streamdown=code-block-body]:rounded-none **:data-[streamdown=code-block-body]:border-0 **:data-[streamdown=code-block-body]:border-t **:data-[streamdown=code-block-body]:bg-background **:data-[streamdown=code-block-body]:p-3\",\n \"[&_strong]:font-semibold\",\n \"[&_table]:my-3 [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_th]:font-semibold\",\n className,\n )}\n controls={controls}\n plugins={responsePlugins}\n {...props}\n >\n {children}\n </Streamdown>\n );\n};\n","import type { UIMessage } from \"ai\";\nimport {\n SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n surveyAssistantTurnFinalSchema,\n} from \"../../protocol\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst asTimestamp = (value: unknown): number | undefined => {\n if (value instanceof Date) return Number.isFinite(value.getTime()) ? value.getTime() : undefined;\n if (typeof value === \"number\") return Number.isFinite(value) ? value : undefined;\n if (typeof value !== \"string\") return undefined;\n\n const timestamp = Date.parse(value);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n};\n\nconst getMastraCreatedAt = (value: unknown): number | undefined => {\n if (!isRecord(value) || !isRecord(value.mastra)) return undefined;\n return asTimestamp(value.mastra.createdAt);\n};\n\nconst getPartTimestamps = (part: UIMessage[\"parts\"][number]): number[] => {\n const value = part as unknown as Record<string, unknown>;\n return [\n getMastraCreatedAt(value.providerMetadata),\n getMastraCreatedAt(value.callProviderMetadata),\n getMastraCreatedAt(value.resultProviderMetadata),\n ].filter((timestamp): timestamp is number => timestamp !== undefined);\n};\n\n/**\n * Mastra persists message and part timestamps already. Reconstructing elapsed\n * time here keeps restored chats informative without a second timing store.\n */\nexport const getPersistedMessageDurationSeconds = (message: UIMessage): number | undefined => {\n const turnFinalPart = message.parts.find(\n (part) => part.type === SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n );\n const turnFinal = surveyAssistantTurnFinalSchema.safeParse(\n turnFinalPart && \"data\" in turnFinalPart ? turnFinalPart.data : undefined,\n );\n if (turnFinal.success && turnFinal.data.durationMs !== undefined) {\n return Math.max(1, Math.ceil(turnFinal.data.durationMs / 1000));\n }\n\n if (!isRecord(message.metadata)) return undefined;\n\n const startedAt = asTimestamp(message.metadata.createdAt);\n if (startedAt === undefined) return undefined;\n\n const completedAt = Math.max(...message.parts.flatMap(getPartTimestamps));\n if (!Number.isFinite(completedAt) || completedAt < startedAt) return undefined;\n\n return Math.max(1, Math.ceil((completedAt - startedAt) / 1000));\n};\n","import {\n SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n surveyAssistantTurnFinalSchema,\n type SurveyAssistantTurnFinal,\n} from \"../../protocol\";\nimport type { UIMessage } from \"ai\";\n\nexport const getPersistedMessageTurnStatus = (\n message: UIMessage,\n): SurveyAssistantTurnFinal[\"status\"] | undefined => {\n for (let index = message.parts.length - 1; index >= 0; index -= 1) {\n const part = message.parts[index];\n if (part?.type !== SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE || !(\"data\" in part)) continue;\n\n const parsed = surveyAssistantTurnFinalSchema.safeParse(part.data);\n if (parsed.success) return parsed.data.status;\n }\n\n return undefined;\n};\n","\"use client\";\n\nimport {\n ChainOfThought,\n ChainOfThoughtContent,\n ChainOfThoughtHeader,\n ChainOfThoughtStep,\n} from \"./internal/chain-of-thought\";\nimport {\n Conversation,\n ConversationContent,\n ConversationEmptyState,\n ConversationScrollButton,\n} from \"./internal/conversation\";\nimport { Message, MessageContent } from \"./internal/message\";\nimport {\n PromptInput,\n PromptInputAttachmentButton,\n PromptInputBody,\n PromptInputFooter,\n PromptInputSubmit,\n PromptInputTextarea,\n type PromptInputMessage,\n} from \"./internal/prompt-input\";\nimport { stringifyToolTechnicalDetails } from \"./internal/tool-technical-details\";\nimport { Response } from \"./internal/response\";\nimport { CodeBlock } from \"./internal/code-block\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./internal/collapsible\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./internal/select\";\nimport { cn } from \"./utils\";\nimport { parseSurveyAssistantError, SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE } from \"../protocol\";\nimport type {\n SurveyApplyResult,\n SurveyAssistantAttachmentReference,\n SurveyAssistantModelOption,\n SurveyAssistantThread,\n SurveyChangeSet,\n} from \"../protocol\";\nimport {\n createSurveyAssistantThreadClient,\n isSurveyAssistantTurnActive,\n parseSurveyChangeSet,\n type SurveyAssistantThreadClient,\n type SurveyAssistantSessionOptions,\n type SurveyTurnOutcome,\n unwrapSurveyAssistantToolOutput,\n useSurveyAssistantSession,\n} from \"../react\";\nimport {\n connectSurveyAssistantThreadLauncher,\n type SurveyAssistantThreadLaunch,\n type SurveyAssistantThreadLauncher,\n} from \"../react/thread-launcher\";\nimport type { LocalizationCatalog, LocalizationTranslate } from \"@case-framework/ui-localization\";\nimport {\n getToolName,\n isFileUIPart,\n isReasoningUIPart,\n isToolUIPart,\n type DynamicToolUIPart,\n type FileUIPart,\n type ToolUIPart,\n type UIMessage,\n} from \"ai\";\nimport {\n CheckCircleIcon,\n ChevronRightIcon,\n ClockIcon,\n FileIcon,\n HistoryIcon,\n ListChecksIcon,\n LoaderCircleIcon,\n BotIcon,\n MessageSquarePlusIcon,\n PencilIcon,\n PlusIcon,\n SparklesIcon,\n Trash2Icon,\n WandSparklesIcon,\n WrenchIcon,\n XCircleIcon,\n} from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { SurveyAssistantLocalizationProvider, useSurveyAssistantTranslation } from \"./localization\";\nimport { getPersistedMessageDurationSeconds } from \"./internal/message-timing\";\nimport { getPersistedMessageTurnStatus } from \"./internal/message-turn-status\";\n\ntype ToolPart = ToolUIPart | DynamicToolUIPart;\n\nconst getAssistantQuickPrompts = (t: LocalizationTranslate) => [\n {\n label: t(\"quickActions.review.label\"),\n description: t(\"quickActions.review.description\"),\n icon: ListChecksIcon,\n prompt: t(\"quickActions.review.prompt\"),\n },\n {\n label: t(\"quickActions.create.label\"),\n description: t(\"quickActions.create.description\"),\n icon: MessageSquarePlusIcon,\n prompt: t(\"quickActions.create.prompt\"),\n },\n {\n label: t(\"quickActions.refine.label\"),\n description: t(\"quickActions.refine.description\"),\n icon: WandSparklesIcon,\n prompt: t(\"quickActions.refine.prompt\"),\n },\n];\n\nconst isSurveyAssistantAttachmentReferencePart = (\n part: UIMessage[\"parts\"][number],\n): part is {\n type: typeof SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE;\n data: SurveyAssistantAttachmentReference;\n} => {\n if (\n part.type !== SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE ||\n typeof part.data !== \"object\" ||\n part.data === null\n ) {\n return false;\n }\n const data = part.data as Partial<SurveyAssistantAttachmentReference>;\n return (\n typeof data.filename === \"string\" &&\n typeof data.mediaType === \"string\" &&\n typeof data.bytes === \"number\"\n );\n};\n\nconst hasRenderableParts = (message: UIMessage) => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" && part.text.length > 0) ||\n isFileUIPart(part) ||\n isSurveyAssistantAttachmentReferencePart(part) ||\n (isReasoningUIPart(part) && part.text.trim().length > 0) ||\n isToolUIPart(part),\n );\n};\n\nconst getFilePartLabel = (part: FileUIPart) => part.filename ?? part.mediaType;\n\nconst getToolOutput = (part: ToolPart) =>\n part.state === \"output-available\" ? part.output : undefined;\n\nconst getToolErrorText = (part: ToolPart) =>\n part.state === \"output-error\" ? part.errorText : undefined;\n\nconst localizedToolNames = new Set([\n \"survey_inspect\",\n \"survey_change\",\n \"survey_expression\",\n \"survey_authoring_reference\",\n \"survey_attachment\",\n \"recall\",\n]);\n\nconst getToolDisplayName = (\n t: LocalizationTranslate,\n toolName: string,\n phase: \"active\" | \"complete\" = \"complete\",\n) =>\n localizedToolNames.has(toolName)\n ? t(`activity.tools.${toolName}.${phase}`)\n : t(phase === \"active\" ? \"activity.genericActive\" : \"activity.genericComplete\");\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst unwrapOutput = unwrapSurveyAssistantToolOutput;\n\ntype AssistantErrorPresentation = {\n description: string;\n hint: string;\n title: string;\n tone: \"warning\" | \"error\";\n};\n\nconst getAssistantErrorPresentation = (\n error: unknown,\n t: LocalizationTranslate,\n): AssistantErrorPresentation => {\n const parsed = parseSurveyAssistantError(error);\n return {\n title: t(`errors.${parsed.code}.title`),\n description: parsed.detail ?? t(\"errors.fallbackDetail\"),\n hint: t(`errors.${parsed.code}.hint`),\n tone:\n parsed.code === \"model_unavailable\" || parsed.code === \"rate_limited\" ? \"warning\" : \"error\",\n };\n};\n\nconst getChangeSet = parseSurveyChangeSet;\n\nconst isChangeSet = (output: unknown): output is SurveyChangeSet => {\n return getChangeSet(output) !== null;\n};\n\nconst getValidationCounts = (validation: unknown) => {\n if (!isRecord(validation)) {\n return { issueCount: 0, warningCount: 0 };\n }\n\n return {\n issueCount: Array.isArray(validation.issues) ? validation.issues.length : 0,\n warningCount: Array.isArray(validation.warnings) ? validation.warnings.length : 0,\n };\n};\n\nconst SurveyAssistantToolOutputSummary = ({\n applyResult,\n output,\n}: {\n applyResult?: SurveyApplyResult;\n output: unknown;\n}) => {\n const t = useSurveyAssistantTranslation();\n const unwrappedOutput = unwrapOutput(output);\n\n if (isChangeSet(unwrappedOutput)) {\n const { issueCount, warningCount } = getValidationCounts(unwrappedOutput.validation);\n const isValid = unwrappedOutput.status === \"validated\";\n const status = applyResult?.status ?? (isValid ? \"validated\" : \"rejected\");\n const isPositiveStatus = status === \"applied\" || status === \"validated\";\n const statusLabel =\n status === \"applied\"\n ? t(\"changes.applied\")\n : status === \"stale\"\n ? t(\"changes.stale\")\n : status === \"failed\"\n ? t(\"changes.failed\")\n : isValid\n ? t(\"changes.prepared\")\n : t(\"changes.rejected\");\n const statusMessage = applyResult?.message ?? unwrappedOutput.summary;\n\n return (\n <div\n className={cn(\n \"relative rounded-md border px-2.5 py-2 text-xs\",\n isPositiveStatus\n ? \"border-emerald-200/80 bg-emerald-50/60 text-emerald-950\"\n : status === \"stale\"\n ? \"border-amber-200 bg-amber-50 text-amber-900\"\n : \"border-red-200 bg-red-50 text-red-900\",\n )}\n >\n <div className=\"flex items-center gap-2 font-medium\">\n {isPositiveStatus ? (\n <CheckCircleIcon className=\"size-3.5 shrink-0\" />\n ) : (\n <XCircleIcon className=\"size-3.5 shrink-0\" />\n )}\n <span>{statusLabel}</span>\n </div>\n <div className=\"mt-1 text-xs\">\n {statusMessage}\n {unwrappedOutput.operations.length > 0 && (\n <span className=\"text-current/70\">\n {\" \"}\n (\n {t(\n unwrappedOutput.operations.length === 1\n ? \"changes.operationCount\"\n : \"changes.operationCountPlural\",\n { count: unwrappedOutput.operations.length },\n )}\n )\n </span>\n )}\n </div>\n {(issueCount > 0 || warningCount > 0) && (\n <div className=\"mt-1 text-current/70\">\n {issueCount > 0 &&\n t(issueCount === 1 ? \"changes.issueCount\" : \"changes.issueCountPlural\", {\n count: issueCount,\n })}\n {issueCount > 0 && warningCount > 0 && \", \"}\n {warningCount > 0 &&\n t(warningCount === 1 ? \"changes.warningCount\" : \"changes.warningCountPlural\", {\n count: warningCount,\n })}\n </div>\n )}\n </div>\n );\n }\n\n return null;\n};\n\nconst getToolTitle = (t: LocalizationTranslate, toolName: string, state: ToolPart[\"state\"]) => {\n if (state === \"output-available\") {\n return getToolDisplayName(t, toolName, \"complete\");\n }\n if (state === \"output-error\") {\n return t(\"activity.failedSuffix\", { name: getToolDisplayName(t, toolName, \"complete\") });\n }\n if (state === \"output-denied\") {\n return t(\"activity.skippedSuffix\", { name: getToolDisplayName(t, toolName, \"active\") });\n }\n\n return getToolDisplayName(t, toolName, \"active\");\n};\n\nconst getToolProgressLabel = (t: LocalizationTranslate, part: ToolPart) => {\n switch (part.state) {\n case \"approval-requested\":\n return t(\"activity.waitingApproval\");\n case \"approval-responded\":\n return t(\"activity.continuingApproval\");\n case \"input-streaming\":\n return t(\"activity.preparingStep\");\n case \"input-available\":\n return getToolDisplayName(t, getToolName(part), \"active\");\n case \"output-available\":\n return t(\"activity.usingResult\");\n case \"output-denied\":\n return t(\"activity.continuingWithoutStep\");\n case \"output-error\":\n return t(\"activity.recoveringToolError\");\n }\n};\n\nconst getToolStatusMeta = (\n t: LocalizationTranslate,\n): Record<\n ToolPart[\"state\"],\n { icon: ReactNode; label: string | null; stepStatus: \"active\" | \"complete\" }\n> => ({\n \"approval-requested\": {\n icon: <ClockIcon className=\"size-3 text-amber-600\" />,\n label: t(\"activity.waitingApproval\"),\n stepStatus: \"active\",\n },\n \"approval-responded\": {\n icon: <CheckCircleIcon className=\"size-3 text-blue-600\" />,\n label: t(\"activity.approvalReceived\"),\n stepStatus: \"complete\",\n },\n \"input-available\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"input-streaming\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"output-available\": {\n icon: <CheckCircleIcon className=\"size-3 text-emerald-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-denied\": {\n icon: <XCircleIcon className=\"size-3 text-orange-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-error\": {\n icon: <XCircleIcon className=\"size-3 text-red-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n});\n\nconst getStoppedToolStatusMeta = (t: LocalizationTranslate) => ({\n icon: <XCircleIcon className=\"size-3 text-muted-foreground\" />,\n label: t(\"activity.stopped\"),\n stepStatus: \"complete\" as const,\n});\n\nconst SurveyAssistantToolStep = ({\n applyResultsByChangeId,\n terminalTurnStatus,\n part,\n isLast,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n terminalTurnStatus?: \"aborted\" | \"failed\";\n part: ToolPart;\n isLast: boolean;\n}) => {\n const t = useSurveyAssistantTranslation();\n const toolStatusMeta = getToolStatusMeta(t);\n const toolName = getToolName(part);\n const output = getToolOutput(part);\n const errorText = getToolErrorText(part);\n const changeSet = output === undefined ? null : getChangeSet(output);\n const applyResult = changeSet ? applyResultsByChangeId[changeSet.id] : undefined;\n const title = changeSet\n ? toolName === \"survey_expression\"\n ? t(\"activity.expressionChange\")\n : t(\"activity.surveyChange\")\n : getToolTitle(t, toolName, part.state);\n const meta =\n terminalTurnStatus && toolStatusMeta[part.state].stepStatus === \"active\"\n ? terminalTurnStatus === \"aborted\"\n ? getStoppedToolStatusMeta(t)\n : {\n icon: <XCircleIcon className=\"size-3 text-red-600\" />,\n label: t(\"activity.failed\"),\n stepStatus: \"complete\" as const,\n }\n : toolStatusMeta[part.state];\n const metaTitle =\n meta.label ??\n (part.state === \"output-denied\"\n ? t(\"activity.skipped\")\n : part.state === \"output-error\"\n ? t(\"activity.failed\")\n : meta.stepStatus === \"active\"\n ? t(\"activity.workingShort\")\n : t(\"activity.done\"));\n const [detailsOpen, setDetailsOpen] = useState(part.state === \"output-error\");\n const hasDetails = part.input !== undefined || output !== undefined || Boolean(errorText);\n\n return (\n <ChainOfThoughtStep\n icon={WrenchIcon}\n isLast={isLast}\n label={\n <span className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span>{title}</span>\n <span\n className={cn(\n \"inline-flex shrink-0 items-center gap-1 text-[11px] font-normal\",\n meta.stepStatus === \"active\" ? \"text-blue-700\" : \"text-muted-foreground\",\n )}\n title={metaTitle}\n >\n {meta.icon}\n {meta.label && <span>{meta.label}</span>}\n {!meta.label && <span className=\"sr-only\">{metaTitle}</span>}\n </span>\n </span>\n }\n result={\n output !== undefined ? (\n <SurveyAssistantToolOutputSummary applyResult={applyResult} output={output} />\n ) : undefined\n }\n status={meta.stepStatus}\n >\n {hasDetails && (\n <Collapsible onOpenChange={setDetailsOpen} open={detailsOpen}>\n <CollapsibleTrigger className=\"flex items-center gap-1 text-muted-foreground text-xs hover:text-foreground\">\n <ChevronRightIcon\n className={cn(\"size-3 transition-transform\", detailsOpen && \"rotate-90\")}\n />\n {t(detailsOpen ? \"activity.hideTechnicalDetails\" : \"activity.technicalDetails\")}\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-2 space-y-2\">\n {part.input !== undefined && (\n <CodeBlock\n className=\"border-border/50 bg-muted/30\"\n code={stringifyToolTechnicalDetails(part.input)}\n language=\"json\"\n />\n )}\n {(output !== undefined || errorText) && (\n <CodeBlock\n className={cn(\n \"bg-muted/30\",\n errorText ? \"border-destructive/30\" : \"border-border/50\",\n )}\n code={errorText ?? stringifyToolTechnicalDetails(output)}\n language=\"json\"\n />\n )}\n </CollapsibleContent>\n </Collapsible>\n )}\n </ChainOfThoughtStep>\n );\n};\n\nconst getStreamingProgressLabel = (t: LocalizationTranslate, message?: UIMessage) => {\n if (!message || message.role !== \"assistant\") {\n return t(\"status.connecting\");\n }\n\n const lastPart = message.parts.at(-1);\n if (!lastPart) {\n return t(\"status.thinking\");\n }\n\n if (isReasoningUIPart(lastPart)) {\n return t(\"status.thinking\");\n }\n\n if (isToolUIPart(lastPart)) {\n return getToolProgressLabel(t, lastPart);\n }\n\n if (lastPart.type === \"text\") {\n return t(\"status.writing\");\n }\n\n return t(\"status.working\");\n};\n\nconst SurveyAssistantProgressIndicator = ({ message }: { message?: UIMessage }) => {\n const t = useSurveyAssistantTranslation();\n return (\n <div\n aria-live=\"polite\"\n className=\"mt-2 flex items-center gap-2 px-1 text-muted-foreground text-xs\"\n role=\"status\"\n >\n <LoaderCircleIcon className=\"size-3.5 animate-spin text-blue-600\" />\n <span>{getStreamingProgressLabel(t, message)}</span>\n </div>\n );\n};\n\ntype ChainOfThoughtEntry =\n | { type: \"reasoning\"; key: string; text: string }\n | { type: \"tool\"; key: string; part: ToolPart };\n\ntype MessageBlock =\n | {\n type: \"attachment-reference\";\n key: string;\n attachment: SurveyAssistantAttachmentReference;\n }\n | { type: \"chain\"; key: string; entries: ChainOfThoughtEntry[] }\n | { type: \"file\"; key: string; part: FileUIPart }\n | { type: \"text\"; key: string; text: string };\n\n// Group the message's parts into ordered blocks, keeping text interleaved\n// with reasoning/tool-call chains in the exact order they were emitted,\n// instead of hoisting all reasoning/tool calls above all text output.\nconst buildMessageBlocks = (parts: UIMessage[\"parts\"]): MessageBlock[] => {\n const blocks: MessageBlock[] = [];\n let pendingEntries: ChainOfThoughtEntry[] = [];\n\n const flushChain = () => {\n if (pendingEntries.length > 0) {\n blocks.push({\n type: \"chain\",\n key: `chain-${pendingEntries[0].key}`,\n entries: pendingEntries,\n });\n pendingEntries = [];\n }\n };\n\n parts.forEach((part, index) => {\n if (isReasoningUIPart(part)) {\n if (part.text) {\n pendingEntries.push({ type: \"reasoning\", key: `reasoning-${index}`, text: part.text });\n }\n return;\n }\n\n if (isToolUIPart(part)) {\n pendingEntries.push({ type: \"tool\", key: `tool-${part.toolCallId}`, part });\n return;\n }\n\n if (part.type === \"text\") {\n flushChain();\n blocks.push({ type: \"text\", key: `text-${index}`, text: part.text });\n return;\n }\n\n if (isFileUIPart(part)) {\n flushChain();\n blocks.push({ type: \"file\", key: `file-${index}`, part });\n return;\n }\n\n if (isSurveyAssistantAttachmentReferencePart(part)) {\n flushChain();\n blocks.push({\n type: \"attachment-reference\",\n key: `attachment-reference-${index}`,\n attachment: part.data,\n });\n }\n });\n\n flushChain();\n\n return blocks;\n};\n\nconst SurveyAssistantMessageParts = ({\n applyResultsByChangeId,\n isLastMessage,\n isStreaming,\n message,\n showProgress,\n terminalTurnStatus,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n isLastMessage: boolean;\n isStreaming: boolean;\n message: UIMessage;\n showProgress?: boolean;\n terminalTurnStatus?: \"aborted\" | \"failed\";\n}) => {\n const blocks = useMemo(() => buildMessageBlocks(message.parts), [message.parts]);\n const persistedDuration = useMemo(() => getPersistedMessageDurationSeconds(message), [message]);\n const lastPart = message.parts.at(-1);\n const hasActiveToolMessage =\n lastPart !== undefined &&\n isToolUIPart(lastPart) &&\n (lastPart.state === \"input-streaming\" || lastPart.state === \"input-available\");\n\n return (\n <>\n {blocks.map((block, blockIndex) => {\n const isLastBlock = blockIndex === blocks.length - 1;\n\n if (block.type === \"text\") {\n if (message.role === \"assistant\") {\n return (\n <Response\n className=\"leading-5 [&_li]:my-0.5 [&_p]:my-1.5 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\"\n key={block.key}\n >\n {block.text}\n </Response>\n );\n }\n\n return <span key={block.key}>{block.text}</span>;\n }\n\n if (block.type === \"file\") {\n return (\n <span\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={block.key}\n title={getFilePartLabel(block.part)}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{getFilePartLabel(block.part)}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.part.mediaType}</span>\n </span>\n );\n }\n\n if (block.type === \"attachment-reference\") {\n return (\n <span\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={block.key}\n title={block.attachment.filename}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{block.attachment.filename}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.attachment.mediaType}</span>\n </span>\n );\n }\n\n const isChainActive = isLastMessage && isStreaming && isLastBlock;\n\n return (\n <ChainOfThought\n autoClose\n className=\"w-full rounded-md bg-muted/35 px-2 py-1.5\"\n defaultDuration={persistedDuration}\n defaultOpen={isChainActive}\n duration={isChainActive ? undefined : persistedDuration}\n isStreaming={isChainActive}\n key={block.key}\n >\n <ChainOfThoughtHeader className=\"text-xs font-medium\" />\n <ChainOfThoughtContent className=\"relative mt-2\">\n <div\n aria-hidden=\"true\"\n className=\"absolute top-0 bottom-0 left-1.75 w-px bg-border\"\n />\n {block.entries.map((entry, index) => {\n const isLastEntry = index === block.entries.length - 1;\n\n if (entry.type === \"reasoning\") {\n return (\n <Response\n className={cn(\n \"pr-1 pl-5 text-muted-foreground text-xs leading-5 [&_p]:my-1 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\",\n !isLastEntry && \"mb-2\",\n )}\n key={entry.key}\n >\n {entry.text}\n </Response>\n );\n }\n\n return (\n <SurveyAssistantToolStep\n applyResultsByChangeId={applyResultsByChangeId}\n isLast={isLastEntry}\n key={entry.key}\n part={entry.part}\n terminalTurnStatus={terminalTurnStatus}\n />\n );\n })}\n </ChainOfThoughtContent>\n </ChainOfThought>\n );\n })}\n {showProgress &&\n !hasActiveToolMessage &&\n (lastPart === undefined || !isReasoningUIPart(lastPart)) && (\n <SurveyAssistantProgressIndicator message={message} />\n )}\n </>\n );\n};\n\nexport type SurveyAssistantPanelProps = Omit<\n SurveyAssistantSessionOptions,\n \"initialMessages\" | \"modelId\" | \"resourceId\" | \"threadId\"\n> & {\n embedded?: boolean;\n language?: string;\n localizations?: LocalizationCatalog;\n modelId?: string;\n models?: SurveyAssistantModelOption[];\n onConfirmDeleteThread?: (thread: SurveyAssistantThread) => boolean | Promise<boolean>;\n onModelChange?(modelId: string): void;\n resourceId: string;\n selectedThreadStorageKey?: string | false;\n threadApi?: string;\n threadClient?: SurveyAssistantThreadClient;\n /** Allows host UI outside the panel to create a new thread and execute its first prompt. */\n threadLauncher?: SurveyAssistantThreadLauncher;\n};\n\ntype SurveyAssistantChatPanelProps = SurveyAssistantSessionOptions & {\n embedded?: boolean;\n initialLaunch?: SurveyAssistantThreadLaunch;\n models: SurveyAssistantModelOption[];\n onInitialLaunchHandled(): void;\n onModelChange(modelId: string): void;\n onFirstSubmit(text: string): void;\n onTurnSettled(): void;\n threadControls: ReactNode;\n threadTitle: string;\n};\n\nconst SurveyAssistantTurnOutcomeNotice = (outcome: SurveyTurnOutcome) => {\n const t = useSurveyAssistantTranslation();\n if (outcome.status === \"failed\" || outcome.status === \"aborted\") {\n const reason = (() => {\n switch (outcome.terminationReason) {\n case \"client-abort\":\n return t(\"turn.reasons.clientAbort\");\n case \"first-response-timeout\":\n return t(\"turn.reasons.firstResponseTimeout\");\n case \"idle-timeout\":\n return t(\"turn.reasons.idleTimeout\");\n case \"max-duration\":\n return t(\"turn.reasons.maxDuration\");\n case \"max-steps\":\n return t(\"turn.reasons.maxSteps\");\n case \"length-limit\":\n return t(\"turn.reasons.lengthLimit\");\n case \"content-filter\":\n return t(\"turn.reasons.contentFilter\");\n case \"provider-error\":\n return t(\"turn.reasons.providerError\");\n case \"stream-error\":\n return t(\"turn.reasons.streamError\");\n case \"incomplete-response\":\n return t(\"turn.reasons.incompleteResponse\");\n default:\n return t(\"turn.reasons.unknown\");\n }\n })();\n\n return (\n <div\n className={cn(\n \"rounded-lg border px-3 py-2 text-xs\",\n outcome.status === \"aborted\"\n ? \"border-border bg-muted/50 text-foreground\"\n : \"border-destructive/20 bg-destructive/5 text-foreground\",\n )}\n >\n <div className=\"font-medium\">\n {t(outcome.status === \"aborted\" ? \"turn.abortedTitle\" : \"turn.failedTitle\")}\n </div>\n <div className=\"mt-1 text-muted-foreground\">{reason}</div>\n </div>\n );\n }\n\n const description =\n outcome.status === \"blocked\"\n ? t(outcome.blockedChangeSetCount === 1 ? \"changes.blocked\" : \"changes.blockedPlural\", {\n count: outcome.blockedChangeSetCount,\n })\n : t(outcome.appliedChangeSetCount === 1 ? \"changes.partial\" : \"changes.partialPlural\", {\n applied: outcome.appliedChangeSetCount,\n failed: outcome.failedChangeSetCount,\n });\n\n return (\n <div className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-amber-950 text-xs\">\n <div className=\"font-medium\">{t(\"changes.incompleteTitle\")}</div>\n <div className=\"mt-1\">\n {description} {t(\"changes.reviewBeforeRetry\")}\n </div>\n </div>\n );\n};\n\nconst SurveyAssistantHeaderIdentity = ({\n indicatorClassName,\n status,\n title,\n}: {\n indicatorClassName: string;\n status: string;\n title: string;\n}) => (\n <div className=\"flex min-w-0 items-center gap-2\">\n <div className=\"relative flex size-6 shrink-0 items-center justify-center rounded-md bg-foreground text-background shadow-sm\">\n <SparklesIcon className=\"size-3.5\" />\n <span\n aria-hidden=\"true\"\n className={cn(\n \"absolute -right-px -bottom-px size-1.5 rounded-full border border-background\",\n indicatorClassName,\n )}\n />\n </div>\n <div className=\"min-w-0\">\n <h2 className=\"truncate font-semibold text-[13px] leading-4\">{title}</h2>\n <span\n aria-live=\"polite\"\n className=\"block truncate text-[10px] text-muted-foreground leading-3\"\n role=\"status\"\n >\n {status}\n </span>\n </div>\n </div>\n);\n\nconst SurveyAssistantChatPanel = ({\n api,\n applyPolicy,\n controller,\n embedded = false,\n initialLaunch,\n initialMessages,\n modelId,\n models,\n onInitialLaunchHandled,\n onModelChange,\n onFirstSubmit,\n onTurnSettled,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadControls,\n threadId,\n threadTitle,\n}: SurveyAssistantChatPanelProps) => {\n const t = useSurveyAssistantTranslation();\n const assistantQuickPrompts = getAssistantQuickPrompts(t);\n const {\n applyResultsByChangeId,\n authorizationError,\n dismissError,\n error,\n isStreaming,\n latestTurnOutcome,\n messages,\n state,\n status,\n stop,\n submit,\n retry,\n } = useSurveyAssistantSession({\n api,\n applyPolicy,\n controller,\n initialMessages,\n modelId,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadId,\n });\n const hasSubmittedMessageRef = useRef((initialMessages?.length ?? 0) > 0);\n const showAssistantError = Boolean(authorizationError) || Boolean(error);\n const assistantErrorPresentation = getAssistantErrorPresentation(authorizationError ?? error, t);\n const selectedModelLabel =\n models.find((model) => model.id === modelId)?.label ?? modelId ?? t(\"input.defaultModel\");\n const lastMessage = messages.at(-1);\n const isAssistantTurnActive = isSurveyAssistantTurnActive({ isStreaming, state });\n const promptTextareaRef = useRef<HTMLTextAreaElement>(null);\n const shouldRestorePromptFocusRef = useRef(false);\n const turnWasActiveRef = useRef(false);\n const isAssistantTurnSettled =\n !isStreaming &&\n (state === \"completed\" || state === \"failed\" || state === \"aborted\" || state === \"applied\");\n\n useEffect(() => {\n if (!isAssistantTurnActive) {\n if (shouldRestorePromptFocusRef.current) {\n shouldRestorePromptFocusRef.current = false;\n promptTextareaRef.current?.focus();\n }\n return;\n }\n\n const cancelFocusRestoreOnPointerDown = (event: PointerEvent) => {\n if (event.target !== promptTextareaRef.current) {\n shouldRestorePromptFocusRef.current = false;\n }\n };\n const cancelFocusRestore = () => {\n shouldRestorePromptFocusRef.current = false;\n };\n\n document.addEventListener(\"focusin\", cancelFocusRestore, true);\n document.addEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.addEventListener(\"blur\", cancelFocusRestore);\n\n return () => {\n document.removeEventListener(\"focusin\", cancelFocusRestore, true);\n document.removeEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.removeEventListener(\"blur\", cancelFocusRestore);\n };\n }, [isAssistantTurnActive]);\n\n useEffect(() => {\n if (isAssistantTurnActive) {\n turnWasActiveRef.current = true;\n return;\n }\n if (!turnWasActiveRef.current || !isAssistantTurnSettled) return;\n\n turnWasActiveRef.current = false;\n onTurnSettled();\n }, [isAssistantTurnActive, isAssistantTurnSettled, onTurnSettled]);\n\n const showPendingAssistantRow =\n isAssistantTurnActive && (!lastMessage || lastMessage.role !== \"assistant\");\n const sessionStatusLabel =\n state === \"applying\"\n ? t(\"status.applying\")\n : state === \"applied\"\n ? t(\"status.applied\")\n : state === \"aborted\"\n ? t(\"status.stopped\")\n : isAssistantTurnActive\n ? getStreamingProgressLabel(t, lastMessage)\n : showAssistantError || state === \"failed\"\n ? t(\"status.attention\")\n : t(\"status.ready\");\n\n const handleSubmit = useCallback(\n (message: PromptInputMessage) => {\n if (isAssistantTurnActive) return false;\n const submittedFromFocusedPrompt = document.activeElement === promptTextareaRef.current;\n const accepted = submit({ files: message.files, text: message.text });\n if (accepted) {\n shouldRestorePromptFocusRef.current = submittedFromFocusedPrompt;\n if (!hasSubmittedMessageRef.current) {\n hasSubmittedMessageRef.current = true;\n onFirstSubmit(message.text);\n }\n }\n return accepted;\n },\n [isAssistantTurnActive, onFirstSubmit, submit],\n );\n\n const handleQuickPrompt = useCallback(\n (prompt: string) => handleSubmit({ files: [], text: prompt }),\n [handleSubmit],\n );\n\n useEffect(() => {\n if (!initialLaunch) return;\n const accepted = submit({\n files: initialLaunch.files ?? [],\n text: initialLaunch.prompt,\n uiContext: initialLaunch.uiContext,\n });\n if (accepted) {\n if (!hasSubmittedMessageRef.current) {\n hasSubmittedMessageRef.current = true;\n onFirstSubmit(initialLaunch.prompt);\n }\n onInitialLaunchHandled();\n }\n }, [initialLaunch, onFirstSubmit, onInitialLaunchHandled, submit]);\n\n return (\n <aside\n aria-label={t(\"panel.ariaLabel\")}\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center justify-between gap-2 border-b border-border bg-muted/20 px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName={\n showAssistantError || state === \"failed\"\n ? \"bg-destructive\"\n : isAssistantTurnActive\n ? \"animate-pulse bg-blue-500\"\n : state === \"aborted\"\n ? \"bg-muted-foreground\"\n : \"bg-emerald-500\"\n }\n status={sessionStatusLabel}\n title={threadTitle}\n />\n {threadControls}\n </header>\n\n <Conversation className=\"min-h-0\">\n <ConversationContent className=\"gap-3 px-3 py-2.5\">\n {messages.length === 0 ? (\n <ConversationEmptyState className=\"min-h-full items-stretch justify-center gap-0 px-1 py-6 text-left\">\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-3 flex size-10 items-center justify-center rounded-xl bg-foreground text-background shadow-sm\">\n <SparklesIcon className=\"size-5\" />\n </div>\n <h3 className=\"font-semibold text-foreground text-base tracking-tight\">\n {t(\"empty.title\")}\n </h3>\n <p className=\"mt-1 text-muted-foreground text-xs leading-relaxed\">\n {t(\"empty.description\")}\n </p>\n <div className=\"mt-4 flex flex-col gap-1.5\">\n {assistantQuickPrompts.map(({ label, description, icon: Icon, prompt }) => (\n <button\n className=\"group flex w-full items-center gap-2.5 rounded-lg border border-border bg-background px-2.5 py-2 text-left transition-colors hover:border-foreground/20 hover:bg-muted/50\"\n key={label}\n onClick={() => handleQuickPrompt(prompt)}\n type=\"button\"\n >\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground transition-colors group-hover:bg-background group-hover:text-foreground\">\n <Icon className=\"size-3.5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium text-foreground text-xs\">\n {label}\n </span>\n <span className=\"block truncate text-[11px] text-muted-foreground\">\n {description}\n </span>\n </span>\n <ChevronRightIcon className=\"size-3.5 shrink-0 text-muted-foreground/40 transition-transform group-hover:translate-x-0.5 group-hover:text-muted-foreground\" />\n </button>\n ))}\n </div>\n </div>\n </ConversationEmptyState>\n ) : (\n <>\n {messages.map((message, index) => {\n const isLastMessage = index === messages.length - 1;\n const persistedTurnStatus = getPersistedMessageTurnStatus(message);\n const terminalTurnStatus =\n persistedTurnStatus === \"aborted\" || persistedTurnStatus === \"failed\"\n ? persistedTurnStatus\n : isLastMessage && (state === \"aborted\" || state === \"failed\")\n ? state\n : undefined;\n const shouldShowProgress =\n isAssistantTurnActive && isLastMessage && message.role === \"assistant\";\n\n return (\n <Message className=\"max-w-[96%] gap-1\" from={message.role} key={message.id}>\n <MessageContent\n className={cn(message.role === \"assistant\" && \"w-full space-y-2\")}\n >\n {hasRenderableParts(message) ? (\n <>\n <SurveyAssistantMessageParts\n applyResultsByChangeId={applyResultsByChangeId}\n isLastMessage={isLastMessage}\n isStreaming={isAssistantTurnActive}\n message={message}\n showProgress={shouldShowProgress}\n terminalTurnStatus={terminalTurnStatus}\n />\n {isLastMessage && latestTurnOutcome && (\n <SurveyAssistantTurnOutcomeNotice {...latestTurnOutcome} />\n )}\n </>\n ) : shouldShowProgress ? (\n <SurveyAssistantProgressIndicator message={message} />\n ) : isLastMessage && latestTurnOutcome ? (\n <SurveyAssistantTurnOutcomeNotice {...latestTurnOutcome} />\n ) : state === \"aborted\" ? (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.stopped\")}\n </span>\n ) : (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.incomplete\")}\n </span>\n )}\n </MessageContent>\n </Message>\n );\n })}\n {showPendingAssistantRow && (\n <Message className=\"max-w-[96%] gap-1\" from=\"assistant\">\n <MessageContent className=\"w-full\">\n <SurveyAssistantProgressIndicator />\n </MessageContent>\n </Message>\n )}\n </>\n )}\n </ConversationContent>\n <ConversationScrollButton className=\"bottom-2.5\" />\n </Conversation>\n\n {showAssistantError && (\n <div\n className={cn(\n \"flex items-start justify-between gap-3 border-t px-3 py-2.5 text-sm\",\n assistantErrorPresentation.tone === \"warning\"\n ? \"border-amber-200 bg-amber-50/60\"\n : \"border-destructive/20 bg-destructive/5\",\n )}\n role=\"alert\"\n >\n <div className=\"flex min-w-0 gap-2.5\">\n {assistantErrorPresentation.tone === \"warning\" ? (\n <WrenchIcon className=\"mt-0.5 size-4 shrink-0 text-amber-700\" />\n ) : (\n <XCircleIcon className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n )}\n <div className=\"min-w-0\">\n <div className=\"font-medium text-foreground\">{assistantErrorPresentation.title}</div>\n <p className=\"mt-0.5 wrap-break-word text-muted-foreground\">\n {assistantErrorPresentation.description}\n </p>\n <p className=\"mt-1 text-muted-foreground/80\">{assistantErrorPresentation.hint}</p>\n <button\n className=\"mt-1.5 font-medium text-foreground text-xs hover:underline\"\n onClick={retry}\n type=\"button\"\n >\n {t(\"errors.retry\")}\n </button>\n </div>\n </div>\n <button\n aria-label={t(\"errors.dismissAssistant\")}\n className=\"shrink-0 text-muted-foreground text-xs hover:text-foreground\"\n onClick={dismissError}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n\n <div className=\"shrink-0 border-t border-border bg-muted/20 p-2\">\n <PromptInput\n aria-busy={isAssistantTurnActive}\n attachmentsDisabled={isAssistantTurnActive}\n className={cn(\n \"rounded-xl border-border bg-background shadow-sm transition-colors\",\n isAssistantTurnActive && \"border-border/60 bg-muted/50 shadow-none\",\n )}\n onSubmit={handleSubmit}\n >\n <PromptInputBody>\n <PromptInputTextarea\n className=\"min-h-11 max-h-28 px-3 pt-2.5 pb-1.5 transition-colors disabled:cursor-not-allowed disabled:text-muted-foreground disabled:placeholder:text-muted-foreground/60\"\n disabled={isAssistantTurnActive}\n placeholder={t(\"input.placeholder\")}\n ref={promptTextareaRef}\n />\n </PromptInputBody>\n <PromptInputFooter\n className={cn(\n \"justify-between border-0 px-1.5 pt-0 pb-1.5 transition-colors\",\n isAssistantTurnActive && \"bg-muted/30\",\n )}\n >\n <PromptInputAttachmentButton className=\"size-8\" disabled={isAssistantTurnActive} />\n <div className=\"flex min-w-0 items-center justify-end gap-1\">\n {models.length > 1 && modelId ? (\n <Select\n disabled={isAssistantTurnActive}\n onValueChange={onModelChange}\n value={modelId}\n >\n <SelectTrigger\n aria-label={t(\"input.model\")}\n className=\"h-8 min-w-0 max-w-48 gap-1.5 border-0 bg-transparent px-2 text-xs shadow-none hover:bg-muted hover:text-foreground focus-visible:ring-1\"\n size=\"sm\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5\" />\n <SelectValue />\n </SelectTrigger>\n <SelectContent\n align=\"end\"\n className=\"min-w-52 rounded-lg border-border p-0 shadow-lg\"\n position=\"popper\"\n >\n {models.map((model) => (\n <SelectItem\n className=\"min-h-9 rounded-md px-2 py-2 text-xs focus:bg-muted\"\n key={model.id}\n title={model.id}\n value={model.id}\n >\n {model.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <div\n className=\"flex h-8 min-w-0 max-w-48 items-center gap-1.5 px-2 text-muted-foreground text-xs\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{selectedModelLabel}</span>\n </div>\n )}\n <PromptInputSubmit onStop={stop} status={status} />\n </div>\n </PromptInputFooter>\n </PromptInput>\n </div>\n </aside>\n );\n};\n\nconst SELECTED_THREAD_STORAGE_KEY = \"survey-assistant-selected-thread\";\n\nconst createThreadTitle = (text: string, fallback: string) => {\n const normalized = text.replace(/\\s+/g, \" \").trim();\n if (!normalized) return fallback;\n const words = normalized.split(\" \").slice(0, 8).join(\" \");\n return words.length > 64 ? `${words.slice(0, 61).trimEnd()}...` : words;\n};\n\ntype SurveyAssistantPanelContentProps = Omit<\n SurveyAssistantPanelProps,\n \"language\" | \"localizations\"\n>;\n\ninterface PendingInitialLaunch {\n input: SurveyAssistantThreadLaunch;\n onSubmitted(): void;\n}\n\nconst SurveyAssistantPanelContent = ({\n embedded = false,\n modelId,\n models = [],\n onConfirmDeleteThread,\n onModelChange = () => {},\n onTurnActiveChange: onAssistantTurnActiveChange,\n resourceId,\n selectedThreadStorageKey,\n surveyId,\n threadApi,\n threadClient: providedThreadClient,\n threadLauncher,\n ...sessionProps\n}: SurveyAssistantPanelContentProps) => {\n const t = useSurveyAssistantTranslation();\n const threadClient = useMemo(\n () => providedThreadClient ?? createSurveyAssistantThreadClient(threadApi),\n [providedThreadClient, threadApi],\n );\n const storageKey =\n selectedThreadStorageKey === false\n ? null\n : (selectedThreadStorageKey ??\n `${SELECTED_THREAD_STORAGE_KEY}:${encodeURIComponent(resourceId)}${\n surveyId ? `:${encodeURIComponent(surveyId)}` : \"\"\n }`);\n const [threads, setThreads] = useState<SurveyAssistantThread[]>([]);\n const [selectedThread, setSelectedThread] = useState<SurveyAssistantThread | null>(null);\n const [initialMessages, setInitialMessages] = useState<UIMessage[]>([]);\n const [historyOpen, setHistoryOpen] = useState(false);\n const [editingThreadId, setEditingThreadId] = useState<string | null>(null);\n const [editingTitle, setEditingTitle] = useState(\"\");\n const [threadError, setThreadError] = useState<string | null>(null);\n const [loadingThread, setLoadingThread] = useState(true);\n const [assistantTurnActive, setAssistantTurnActive] = useState(false);\n const [initialLaunch, setInitialLaunch] = useState<PendingInitialLaunch>();\n const historyControlsRef = useRef<HTMLDivElement>(null);\n\n const selectModel = useCallback(\n (modelId: string) => {\n if (!models.some((model) => model.id === modelId)) return;\n onModelChange(modelId);\n },\n [models, onModelChange],\n );\n\n const selectThread = useCallback(\n async (thread: SurveyAssistantThread) => {\n setLoadingThread(true);\n setThreadError(null);\n try {\n const transcript = await threadClient.read(thread.id);\n setSelectedThread(transcript.thread);\n setInitialMessages(transcript.messages as UIMessage[]);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n const createThread = useCallback(\n async (launch?: SurveyAssistantThreadLaunch) => {\n setLoadingThread(true);\n setThreadError(null);\n try {\n const thread = await threadClient.create(launch?.title);\n setThreads((current) => [thread, ...current]);\n setSelectedThread(thread);\n setInitialMessages([]);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n return thread;\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n if (launch) throw error;\n return null;\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n useEffect(() => {\n let cancelled = false;\n void threadClient\n .list()\n .then(async (availableThreads) => {\n if (cancelled) return;\n setThreads(availableThreads);\n const rememberedId = storageKey ? window.localStorage.getItem(storageKey) : null;\n const initialThread =\n availableThreads.find((thread) => thread.id === rememberedId) ?? availableThreads[0];\n if (initialThread) {\n await selectThread(initialThread);\n } else {\n await createThread();\n }\n })\n .catch((error) => {\n if (!cancelled) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n setLoadingThread(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [createThread, selectThread, storageKey, t, threadClient]);\n\n useEffect(() => {\n if (!threadLauncher || loadingThread) return;\n return connectSurveyAssistantThreadLauncher(threadLauncher, async (launch) => {\n const thread = await createThread(launch);\n if (!thread) throw new Error(\"The survey assistant thread could not be created.\");\n return new Promise<SurveyAssistantThread>((resolve) => {\n setInitialLaunch({\n input: launch,\n onSubmitted: () => resolve(thread),\n });\n });\n });\n }, [createThread, loadingThread, threadLauncher]);\n\n const renameThread = useCallback(\n async (thread: SurveyAssistantThread, title: string) => {\n const normalized = title.trim();\n if (!normalized || normalized === thread.title) {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n return;\n }\n try {\n const updated = await threadClient.rename(thread.id, normalized);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const setAutomaticTitle = useCallback(\n async (thread: SurveyAssistantThread, title?: string) => {\n try {\n const updated = await threadClient.setAutomaticTitle(thread.id, title);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const beginEditingThread = useCallback((thread: SurveyAssistantThread) => {\n setEditingThreadId(thread.id);\n setEditingTitle(thread.title);\n }, []);\n\n const cancelEditingThread = useCallback(() => {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n }, []);\n\n const handleTurnActiveChange = useCallback(\n (active: boolean) => {\n setAssistantTurnActive(active);\n onAssistantTurnActiveChange?.(active);\n if (active) {\n cancelEditingThread();\n setHistoryOpen(false);\n }\n },\n [cancelEditingThread, onAssistantTurnActiveChange],\n );\n\n const commitEditingThread = useCallback(async () => {\n if (!editingThreadId) return;\n const thread = threads.find((item) => item.id === editingThreadId);\n const title = editingTitle;\n if (thread) await renameThread(thread, title);\n }, [editingThreadId, editingTitle, renameThread, threads]);\n\n const deleteThread = useCallback(\n async (thread: SurveyAssistantThread) => {\n const confirmed = onConfirmDeleteThread\n ? await onConfirmDeleteThread(thread)\n : window.confirm(t(\"threads.deleteConfirm\", { title: thread.title }));\n if (!confirmed) return;\n try {\n await threadClient.delete(thread.id);\n const remaining = threads.filter((item) => item.id !== thread.id);\n setThreads(remaining);\n if (selectedThread?.id === thread.id) {\n if (remaining[0]) await selectThread(remaining[0]);\n else await createThread();\n }\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [createThread, onConfirmDeleteThread, selectThread, selectedThread, t, threadClient, threads],\n );\n\n const handleFirstSubmit = useCallback(\n (text: string) => {\n if (!selectedThread || selectedThread.titleMode === \"manual\") {\n return;\n }\n void setAutomaticTitle(selectedThread, createThreadTitle(text, t(\"threads.newChat\")));\n },\n [selectedThread, setAutomaticTitle, t],\n );\n\n const handleInitialLaunchHandled = useCallback(() => {\n if (!initialLaunch) return;\n setInitialLaunch(undefined);\n initialLaunch.onSubmitted();\n }, [initialLaunch]);\n\n const refreshThreadList = useCallback(\n async (reportError: boolean) => {\n try {\n const availableThreads = await threadClient.list();\n setThreads(availableThreads);\n const current = availableThreads.find((thread) => thread.id === selectedThread?.id);\n if (current && !editingThreadId) {\n setSelectedThread((selected) => {\n if (!selected || selected.id !== current.id) return selected;\n return selected.title === current.title &&\n selected.titleMode === current.titleMode &&\n selected.updatedAt === current.updatedAt\n ? selected\n : current;\n });\n }\n } catch (error) {\n if (reportError) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n }\n },\n [editingThreadId, selectedThread?.id, t, threadClient],\n );\n\n const toggleHistory = useCallback(() => {\n if (historyOpen) {\n void commitEditingThread();\n setHistoryOpen(false);\n return;\n }\n\n setHistoryOpen(true);\n void refreshThreadList(true);\n }, [commitEditingThread, historyOpen, refreshThreadList]);\n\n const handleTurnSettled = useCallback(() => {\n void refreshThreadList(false);\n }, [refreshThreadList]);\n\n useEffect(() => {\n if (!historyOpen) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n if (!historyControlsRef.current?.contains(event.target as Node)) {\n void commitEditingThread();\n setHistoryOpen(false);\n }\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n cancelEditingThread();\n setHistoryOpen(false);\n }\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [cancelEditingThread, commitEditingThread, historyOpen]);\n\n useEffect(() => {\n const handleFocus = () => {\n void refreshThreadList(false);\n };\n\n window.addEventListener(\"focus\", handleFocus);\n return () => window.removeEventListener(\"focus\", handleFocus);\n }, [refreshThreadList]);\n\n if (loadingThread || !selectedThread) {\n return (\n <aside\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center border-b border-border bg-muted/20 px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName=\"animate-pulse bg-blue-500\"\n status={t(\"panel.loadingChats\")}\n title={t(\"panel.title\")}\n />\n </header>\n <div className=\"flex min-h-0 flex-1 items-center justify-center text-muted-foreground text-sm\">\n <LoaderCircleIcon className=\"mr-2 size-4 animate-spin\" />\n {t(\"panel.loadingChats\")}\n </div>\n </aside>\n );\n }\n\n const threadControls = (\n <div className=\"relative flex shrink-0 items-center gap-1\" ref={historyControlsRef}>\n <button\n aria-label={t(\"threads.newChat\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50\"\n disabled={assistantTurnActive}\n onClick={() => void createThread()}\n title={t(\"threads.newChat\")}\n type=\"button\"\n >\n <PlusIcon className=\"size-4\" />\n </button>\n <button\n aria-expanded={historyOpen}\n aria-label={t(\"threads.history\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50\"\n disabled={assistantTurnActive}\n onClick={toggleHistory}\n title={t(\"threads.history\")}\n type=\"button\"\n >\n <HistoryIcon className=\"size-4\" />\n </button>\n {historyOpen && (\n <div className=\"absolute top-10 right-0 z-30 w-72 overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\">\n <div className=\"border-b border-border px-3 py-2 font-medium text-xs\">\n {t(\"threads.recent\")}\n </div>\n <div className=\"max-h-72 overflow-y-auto p-1\">\n {threads.map((thread) => (\n <div\n className={cn(\n \"group flex min-h-10 items-center gap-1 rounded-md px-2\",\n thread.id === selectedThread.id ? \"bg-muted\" : \"hover:bg-muted/60\",\n )}\n key={thread.id}\n >\n {editingThreadId === thread.id ? (\n <>\n <input\n autoFocus\n className=\"min-w-0 flex-1 rounded border border-input bg-background px-1.5 py-1 text-xs outline-none focus:ring-1 focus:ring-ring\"\n onBlur={() => void commitEditingThread()}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n void commitEditingThread();\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n cancelEditingThread();\n setHistoryOpen(false);\n }\n }}\n value={editingTitle}\n />\n {thread.titleMode === \"manual\" && (\n <button\n aria-label={t(\"threads.automaticTitle\")}\n className=\"flex h-7 shrink-0 items-center gap-1 rounded px-1.5 text-muted-foreground text-xs hover:bg-background hover:text-foreground\"\n onClick={() => void setAutomaticTitle(thread)}\n onMouseDown={(event) => event.preventDefault()}\n title={t(\"threads.automaticTitle\")}\n type=\"button\"\n >\n <SparklesIcon className=\"size-3\" />\n <span>{t(\"threads.automaticShort\")}</span>\n </button>\n )}\n </>\n ) : (\n <button\n className=\"min-w-0 flex-1 truncate py-2 text-left text-xs\"\n onClick={() => void selectThread(thread)}\n type=\"button\"\n >\n {thread.title}\n </button>\n )}\n <button\n aria-label={t(\"threads.rename\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => beginEditingThread(thread)}\n title={t(\"threads.renameTitle\")}\n type=\"button\"\n >\n <PencilIcon className=\"size-3.5\" />\n </button>\n <button\n aria-label={t(\"threads.delete\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => void deleteThread(thread)}\n title={t(\"threads.deleteTitle\")}\n type=\"button\"\n >\n <Trash2Icon className=\"size-3.5\" />\n </button>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n\n return (\n <div className=\"relative h-full min-h-0\">\n <SurveyAssistantChatPanel\n {...sessionProps}\n embedded={embedded}\n initialLaunch={initialLaunch?.input}\n initialMessages={initialMessages}\n key={selectedThread.id}\n modelId={modelId}\n models={models}\n onInitialLaunchHandled={handleInitialLaunchHandled}\n onModelChange={selectModel}\n onFirstSubmit={handleFirstSubmit}\n onTurnSettled={handleTurnSettled}\n onTurnActiveChange={handleTurnActiveChange}\n resourceId={resourceId}\n surveyId={surveyId}\n threadControls={threadControls}\n threadId={selectedThread.id}\n threadTitle={selectedThread.title}\n />\n {threadError && (\n <div className=\"absolute right-3 bottom-3 left-3 z-40 rounded-lg border border-destructive/20 bg-background px-3 py-2 text-xs shadow-lg\">\n <div className=\"font-medium\">{t(\"panel.controlsUnavailable\")}</div>\n <div className=\"mt-0.5 text-muted-foreground\">{threadError}</div>\n <button\n className=\"mt-1 font-medium hover:underline\"\n onClick={() => setThreadError(null)}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n </div>\n );\n};\n\nexport const SurveyAssistantPanel = ({\n language,\n localizations,\n ...props\n}: SurveyAssistantPanelProps) => (\n <div className=\"case-survey-assistant\">\n <SurveyAssistantLocalizationProvider language={language} localizations={localizations}>\n <SurveyAssistantPanelContent\n {...props}\n key={JSON.stringify([props.resourceId, props.surveyId])}\n />\n </SurveyAssistantLocalizationProvider>\n </div>\n);\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useSurveyAssistantModelCatalog } from \"../react\";\nimport { SurveyAssistantPanel, type SurveyAssistantPanelProps } from \"./survey-assistant-panel\";\n\nexport type ConnectedSurveyAssistantPanelProps = Omit<\n SurveyAssistantPanelProps,\n \"modelId\" | \"models\" | \"onModelChange\"\n> & {\n modelCatalogApi?: string;\n modelStorageKey?: string | false;\n onModelCatalogError?(error: Error): void;\n onModelChange?(modelId: string): void;\n};\n\nexport const ConnectedSurveyAssistantPanel = ({\n modelCatalogApi,\n modelStorageKey,\n onModelCatalogError,\n onModelChange,\n ...props\n}: ConnectedSurveyAssistantPanelProps) => {\n const catalog = useSurveyAssistantModelCatalog({\n api: modelCatalogApi,\n onModelChange,\n storageKey: modelStorageKey,\n });\n\n useEffect(() => {\n if (catalog.error) onModelCatalogError?.(catalog.error);\n }, [catalog.error, onModelCatalogError]);\n\n return (\n <SurveyAssistantPanel\n {...props}\n modelId={catalog.modelId}\n models={catalog.models}\n onModelChange={catalog.selectModel}\n />\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAIA,SAASA,cAAY,EAAE,GAAG,SAAiE;AACzF,QAAO,oBAACC,YAAqB,MAAtB;EAA2B,aAAU;EAAc,GAAI;EAAS,CAAA;;AAGzE,SAAS,mBAAmB,EAC1B,GAAG,SACoE;AACvE,QAAO,oBAACA,YAAqB,oBAAtB;EAAyC,aAAU;EAAsB,GAAI;EAAS,CAAA;;AAG/F,SAAS,mBAAmB,EAC1B,GAAG,SACoE;AACvE,QAAO,oBAACA,YAAqB,oBAAtB;EAAyC,aAAU;EAAsB,GAAI;EAAS,CAAA;;;;ACd/F,MAAa,MAAM,GAAG,WAAyB,QAAQ,KAAK,OAAO,CAAC;;;ACUpE,MAAM,uCAAuB,IAAI,KAG9B;AAEH,MAAM,sBAAsB,YAAyC;CACnE,IAAI,YAAY,qBAAqB,IAAI,QAAQ;AACjD,KAAI,CAAC,WAAW;AACd,cAAY,OAAO,OAAO,QAAQ;AAClC,uBAAqB,IAAI,SAAS,UAAU;;AAE9C,QAAO;;AAWT,MAAM,oBAAoB,EACxB,UACA,IAAI,YAAY,KAChB,WACA,WAAW,GACX,SAAS,QACa;CACtB,MAAM,kBAAkB,mBAAmB,UAAyC;CAEpF,MAAM,gBAAgB,eAAe,UAAU,UAAU,KAAK,QAAQ,CAAC,UAAU,OAAO,CAAC;AAEzF,QACE,oBAAC,iBAAD;EACE,SAAS,EAAE,oBAAoB,aAAa;EAC5C,WAAW,GACT,kFACA,+JACA,UACD;EACD,SAAS,EAAE,oBAAoB,eAAe;EAC9C,OACE;GACE,YAAY,GAAG,cAAc;GAC7B,iBACE;GACH;EAEH,YAAY;GACV;GACA,MAAM;GACN,QAAQ,OAAO;GAChB;EAEA;EACe,CAAA;;AAItB,MAAa,UAAU,KAAK,iBAAiB;;;ACvE7C,MAAa,4BAAkD;CAC7D,OAAO;EACL,WAAW;EACX,OAAO;EACP,cAAc;EACd,qBAAqB;EACtB;CACD,OAAO;EACL,OAAO;EACP,aACE;EACH;CACD,cAAc;EACZ,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACF;CACD,OAAO;EACL,aAAa;EACb,aAAa;EACb,WAAW;EACX,kBAAkB;EAClB,YAAY;EACZ,MAAM;EACN,MAAM;EACN,OAAO;EACP,cAAc;EACf;CACD,cAAc;EACZ,YAAY;EACZ,mBAAmB;EACnB,gBAAgB;EAChB,SAAS;EACT,SAAS;EACT,YAAY;EACb;CACD,MAAM;EACJ,aAAa;EACb,cAAc;EACd,SAAS;GACP,aAAa;GACb,sBAAsB;GACtB,aAAa;GACb,aAAa;GACb,UAAU;GACV,aAAa;GACb,eAAe;GACf,eAAe;GACf,aAAa;GACb,oBAAoB;GACpB,SAAS;GACV;EACF;CACD,QAAQ;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACT,WAAW;EACX,OAAO;EACP,YAAY;EACZ,UAAU;EACV,SAAS;EACT,SAAS;EACV;CACD,UAAU;EACR,OAAO;EACP,SAAS;EACT,WAAW;EACX,kBAAkB;EAClB,sBAAsB;EACtB,iBAAiB;EACjB,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,aAAa;EACb,uBAAuB;EACvB,qBAAqB;EACrB,SAAS;EACT,QAAQ;EACR,cAAc;EACd,MAAM;EACN,SAAS;EACT,kBAAkB;EAClB,cAAc;EACd,eAAe;EACf,iBAAiB;EACjB,cAAc;EACd,eAAe;EACf,OAAO;GACL,gBAAgB;IAAE,QAAQ;IAAoB,UAAU;IAAmB;GAC3E,eAAe;IAAE,QAAQ;IAAoB,UAAU;IAAmB;GAC1E,mBAAmB;IAAE,QAAQ;IAAwB,UAAU;IAAuB;GACtF,4BAA4B;IAC1B,QAAQ;IACR,UAAU;IACX;GACD,mBAAmB;IAAE,QAAQ;IAAsB,UAAU;IAAqB;GAClF,QAAQ;IACN,QAAQ;IACR,UAAU;IACX;GACF;EACF;CACD,SAAS;EACP,SAAS;EACT,OAAO;EACP,QAAQ;EACR,UAAU;EACV,UAAU;EACV,gBAAgB;EAChB,sBAAsB;EACtB,YAAY;EACZ,kBAAkB;EAClB,cAAc;EACd,oBAAoB;EACpB,iBAAiB;EACjB,SACE;EACF,eACE;EACF,SAAS;EACT,eAAe;EACf,mBAAmB;EACpB;CACD,QAAQ;EACN,SAAS;EACT,kBAAkB;EAClB,OAAO;EACP,gBAAgB;EAChB,mBAAmB;GACjB,OAAO;GACP,MAAM;GACP;EACD,cAAc;GACZ,OAAO;GACP,MAAM;GACP;EACD,sBAAsB;GACpB,OAAO;GACP,MAAM;GACP;EACD,wBAAwB;GACtB,OAAO;GACP,MAAM;GACP;EACD,gBAAgB;GACd,OAAO;GACP,MAAM;GACP;EACF;CACD,SAAS;EACP,SAAS;EACT,SAAS;EACT,QAAQ;EACR,gBAAgB;EAChB,gBAAgB;EAChB,QAAQ;EACR,aAAa;EACb,QAAQ;EACR,aAAa;EACb,eAAe;EAChB;CACF;;;AC9KD,MAAa,4BAAkD;CAC7D,OAAO;EACL,WAAW;EACX,OAAO;EACP,cAAc;EACd,qBAAqB;EACtB;CACD,OAAO;EACL,OAAO;EACP,aACE;EACH;CACD,cAAc;EACZ,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACF;CACD,OAAO;EACL,aAAa;EACb,aAAa;EACb,WAAW;EACX,kBAAkB;EAClB,YAAY;EACZ,MAAM;EACN,MAAM;EACN,OAAO;EACP,cAAc;EACf;CACD,cAAc;EACZ,YAAY;EACZ,mBAAmB;EACnB,gBAAgB;EAChB,SAAS;EACT,SAAS;EACT,YAAY;EACb;CACD,MAAM;EACJ,aAAa;EACb,cAAc;EACd,SAAS;GACP,aAAa;GACb,sBAAsB;GACtB,aAAa;GACb,aAAa;GACb,UAAU;GACV,aAAa;GACb,eAAe;GACf,eAAe;GACf,aAAa;GACb,oBAAoB;GACpB,SAAS;GACV;EACF;CACD,QAAQ;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACT,WAAW;EACX,OAAO;EACP,YAAY;EACZ,UAAU;EACV,SAAS;EACT,SAAS;EACV;CACD,UAAU;EACR,OAAO;EACP,SAAS;EACT,WAAW;EACX,kBAAkB;EAClB,sBAAsB;EACtB,iBAAiB;EACjB,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,aAAa;EACb,uBAAuB;EACvB,qBAAqB;EACrB,SAAS;EACT,QAAQ;EACR,cAAc;EACd,MAAM;EACN,SAAS;EACT,kBAAkB;EAClB,cAAc;EACd,eAAe;EACf,iBAAiB;EACjB,cAAc;EACd,eAAe;EACf,OAAO;GACL,gBAAgB;IAAE,QAAQ;IAAsB,UAAU;IAAwB;GAClF,eAAe;IAAE,QAAQ;IAA0B,UAAU;IAAwB;GACrF,mBAAmB;IACjB,QAAQ;IACR,UAAU;IACX;GACD,4BAA4B;IAC1B,QAAQ;IACR,UAAU;IACX;GACD,mBAAmB;IAAE,QAAQ;IAAkB,UAAU;IAAmB;GAC5E,QAAQ;IACN,QAAQ;IACR,UAAU;IACX;GACF;EACF;CACD,SAAS;EACP,SAAS;EACT,OAAO;EACP,QAAQ;EACR,UAAU;EACV,UAAU;EACV,gBAAgB;EAChB,sBAAsB;EACtB,YAAY;EACZ,kBAAkB;EAClB,cAAc;EACd,oBAAoB;EACpB,iBAAiB;EACjB,SACE;EACF,eACE;EACF,SAAS;EACT,eACE;EACF,mBACE;EACH;CACD,QAAQ;EACN,SAAS;EACT,kBAAkB;EAClB,OAAO;EACP,gBAAgB;EAChB,mBAAmB;GACjB,OAAO;GACP,MAAM;GACP;EACD,cAAc;GACZ,OAAO;GACP,MAAM;GACP;EACD,sBAAsB;GACpB,OAAO;GACP,MAAM;GACP;EACD,wBAAwB;GACtB,OAAO;GACP,MAAM;GACP;EACD,gBAAgB;GACd,OAAO;GACP,MAAM;GACP;EACF;CACD,SAAS;EACP,SAAS;EACT,SAAS;EACT,QAAQ;EACR,gBAAgB;EAChB,gBAAgB;EAChB,QAAQ;EACR,aAAa;EACb,QAAQ;EACR,aAAa;EACb,eAAe;EAChB;CACF;;;ACtKD,MAAa,sCAA2D;CACtE,IAAI;CACJ,IAAI;CACL;AAED,MAAM,qCAAqC,cAA4C,KAAK;AAQ5F,MAAa,uCAAuC,EAClD,UACA,WAAW,MACX,oBAC8C;CAC9C,MAAM,YAAY,cAEd,6BAA6B;EAC3B,gBAAgB;EAChB,QAAQ;EACR,eAAe,0BACb,qCACA,cACD;EACD,YAAY,KAAK,WACf,QAAQ,IACN,mDAAmD,IAAI,iBAAiB,OAAO,IAChF;EACJ,CAAC,EACJ,CAAC,UAAU,cAAc,CAC1B;AAED,QACE,oBAAC,mCAAmC,UAApC;EAA6C,OAAO;EACjD;EAC2C,CAAA;;AAIlD,MAAa,sCAA6D;CACxE,MAAM,YAAY,WAAW,mCAAmC;AAChE,KAAI,CAAC,UACH,OAAM,IAAI,MACR,yFACD;AAEH,QAAO;;;;ACpCT,MAAM,wBAAwB,cAAiD,KAAK;AAEpF,MAAa,0BAA0B;CACrC,MAAM,UAAU,WAAW,sBAAsB;AACjD,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,+DAA+D;AAEjF,QAAO;;AAWT,MAAM,mBAAmB;AACzB,MAAM,UAAU;AAEhB,MAAM,kBAAkB,oBAA4B;CAClD,MAAM,QAAQ,KAAK,MAAM,kBAAkB,KAAK;CAChD,MAAM,UAAU,KAAK,MAAO,kBAAkB,OAAQ,GAAG;CACzD,MAAM,UAAU,kBAAkB;AAElC,KAAI,QAAQ,EAAG,QAAO,GAAG,MAAM,IAAI,QAAQ;AAC3C,KAAI,UAAU,EAAG,QAAO,UAAU,IAAI,GAAG,QAAQ,IAAI,QAAQ,KAAK,GAAG,QAAQ;AAC7E,QAAO,GAAG,QAAQ;;AAGpB,MAAa,iBAAiB,MAC3B,EACC,WACA,cAAc,OACd,MACA,aACA,iBACA,cACA,UAAU,cACV,YAAY,MACZ,UACA,GAAG,YACsB;CACzB,MAAM,sBAAsB,eAAe;CAE3C,MAAM,qBAAqB,gBAAgB;CAE3C,MAAM,CAAC,QAAQ,aAAa,qBAA8B;EACxD,aAAa;EACb,UAAU;EACV,MAAM;EACP,CAAC;CACF,MAAM,CAAC,UAAU,eAAe,qBAAyC;EACvE,aAAa;EACb,MAAM;EACP,CAAC;CAEF,MAAM,qBAAqB,OAAO,YAAY;CAC9C,MAAM,CAAC,eAAe,oBAAoB,SAAS,MAAM;CACzD,MAAM,eAAe,OAAsB,KAAK;AAGhD,iBAAgB;AACd,MAAI,aAAa;AACf,sBAAmB,UAAU;AAC7B,OAAI,aAAa,YAAY,KAC3B,cAAa,UAAU,KAAK,KAAK;aAE1B,aAAa,YAAY,MAAM;AACxC,eAAY,KAAK,MAAM,KAAK,KAAK,GAAG,aAAa,WAAW,QAAQ,CAAC;AACrE,gBAAa,UAAU;;IAExB,CAAC,aAAa,YAAY,CAAC;AAG9B,iBAAgB;AACd,MAAI,eAAe,CAAC,UAAU,CAAC,mBAC7B,WAAU,KAAK;IAEhB;EAAC;EAAa;EAAQ;EAAW;EAAmB,CAAC;AAGxD,iBAAgB;AACd,MAAI,aAAa,mBAAmB,WAAW,CAAC,eAAe,UAAU,CAAC,eAAe;GACvF,MAAM,QAAQ,iBAAiB;AAC7B,cAAU,MAAM;AAChB,qBAAiB,KAAK;MACrB,iBAAiB;AAEpB,gBAAa,aAAa,MAAM;;IAEjC;EAAC;EAAW;EAAa;EAAQ;EAAW;EAAc,CAAC;CAE9D,MAAM,mBAAmB,aACtB,YAAqB;AACpB,YAAU,QAAQ;IAEpB,CAAC,UAAU,CACZ;CAED,MAAM,eAAe,eACZ;EAAE;EAAU;EAAQ;EAAa;EAAW,GACnD;EAAC;EAAU;EAAQ;EAAa;EAAU,CAC3C;AAED,QACE,oBAAC,sBAAsB,UAAvB;EAAgC,OAAO;YACrC,oBAACC,eAAD;GACE,WAAW,GAAG,oBAAoB,UAAU;GAC5C,cAAc;GACd,MAAM;GACN,GAAI;GAEH;GACW,CAAA;EACiB,CAAA;EAGtC;AAMD,MAAa,uBAAuB,MACjC,EAAE,WAAW,UAAU,oBAAoB,GAAG,YAAuC;CACpF,MAAM,EAAE,QAAQ,aAAa,aAAa,mBAAmB;CAC7D,MAAM,IAAI,+BAA+B;CACzC,MAAM,yBAAyB,cAC7B,oBAAC,SAAD;EAAS,UAAU;YAAI,EAAE,mBAAmB;EAAW,CAAA,GACrD,aAAa,KAAA,IACf,oBAAC,QAAD,EAAA,UAAO,EAAE,iBAAiB,EAAQ,CAAA,GAElC,oBAAC,QAAD,EAAA,UAAO,EAAE,sBAAsB,EAAE,UAAU,eAAe,SAAS,EAAE,CAAC,EAAQ,CAAA;AAGhF,QACE,qBAAC,oBAAD;EACE,WAAW,GACT,0GACA,UACD;EACD,GAAI;YALN;GAOE,oBAAC,WAAD,EAAW,WAAU,qBAAsB,CAAA;GAC3C,oBAAC,QAAD;IAAM,WAAU;cACb,YAAY,qBAAqB,aAAa,SAAS,IAAI;IACvD,CAAA;GACP,oBAAC,iBAAD,EACE,WAAW,GACT,0CACA,SAAS,eAAe,WACzB,EACD,CAAA;GACiB;;EAG1B;AAID,MAAa,wBAAwB,MAAM,EAAE,WAAW,GAAG,YACzD,oBAAC,oBAAD;CACE,WAAW,GACT,QACA,yLACA,UACD;CACD,GAAI;CACJ,CAAA,CACF;AAWF,MAAM,mBAAmB;CACvB,UAAU;CACV,QAAQ;CACR,SAAS;CACV;AAED,MAAa,qBAAqB,MAC/B,EACC,WACA,MAAM,OAAO,SACb,OACA,aACA,QACA,SAAS,YACT,SAAS,OACT,UACA,GAAG,YAEH,qBAAC,OAAD;CACE,WAAW,GACT,6DACA,SAAS,SAAS,UAClB,iBAAiB,SACjB,UACD;CACD,GAAI;WAPN;EASE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA;IACzB,CAAA,EACN,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,OAAD;KAAK,WAAU;eAAmB;KAAY,CAAA,EAC7C,eAAe,oBAAC,OAAD;KAAK,WAAU;eAAwC;KAAkB,CAAA,CACrF;MACF;;EACL,UAAU,oBAAC,OAAD;GAAK,WAAU;aAA6B;GAAa,CAAA;EACnE,YAAY,oBAAC,OAAD;GAAK,WAAU;GAAgC;GAAe,CAAA;EACvE;GAET;AAED,eAAe,cAAc;AAC7B,qBAAqB,cAAc;AACnC,sBAAsB,cAAc;AACpC,mBAAmB,cAAc;;;AC1PjC,MAAM,iBAAiB,IACrB,wVACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,WAAW;GACX,OAAO;GACR;EACD,MAAM;GACJ,SAAS;GACT,MAAM;GACN,WAAW;GACZ;EACF;CACD,iBAAiB;EAAE,SAAS;EAAW,MAAM;EAAW;CACzD,CACF;AAED,MAAa,UAAU,EACrB,WACA,UAAU,WACV,OAAO,WACP,UAAU,OACV,GAAG,YAIG;AAEN,QAAO,oBADW,UAAU,KAAK,OAAO,UACjC;EAAW,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;GAAW,CAAC,CAAC;EAAE,GAAI;EAAS,CAAA;;;;ACvB9F,MAAa,gBAAgB,EAAE,WAAW,GAAG,YAC3C,oBAAC,eAAD;CACE,WAAW,GAAG,6CAA6C,UAAU;CACrE,SAAQ;CACR,MAAK;CACL,QAAO;CACP,GAAI;CACJ,CAAA;AAKJ,MAAa,uBAAuB,EAAE,WAAW,GAAG,YAClD,oBAAC,cAAc,SAAf;CAAuB,WAAW,GAAG,2BAA2B,UAAU;CAAE,GAAI;CAAS,CAAA;AAS3F,MAAa,0BAA0B,EACrC,WACA,OACA,aACA,MACA,UACA,GAAG,YAC8B;CACjC,MAAM,IAAI,+BAA+B;CACzC,MAAM,gBAAgB,SAAS,EAAE,0BAA0B;CAC3D,MAAM,sBAAsB,eAAe,EAAE,iCAAiC;AAE9E,QACE,oBAAC,OAAD;EACE,WAAW,GACT,6EACA,UACD;EACD,GAAI;YAEH,YACC,qBAAA,UAAA,EAAA,UAAA,CACG,QAAQ,oBAAC,OAAD;GAAK,WAAU;aAAyB;GAAW,CAAA,EAC5D,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,MAAD;IAAI,WAAU;cAAuB;IAAmB,CAAA,EACvD,uBACC,oBAAC,KAAD;IAAG,WAAU;cAAiC;IAAwB,CAAA,CAEpE;KACL,EAAA,CAAA;EAED,CAAA;;AAMV,MAAa,4BAA4B,EACvC,WACA,GAAG,YACgC;CACnC,MAAM,EAAE,YAAY,mBAAmB,yBAAyB;CAChE,MAAM,IAAI,+BAA+B;CAEzC,MAAM,uBAAuB,kBAAkB;AAC7C,kBAAgB;IACf,CAAC,eAAe,CAAC;AAEpB,QACE,CAAC,cACC,oBAAC,QAAD;EACE,WAAW,GACT,sMACA,UACD;EACD,cAAY,EAAE,8BAA8B;EAC5C,SAAS;EACT,MAAK;EACL,MAAK;EACL,SAAQ;EACR,GAAI;YAEJ,oBAAC,eAAD,EAAe,WAAU,UAAW,CAAA;EAC7B,CAAA;;;;ACvFf,MAAa,WAAW,EAAE,WAAW,MAAM,GAAG,YAC5C,oBAAC,OAAD;CACE,WAAW,GACT,gDACA,SAAS,SAAS,sBAAsB,eACxC,UACD;CACD,aAAW;CACX,GAAI;CACJ,CAAA;AAKJ,MAAa,kBAAkB,EAAE,UAAU,WAAW,GAAG,YACvD,oBAAC,OAAD;CACE,WAAW,GACT,gDACA,oZACA,+CACA,UACD;CACD,GAAI;CAEH;CACG,CAAA;;;ACfR,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB,SACvB,KAAK,KAAK,WAAW,SAAS,IAAI,KAAK,SAAS;AAElD,MAAM,kBAAkB,SAAiB;AACvC,KAAI,OAAO,OAAO,KAChB,QAAO,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,KAAK,CAAC,CAAC;AAGjD,QAAO,IAAI,QAAQ,OAAO,OAAO,QAAQ,OAAO,KAAK,OAAO,OAAO,IAAI,EAAE,CAAC;;AAG5E,MAAM,eAAe,OAAO,SAAoC;CAC9D,MAAM,YAAY,KAAK,QAAQ;CAC/B,MAAM,QAAQ,IAAI,WAAW,MAAM,KAAK,aAAa,CAAC;CACtD,MAAM,YAAY;CAClB,IAAI,SAAS;AAEb,MAAK,IAAI,SAAS,GAAG,SAAS,MAAM,QAAQ,UAAU,UACpD,WAAU,OAAO,aAAa,GAAG,MAAM,SAAS,QAAQ,SAAS,UAAU,CAAC;AAG9E,QAAO;EACL,MAAM;EACN;EACA,UAAU,KAAK;EACf,KAAK,QAAQ,UAAU,UAAU,KAAK,OAAO;EAC9C;;AAiBH,MAAM,qBAAqB,cAA8C,KAAK;AAE9E,MAAM,uBAAuB;CAC3B,MAAM,UAAU,WAAW,mBAAmB;AAC9C,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,0DAA0D;AAE5E,QAAO;;AAWT,MAAa,eAAe,EAC1B,sBAAsB,OACtB,UACA,WACA,aACA,aACA,YACA,QACA,SACA,UACA,GAAG,YACmB;CACtB,MAAM,CAAC,OAAO,YAAY,SAAS,GAAG;CACtC,MAAM,CAAC,OAAO,YAAY,SAAiB,EAAE,CAAC;CAC9C,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,MAAM;CAC7D,MAAM,CAAC,sBAAsB,2BAA2B,SAAmB,EAAE,CAAC;CAC9E,MAAM,mBAAmB,OAAO,EAAE;CAClC,MAAM,IAAI,+BAA+B;CAEzC,MAAM,WAAW,aAAa,aAA8B;EAC1D,MAAM,YAAY,MAAM,KAAK,YAAY,EAAE,CAAC;EAC5C,MAAM,iBAAiB,UAAU,OAAO,gBAAgB;EACxD,MAAM,mBAAmB,UAAU,QAAQ,SAAS,CAAC,gBAAgB,KAAK,CAAC;AAE3E,YAAU,iBAAiB,CAAC,GAAG,cAAc,GAAG,eAAe,CAAC;AAChE,0BAAwB,iBAAiB,KAAK,SAAS,KAAK,KAAK,CAAC;IACjE,EAAE,CAAC;CAEN,MAAM,aAAa,aAAa,UAAkB;AAChD,YAAU,iBAAiB,aAAa,QAAQ,GAAG,cAAc,cAAc,MAAM,CAAC;IACrF,EAAE,CAAC;CAEN,MAAM,eAAe,eACZ;EACL;EACA;EACA;EACA;EACA;EACA;EACD,GACD;EAAC;EAAU;EAAO;EAAY;EAAsB;EAAM,CAC3D;CAED,MAAM,eAAe,YACnB,OAAO,UAAsC;AAC3C,QAAM,gBAAgB;EACtB,MAAM,OAAO,MAAM,MAAM;AACzB,MAAI,CAAC,QAAQ,MAAM,WAAW,EAC5B;AAKF,MAAI,MADmB,SAAS;GAAE;GAAM,OAAO,MADrB,QAAQ,IAAI,MAAM,IAAI,aAAa,CAAC;GACF,EAAE,MAAM,KACnD,MAAO;AACxB,WAAS,GAAG;AACZ,WAAS,EAAE,CAAC;AACZ,0BAAwB,EAAE,CAAC;IAE7B;EAAC;EAAO;EAAU;EAAM,CACzB;CAED,MAAM,cAAc,UAClB,MAAM,aAAa,MAAM,SAAS,QAAQ;CAE5C,MAAM,mBAAmB,UAAsC;AAC7D,gBAAc,MAAM;AACpB,MAAI,MAAM,oBAAoB,CAAC,WAAW,MAAM,CAAE;AAElD,QAAM,gBAAgB;AACtB,mBAAiB,WAAW;AAC5B,MAAI,CAAC,oBAAqB,oBAAmB,KAAK;;CAGpD,MAAM,mBAAmB,UAAsC;AAC7D,gBAAc,MAAM;AACpB,MAAI,CAAC,WAAW,MAAM,CAAE;AAExB,mBAAiB,UAAU,KAAK,IAAI,GAAG,iBAAiB,UAAU,EAAE;AACpE,MAAI,iBAAiB,YAAY,EAAG,oBAAmB,MAAM;;CAG/D,MAAM,kBAAkB,UAAsC;AAC5D,eAAa,MAAM;AACnB,MAAI,MAAM,oBAAoB,CAAC,WAAW,MAAM,CAAE;AAElD,QAAM,gBAAgB;AACtB,QAAM,aAAa,aAAa,sBAAsB,SAAS;;CAGjE,MAAM,cAAc,UAAsC;AACxD,WAAS,MAAM;AACf,MAAI,CAAC,WAAW,MAAM,CAAE;AAExB,mBAAiB,UAAU;AAC3B,qBAAmB,MAAM;AACzB,MAAI,MAAM,iBAAkB;AAE5B,QAAM,gBAAgB;AACtB,MAAI,CAAC,oBAAqB,UAAS,MAAM,aAAa,MAAM;;CAG9D,MAAM,eAAe,UAA2C;AAC9D,YAAU,MAAM;AAChB,MAAI,MAAM,oBAAoB,uBAAuB,MAAM,cAAc,MAAM,WAAW,EACxF;AAGF,QAAM,gBAAgB;AACtB,WAAS,MAAM,cAAc,MAAM;;AAGrC,QACE,oBAAC,mBAAmB,UAApB;EAA6B,OAAO;YAClC,qBAAC,QAAD;GACE,WAAW,GAAG,yDAAyD,UAAU;GACjF,aAAa;GACb,aAAa;GACb,YAAY;GACZ,QAAQ;GACR,SAAS;GACT,UAAU;GACV,GAAI;aARN,CAUG,UACA,mBACC,oBAAC,OAAD;IAAK,WAAU;cACZ,EAAE,kBAAkB;IACjB,CAAA,CAEH;;EACqB,CAAA;;AAMlC,MAAa,mBAAmB,EAAE,UAAU,WAAW,GAAG,YAAkC;CAC1F,MAAM,EAAE,OAAO,YAAY,yBAAyB,gBAAgB;CACpE,MAAM,IAAI,+BAA+B;AAEzC,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,YAAY,UAAU;EAAE,GAAI;YAA/C,CACG,WACC,MAAM,SAAS,KAAK,qBAAqB,SAAS,MAClD,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,MAAM,KAAK,MAAM,UAChB,qBAAC,OAAD;IACE,WAAU;cADZ;KAIE,oBAAC,UAAD,EAAU,WAAU,2CAA4C,CAAA;KAChE,oBAAC,QAAD;MAAM,WAAU;gBAAoB,KAAK;MAAY,CAAA;KACrD,oBAAC,QAAD;MAAM,WAAU;gBAAkC,eAAe,KAAK,KAAK;MAAQ,CAAA;KACnF,qBAAC,UAAD;MACE,WAAU;MACV,eAAe,WAAW,MAAM;MAChC,MAAK;gBAHP,CAKE,oBAAC,OAAD,EAAO,WAAU,YAAa,CAAA,EAC9B,oBAAC,QAAD;OAAM,WAAU;iBAAW,EAAE,oBAAoB,EAAE,UAAU,KAAK,MAAM,CAAC;OAAQ,CAAA,CAC1E;;KACL;MAbC,GAAG,KAAK,KAAK,GAAG,KAAK,aAAa,GAAG,QAatC,CACN,EACD,qBAAqB,SAAS,KAC7B,oBAAC,OAAD;IAAK,WAAU;cACZ,EAAE,0BAA0B,EAAE,WAAW,qBAAqB,KAAK,KAAK,EAAE,CAAC;IACxE,CAAA,CAEJ;KAEJ;;;AAMV,MAAa,uBAAuB,EAClC,WACA,UACA,WACA,GAAG,YAC2B;CAC9B,MAAM,EAAE,OAAO,aAAa,gBAAgB;AAE5C,QACE,oBAAC,YAAD;EACE,WAAW,GACT,wHACA,UACD;EACD,WAAW,UAAU;AACnB,YAAS,MAAM,OAAO,MAAM;AAC5B,cAAW,MAAM;;EAEnB,YAAY,UAAU;AACpB,eAAY,MAAM;AAClB,OAAI,MAAM,oBAAoB,MAAM,YAAY,MAAM,QAAQ,QAC5D;AAEF,SAAM,gBAAgB;AACtB,SAAM,cAAc,MAAM,eAAe;;EAEpC;EACP,GAAI;EACJ,CAAA;;AAMN,MAAa,qBAAqB,EAAE,WAAW,GAAG,YAChD,oBAAC,OAAD;CACE,WAAW,GAAG,4DAA4D,UAAU;CACpF,GAAI;CACJ,CAAA;AAKJ,MAAa,+BAA+B,EAC1C,SAAS,uBACT,WACA,UACA,UACA,GAAG,YACmC;CACtC,MAAM,EAAE,aAAa,gBAAgB;CACrC,MAAM,IAAI,+BAA+B;AAEzC,QACE,qBAAC,SAAD;EACE,WAAW,GACT,yJACA,YAAY,iDACZ,UACD;YALH;GAOE,oBAAC,eAAD,EAAe,WAAU,UAAW,CAAA;GACpC,oBAAC,QAAD;IAAM,WAAU;cAAW,EAAE,oBAAoB;IAAQ,CAAA;GACzD,oBAAC,SAAD;IACU;IACR,WAAU;IACA;IACV,UAAA;IACA,WAAW,UAAU;AACnB,cAAS,MAAM,cAAc,MAAM;AACnC,gBAAW,MAAM;AACjB,WAAM,cAAc,QAAQ;;IAE9B,MAAK;IACL,GAAI;IACJ,CAAA;GACI;;;AASZ,MAAa,qBAAqB,EAChC,WACA,QACA,QACA,SACA,GAAG,YACyB;CAC5B,MAAM,eAAe,WAAW,eAAe,WAAW;CAC1D,MAAM,IAAI,+BAA+B;AAEzC,QACE,qBAAC,UAAD;EACE,WAAW,GACT,kLACA,UACD;EACD,UAAU,UAAU;AAClB,OAAI,gBAAgB,QAAQ;AAC1B,UAAM,gBAAgB;AACtB,YAAQ;AACR;;AAEF,aAAU,MAAM;;EAElB,MAAK;EACL,GAAI;YAdN,CAgBG,eAAe,oBAAC,YAAD,EAAY,WAAU,YAAa,CAAA,GAAG,oBAAC,aAAD,EAAa,WAAU,UAAW,CAAA,EACxF,oBAAC,QAAD;GAAM,WAAU;aAAW,eAAe,EAAE,aAAa,GAAG,EAAE,aAAa;GAAQ,CAAA,CAC5E;;;;;ACrXb,MAAM,uBAAuB,WAAmB,OAAO,eAAe,QAAQ;AAE9E,MAAa,iCAAiC,UAC5C,KAAK,UACH,OACA,SAAS,qBAAoC,KAAK,cAAc;CAC9D,MAAM,SACJ,QAAQ,OAAO,SAAS,WAAY,OAAmC,KAAA;AACzE,KACE,QAAQ,UACR,OAAO,iBAAiB,YACxB,QAAQ,SAAS,cACjB,OAAO,aAAa,SAEpB,QAAO,6BAA6B,oBAAoB,aAAa,OAAO,CAAC;AAG/E,KACE,OAAO,iBAAiB,YACxB,aAAa,SAAS,OACtB,uBAAuB,KAAK,aAAa,CAEzC,QAAO,6BAA6B,oBAAoB,aAAa,OAAO,CAAC;AAG/E,QAAO;GAET,EACD;;;ACpBH,SAASC,SAAO,EAAE,GAAG,SAA4D;AAC/E,QAAO,oBAACC,OAAgB,MAAjB;EAAsB,aAAU;EAAS,GAAI;EAAS,CAAA;;AAO/D,SAAS,YAAY,EAAE,GAAG,SAA6D;AACrF,QAAO,oBAACA,OAAgB,OAAjB;EAAuB,aAAU;EAAe,GAAI;EAAS,CAAA;;AAGtE,SAAS,cAAc,EACrB,WACA,OAAO,WACP,UACA,GAAG,SAGF;AACD,QACE,qBAACA,OAAgB,SAAjB;EACE,aAAU;EACV,aAAW;EACX,WAAW,GACT,gzBACA,UACD;EACD,GAAI;YAPN,CASG,UACD,oBAACA,OAAgB,MAAjB;GAAsB,SAAA;aACpB,oBAAC,iBAAD,EAAiB,WAAU,qBAAsB,CAAA;GAC5B,CAAA,CACC;;;AAI9B,SAAS,cAAc,EACrB,WACA,UACA,WAAW,gBACX,QAAQ,UACR,GAAG,SACoD;AACvD,QACE,oBAACA,OAAgB,QAAjB,EAAA,UACE,oBAAC,OAAD;EAAK,WAAU;YACb,qBAACA,OAAgB,SAAjB;GACE,aAAU;GACV,WAAW,GACT,ijBACA,aAAa,YACX,mIACF,UACD;GACS;GACH;GACP,GAAI;aAVN;IAYE,oBAAC,sBAAD,EAAwB,CAAA;IACxB,oBAACA,OAAgB,UAAjB;KACE,WAAW,GACT,OACA,aAAa,YACX,sGACH;KAEA;KACwB,CAAA;IAC3B,oBAAC,wBAAD,EAA0B,CAAA;IACF;;EACtB,CAAA,EACiB,CAAA;;AAc7B,SAAS,WAAW,EAClB,WACA,UACA,GAAG,SACiD;AACpD,QACE,qBAACA,OAAgB,MAAjB;EACE,aAAU;EACV,WAAW,GACT,6aACA,UACD;EACD,GAAI;YANN,CAQE,oBAAC,QAAD;GACE,aAAU;GACV,WAAU;aAEV,oBAACA,OAAgB,eAAjB,EAAA,UACE,oBAAC,WAAD,EAAW,WAAU,UAAW,CAAA,EACF,CAAA;GAC3B,CAAA,EACP,oBAACA,OAAgB,UAAjB,EAA2B,UAAoC,CAAA,CAC1C;;;AAiB3B,SAAS,qBAAqB,EAC5B,WACA,GAAG,SAC2D;AAC9D,QACE,oBAACA,OAAgB,gBAAjB;EACE,aAAU;EACV,WAAW,GAAG,wDAAwD,UAAU;EAChF,GAAI;YAEJ,oBAAC,eAAD,EAAe,WAAU,UAAW,CAAA;EACL,CAAA;;AAIrC,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;AAChE,QACE,oBAACA,OAAgB,kBAAjB;EACE,aAAU;EACV,WAAW,GAAG,wDAAwD,UAAU;EAChF,GAAI;YAEJ,oBAAC,iBAAD,EAAiB,WAAU,UAAW,CAAA;EACL,CAAA;;;;AC1IvC,MAAM,YAAY,cAAkC,aAAa,YAAY;AAE7E,MAAM,UAAU,cAAkC,aAAa,YAAY;AAC3E,MAAM,eAAe,cAEnB,aAAa,YAAY;AAY3B,MAAM,mBAAmB,UACvB,MAAM,KAAK,MAAM,aAAa;CAC5B,KAAK,QAAQ;CACb,QAAQ,KAAK,KAAK,OAAO,cAAc;EACrC,KAAK,QAAQ,QAAQ,GAAG;EACxB;EACD,EAAE;CACJ,EAAE;AAGL,MAAM,aAAa,EAAE,YACnB,oBAAC,QAAD;CACE,WAAU;CACV,OACE;EACE,iBAAiB,MAAM;EACvB,OAAO,MAAM;EACb,WAAW,SAAS,MAAM,UAAU,GAAG,WAAW,KAAA;EAClD,YAAY,OAAO,MAAM,UAAU,GAAG,SAAS,KAAA;EAC/C,gBAAgB,YAAY,MAAM,UAAU,GAAG,cAAc,KAAA;EAC7D,GAAG,MAAM;EACV;WAGF,MAAM;CACF,CAAA;AAIT,MAAM,sBAAsB,GAC1B,SACA,kCACA,uBACA,mCACA,cACA,eACA,qBACA,mCACA,oBACA,qBACD;AAGD,MAAM,YAAY,EAChB,WACA,sBAKA,oBAAC,QAAD;CAAM,WAAW,kBAAkB,sBAAsB;WACtD,UAAU,OAAO,WAAW,IACzB,OACA,UAAU,OAAO,KAAK,EAAE,OAAO,UAAU,oBAAC,WAAD,EAA4B,OAAS,EAArB,IAAqB,CAAC;CAC9E,CAAA;AAqBT,MAAM,mBAAmB,cAAoC,EAC3D,MAAM,IACP,CAAC;AAGF,MAAM,mCAAmB,IAAI,KAG1B;AAGH,MAAM,8BAAc,IAAI,KAA4B;AAGpD,MAAM,8BAAc,IAAI,KAAmD;AAE3E,MAAM,qBAAqB,MAAc,aAA8B;CACrE,MAAM,QAAQ,KAAK,MAAM,GAAG,IAAI;CAChC,MAAM,MAAM,KAAK,SAAS,MAAM,KAAK,MAAM,KAAK,GAAG;AACnD,QAAO,GAAG,SAAS,GAAG,KAAK,OAAO,GAAG,MAAM,GAAG;;AAGhD,MAAM,kBACJ,aAC+D;CAC/D,MAAM,SAAS,iBAAiB,IAAI,SAAS;AAC7C,KAAI,OACF,QAAO;CAGT,MAAM,qBAAqB,OAAO,SAAS,MAAM,EAAE,wBACjD,kBAAkB;EAChB,OAAO,CAAC,SAAS;EACjB,QAAQ,CAAC,gBAAgB,cAAc;EACxC,CAAC,CACH;AAED,kBAAiB,IAAI,UAAU,mBAAmB;AAClD,QAAO;;AAIT,MAAM,mBAAmB,UAAiC;CACxD,IAAI;CACJ,IAAI;CACJ,QAAQ,KAAK,MAAM,KAAK,CAAC,KAAK,SAC5B,SAAS,KACL,EAAE,GACF,CACE;EACE,OAAO;EACP,SAAS;EACV,CACF,CACN;CACF;AAGD,MAAa,iBACX,MACA,UAEA,aACyB;CACzB,MAAM,iBAAiB,kBAAkB,MAAM,SAAS;CAGxD,MAAM,SAAS,YAAY,IAAI,eAAe;AAC9C,KAAI,OACF,QAAO;AAIT,KAAI,UAAU;AACZ,MAAI,CAAC,YAAY,IAAI,eAAe,CAClC,aAAY,IAAI,gCAAgB,IAAI,KAAK,CAAC;AAE5C,cAAY,IAAI,eAAe,EAAE,IAAI,SAAS;;AAIhD,gBAAe,SAAS,CAErB,MAAM,gBAAgB;EAErB,MAAM,YADiB,YAAY,oBACH,CAAC,SAAS,SAAS,GAAG,WAAW;EAEjE,MAAM,SAAS,YAAY,aAAa,MAAM;GAC5C,MAAM;GACN,QAAQ;IACN,MAAM;IACN,OAAO;IACR;GACF,CAAC;EAEF,MAAM,YAA2B;GAC/B,IAAI,OAAO,MAAM;GACjB,IAAI,OAAO,MAAM;GACjB,QAAQ,OAAO;GAChB;AAGD,cAAY,IAAI,gBAAgB,UAAU;EAG1C,MAAM,OAAO,YAAY,IAAI,eAAe;AAC5C,MAAI,MAAM;AACR,QAAK,MAAM,OAAO,KAChB,KAAI,UAAU;AAEhB,eAAY,OAAO,eAAe;;GAEpC,CAED,OAAO,UAAU;AAChB,UAAQ,MAAM,6BAA6B,MAAM;AACjD,cAAY,OAAO,eAAe;GAClC;AAEJ,QAAO;;AAGT,MAAM,gBAAgB,MACnB,EACC,WACA,iBACA,gBAKI;CACJ,MAAM,WAAW,eACR;EACL,iBAAiB,UAAU;EAC3B,OAAO,UAAU;EAClB,GACD,CAAC,UAAU,IAAI,UAAU,GAAG,CAC7B;CAED,MAAM,aAAa,cAAc,gBAAgB,UAAU,OAAO,EAAE,CAAC,UAAU,OAAO,CAAC;AAEvF,QACE,oBAAC,OAAD;EACE,WAAW,GACT,kFACA,UACD;EACD,OAAO;YAEP,oBAAC,QAAD;GACE,WAAW,GACT,qBACA,mBAAmB,kDACpB;aAEA,WAAW,KAAK,cACf,oBAAC,UAAD;IAAyC;IAA4B;IAAmB,EAAzE,UAAU,IAA+D,CACxF;GACG,CAAA;EACH,CAAA;IAGT,WAAW,cACV,UAAU,cAAc,UAAU,aAClC,UAAU,oBAAoB,UAAU,mBACxC,UAAU,cAAc,UAAU,UACrC;AAED,cAAc,cAAc;AAE5B,MAAa,sBAAsB,EACjC,WACA,UACA,OACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GACT,yFACA,UACD;CACD,iBAAe;CACf,OAAO;EACL,sBAAsB;EACtB,mBAAmB;EACnB,GAAG;EACJ;CACD,GAAI;CACJ,CAAA;AAiDJ,MAAa,oBAAoB,EAC/B,MACA,UACA,kBAAkB,YAKd;CAEJ,MAAM,YAAY,cAAc,gBAAgB,KAAK,EAAE,CAAC,KAAK,CAAC;CAG9D,MAAM,aAAa,cACX,cAAc,MAAM,SAAS,IAAI,WACvC;EAAC;EAAM;EAAU;EAAU,CAC5B;CAGD,MAAM,CAAC,aAAa,kBAAkB,SAA+B,KAAK;CAC1E,MAAM,cAAc,OAAO;EAAE;EAAM;EAAU,CAAC;AAG9C,KAAI,YAAY,QAAQ,SAAS,QAAQ,YAAY,QAAQ,aAAa,UAAU;AAClF,cAAY,UAAU;GAAE;GAAM;GAAU;AACxC,iBAAe,KAAK;;AAGtB,iBAAgB;EACd,IAAI,YAAY;AAEhB,gBAAc,MAAM,WAAW,WAAW;AACxC,OAAI,CAAC,UACH,gBAAe,OAAO;IAExB;AAEF,eAAa;AACX,eAAY;;IAEb,CAAC,MAAM,SAAS,CAAC;AAIpB,QACE,oBAAC,OAAD;EAAK,WAAU;YACb,oBAAC,eAAD;GAAgC;GAAiB,WAJnC,eAAe;GAI4C,CAAA;EACrE,CAAA;;AAIV,MAAa,aAAa,EACxB,MACA,UACA,kBAAkB,OAClB,WACA,UACA,GAAG,YACiB;CACpB,MAAM,eAAe,eAAe,EAAE,MAAM,GAAG,CAAC,KAAK,CAAC;AAEtD,QACE,oBAAC,iBAAiB,UAAlB;EAA2B,OAAO;YAChC,qBAAC,oBAAD;GAA+B;GAAqB;GAAU,GAAI;aAAlE,CACG,UACD,oBAAC,kBAAD;IAAwB;IAAgB;IAA2B;IAAmB,CAAA,CACnE;;EACK,CAAA;;;;AC3ZhC,MAAM,uBAAuB,OAAO,KAAK,iBAAiB;AAE1D,MAAM,kBAAkB;CACtB,6BAA6B;CAC7B,iBAAiB,CAAC,gBAAgB,cAAc;CAChD,YAAY,EAAE,MAAM,YAAY,aAAa,cAAc,MAAM,UAAU,SAAS;CACpF,MAAM;CACN,mBAAmB,aAAa,YAAY;CAC5C,MAAM;CACP;AAMD,MAAa,YAAY,EACvB,UACA,WACA,WAAW,OACX,SACA,GAAG,YACgB;CACnB,MAAM,kBAAkB,eACf;EAAE,GAAG;EAAS,MAAM,SAAS,QAAQ;EAAiB,GAC7D,CAAC,QAAQ,CACV;AAED,QACE,oBAAC,YAAD;EACE,WAAW,GACT,aACA,4BACA,+DACA,uIACA,iEACA,+DACA,iEACA,oGACA,cACA,yPACA,+CACA,6OACA,4BACA,yNACA,UACD;EACS;EACV,SAAS;EACT,GAAI;EAEH;EACU,CAAA;;;;ACtDjB,MAAMC,cAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;AAEtE,MAAM,eAAe,UAAuC;AAC1D,KAAI,iBAAiB,KAAM,QAAO,OAAO,SAAS,MAAM,SAAS,CAAC,GAAG,MAAM,SAAS,GAAG,KAAA;AACvF,KAAI,OAAO,UAAU,SAAU,QAAO,OAAO,SAAS,MAAM,GAAG,QAAQ,KAAA;AACvE,KAAI,OAAO,UAAU,SAAU,QAAO,KAAA;CAEtC,MAAM,YAAY,KAAK,MAAM,MAAM;AACnC,QAAO,OAAO,SAAS,UAAU,GAAG,YAAY,KAAA;;AAGlD,MAAM,sBAAsB,UAAuC;AACjE,KAAI,CAACA,WAAS,MAAM,IAAI,CAACA,WAAS,MAAM,OAAO,CAAE,QAAO,KAAA;AACxD,QAAO,YAAY,MAAM,OAAO,UAAU;;AAG5C,MAAM,qBAAqB,SAA+C;CACxE,MAAM,QAAQ;AACd,QAAO;EACL,mBAAmB,MAAM,iBAAiB;EAC1C,mBAAmB,MAAM,qBAAqB;EAC9C,mBAAmB,MAAM,uBAAuB;EACjD,CAAC,QAAQ,cAAmC,cAAc,KAAA,EAAU;;;;;;AAOvE,MAAa,sCAAsC,YAA2C;CAC5F,MAAM,gBAAgB,QAAQ,MAAM,MACjC,SAAS,KAAK,SAAS,sCACzB;CACD,MAAM,YAAY,+BAA+B,UAC/C,iBAAiB,UAAU,gBAAgB,cAAc,OAAO,KAAA,EACjE;AACD,KAAI,UAAU,WAAW,UAAU,KAAK,eAAe,KAAA,EACrD,QAAO,KAAK,IAAI,GAAG,KAAK,KAAK,UAAU,KAAK,aAAa,IAAK,CAAC;AAGjE,KAAI,CAACA,WAAS,QAAQ,SAAS,CAAE,QAAO,KAAA;CAExC,MAAM,YAAY,YAAY,QAAQ,SAAS,UAAU;AACzD,KAAI,cAAc,KAAA,EAAW,QAAO,KAAA;CAEpC,MAAM,cAAc,KAAK,IAAI,GAAG,QAAQ,MAAM,QAAQ,kBAAkB,CAAC;AACzE,KAAI,CAAC,OAAO,SAAS,YAAY,IAAI,cAAc,UAAW,QAAO,KAAA;AAErE,QAAO,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,aAAa,IAAK,CAAC;;;;AChDjE,MAAa,iCACX,YACmD;AACnD,MAAK,IAAI,QAAQ,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EACjE,MAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,MAAM,SAAS,yCAAyC,EAAE,UAAU,MAAO;EAE/E,MAAM,SAAS,+BAA+B,UAAU,KAAK,KAAK;AAClE,MAAI,OAAO,QAAS,QAAO,OAAO,KAAK;;;;;AC0E3C,MAAM,4BAA4B,MAA6B;CAC7D;EACE,OAAO,EAAE,4BAA4B;EACrC,aAAa,EAAE,kCAAkC;EACjD,MAAM;EACN,QAAQ,EAAE,6BAA6B;EACxC;CACD;EACE,OAAO,EAAE,4BAA4B;EACrC,aAAa,EAAE,kCAAkC;EACjD,MAAM;EACN,QAAQ,EAAE,6BAA6B;EACxC;CACD;EACE,OAAO,EAAE,4BAA4B;EACrC,aAAa,EAAE,kCAAkC;EACjD,MAAM;EACN,QAAQ,EAAE,6BAA6B;EACxC;CACF;AAED,MAAM,4CACJ,SAIG;AACH,KACE,KAAK,SAAA,sCACL,OAAO,KAAK,SAAS,YACrB,KAAK,SAAS,KAEd,QAAO;CAET,MAAM,OAAO,KAAK;AAClB,QACE,OAAO,KAAK,aAAa,YACzB,OAAO,KAAK,cAAc,YAC1B,OAAO,KAAK,UAAU;;AAI1B,MAAM,sBAAsB,YAAuB;AACjD,QAAO,QAAQ,MAAM,MAClB,SACE,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,KAC5C,aAAa,KAAK,IAClB,yCAAyC,KAAK,IAC7C,kBAAkB,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC,SAAS,KACtD,aAAa,KAAK,CACrB;;AAGH,MAAM,oBAAoB,SAAqB,KAAK,YAAY,KAAK;AAErE,MAAM,iBAAiB,SACrB,KAAK,UAAU,qBAAqB,KAAK,SAAS,KAAA;AAEpD,MAAM,oBAAoB,SACxB,KAAK,UAAU,iBAAiB,KAAK,YAAY,KAAA;AAEnD,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,sBACJ,GACA,UACA,QAA+B,eAE/B,mBAAmB,IAAI,SAAS,GAC5B,EAAE,kBAAkB,SAAS,GAAG,QAAQ,GACxC,EAAE,UAAU,WAAW,2BAA2B,2BAA2B;AAEnF,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;AAEtE,MAAM,eAAe;AASrB,MAAM,iCACJ,OACA,MAC+B;CAC/B,MAAM,SAAS,0BAA0B,MAAM;AAC/C,QAAO;EACL,OAAO,EAAE,UAAU,OAAO,KAAK,QAAQ;EACvC,aAAa,OAAO,UAAU,EAAE,wBAAwB;EACxD,MAAM,EAAE,UAAU,OAAO,KAAK,OAAO;EACrC,MACE,OAAO,SAAS,uBAAuB,OAAO,SAAS,iBAAiB,YAAY;EACvF;;AAGH,MAAM,eAAe;AAErB,MAAM,eAAe,WAA+C;AAClE,QAAO,aAAa,OAAO,KAAK;;AAGlC,MAAM,uBAAuB,eAAwB;AACnD,KAAI,CAAC,SAAS,WAAW,CACvB,QAAO;EAAE,YAAY;EAAG,cAAc;EAAG;AAG3C,QAAO;EACL,YAAY,MAAM,QAAQ,WAAW,OAAO,GAAG,WAAW,OAAO,SAAS;EAC1E,cAAc,MAAM,QAAQ,WAAW,SAAS,GAAG,WAAW,SAAS,SAAS;EACjF;;AAGH,MAAM,oCAAoC,EACxC,aACA,aAII;CACJ,MAAM,IAAI,+BAA+B;CACzC,MAAM,kBAAkB,aAAa,OAAO;AAE5C,KAAI,YAAY,gBAAgB,EAAE;EAChC,MAAM,EAAE,YAAY,iBAAiB,oBAAoB,gBAAgB,WAAW;EACpF,MAAM,UAAU,gBAAgB,WAAW;EAC3C,MAAM,SAAS,aAAa,WAAW,UAAU,cAAc;EAC/D,MAAM,mBAAmB,WAAW,aAAa,WAAW;EAC5D,MAAM,cACJ,WAAW,YACP,EAAE,kBAAkB,GACpB,WAAW,UACT,EAAE,gBAAgB,GAClB,WAAW,WACT,EAAE,iBAAiB,GACnB,UACE,EAAE,mBAAmB,GACrB,EAAE,mBAAmB;EACjC,MAAM,gBAAgB,aAAa,WAAW,gBAAgB;AAE9D,SACE,qBAAC,OAAD;GACE,WAAW,GACT,kDACA,mBACI,4DACA,WAAW,UACT,gDACA,wCACP;aARH;IAUE,qBAAC,OAAD;KAAK,WAAU;eAAf,CACG,mBACC,oBAAC,iBAAD,EAAiB,WAAU,qBAAsB,CAAA,GAEjD,oBAAC,aAAD,EAAa,WAAU,qBAAsB,CAAA,EAE/C,oBAAC,QAAD,EAAA,UAAO,aAAmB,CAAA,CACtB;;IACN,qBAAC,OAAD;KAAK,WAAU;eAAf,CACG,eACA,gBAAgB,WAAW,SAAS,KACnC,qBAAC,QAAD;MAAM,WAAU;gBAAhB;OACG;OAAI;OAEJ,EACC,gBAAgB,WAAW,WAAW,IAClC,2BACA,gCACJ,EAAE,OAAO,gBAAgB,WAAW,QAAQ,CAC7C;OAAC;OAEG;QAEL;;KACJ,aAAa,KAAK,eAAe,MACjC,qBAAC,OAAD;KAAK,WAAU;eAAf;MACG,aAAa,KACZ,EAAE,eAAe,IAAI,uBAAuB,4BAA4B,EACtE,OAAO,YACR,CAAC;MACH,aAAa,KAAK,eAAe,KAAK;MACtC,eAAe,KACd,EAAE,iBAAiB,IAAI,yBAAyB,8BAA8B,EAC5E,OAAO,cACR,CAAC;MACA;;IAEJ;;;AAIV,QAAO;;AAGT,MAAM,gBAAgB,GAA0B,UAAkB,UAA6B;AAC7F,KAAI,UAAU,mBACZ,QAAO,mBAAmB,GAAG,UAAU,WAAW;AAEpD,KAAI,UAAU,eACZ,QAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,GAAG,UAAU,WAAW,EAAE,CAAC;AAE1F,KAAI,UAAU,gBACZ,QAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,GAAG,UAAU,SAAS,EAAE,CAAC;AAGzF,QAAO,mBAAmB,GAAG,UAAU,SAAS;;AAGlD,MAAM,wBAAwB,GAA0B,SAAmB;AACzE,SAAQ,KAAK,OAAb;EACE,KAAK,qBACH,QAAO,EAAE,2BAA2B;EACtC,KAAK,qBACH,QAAO,EAAE,8BAA8B;EACzC,KAAK,kBACH,QAAO,EAAE,yBAAyB;EACpC,KAAK,kBACH,QAAO,mBAAmB,GAAG,YAAY,KAAK,EAAE,SAAS;EAC3D,KAAK,mBACH,QAAO,EAAE,uBAAuB;EAClC,KAAK,gBACH,QAAO,EAAE,iCAAiC;EAC5C,KAAK,eACH,QAAO,EAAE,+BAA+B;;;AAI9C,MAAM,qBACJ,OAII;CACJ,sBAAsB;EACpB,MAAM,oBAAC,WAAD,EAAW,WAAU,yBAA0B,CAAA;EACrD,OAAO,EAAE,2BAA2B;EACpC,YAAY;EACb;CACD,sBAAsB;EACpB,MAAM,oBAAC,iBAAD,EAAiB,WAAU,wBAAyB,CAAA;EAC1D,OAAO,EAAE,4BAA4B;EACrC,YAAY;EACb;CACD,mBAAmB;EACjB,MAAM,oBAAC,kBAAD,EAAkB,WAAU,qCAAsC,CAAA;EACxE,OAAO;EACP,YAAY;EACb;CACD,mBAAmB;EACjB,MAAM,oBAAC,kBAAD,EAAkB,WAAU,qCAAsC,CAAA;EACxE,OAAO;EACP,YAAY;EACb;CACD,oBAAoB;EAClB,MAAM,oBAAC,iBAAD,EAAiB,WAAU,2BAA4B,CAAA;EAC7D,OAAO;EACP,YAAY;EACb;CACD,iBAAiB;EACf,MAAM,oBAAC,aAAD,EAAa,WAAU,0BAA2B,CAAA;EACxD,OAAO;EACP,YAAY;EACb;CACD,gBAAgB;EACd,MAAM,oBAAC,aAAD,EAAa,WAAU,uBAAwB,CAAA;EACrD,OAAO;EACP,YAAY;EACb;CACF;AAED,MAAM,4BAA4B,OAA8B;CAC9D,MAAM,oBAAC,aAAD,EAAa,WAAU,gCAAiC,CAAA;CAC9D,OAAO,EAAE,mBAAmB;CAC5B,YAAY;CACb;AAED,MAAM,2BAA2B,EAC/B,wBACA,oBACA,MACA,aAMI;CACJ,MAAM,IAAI,+BAA+B;CACzC,MAAM,iBAAiB,kBAAkB,EAAE;CAC3C,MAAM,WAAW,YAAY,KAAK;CAClC,MAAM,SAAS,cAAc,KAAK;CAClC,MAAM,YAAY,iBAAiB,KAAK;CACxC,MAAM,YAAY,WAAW,KAAA,IAAY,OAAO,aAAa,OAAO;CACpE,MAAM,cAAc,YAAY,uBAAuB,UAAU,MAAM,KAAA;CACvE,MAAM,QAAQ,YACV,aAAa,sBACX,EAAE,4BAA4B,GAC9B,EAAE,wBAAwB,GAC5B,aAAa,GAAG,UAAU,KAAK,MAAM;CACzC,MAAM,OACJ,sBAAsB,eAAe,KAAK,OAAO,eAAe,WAC5D,uBAAuB,YACrB,yBAAyB,EAAE,GAC3B;EACE,MAAM,oBAAC,aAAD,EAAa,WAAU,uBAAwB,CAAA;EACrD,OAAO,EAAE,kBAAkB;EAC3B,YAAY;EACb,GACH,eAAe,KAAK;CAC1B,MAAM,YACJ,KAAK,UACJ,KAAK,UAAU,kBACZ,EAAE,mBAAmB,GACrB,KAAK,UAAU,iBACb,EAAE,kBAAkB,GACpB,KAAK,eAAe,WAClB,EAAE,wBAAwB,GAC1B,EAAE,gBAAgB;CAC5B,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK,UAAU,eAAe;CAC7E,MAAM,aAAa,KAAK,UAAU,KAAA,KAAa,WAAW,KAAA,KAAa,QAAQ,UAAU;AAEzF,QACE,oBAAC,oBAAD;EACE,MAAM;EACE;EACR,OACE,qBAAC,QAAD;GAAM,WAAU;aAAhB,CACE,oBAAC,QAAD,EAAA,UAAO,OAAa,CAAA,EACpB,qBAAC,QAAD;IACE,WAAW,GACT,mEACA,KAAK,eAAe,WAAW,kBAAkB,wBAClD;IACD,OAAO;cALT;KAOG,KAAK;KACL,KAAK,SAAS,oBAAC,QAAD,EAAA,UAAO,KAAK,OAAa,CAAA;KACvC,CAAC,KAAK,SAAS,oBAAC,QAAD;MAAM,WAAU;gBAAW;MAAiB,CAAA;KACvD;MACF;;EAET,QACE,WAAW,KAAA,IACT,oBAAC,kCAAD;GAA+C;GAAqB;GAAU,CAAA,GAC5E,KAAA;EAEN,QAAQ,KAAK;YAEZ,cACC,qBAACC,eAAD;GAAa,cAAc;GAAgB,MAAM;aAAjD,CACE,qBAAC,oBAAD;IAAoB,WAAU;cAA9B,CACE,oBAAC,kBAAD,EACE,WAAW,GAAG,+BAA+B,eAAe,YAAY,EACxE,CAAA,EACD,EAAE,cAAc,kCAAkC,4BAA4B,CAC5D;OACrB,qBAAC,oBAAD;IAAoB,WAAU;cAA9B,CACG,KAAK,UAAU,KAAA,KACd,oBAAC,WAAD;KACE,WAAU;KACV,MAAM,8BAA8B,KAAK,MAAM;KAC/C,UAAS;KACT,CAAA,GAEF,WAAW,KAAA,KAAa,cACxB,oBAAC,WAAD;KACE,WAAW,GACT,eACA,YAAY,0BAA0B,mBACvC;KACD,MAAM,aAAa,8BAA8B,OAAO;KACxD,UAAS;KACT,CAAA,CAEe;MACT;;EAEG,CAAA;;AAIzB,MAAM,6BAA6B,GAA0B,YAAwB;AACnF,KAAI,CAAC,WAAW,QAAQ,SAAS,YAC/B,QAAO,EAAE,oBAAoB;CAG/B,MAAM,WAAW,QAAQ,MAAM,GAAG,GAAG;AACrC,KAAI,CAAC,SACH,QAAO,EAAE,kBAAkB;AAG7B,KAAI,kBAAkB,SAAS,CAC7B,QAAO,EAAE,kBAAkB;AAG7B,KAAI,aAAa,SAAS,CACxB,QAAO,qBAAqB,GAAG,SAAS;AAG1C,KAAI,SAAS,SAAS,OACpB,QAAO,EAAE,iBAAiB;AAG5B,QAAO,EAAE,iBAAiB;;AAG5B,MAAM,oCAAoC,EAAE,cAAuC;CACjF,MAAM,IAAI,+BAA+B;AACzC,QACE,qBAAC,OAAD;EACE,aAAU;EACV,WAAU;EACV,MAAK;YAHP,CAKE,oBAAC,kBAAD,EAAkB,WAAU,uCAAwC,CAAA,EACpE,oBAAC,QAAD,EAAA,UAAO,0BAA0B,GAAG,QAAQ,EAAQ,CAAA,CAChD;;;AAqBV,MAAM,sBAAsB,UAA8C;CACxE,MAAM,SAAyB,EAAE;CACjC,IAAI,iBAAwC,EAAE;CAE9C,MAAM,mBAAmB;AACvB,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAO,KAAK;IACV,MAAM;IACN,KAAK,SAAS,eAAe,GAAG;IAChC,SAAS;IACV,CAAC;AACF,oBAAiB,EAAE;;;AAIvB,OAAM,SAAS,MAAM,UAAU;AAC7B,MAAI,kBAAkB,KAAK,EAAE;AAC3B,OAAI,KAAK,KACP,gBAAe,KAAK;IAAE,MAAM;IAAa,KAAK,aAAa;IAAS,MAAM,KAAK;IAAM,CAAC;AAExF;;AAGF,MAAI,aAAa,KAAK,EAAE;AACtB,kBAAe,KAAK;IAAE,MAAM;IAAQ,KAAK,QAAQ,KAAK;IAAc;IAAM,CAAC;AAC3E;;AAGF,MAAI,KAAK,SAAS,QAAQ;AACxB,eAAY;AACZ,UAAO,KAAK;IAAE,MAAM;IAAQ,KAAK,QAAQ;IAAS,MAAM,KAAK;IAAM,CAAC;AACpE;;AAGF,MAAI,aAAa,KAAK,EAAE;AACtB,eAAY;AACZ,UAAO,KAAK;IAAE,MAAM;IAAQ,KAAK,QAAQ;IAAS;IAAM,CAAC;AACzD;;AAGF,MAAI,yCAAyC,KAAK,EAAE;AAClD,eAAY;AACZ,UAAO,KAAK;IACV,MAAM;IACN,KAAK,wBAAwB;IAC7B,YAAY,KAAK;IAClB,CAAC;;GAEJ;AAEF,aAAY;AAEZ,QAAO;;AAGT,MAAM,+BAA+B,EACnC,wBACA,eACA,aACA,SACA,cACA,yBAQI;CACJ,MAAM,SAAS,cAAc,mBAAmB,QAAQ,MAAM,EAAE,CAAC,QAAQ,MAAM,CAAC;CAChF,MAAM,oBAAoB,cAAc,mCAAmC,QAAQ,EAAE,CAAC,QAAQ,CAAC;CAC/F,MAAM,WAAW,QAAQ,MAAM,GAAG,GAAG;CACrC,MAAM,uBACJ,aAAa,KAAA,KACb,aAAa,SAAS,KACrB,SAAS,UAAU,qBAAqB,SAAS,UAAU;AAE9D,QACE,qBAAA,UAAA,EAAA,UAAA,CACG,OAAO,KAAK,OAAO,eAAe;EACjC,MAAM,cAAc,eAAe,OAAO,SAAS;AAEnD,MAAI,MAAM,SAAS,QAAQ;AACzB,OAAI,QAAQ,SAAS,YACnB,QACE,oBAAC,UAAD;IACE,WAAU;cAGT,MAAM;IACE,EAHJ,MAAM,IAGF;AAIf,UAAO,oBAAC,QAAD,EAAA,UAAuB,MAAM,MAAY,EAA9B,MAAM,IAAwB;;AAGlD,MAAI,MAAM,SAAS,OACjB,QACE,qBAAC,QAAD;GACE,WAAU;GAEV,OAAO,iBAAiB,MAAM,KAAK;aAHrC;IAKE,oBAAC,UAAD,EAAU,WAAU,2CAA4C,CAAA;IAChE,oBAAC,QAAD;KAAM,WAAU;eAAoB,iBAAiB,MAAM,KAAK;KAAQ,CAAA;IACxE,oBAAC,QAAD;KAAM,WAAU;eAAkC,MAAM,KAAK;KAAiB,CAAA;IACzE;KANA,MAAM,IAMN;AAIX,MAAI,MAAM,SAAS,uBACjB,QACE,qBAAC,QAAD;GACE,WAAU;GAEV,OAAO,MAAM,WAAW;aAH1B;IAKE,oBAAC,UAAD,EAAU,WAAU,2CAA4C,CAAA;IAChE,oBAAC,QAAD;KAAM,WAAU;eAAoB,MAAM,WAAW;KAAgB,CAAA;IACrE,oBAAC,QAAD;KAAM,WAAU;eAAkC,MAAM,WAAW;KAAiB,CAAA;IAC/E;KANA,MAAM,IAMN;EAIX,MAAM,gBAAgB,iBAAiB,eAAe;AAEtD,SACE,qBAAC,gBAAD;GACE,WAAA;GACA,WAAU;GACV,iBAAiB;GACjB,aAAa;GACb,UAAU,gBAAgB,KAAA,IAAY;GACtC,aAAa;aANf,CASE,oBAAC,sBAAD,EAAsB,WAAU,uBAAwB,CAAA,EACxD,qBAAC,uBAAD;IAAuB,WAAU;cAAjC,CACE,oBAAC,OAAD;KACE,eAAY;KACZ,WAAU;KACV,CAAA,EACD,MAAM,QAAQ,KAAK,OAAO,UAAU;KACnC,MAAM,cAAc,UAAU,MAAM,QAAQ,SAAS;AAErD,SAAI,MAAM,SAAS,YACjB,QACE,oBAAC,UAAD;MACE,WAAW,GACT,6GACA,CAAC,eAAe,OACjB;gBAGA,MAAM;MACE,EAHJ,MAAM,IAGF;AAIf,YACE,oBAAC,yBAAD;MAC0B;MACxB,QAAQ;MAER,MAAM,MAAM;MACQ;MACpB,EAHK,MAAM,IAGX;MAEJ,CACoB;MACT;KApCV,MAAM,IAoCI;GAEnB,EACD,gBACC,CAAC,yBACA,aAAa,KAAA,KAAa,CAAC,kBAAkB,SAAS,KACrD,oBAAC,kCAAD,EAA2C,SAAW,CAAA,CAEzD,EAAA,CAAA;;AAmCP,MAAM,oCAAoC,YAA+B;CACvE,MAAM,IAAI,+BAA+B;AACzC,KAAI,QAAQ,WAAW,YAAY,QAAQ,WAAW,WAAW;EAC/D,MAAM,gBAAgB;AACpB,WAAQ,QAAQ,mBAAhB;IACE,KAAK,eACH,QAAO,EAAE,2BAA2B;IACtC,KAAK,yBACH,QAAO,EAAE,oCAAoC;IAC/C,KAAK,eACH,QAAO,EAAE,2BAA2B;IACtC,KAAK,eACH,QAAO,EAAE,2BAA2B;IACtC,KAAK,YACH,QAAO,EAAE,wBAAwB;IACnC,KAAK,eACH,QAAO,EAAE,2BAA2B;IACtC,KAAK,iBACH,QAAO,EAAE,6BAA6B;IACxC,KAAK,iBACH,QAAO,EAAE,6BAA6B;IACxC,KAAK,eACH,QAAO,EAAE,2BAA2B;IACtC,KAAK,sBACH,QAAO,EAAE,kCAAkC;IAC7C,QACE,QAAO,EAAE,uBAAuB;;MAElC;AAEJ,SACE,qBAAC,OAAD;GACE,WAAW,GACT,uCACA,QAAQ,WAAW,YACf,8CACA,yDACL;aANH,CAQE,oBAAC,OAAD;IAAK,WAAU;cACZ,EAAE,QAAQ,WAAW,YAAY,sBAAsB,mBAAmB;IACvE,CAAA,EACN,oBAAC,OAAD;IAAK,WAAU;cAA8B;IAAa,CAAA,CACtD;;;CAIV,MAAM,cACJ,QAAQ,WAAW,YACf,EAAE,QAAQ,0BAA0B,IAAI,oBAAoB,yBAAyB,EACnF,OAAO,QAAQ,uBAChB,CAAC,GACF,EAAE,QAAQ,0BAA0B,IAAI,oBAAoB,yBAAyB;EACnF,SAAS,QAAQ;EACjB,QAAQ,QAAQ;EACjB,CAAC;AAER,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,OAAD;GAAK,WAAU;aAAe,EAAE,0BAA0B;GAAO,CAAA,EACjE,qBAAC,OAAD;GAAK,WAAU;aAAf;IACG;IAAY;IAAE,EAAE,4BAA4B;IACzC;KACF;;;AAIV,MAAM,iCAAiC,EACrC,oBACA,QACA,YAMA,qBAAC,OAAD;CAAK,WAAU;WAAf,CACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,cAAD,EAAc,WAAU,YAAa,CAAA,EACrC,oBAAC,QAAD;GACE,eAAY;GACZ,WAAW,GACT,gFACA,mBACD;GACD,CAAA,CACE;KACN,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,MAAD;GAAI,WAAU;aAAgD;GAAW,CAAA,EACzE,oBAAC,QAAD;GACE,aAAU;GACV,WAAU;GACV,MAAK;aAEJ;GACI,CAAA,CACH;IACF;;AAGR,MAAM,4BAA4B,EAChC,KACA,aACA,YACA,WAAW,OACX,eACA,iBACA,SACA,QACA,wBACA,eACA,eACA,eACA,iBACA,eACA,oBACA,oBACA,YACA,UACA,gBACA,UACA,kBACmC;CACnC,MAAM,IAAI,+BAA+B;CACzC,MAAM,wBAAwB,yBAAyB,EAAE;CACzD,MAAM,EACJ,wBACA,oBACA,cACA,OACA,aACA,mBACA,UACA,OACA,QACA,MACA,QACA,UACE,0BAA0B;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CACF,MAAM,yBAAyB,QAAQ,iBAAiB,UAAU,KAAK,EAAE;CACzE,MAAM,qBAAqB,QAAQ,mBAAmB,IAAI,QAAQ,MAAM;CACxE,MAAM,6BAA6B,8BAA8B,sBAAsB,OAAO,EAAE;CAChG,MAAM,qBACJ,OAAO,MAAM,UAAU,MAAM,OAAO,QAAQ,EAAE,SAAS,WAAW,EAAE,qBAAqB;CAC3F,MAAM,cAAc,SAAS,GAAG,GAAG;CACnC,MAAM,wBAAwB,4BAA4B;EAAE;EAAa;EAAO,CAAC;CACjF,MAAM,oBAAoB,OAA4B,KAAK;CAC3D,MAAM,8BAA8B,OAAO,MAAM;CACjD,MAAM,mBAAmB,OAAO,MAAM;CACtC,MAAM,yBACJ,CAAC,gBACA,UAAU,eAAe,UAAU,YAAY,UAAU,aAAa,UAAU;AAEnF,iBAAgB;AACd,MAAI,CAAC,uBAAuB;AAC1B,OAAI,4BAA4B,SAAS;AACvC,gCAA4B,UAAU;AACtC,sBAAkB,SAAS,OAAO;;AAEpC;;EAGF,MAAM,mCAAmC,UAAwB;AAC/D,OAAI,MAAM,WAAW,kBAAkB,QACrC,6BAA4B,UAAU;;EAG1C,MAAM,2BAA2B;AAC/B,+BAA4B,UAAU;;AAGxC,WAAS,iBAAiB,WAAW,oBAAoB,KAAK;AAC9D,WAAS,iBAAiB,eAAe,iCAAiC,KAAK;AAC/E,SAAO,iBAAiB,QAAQ,mBAAmB;AAEnD,eAAa;AACX,YAAS,oBAAoB,WAAW,oBAAoB,KAAK;AACjE,YAAS,oBAAoB,eAAe,iCAAiC,KAAK;AAClF,UAAO,oBAAoB,QAAQ,mBAAmB;;IAEvD,CAAC,sBAAsB,CAAC;AAE3B,iBAAgB;AACd,MAAI,uBAAuB;AACzB,oBAAiB,UAAU;AAC3B;;AAEF,MAAI,CAAC,iBAAiB,WAAW,CAAC,uBAAwB;AAE1D,mBAAiB,UAAU;AAC3B,iBAAe;IACd;EAAC;EAAuB;EAAwB;EAAc,CAAC;CAElE,MAAM,0BACJ,0BAA0B,CAAC,eAAe,YAAY,SAAS;CACjE,MAAM,qBACJ,UAAU,aACN,EAAE,kBAAkB,GACpB,UAAU,YACR,EAAE,iBAAiB,GACnB,UAAU,YACR,EAAE,iBAAiB,GACnB,wBACE,0BAA0B,GAAG,YAAY,GACzC,sBAAsB,UAAU,WAC9B,EAAE,mBAAmB,GACrB,EAAE,eAAe;CAE/B,MAAM,eAAe,aAClB,YAAgC;AAC/B,MAAI,sBAAuB,QAAO;EAClC,MAAM,6BAA6B,SAAS,kBAAkB,kBAAkB;EAChF,MAAM,WAAW,OAAO;GAAE,OAAO,QAAQ;GAAO,MAAM,QAAQ;GAAM,CAAC;AACrE,MAAI,UAAU;AACZ,+BAA4B,UAAU;AACtC,OAAI,CAAC,uBAAuB,SAAS;AACnC,2BAAuB,UAAU;AACjC,kBAAc,QAAQ,KAAK;;;AAG/B,SAAO;IAET;EAAC;EAAuB;EAAe;EAAO,CAC/C;CAED,MAAM,oBAAoB,aACvB,WAAmB,aAAa;EAAE,OAAO,EAAE;EAAE,MAAM;EAAQ,CAAC,EAC7D,CAAC,aAAa,CACf;AAED,iBAAgB;AACd,MAAI,CAAC,cAAe;AAMpB,MALiB,OAAO;GACtB,OAAO,cAAc,SAAS,EAAE;GAChC,MAAM,cAAc;GACpB,WAAW,cAAc;GAC1B,CACW,EAAE;AACZ,OAAI,CAAC,uBAAuB,SAAS;AACnC,2BAAuB,UAAU;AACjC,kBAAc,cAAc,OAAO;;AAErC,2BAAwB;;IAEzB;EAAC;EAAe;EAAe;EAAwB;EAAO,CAAC;AAElE,QACE,qBAAC,SAAD;EACE,cAAY,EAAE,kBAAkB;EAChC,WAAW,GACT,+DACA,CAAC,YAAY,4CACd;YALH;GAOE,qBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,oBAAC,+BAAD;KACE,oBACE,sBAAsB,UAAU,WAC5B,mBACA,wBACE,8BACA,UAAU,YACR,wBACA;KAEV,QAAQ;KACR,OAAO;KACP,CAAA,EACD,eACM;;GAET,qBAAC,cAAD;IAAc,WAAU;cAAxB,CACE,oBAAC,qBAAD;KAAqB,WAAU;eAC5B,SAAS,WAAW,IACnB,oBAAC,wBAAD;MAAwB,WAAU;gBAChC,qBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,oBAAC,OAAD;SAAK,WAAU;mBACb,oBAAC,cAAD,EAAc,WAAU,UAAW,CAAA;SAC/B,CAAA;QACN,oBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,cAAc;SACd,CAAA;QACL,oBAAC,KAAD;SAAG,WAAU;mBACV,EAAE,oBAAoB;SACrB,CAAA;QACJ,oBAAC,OAAD;SAAK,WAAU;mBACZ,sBAAsB,KAAK,EAAE,OAAO,aAAa,MAAM,MAAM,aAC5D,qBAAC,UAAD;UACE,WAAU;UAEV,eAAe,kBAAkB,OAAO;UACxC,MAAK;oBAJP;WAME,oBAAC,QAAD;YAAM,WAAU;sBACd,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA;YACxB,CAAA;WACP,qBAAC,QAAD;YAAM,WAAU;sBAAhB,CACE,oBAAC,QAAD;aAAM,WAAU;uBACb;aACI,CAAA,EACP,oBAAC,QAAD;aAAM,WAAU;uBACb;aACI,CAAA,CACF;;WACP,oBAAC,kBAAD,EAAkB,WAAU,iIAAkI,CAAA;WACvJ;YAhBF,MAgBE,CACT;SACE,CAAA;QACF;;MACiB,CAAA,GAEzB,qBAAA,UAAA,EAAA,UAAA,CACG,SAAS,KAAK,SAAS,UAAU;MAChC,MAAM,gBAAgB,UAAU,SAAS,SAAS;MAClD,MAAM,sBAAsB,8BAA8B,QAAQ;MAClE,MAAM,qBACJ,wBAAwB,aAAa,wBAAwB,WACzD,sBACA,kBAAkB,UAAU,aAAa,UAAU,YACjD,QACA,KAAA;MACR,MAAM,qBACJ,yBAAyB,iBAAiB,QAAQ,SAAS;AAE7D,aACE,oBAAC,SAAD;OAAS,WAAU;OAAoB,MAAM,QAAQ;iBACnD,oBAAC,gBAAD;QACE,WAAW,GAAG,QAAQ,SAAS,eAAe,mBAAmB;kBAEhE,mBAAmB,QAAQ,GAC1B,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,6BAAD;SAC0B;SACT;SACf,aAAa;SACJ;SACT,cAAc;SACM;SACpB,CAAA,EACD,iBAAiB,qBAChB,oBAAC,kCAAD,EAAkC,GAAI,mBAAqB,CAAA,CAE5D,EAAA,CAAA,GACD,qBACF,oBAAC,kCAAD,EAA2C,SAAW,CAAA,GACpD,iBAAiB,oBACnB,oBAAC,kCAAD,EAAkC,GAAI,mBAAqB,CAAA,GACzD,UAAU,YACZ,oBAAC,QAAD;SAAM,WAAU;mBACb,EAAE,uBAAuB;SACrB,CAAA,GAEP,oBAAC,QAAD;SAAM,WAAU;mBACb,EAAE,0BAA0B;SACxB,CAAA;QAEM,CAAA;OACT,EAhCsD,QAAQ,GAgC9D;OAEZ,EACD,2BACC,oBAAC,SAAD;MAAS,WAAU;MAAoB,MAAK;gBAC1C,oBAAC,gBAAD;OAAgB,WAAU;iBACxB,oBAAC,kCAAD,EAAoC,CAAA;OACrB,CAAA;MACT,CAAA,CAEX,EAAA,CAAA;KAEe,CAAA,EACtB,oBAAC,0BAAD,EAA0B,WAAU,cAAe,CAAA,CACtC;;GAEd,sBACC,qBAAC,OAAD;IACE,WAAW,GACT,uEACA,2BAA2B,SAAS,YAChC,oCACA,yCACL;IACD,MAAK;cAPP,CASE,qBAAC,OAAD;KAAK,WAAU;eAAf,CACG,2BAA2B,SAAS,YACnC,oBAAC,YAAD,EAAY,WAAU,yCAA0C,CAAA,GAEhE,oBAAC,aAAD,EAAa,WAAU,2CAA4C,CAAA,EAErE,qBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,oBAAC,OAAD;QAAK,WAAU;kBAA+B,2BAA2B;QAAY,CAAA;OACrF,oBAAC,KAAD;QAAG,WAAU;kBACV,2BAA2B;QAC1B,CAAA;OACJ,oBAAC,KAAD;QAAG,WAAU;kBAAiC,2BAA2B;QAAS,CAAA;OAClF,oBAAC,UAAD;QACE,WAAU;QACV,SAAS;QACT,MAAK;kBAEJ,EAAE,eAAe;QACX,CAAA;OACL;QACF;QACN,oBAAC,UAAD;KACE,cAAY,EAAE,0BAA0B;KACxC,WAAU;KACV,SAAS;KACT,MAAK;eAEJ,EAAE,iBAAiB;KACb,CAAA,CACL;;GAGR,oBAAC,OAAD;IAAK,WAAU;cACb,qBAAC,aAAD;KACE,aAAW;KACX,qBAAqB;KACrB,WAAW,GACT,sEACA,yBAAyB,2CAC1B;KACD,UAAU;eAPZ,CASE,oBAAC,iBAAD,EAAA,UACE,oBAAC,qBAAD;MACE,WAAU;MACV,UAAU;MACV,aAAa,EAAE,oBAAoB;MACnC,KAAK;MACL,CAAA,EACc,CAAA,EAClB,qBAAC,mBAAD;MACE,WAAW,GACT,iEACA,yBAAyB,cAC1B;gBAJH,CAME,oBAAC,6BAAD;OAA6B,WAAU;OAAS,UAAU;OAAyB,CAAA,EACnF,qBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,OAAO,SAAS,KAAK,UACpB,qBAACC,UAAD;QACE,UAAU;QACV,eAAe;QACf,OAAO;kBAHT,CAKE,qBAAC,eAAD;SACE,cAAY,EAAE,cAAc;SAC5B,WAAU;SACV,MAAK;SACL,OAAO;mBAJT,CAME,oBAAC,SAAD,EAAS,WAAU,YAAa,CAAA,EAChC,oBAAC,aAAD,EAAe,CAAA,CACD;YAChB,oBAAC,eAAD;SACE,OAAM;SACN,WAAU;SACV,UAAS;mBAER,OAAO,KAAK,UACX,oBAAC,YAAD;UACE,WAAU;UAEV,OAAO,MAAM;UACb,OAAO,MAAM;oBAEZ,MAAM;UACI,EALN,MAAM,GAKA,CACb;SACY,CAAA,CACT;YAET,qBAAC,OAAD;QACE,WAAU;QACV,OAAO;kBAFT,CAIE,oBAAC,SAAD,EAAS,WAAU,qBAAsB,CAAA,EACzC,oBAAC,QAAD;SAAM,WAAU;mBAAY;SAA0B,CAAA,CAClD;WAER,oBAAC,mBAAD;QAAmB,QAAQ;QAAc;QAAU,CAAA,CAC/C;SACY;QACR;;IACV,CAAA;GACA;;;AAIZ,MAAM,8BAA8B;AAEpC,MAAM,qBAAqB,MAAc,aAAqB;CAC5D,MAAM,aAAa,KAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM;AACnD,KAAI,CAAC,WAAY,QAAO;CACxB,MAAM,QAAQ,WAAW,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI;AACzD,QAAO,MAAM,SAAS,KAAK,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO;;AAapE,MAAM,+BAA+B,EACnC,WAAW,OACX,SACA,SAAS,EAAE,EACX,uBACA,sBAAsB,IACtB,oBAAoB,6BACpB,YACA,0BACA,UACA,WACA,cAAc,sBACd,gBACA,GAAG,mBACmC;CACtC,MAAM,IAAI,+BAA+B;CACzC,MAAM,eAAe,cACb,wBAAwB,kCAAkC,UAAU,EAC1E,CAAC,sBAAsB,UAAU,CAClC;CACD,MAAM,aACJ,6BAA6B,QACzB,OACC,4BACD,GAAG,4BAA4B,GAAG,mBAAmB,WAAW,GAC9D,WAAW,IAAI,mBAAmB,SAAS,KAAK;CAExD,MAAM,CAAC,SAAS,cAAc,SAAkC,EAAE,CAAC;CACnE,MAAM,CAAC,gBAAgB,qBAAqB,SAAuC,KAAK;CACxF,MAAM,CAAC,iBAAiB,sBAAsB,SAAsB,EAAE,CAAC;CACvE,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,CAAC,iBAAiB,sBAAsB,SAAwB,KAAK;CAC3E,MAAM,CAAC,cAAc,mBAAmB,SAAS,GAAG;CACpD,MAAM,CAAC,aAAa,kBAAkB,SAAwB,KAAK;CACnE,MAAM,CAAC,eAAe,oBAAoB,SAAS,KAAK;CACxD,MAAM,CAAC,qBAAqB,0BAA0B,SAAS,MAAM;CACrE,MAAM,CAAC,eAAe,oBAAoB,UAAgC;CAC1E,MAAM,qBAAqB,OAAuB,KAAK;CAEvD,MAAM,cAAc,aACjB,YAAoB;AACnB,MAAI,CAAC,OAAO,MAAM,UAAU,MAAM,OAAO,QAAQ,CAAE;AACnD,gBAAc,QAAQ;IAExB,CAAC,QAAQ,cAAc,CACxB;CAED,MAAM,eAAe,YACnB,OAAO,WAAkC;AACvC,mBAAiB,KAAK;AACtB,iBAAe,KAAK;AACpB,MAAI;GACF,MAAM,aAAa,MAAM,aAAa,KAAK,OAAO,GAAG;AACrD,qBAAkB,WAAW,OAAO;AACpC,sBAAmB,WAAW,SAAwB;AACtD,kBAAe,MAAM;AACrB,OAAI,WAAY,QAAO,aAAa,QAAQ,YAAY,OAAO,GAAG;WAC3D,OAAO;AACd,kBAAe,0BAA0B,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;YAC7E;AACR,oBAAiB,MAAM;;IAG3B;EAAC;EAAY;EAAG;EAAa,CAC9B;CAED,MAAM,eAAe,YACnB,OAAO,WAAyC;AAC9C,mBAAiB,KAAK;AACtB,iBAAe,KAAK;AACpB,MAAI;GACF,MAAM,SAAS,MAAM,aAAa,OAAO,QAAQ,MAAM;AACvD,eAAY,YAAY,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAC7C,qBAAkB,OAAO;AACzB,sBAAmB,EAAE,CAAC;AACtB,kBAAe,MAAM;AACrB,OAAI,WAAY,QAAO,aAAa,QAAQ,YAAY,OAAO,GAAG;AAClE,UAAO;WACA,OAAO;AACd,kBAAe,0BAA0B,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;AACrF,OAAI,OAAQ,OAAM;AAClB,UAAO;YACC;AACR,oBAAiB,MAAM;;IAG3B;EAAC;EAAY;EAAG;EAAa,CAC9B;AAED,iBAAgB;EACd,IAAI,YAAY;AACX,eACF,MAAM,CACN,KAAK,OAAO,qBAAqB;AAChC,OAAI,UAAW;AACf,cAAW,iBAAiB;GAC5B,MAAM,eAAe,aAAa,OAAO,aAAa,QAAQ,WAAW,GAAG;GAC5E,MAAM,gBACJ,iBAAiB,MAAM,WAAW,OAAO,OAAO,aAAa,IAAI,iBAAiB;AACpF,OAAI,cACF,OAAM,aAAa,cAAc;OAEjC,OAAM,cAAc;IAEtB,CACD,OAAO,UAAU;AAChB,OAAI,CAAC,WAAW;AACd,mBAAe,0BAA0B,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;AACrF,qBAAiB,MAAM;;IAEzB;AACJ,eAAa;AACX,eAAY;;IAEb;EAAC;EAAc;EAAc;EAAY;EAAG;EAAa,CAAC;AAE7D,iBAAgB;AACd,MAAI,CAAC,kBAAkB,cAAe;AACtC,SAAO,qCAAqC,gBAAgB,OAAO,WAAW;GAC5E,MAAM,SAAS,MAAM,aAAa,OAAO;AACzC,OAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,oDAAoD;AACjF,UAAO,IAAI,SAAgC,YAAY;AACrD,qBAAiB;KACf,OAAO;KACP,mBAAmB,QAAQ,OAAO;KACnC,CAAC;KACF;IACF;IACD;EAAC;EAAc;EAAe;EAAe,CAAC;CAEjD,MAAM,eAAe,YACnB,OAAO,QAA+B,UAAkB;EACtD,MAAM,aAAa,MAAM,MAAM;AAC/B,MAAI,CAAC,cAAc,eAAe,OAAO,OAAO;AAC9C,sBAAmB,KAAK;AACxB,mBAAgB,GAAG;AACnB;;AAEF,MAAI;GACF,MAAM,UAAU,MAAM,aAAa,OAAO,OAAO,IAAI,WAAW;AAChE,eAAY,YAAY,QAAQ,KAAK,SAAU,KAAK,OAAO,QAAQ,KAAK,UAAU,KAAM,CAAC;AACzF,sBAAmB,YAAa,SAAS,OAAO,QAAQ,KAAK,UAAU,QAAS;AAChF,sBAAmB,KAAK;AACxB,mBAAgB,GAAG;WACZ,OAAO;AACd,kBAAe,0BAA0B,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;;IAGzF,CAAC,GAAG,aAAa,CAClB;CAED,MAAM,oBAAoB,YACxB,OAAO,QAA+B,UAAmB;AACvD,MAAI;GACF,MAAM,UAAU,MAAM,aAAa,kBAAkB,OAAO,IAAI,MAAM;AACtE,eAAY,YAAY,QAAQ,KAAK,SAAU,KAAK,OAAO,QAAQ,KAAK,UAAU,KAAM,CAAC;AACzF,sBAAmB,YAAa,SAAS,OAAO,QAAQ,KAAK,UAAU,QAAS;AAChF,sBAAmB,KAAK;AACxB,mBAAgB,GAAG;WACZ,OAAO;AACd,kBAAe,0BAA0B,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;;IAGzF,CAAC,GAAG,aAAa,CAClB;CAED,MAAM,qBAAqB,aAAa,WAAkC;AACxE,qBAAmB,OAAO,GAAG;AAC7B,kBAAgB,OAAO,MAAM;IAC5B,EAAE,CAAC;CAEN,MAAM,sBAAsB,kBAAkB;AAC5C,qBAAmB,KAAK;AACxB,kBAAgB,GAAG;IAClB,EAAE,CAAC;CAEN,MAAM,yBAAyB,aAC5B,WAAoB;AACnB,yBAAuB,OAAO;AAC9B,gCAA8B,OAAO;AACrC,MAAI,QAAQ;AACV,wBAAqB;AACrB,kBAAe,MAAM;;IAGzB,CAAC,qBAAqB,4BAA4B,CACnD;CAED,MAAM,sBAAsB,YAAY,YAAY;AAClD,MAAI,CAAC,gBAAiB;EACtB,MAAM,SAAS,QAAQ,MAAM,SAAS,KAAK,OAAO,gBAAgB;EAClE,MAAM,QAAQ;AACd,MAAI,OAAQ,OAAM,aAAa,QAAQ,MAAM;IAC5C;EAAC;EAAiB;EAAc;EAAc;EAAQ,CAAC;CAE1D,MAAM,eAAe,YACnB,OAAO,WAAkC;AAIvC,MAAI,EAHc,wBACd,MAAM,sBAAsB,OAAO,GACnC,OAAO,QAAQ,EAAE,yBAAyB,EAAE,OAAO,OAAO,OAAO,CAAC,CAAC,EACvD;AAChB,MAAI;AACF,SAAM,aAAa,OAAO,OAAO,GAAG;GACpC,MAAM,YAAY,QAAQ,QAAQ,SAAS,KAAK,OAAO,OAAO,GAAG;AACjE,cAAW,UAAU;AACrB,OAAI,gBAAgB,OAAO,OAAO,GAChC,KAAI,UAAU,GAAI,OAAM,aAAa,UAAU,GAAG;OAC7C,OAAM,cAAc;WAEpB,OAAO;AACd,kBAAe,0BAA0B,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;;IAGzF;EAAC;EAAc;EAAuB;EAAc;EAAgB;EAAG;EAAc;EAAQ,CAC9F;CAED,MAAM,oBAAoB,aACvB,SAAiB;AAChB,MAAI,CAAC,kBAAkB,eAAe,cAAc,SAClD;AAEG,oBAAkB,gBAAgB,kBAAkB,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAEvF;EAAC;EAAgB;EAAmB;EAAE,CACvC;CAED,MAAM,6BAA6B,kBAAkB;AACnD,MAAI,CAAC,cAAe;AACpB,mBAAiB,KAAA,EAAU;AAC3B,gBAAc,aAAa;IAC1B,CAAC,cAAc,CAAC;CAEnB,MAAM,oBAAoB,YACxB,OAAO,gBAAyB;AAC9B,MAAI;GACF,MAAM,mBAAmB,MAAM,aAAa,MAAM;AAClD,cAAW,iBAAiB;GAC5B,MAAM,UAAU,iBAAiB,MAAM,WAAW,OAAO,OAAO,gBAAgB,GAAG;AACnF,OAAI,WAAW,CAAC,gBACd,oBAAmB,aAAa;AAC9B,QAAI,CAAC,YAAY,SAAS,OAAO,QAAQ,GAAI,QAAO;AACpD,WAAO,SAAS,UAAU,QAAQ,SAChC,SAAS,cAAc,QAAQ,aAC/B,SAAS,cAAc,QAAQ,YAC7B,WACA;KACJ;WAEG,OAAO;AACd,OAAI,YACF,gBAAe,0BAA0B,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC;;IAI3F;EAAC;EAAiB,gBAAgB;EAAI;EAAG;EAAa,CACvD;CAED,MAAM,gBAAgB,kBAAkB;AACtC,MAAI,aAAa;AACV,wBAAqB;AAC1B,kBAAe,MAAM;AACrB;;AAGF,iBAAe,KAAK;AACf,oBAAkB,KAAK;IAC3B;EAAC;EAAqB;EAAa;EAAkB,CAAC;CAEzD,MAAM,oBAAoB,kBAAkB;AACrC,oBAAkB,MAAM;IAC5B,CAAC,kBAAkB,CAAC;AAEvB,iBAAgB;AACd,MAAI,CAAC,YAAa;EAElB,MAAM,qBAAqB,UAAwB;AACjD,OAAI,CAAC,mBAAmB,SAAS,SAAS,MAAM,OAAe,EAAE;AAC1D,yBAAqB;AAC1B,mBAAe,MAAM;;;EAGzB,MAAM,iBAAiB,UAAyB;AAC9C,OAAI,MAAM,QAAQ,UAAU;AAC1B,yBAAqB;AACrB,mBAAe,MAAM;;;AAIzB,WAAS,iBAAiB,eAAe,kBAAkB;AAC3D,WAAS,iBAAiB,WAAW,cAAc;AACnD,eAAa;AACX,YAAS,oBAAoB,eAAe,kBAAkB;AAC9D,YAAS,oBAAoB,WAAW,cAAc;;IAEvD;EAAC;EAAqB;EAAqB;EAAY,CAAC;AAE3D,iBAAgB;EACd,MAAM,oBAAoB;AACnB,qBAAkB,MAAM;;AAG/B,SAAO,iBAAiB,SAAS,YAAY;AAC7C,eAAa,OAAO,oBAAoB,SAAS,YAAY;IAC5D,CAAC,kBAAkB,CAAC;AAEvB,KAAI,iBAAiB,CAAC,eACpB,QACE,qBAAC,SAAD;EACE,WAAW,GACT,+DACA,CAAC,YAAY,4CACd;YAJH,CAME,oBAAC,UAAD;GAAQ,WAAU;aAChB,oBAAC,+BAAD;IACE,oBAAmB;IACnB,QAAQ,EAAE,qBAAqB;IAC/B,OAAO,EAAE,cAAc;IACvB,CAAA;GACK,CAAA,EACT,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,kBAAD,EAAkB,WAAU,4BAA6B,CAAA,EACxD,EAAE,qBAAqB,CACpB;KACA;;CAIZ,MAAM,iBACJ,qBAAC,OAAD;EAAK,WAAU;EAA4C,KAAK;YAAhE;GACE,oBAAC,UAAD;IACE,cAAY,EAAE,kBAAkB;IAChC,WAAU;IACV,UAAU;IACV,eAAe,KAAK,cAAc;IAClC,OAAO,EAAE,kBAAkB;IAC3B,MAAK;cAEL,oBAAC,UAAD,EAAU,WAAU,UAAW,CAAA;IACxB,CAAA;GACT,oBAAC,UAAD;IACE,iBAAe;IACf,cAAY,EAAE,kBAAkB;IAChC,WAAU;IACV,UAAU;IACV,SAAS;IACT,OAAO,EAAE,kBAAkB;IAC3B,MAAK;cAEL,oBAAC,aAAD,EAAa,WAAU,UAAW,CAAA;IAC3B,CAAA;GACR,eACC,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,OAAD;KAAK,WAAU;eACZ,EAAE,iBAAiB;KAChB,CAAA,EACN,oBAAC,OAAD;KAAK,WAAU;eACZ,QAAQ,KAAK,WACZ,qBAAC,OAAD;MACE,WAAW,GACT,0DACA,OAAO,OAAO,eAAe,KAAK,aAAa,oBAChD;gBAJH;OAOG,oBAAoB,OAAO,KAC1B,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,SAAD;QACE,WAAA;QACA,WAAU;QACV,cAAc,KAAK,qBAAqB;QACxC,WAAW,UAAU,gBAAgB,MAAM,cAAc,MAAM;QAC/D,YAAY,UAAU;AACpB,aAAI,MAAM,QAAQ,SAAS;AACzB,gBAAM,gBAAgB;AACjB,+BAAqB;;AAE5B,aAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAM,gBAAgB;AACtB,gBAAM,iBAAiB;AACvB,+BAAqB;AACrB,yBAAe,MAAM;;;QAGzB,OAAO;QACP,CAAA,EACD,OAAO,cAAc,YACpB,qBAAC,UAAD;QACE,cAAY,EAAE,yBAAyB;QACvC,WAAU;QACV,eAAe,KAAK,kBAAkB,OAAO;QAC7C,cAAc,UAAU,MAAM,gBAAgB;QAC9C,OAAO,EAAE,yBAAyB;QAClC,MAAK;kBANP,CAQE,oBAAC,cAAD,EAAc,WAAU,UAAW,CAAA,EACnC,oBAAC,QAAD,EAAA,UAAO,EAAE,yBAAyB,EAAQ,CAAA,CACnC;UAEV,EAAA,CAAA,GAEH,oBAAC,UAAD;QACE,WAAU;QACV,eAAe,KAAK,aAAa,OAAO;QACxC,MAAK;kBAEJ,OAAO;QACD,CAAA;OAEX,oBAAC,UAAD;QACE,cAAY,EAAE,kBAAkB,EAAE,OAAO,OAAO,OAAO,CAAC;QACxD,WAAU;QACV,eAAe,mBAAmB,OAAO;QACzC,OAAO,EAAE,sBAAsB;QAC/B,MAAK;kBAEL,oBAAC,YAAD,EAAY,WAAU,YAAa,CAAA;QAC5B,CAAA;OACT,oBAAC,UAAD;QACE,cAAY,EAAE,kBAAkB,EAAE,OAAO,OAAO,OAAO,CAAC;QACxD,WAAU;QACV,eAAe,KAAK,aAAa,OAAO;QACxC,OAAO,EAAE,sBAAsB;QAC/B,MAAK;kBAEL,oBAAC,YAAD,EAAY,WAAU,YAAa,CAAA;QAC5B,CAAA;OACL;QAhEC,OAAO,GAgER,CACN;KACE,CAAA,CACF;;GAEJ;;AAGR,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,8BAAC,0BAAD;GACE,GAAI;GACM;GACV,eAAe,eAAe;GACb;GACjB,KAAK,eAAe;GACX;GACD;GACR,wBAAwB;GACxB,eAAe;GACf,eAAe;GACf,eAAe;GACf,oBAAoB;GACR;GACF;GACM;GAChB,UAAU,eAAe;GACzB,aAAa,eAAe;GAC5B,CAAA,EACD,eACC,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,oBAAC,OAAD;KAAK,WAAU;eAAe,EAAE,4BAA4B;KAAO,CAAA;IACnE,oBAAC,OAAD;KAAK,WAAU;eAAgC;KAAkB,CAAA;IACjE,oBAAC,UAAD;KACE,WAAU;KACV,eAAe,eAAe,KAAK;KACnC,MAAK;eAEJ,EAAE,iBAAiB;KACb,CAAA;IACL;KAEJ;;;AAIV,MAAa,wBAAwB,EACnC,UACA,eACA,GAAG,YAEH,oBAAC,OAAD;CAAK,WAAU;WACb,oBAAC,qCAAD;EAA+C;EAAyB;YACtE,8BAAC,6BAAD;GACE,GAAI;GACJ,KAAK,KAAK,UAAU,CAAC,MAAM,YAAY,MAAM,SAAS,CAAC;GACvD,CAAA;EACkC,CAAA;CAClC,CAAA;;;AC/sDR,MAAa,iCAAiC,EAC5C,iBACA,iBACA,qBACA,eACA,GAAG,YACqC;CACxC,MAAM,UAAU,+BAA+B;EAC7C,KAAK;EACL;EACA,YAAY;EACb,CAAC;AAEF,iBAAgB;AACd,MAAI,QAAQ,MAAO,uBAAsB,QAAQ,MAAM;IACtD,CAAC,QAAQ,OAAO,oBAAoB,CAAC;AAExC,QACE,oBAAC,sBAAD;EACE,GAAI;EACJ,SAAS,QAAQ;EACjB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,CAAA"}
|