langchain_agentx_stream_ui 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/view/nodes/ReasoningNode.tsx","../src/view/tools/presentation/StreamingMarkdown.tsx","../src/view/nodes/TextNode.tsx","../src/view/nodes/ToolCallNode.tsx","../src/view/nodes/StepNode.tsx","../src/view/nodes/ErrorNode.tsx","../src/view/nodes/UnknownNode.tsx","../src/view/nodes/PermissionNode.tsx","../src/view/nodes/MemorySavedNode.tsx","../src/view/NodeRegistry.ts","../src/view/defaultRegistry.ts","../src/core/sessionStore.ts","../src/core/dedupe.ts","../src/view/MultiAgentSession.tsx"],"sourcesContent":["/**\n * 职责:ReasoningNode — 对齐 CC AssistantTextMessage / CLI assistant_message。\n * 正文前加 BLACK_CIRCLE(●);streaming 时圆点闪烁;正常字色、不折叠。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\n/** 对齐 CC constants/figures.ts BLACK_CIRCLE · CLI assistant_message._BLACK_CIRCLE */\nexport const REASONING_DOT = '●';\n\nexport interface ReasoningBubbleProps {\n nodeId: string;\n}\n\nexport function ReasoningBubble({ nodeId }: ReasoningBubbleProps) {\n const node = useNodeTyped(nodeId, 'reasoning');\n if (!node) return null;\n\n const text = node.accumulated.trim();\n if (!text) return null;\n\n return (\n <div className=\"lax-reasoning-bubble\" data-status={node.status} data-round-id={node.roundId}>\n <div className=\"lax-reasoning-bubble__body\">\n <span className=\"lax-reasoning-bubble__dot\" aria-hidden=\"true\">\n {REASONING_DOT}\n </span>\n <span className=\"lax-reasoning-bubble__content\">{node.accumulated}</span>\n </div>\n </div>\n );\n}\n","/**\n * StreamingMarkdown.tsx — 流式 markdown 渲染(对齐 CC)\n *\n * CC 实现参考(C:\\git_code\\claude-code-main-ghuntley-03-31\\src\\components\\Markdown.tsx):\n * - 使用 marked.lexer() 解析,更精确的边界跟踪\n * - 模块级 token 缓存(MRU 策略)\n * - 基于 tokens 的精确边界判断\n * - 流式过程中就渲染 markdown\n *\n * 性能优化(对齐 CC):\n * - 快速路径:纯文本跳过 marked.lexer() 调用\n * - Token 缓存:模块级 Map,LRU 淘汰\n * - 边界跟踪:O(unstable length) 而不是 O(full text)\n *\n * 链路位置:TextNode 流式内容渲染\n */\nimport React, { useRef, useMemo, useState } from 'react';\nimport { marked, type Token, type Tokens } from 'marked';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\n// =============================================================================\n// 模块级 Token 缓存(对齐 CC)\n// =============================================================================\n// marked.lexer 是虚拟滚动时的热点成本(~3ms 每条消息)\n// useMemo 无法在 unmount → remount 后存活,导致滚动回历史消息时重新解析\n// 消息在历史中不可变:相同内容 → 相同 tokens\n// 使用内容哈希作为 key,避免保留完整内容字符串(避免 RSS 回归)\nconst TOKEN_CACHE_MAX = 500;\nconst tokenCache = new Map<string, Token[]>();\n\n// =============================================================================\n// 快速路径检测(对齐 CC)\n// =============================================================================\n// 检测 markdown 语法标记。如果没有,跳过 ~3ms 的 marked.lexer 调用\n// 单次正则匹配,而不是 10 次 indexOf 调用\nconst MD_SYNTAX_RE = /[#*`|\\[>\\\\\\-~]|\\n\\n|^\\d+\\. |\\n\\d+\\. /;\n\nfunction hasMarkdownSyntax(s: string): boolean {\n // 检查前 500 字符 — markdown 语法通常在前面(标题、代码块、列表)\n return MD_SYNTAX_RE.test(s.length > 500 ? s.slice(0, 500) : s);\n}\n\n// =============================================================================\n// 内容哈希(用于缓存 key)\n// =============================================================================\nfunction hashContent(content: string): string {\n let hash = 5381;\n for (let i = 0; i < content.length; i++) {\n hash = ((hash << 5) + hash + content.charCodeAt(i)) & 0xffffffff;\n }\n return hash.toString(36);\n}\n\n// =============================================================================\n// Cached Lexer(对齐 CC)\n// =============================================================================\nfunction cachedLexer(content: string): Token[] {\n // 快速路径:纯文本 → 单个 paragraph token\n // 跳过 marked.lexer 的完整 GFM 解析(~3ms)\n if (!hasMarkdownSyntax(content)) {\n return [{\n type: 'paragraph',\n raw: content,\n text: content,\n tokens: [{\n type: 'text',\n raw: content,\n text: content\n }]\n } as Token];\n }\n\n const key = hashContent(content);\n const hit = tokenCache.get(key);\n\n if (hit) {\n // 提升 MRU — 没有 LRU,滚动回早期消息会驱逐正在查看的条目\n tokenCache.delete(key);\n tokenCache.set(key, hit);\n return hit;\n }\n\n const tokens = marked.lexer(content);\n\n if (tokenCache.size >= TOKEN_CACHE_MAX) {\n // LRU-ish: 删除最旧的。Map 保留插入顺序。\n const first = tokenCache.keys().next().value;\n if (first !== undefined) tokenCache.delete(first);\n }\n\n tokenCache.set(key, tokens);\n return tokens;\n}\n\n// =============================================================================\n// Markdown 组件配置(复用)\n// =============================================================================\nconst MARKDOWN_COMPONENTS = {\n code({ node, className, children, ...props }: any) {\n const match = /language-(\\w+)/.exec(className || '');\n const codeContent = String(children).replace(/\\n$/, '');\n const inline = !className;\n\n if (!inline && match) {\n return (\n <CodeBlock language={match[1]} content={codeContent} />\n );\n }\n\n return (\n <code className=\"lax-markdown__inline-code\" {...props}>\n {children}\n </code>\n );\n },\n h1({ children }: any) { return <h1 className=\"lax-markdown__heading lax-markdown__h1\">{children}</h1>; },\n h2({ children }: any) { return <h2 className=\"lax-markdown__heading lax-markdown__h2\">{children}</h2>; },\n h3({ children }: any) { return <h3 className=\"lax-markdown__heading lax-markdown__h3\">{children}</h3>; },\n h4({ children }: any) { return <h4 className=\"lax-markdown__heading lax-markdown__h4\">{children}</h4>; },\n h5({ children }: any) { return <h5 className=\"lax-markdown__heading lax-markdown__h5\">{children}</h5>; },\n h6({ children }: any) { return <h6 className=\"lax-markdown__heading lax-markdown__h6\">{children}</h6>; },\n p({ children }: any) { return <p className=\"lax-markdown__paragraph\">{children}</p>; },\n ul({ children }: any) { return <ul className=\"lax-markdown__list lax-markdown__ul\">{children}</ul>; },\n ol({ children }: any) { return <ol className=\"lax-markdown__list lax-markdown__ol\">{children}</ol>; },\n li({ children }: any) { return <li className=\"lax-markdown__li\">{children}</li>; },\n a({ children, href }: any) {\n return (\n <a href={href} className=\"lax-markdown__link\" target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n },\n blockquote({ children }: any) { return <blockquote className=\"lax-markdown__blockquote\">{children}</blockquote>; },\n table({ children }: any) {\n return (\n <div className=\"lax-markdown__table-wrapper\">\n <table className=\"lax-markdown__table\">{children}</table>\n </div>\n );\n },\n thead({ children }: any) { return <thead className=\"lax-markdown__thead\">{children}</thead>; },\n tbody({ children }: any) { return <tbody className=\"lax-markdown__tbody\">{children}</tbody>; },\n tr({ children }: any) { return <tr className=\"lax-markdown__tr\">{children}</tr>; },\n th({ children }: any) { return <th className=\"lax-markdown__th\">{children}</th>; },\n td({ children }: any) { return <td className=\"lax-markdown__td\">{children}</td>; },\n hr() { return <hr className=\"lax-markdown__hr\" />; },\n strong({ children }: any) { return <strong className=\"lax-markdown__strong\">{children}</strong>; },\n em({ children }: any) { return <em className=\"lax-markdown__em\">{children}</em>; },\n};\n\n// =============================================================================\n// 代码块组件(带拷贝功能)\n// =============================================================================\ninterface CodeBlockProps {\n language: string;\n content: string;\n}\n\nfunction CodeBlock({ language, content }: CodeBlockProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n };\n\n return (\n <div className=\"lax-code-block\">\n <div className=\"lax-code-block__header\">\n <span className=\"lax-code-block__lang\">{language || 'code'}</span>\n <button\n type=\"button\"\n className={`lax-code-block__copy ${copied ? 'lax-code-block__copy--copied' : ''}`}\n onClick={handleCopy}\n title={copied ? '已拷贝!' : '拷贝代码'}\n >\n {copied ? (\n <>\n <svg className=\"lax-code-block__icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n <span>已拷贝</span>\n </>\n ) : (\n <>\n <svg className=\"lax-code-block__icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n <span>拷贝</span>\n </>\n )}\n </button>\n </div>\n <SyntaxHighlighter\n language={language}\n style={oneDark}\n customStyle={{\n margin: 0,\n padding: 0,\n background: 'transparent',\n }}\n showLineNumbers={false}\n wrapLongLines={true}\n >\n {content}\n </SyntaxHighlighter>\n </div>\n );\n}\n\n// =============================================================================\n// Markdown 渲染器(Memoized)\n// =============================================================================\ninterface MarkdownRendererProps {\n content: string;\n}\n\nfunction MarkdownRenderer({ content }: MarkdownRendererProps) {\n if (!content.trim()) {\n return null;\n }\n\n const elements = useMemo(() => {\n const hash = hashContent(content);\n\n // 快速路径:检测 markdown 语法\n if (!hasMarkdownSyntax(content)) {\n return (\n <p key={hash.toString(36)} className=\"lax-markdown__paragraph\">\n {content}\n </p>\n );\n }\n\n // 完整 markdown 渲染\n return (\n <ReactMarkdown\n key={hash.toString(36)}\n remarkPlugins={[remarkGfm]}\n components={MARKDOWN_COMPONENTS}\n >\n {content}\n </ReactMarkdown>\n );\n }, [content]);\n\n return <>{elements}</>;\n}\n\n// =============================================================================\n// StreamingMarkdown 组件(对齐 CC)\n// =============================================================================\n/**\n * 流式过程中渲染 markdown(对齐 CC):\n * - 使用 marked.lexer() 解析不稳定部分\n * - 基于 tokens 精确判断块边界\n * - 稳定前缀 memo 化,不重新解析\n */\nexport interface StreamingMarkdownProps {\n children: string;\n}\n\nexport function StreamingMarkdown({ children }: StreamingMarkdownProps) {\n // React Compiler: 这个组件在 render 时读写 stablePrefixRef.current\n // 边界只前进(单调递增),所以 ref mutation 是幂等的,在 StrictMode 双渲染下安全\n // 但 Compiler 无法证明这一点,memo 会破坏算法(导致边界不更新)。Opt out。\n 'use no memo';\n\n // 边界跟踪 ref - 记录已确认稳定的前缀长度\n const stablePrefixRef = useRef('');\n\n // 如果内容被替换(非增量更新),重置边界\n if (!children.startsWith(stablePrefixRef.current)) {\n stablePrefixRef.current = '';\n }\n\n // 只从当前边界开始解析 — O(unstable length),不是 O(full text)\n const boundary = stablePrefixRef.current.length;\n const tokens = cachedLexer(children.substring(boundary));\n\n // 最后一个非 space token 是增长中的块;之前的都是最终的\n let lastContentIdx = tokens.length - 1;\n while (lastContentIdx >= 0 && tokens[lastContentIdx]!.type === 'space') {\n lastContentIdx--;\n }\n\n let advance = 0;\n for (let i = 0; i < lastContentIdx; i++) {\n advance += tokens[i]!.raw.length;\n }\n\n if (advance > 0) {\n stablePrefixRef.current = children.substring(0, boundary + advance);\n }\n\n const stablePrefix = stablePrefixRef.current;\n const unstableSuffix = children.substring(stablePrefix.length);\n\n return (\n <div className=\"lax-markdown\">\n {/* 稳定前缀:使用内容哈希作为 key,React 会复用已有渲染 */}\n {stablePrefix && (\n <MarkdownRenderer key={`stable-${hashContent(stablePrefix)}`} content={stablePrefix} />\n )}\n {/* 不稳定后缀:每次重新渲染 */}\n {unstableSuffix && (\n <MarkdownRenderer key={`unstable-${hashContent(unstableSuffix)}`} content={unstableSuffix} />\n )}\n </div>\n );\n}\n","/**\n * 职责:默认 TextNode 主舞台 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n *\n * 渲染策略(对齐 CC):\n * - Streaming 时显示纯文本(避免高频 markdown 解析)\n * - Done 时使用边界跟踪优化的流式 markdown 渲染\n */\nimport { useNodeTyped } from '../../core/hooks';\n\n// 内置流式 markdown 渲染\nimport { StreamingMarkdown } from '../tools/presentation/StreamingMarkdown';\nimport { REASONING_DOT } from './ReasoningNode';\n\nexport interface TextBubbleProps {\n nodeId: string;\n}\n\nexport function TextBubble({ nodeId }: TextBubbleProps) {\n const node = useNodeTyped(nodeId, 'text');\n if (!node) return null;\n\n // 使用流式 markdown 渲染(对齐 CC:流式过程中就渲染 markdown)\n return (\n <div className=\"lax-text-bubble\" data-status={node.status}>\n <div className=\"lax-text-bubble__body\">\n <span className=\"lax-text-bubble__dot\" aria-hidden=\"true\">\n {REASONING_DOT}\n </span>\n <div className=\"lax-text-bubble__content lax-text-bubble__content--markdown\">\n <StreamingMarkdown>\n {node.accumulated}\n </StreamingMarkdown>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * 职责:默认 ToolCallNode 主舞台 widget(V3 Shell + resolveToolBody)。\n * 链路位置:NodeRegistry → Timeline。\n * 当前裁剪范围:T4.6 内嵌 permission 等待态(permissionUiMode 控制)。\n */\nimport { useEffect, useState } from 'react';\n\nimport {\n useSessionViewOptions,\n useToolDisplayOptions,\n} from '../../core/context/SessionContext';\nimport { useNodeTyped, usePendingPermissionForTool } from '../../core/hooks';\nimport { resolveEffectiveToolBodyMode } from '../sessionViewOptions';\nimport { formatToolTitle } from '../tools/formatToolTitle';\nimport { resolveToolBody } from '../tools/resolveToolBody';\nimport { ToolCallShell } from '../tools/ToolCallShell';\nimport type { ToolDisplayProps } from '../tools/types';\n\nexport interface ToolCallCardProps {\n nodeId: string;\n layout?: 'default' | 'grouped';\n}\n\nexport function ToolCallCard({ nodeId, layout = 'default' }: ToolCallCardProps) {\n const node = useNodeTyped(nodeId, 'tool_call');\n const { registry, defaultBodyMode } = useToolDisplayOptions();\n const viewOptions = useSessionViewOptions();\n const pendingPermission = usePendingPermissionForTool(node?.toolName ?? '');\n const effectiveDefault = resolveEffectiveToolBodyMode(viewOptions, defaultBodyMode);\n const [bodyMode, setBodyMode] = useState(effectiveDefault);\n\n useEffect(() => {\n setBodyMode(resolveEffectiveToolBodyMode(viewOptions, defaultBodyMode));\n }, [viewOptions.displayMode, viewOptions.verbose, defaultBodyMode]);\n\n if (!node) return null;\n\n // 内部工具(Task* 等)不在 Timeline 显示(对齐 CC renderToolUseMessage 返回 null)\n if (node.hidden) return null;\n\n const details = node.details;\n const inputStream = details?.inputStream ?? node.inputDelta;\n const result = node.result;\n const displayBody = result?.display ?? null;\n const hasSubagentProgress = (node.subagentProgress?.length ?? 0) > 0;\n const showBody =\n hasSubagentProgress || !(node.status === 'running' && result == null);\n\n const BodyComponent = resolveToolBody(node.toolName, displayBody, registry);\n const title = formatToolTitle(\n node.toolName,\n details?.input ?? node.input,\n displayBody,\n result?.summary,\n result?.meta,\n );\n\n const bodyProps: ToolDisplayProps = {\n nodeId,\n toolName: node.toolName,\n status: node.status,\n input: details?.input ?? node.input,\n inputStream,\n result,\n progress: node.progress ?? undefined,\n subagentProgress: node.subagentProgress,\n subagentSessions: node.subagentSessions,\n bodyMode,\n onBodyModeChange: setBodyMode,\n };\n\n const errorMessage = result?.error?.message ?? null;\n const permissionWait =\n viewOptions.permissionUiMode !== 'standalone' && node.status === 'running'\n ? pendingPermission\n : undefined;\n\n return (\n <ToolCallShell\n status={node.status}\n title={title}\n progress={node.progress ?? undefined}\n errorMessage={errorMessage}\n layout={layout}\n permissionWait={permissionWait}\n permissionUiMode={viewOptions.permissionUiMode}\n >\n {showBody ? (\n <div className=\"lax-tool-shell__body\">\n <BodyComponent {...bodyProps} />\n </div>\n ) : null}\n\n </ToolCallShell>\n );\n}\n","/**\n * 职责:默认 StepNode 折叠详情 widget。\n * 链路位置:NodeRegistry;MVP 折叠展示。\n * 当前裁剪范围:简单 label/status;不含复杂编排 UI。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface StepCardProps {\n nodeId: string;\n}\n\nexport function StepCard({ nodeId }: StepCardProps) {\n const node = useNodeTyped(nodeId, 'step');\n if (!node) return null;\n return (\n <details className=\"lax-step-card\" data-status={node.status}>\n <summary className=\"lax-step-card__summary\">{node.label}</summary>\n </details>\n );\n}\n","/**\n * 职责:默认 ErrorNode 主舞台 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n * 当前裁剪范围:展示 message/type;不打断流。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface ErrorCardProps {\n nodeId: string;\n}\n\nexport function ErrorCard({ nodeId }: ErrorCardProps) {\n const node = useNodeTyped(nodeId, 'error');\n if (!node) return null;\n return (\n <div className=\"lax-error-card\" role=\"alert\">\n <div className=\"lax-error-card__message\">{node.message}</div>\n {node.errorType ? (\n <div className=\"lax-error-card__type\">{node.errorType}</div>\n ) : null}\n </div>\n );\n}\n","/**\n * 职责:未知 event_type 兜底 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n * 当前裁剪范围:展示 eventType 与原始 data JSON。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface UnknownCardProps {\n nodeId: string;\n}\n\nexport function UnknownCard({ nodeId }: UnknownCardProps) {\n const node = useNodeTyped(nodeId, 'unknown');\n if (!node) return null;\n return (\n <div className=\"lax-unknown-card\">\n <div className=\"lax-unknown-card__type\">Unknown: {node.eventType}</div>\n <pre className=\"lax-unknown-card__data\">\n {JSON.stringify(node.rawData, null, 2)}\n </pre>\n </div>\n );\n}\n","/**\n * 职责:默认 PermissionNode 主舞台 widget(V2-D)。\n * 链路位置:NodeRegistry → Timeline;Allow/Deny 经 InteractionBus 回写业务 HTTP。\n * 当前裁剪范围:pending 态按钮;不含 suggestions 列表与 HITL 表单。\n */\nimport { useState } from 'react';\n\nimport { useInteractionBus } from '../../core/context/InteractionContext';\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface PermissionCardProps {\n nodeId: string;\n}\n\nexport function PermissionCard({ nodeId }: PermissionCardProps) {\n const node = useNodeTyped(nodeId, 'permission');\n const bus = useInteractionBus();\n const [resolvedLocally, setResolvedLocally] = useState(false);\n\n if (!node) return null;\n\n const pending = node.status === 'pending' && !resolvedLocally;\n\n const onAllow = () => {\n void bus.resolvePermission({ requestId: node.requestId, allow: true });\n setResolvedLocally(true);\n };\n\n const onDeny = () => {\n void bus.resolvePermission({ requestId: node.requestId, allow: false });\n setResolvedLocally(true);\n };\n\n return (\n <div\n className=\"lax-permission-card\"\n data-status={pending ? 'pending' : 'resolved'}\n data-request-id={node.requestId}\n >\n <div className=\"lax-permission-card__header\">\n <span className=\"lax-permission-card__label\">Permission</span>\n <span className=\"lax-permission-card__tool\">{node.toolName}</span>\n </div>\n <div className=\"lax-permission-card__message\">{node.message}</div>\n {node.askPrompt && node.askPrompt !== node.message ? (\n <div className=\"lax-permission-card__prompt\">{node.askPrompt}</div>\n ) : null}\n {pending ? (\n <div className=\"lax-permission-card__actions\">\n <button type=\"button\" className=\"lax-permission-card__allow\" onClick={onAllow}>\n Allow\n </button>\n <button type=\"button\" className=\"lax-permission-card__deny\" onClick={onDeny}>\n Deny\n </button>\n </div>\n ) : (\n <div className=\"lax-permission-card__resolved\">Resolved</div>\n )}\n </div>\n );\n}\n","/**\n * 职责:MEMORY_SAVED 摘要节点 widget — \"Saved N memories\" 一行折叠展示。\n *\n * 链路位置:\n * NodeRegistry → TimelineItem → 主舞台。\n *\n * 当前裁剪范围:\n * 默认折叠态;writtenPaths 非空时可展开列出路径。\n * 不解析路径语义(绝对 / 相对 / index 文件),由后端 SDK 契约保证。\n *\n * CLI 对照:\n * langchain_agentx_cli/screens/repl.py MemorySavedSummary 一行渲染。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface MemorySavedRowProps {\n nodeId: string;\n}\n\nexport function MemorySavedRow({ nodeId }: MemorySavedRowProps) {\n const node = useNodeTyped(nodeId, 'memory_saved');\n if (!node) return null;\n const hasPaths = node.writtenPaths.length > 0;\n return (\n <details\n className=\"lax-memory-saved\"\n data-testid=\"lax-memory-saved\"\n data-node-id={nodeId}\n >\n <summary className=\"lax-memory-saved__summary\">\n <span className=\"lax-memory-saved__icon\" aria-hidden=\"true\">\n 💾\n </span>\n <span className=\"lax-memory-saved__hint\">{node.displayHint}</span>\n </summary>\n {hasPaths ? (\n <ul className=\"lax-memory-saved__paths\">\n {node.writtenPaths.map((p) => (\n <li key={p} className=\"lax-memory-saved__path\">\n <code>{p}</code>\n </li>\n ))}\n </ul>\n ) : null}\n </details>\n );\n}\n","/**\n * 职责:kind → React widget 映射,支持 override/register 扩展。\n * 链路位置:Timeline 按节点 kind 查找 widget;业务通过 override 替换。\n * 当前裁剪范围:8 类内置 kind + 自定义 register;无插件系统。\n */\nimport type { ComponentType } from 'react';\n\nimport type { SessionNodeKind } from '../types/nodes';\nimport { TextBubble } from './nodes/TextNode';\nimport { ReasoningBubble } from './nodes/ReasoningNode';\nimport { ToolCallCard } from './nodes/ToolCallNode';\nimport { StepCard } from './nodes/StepNode';\nimport { ErrorCard } from './nodes/ErrorNode';\nimport { UnknownCard } from './nodes/UnknownNode';\nimport { PermissionCard } from './nodes/PermissionNode';\nimport { MemorySavedRow } from './nodes/MemorySavedNode';\n\nconst DEFAULT_WIDGETS = new Map<string, NodeWidget>([\n ['text', TextBubble],\n ['reasoning', ReasoningBubble],\n ['tool_call', ToolCallCard],\n ['step', StepCard],\n ['error', ErrorCard],\n ['unknown', UnknownCard],\n ['permission', PermissionCard],\n ['memory_saved', MemorySavedRow],\n]);\n\nexport interface NodeWidgetProps {\n nodeId: string;\n}\n\nexport type NodeWidget = ComponentType<NodeWidgetProps>;\n\nexport class NodeRegistry {\n private readonly widgets: Map<string, NodeWidget>;\n\n constructor(widgets: Map<string, NodeWidget>) {\n this.widgets = widgets;\n }\n\n static default(): NodeRegistry {\n return new NodeRegistry(new Map(DEFAULT_WIDGETS));\n }\n\n override(kind: SessionNodeKind | string, widget: NodeWidget): NodeRegistry {\n const next = new Map(this.widgets);\n next.set(kind, widget);\n return new NodeRegistry(next);\n }\n\n register(kind: string, widget: NodeWidget): NodeRegistry {\n return this.override(kind, widget);\n }\n\n get(kind: string): NodeWidget | undefined {\n return this.widgets.get(kind);\n }\n\n has(kind: string): boolean {\n return this.widgets.has(kind);\n }\n}\n","/**\n * 职责:默认 registry 工厂别名,供 AgentSession 内部使用。\n * 链路位置:AgentSession 未传 registry 时的 fallback。\n * 当前裁剪范围:委托 NodeRegistry.default()。\n */\nimport { NodeRegistry } from './NodeRegistry';\n\nexport function createDefaultRegistry(): NodeRegistry {\n return NodeRegistry.default();\n}\n","/**\n * 职责:多会话顶层 store,按 sessionId 路由事件到独立 SessionTree。\n * 链路位置:MultiAgentSession 消费;业务也可直接 createMultiSessionStore。\n * 当前裁剪范围:进程内 LRU(默认 10);不含 Source 生命周期管理。\n */\nimport { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport { createEmptyTree, type ReducerError, type SessionTree } from '../types/tree';\nimport { replayEvents } from './replay';\nimport { reduceTree, type ReduceOptions } from './reducer';\nimport { markEventIdSeen, shouldSkipDuplicateEvent } from './dedupe';\nimport type { SessionStoreState } from './store';\nimport type { SourceEventContext } from '../transport/types';\n\nexport interface SessionSlice {\n tree: SessionTree;\n eventCount: number;\n}\n\nexport interface MultiSessionStoreOptions {\n maxSessions?: number;\n tierOverrides?: TierOverrides;\n debug?: boolean;\n /** 初始活跃 session;默认 null */\n activeSessionId?: string | null;\n}\n\nexport interface MultiSessionStoreState {\n sessions: Record<string, SessionSlice>;\n activeSessionId: string | null;\n order: string[];\n applyEvent: (sessionId: string, event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (sessionId: string, events: LangchainAgentEvent[]) => void;\n setActiveSessionId: (id: string | null) => void;\n removeSession: (id: string) => void;\n replaySession: (sessionId: string, events: LangchainAgentEvent[]) => void;\n ensureSession: (sessionId: string, initialEvents?: LangchainAgentEvent[]) => void;\n getSessionTree: (sessionId: string) => SessionTree | undefined;\n}\n\nconst DEFAULT_MAX_SESSIONS = 10;\n\nfunction touchOrder(order: string[], sessionId: string): string[] {\n return [...order.filter((id) => id !== sessionId), sessionId];\n}\n\nfunction safeReduce(\n tree: SessionTree,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): SessionTree {\n try {\n return reduceTree(tree, event, eventIndex, options);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n if (import.meta.env?.DEV) {\n console.error('[langchain_agentx_stream_ui] reducer error:', err);\n }\n const reducerError: ReducerError = {\n eventIndex,\n eventType: event.event_type,\n message,\n stack,\n };\n return {\n ...tree,\n internalErrors: [...tree.internalErrors, reducerError],\n };\n }\n}\n\nfunction evictSessions(\n sessions: Record<string, SessionSlice>,\n order: string[],\n maxSessions: number,\n activeSessionId: string | null,\n): { sessions: Record<string, SessionSlice>; order: string[] } {\n let nextSessions = { ...sessions };\n let nextOrder = [...order];\n while (nextOrder.length > maxSessions) {\n const candidate = nextOrder.find((id) => id !== activeSessionId) ?? nextOrder[0];\n if (!candidate) break;\n const { [candidate]: _removed, ...rest } = nextSessions;\n nextSessions = rest;\n nextOrder = nextOrder.filter((id) => id !== candidate);\n }\n return { sessions: nextSessions, order: nextOrder };\n}\n\nexport function createMultiSessionStore(\n options?: MultiSessionStoreOptions,\n): StoreApi<MultiSessionStoreState> {\n const maxSessions = options?.maxSessions ?? DEFAULT_MAX_SESSIONS;\n const reduceOpts: ReduceOptions = {\n tierOverrides: options?.tierOverrides,\n collectDebug: options?.debug === true,\n };\n const replayOpts = {\n tierOverrides: options?.tierOverrides,\n collectDebug: options?.debug === true,\n };\n const seenBySession = new Map<string, Set<string>>();\n\n function getSeenSet(sessionId: string): Set<string> {\n let set = seenBySession.get(sessionId);\n if (!set) {\n set = new Set<string>();\n seenBySession.set(sessionId, set);\n }\n return set;\n }\n\n return createStore<MultiSessionStoreState>((set, get) => ({\n sessions: {},\n activeSessionId: options?.activeSessionId ?? null,\n order: [],\n\n getSessionTree(sessionId) {\n return get().sessions[sessionId]?.tree;\n },\n\n ensureSession(sessionId, initialEvents) {\n const state = get();\n if (state.sessions[sessionId]) return;\n\n const tree =\n initialEvents && initialEvents.length > 0\n ? replayEvents(initialEvents, replayOpts)\n : createEmptyTree();\n const slice: SessionSlice = {\n tree,\n eventCount: initialEvents?.length ?? 0,\n };\n let order = touchOrder(state.order, sessionId);\n let sessions = { ...state.sessions, [sessionId]: slice };\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n\n set({\n sessions,\n order,\n activeSessionId: state.activeSessionId ?? sessionId,\n });\n },\n\n applyEvent(sessionId, event, ctx) {\n const sseEventId = ctx?.sseEventId;\n const seen = getSeenSet(sessionId);\n if (shouldSkipDuplicateEvent(seen, sseEventId)) return;\n\n const state = get();\n let slice = state.sessions[sessionId];\n if (!slice) {\n get().ensureSession(sessionId);\n slice = get().sessions[sessionId]!;\n }\n const reduced = safeReduce(slice.tree, event, slice.eventCount, reduceOpts);\n const nextTree: SessionTree =\n sseEventId\n ? { ...reduced, meta: { ...reduced.meta, lastEventId: sseEventId } }\n : reduced;\n const nextSlice: SessionSlice = {\n tree: nextTree,\n eventCount: slice.eventCount + 1,\n };\n markEventIdSeen(seen, sseEventId);\n let sessions = { ...state.sessions, [sessionId]: nextSlice };\n let order = touchOrder(state.order, sessionId);\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n set({ sessions, order });\n },\n\n applyEvents(sessionId, events) {\n for (const event of events) {\n get().applyEvent(sessionId, event);\n }\n },\n\n setActiveSessionId(id) {\n set({ activeSessionId: id });\n },\n\n removeSession(sessionId) {\n const state = get();\n if (!state.sessions[sessionId]) return;\n seenBySession.delete(sessionId);\n const { [sessionId]: _removed, ...sessions } = state.sessions;\n const order = state.order.filter((id) => id !== sessionId);\n const activeSessionId =\n state.activeSessionId === sessionId\n ? (order[order.length - 1] ?? null)\n : state.activeSessionId;\n set({ sessions, order, activeSessionId });\n },\n\n replaySession(sessionId, events) {\n const tree = replayEvents(events, replayOpts);\n const slice: SessionSlice = { tree, eventCount: events.length };\n const state = get();\n let order = touchOrder(state.order, sessionId);\n let sessions = { ...state.sessions, [sessionId]: slice };\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n set({ sessions, order });\n },\n }));\n}\n\nexport type MultiSessionStore = StoreApi<MultiSessionStoreState>;\n\n/** 将 MultiSessionStore 活跃会话投影为 SessionStore,供 Timeline hooks 复用。 */\nexport function createActiveSessionBridge(multiStore: MultiSessionStore): StoreApi<SessionStoreState> {\n type BridgeState = Pick<SessionStoreState, 'tree' | 'eventCount' | 'applyEvent' | 'applyEvents' | 'reset'>;\n\n const bridge = createStore<BridgeState>(() => ({\n tree: createEmptyTree(),\n eventCount: 0,\n applyEvent(event, ctx) {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().applyEvent(id, event, ctx);\n },\n applyEvents(events) {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().applyEvents(id, events);\n },\n reset() {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().replaySession(id, []);\n },\n }));\n\n const sync = (): void => {\n const { activeSessionId, sessions } = multiStore.getState();\n const slice = activeSessionId ? sessions[activeSessionId] : undefined;\n bridge.setState({\n tree: slice?.tree ?? createEmptyTree(),\n eventCount: slice?.eventCount ?? 0,\n });\n };\n\n multiStore.subscribe(sync);\n sync();\n return bridge as StoreApi<SessionStoreState>;\n}\n","/**\n * 职责:SSE 事件 id 幂等去重(M4 续传重叠帧)。\n * 链路位置:SessionStore / MultiSessionStore applyEvent 前置检查。\n * 当前裁剪范围:按 sseEventId 字符串去重;无 id 时始终应用。\n */\n\nexport function shouldSkipDuplicateEvent(\n seenEventIds: ReadonlySet<string>,\n sseEventId: string | undefined,\n): boolean {\n if (!sseEventId) return false;\n return seenEventIds.has(sseEventId);\n}\n\nexport function markEventIdSeen(\n seenEventIds: Set<string>,\n sseEventId: string | undefined,\n): void {\n if (sseEventId) seenEventIds.add(sseEventId);\n}\n","/**\n * 职责:多会话顶层容器,每 session 独立 Source + initialEvents,共享 MultiSessionStore。\n * 链路位置:业务多 Tab / 双路 SSE;Timeline 只渲染 activeSessionId 对应树。\n * 当前裁剪范围:薄封装;Source 生命周期由本组件管理;LRU 默认 10。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nimport {\n createMultiSessionStore,\n createActiveSessionBridge,\n type MultiSessionStore,\n} from '../core/sessionStore';\nimport {\n MultiSessionStoreContext,\n SessionStoreContext,\n NodeRegistryContext,\n ToolDisplayOptionsContext,\n SessionViewOptionsContext,\n} from '../core/context/SessionContext';\nimport type { Source } from '../transport/types';\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport type { ReducerError } from '../types/tree';\nimport { createDefaultRegistry } from './defaultRegistry';\nimport type { NodeRegistry } from './NodeRegistry';\nimport { SessionTimeline } from './SessionTimeline';\nimport { InteractionBusContext } from '../core/context/InteractionContext';\nimport type { InteractionBus } from '../core/interaction/InteractionBus';\nimport { getNoopInteractionBus } from '../core/interaction/InteractionBus';\nimport { useInternalErrors, useSessionStatus } from '../core/hooks';\nimport {\n createDefaultToolRegistry,\n type ToolDisplayRegistry,\n} from './tools/registry';\nimport type { ToolBodyMode } from './tools/types';\nimport type { MarkdownRenderer } from '../core/context/MarkdownRendererContext';\nimport { MarkdownRendererContext } from '../core/context/MarkdownRendererContext';\nimport type { PermissionUiMode } from './sessionViewOptions';\nimport { DEFAULT_SESSION_VIEW_OPTIONS } from './sessionViewOptions';\n\nexport interface MultiSessionSourceConfig {\n sessionId: string;\n source: Source;\n /** EventBuffer ingest 快照或历史事件;挂载时 replay 后再接 source 续流(M3) */\n initialEvents?: LangchainAgentEvent[];\n}\n\nexport interface MultiAgentSessionProps {\n sessions: MultiSessionSourceConfig[];\n /** 受控活跃 session */\n activeSessionId?: string | null;\n /** 非受控默认活跃 session */\n defaultActiveSessionId?: string | null;\n onActiveSessionChange?: (sessionId: string | null) => void;\n maxSessions?: number;\n tierOverrides?: TierOverrides;\n debug?: boolean;\n registry?: NodeRegistry;\n onError?: (error: Error, sessionId: string) => void;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n interactionBus?: InteractionBus;\n toolDisplayRegistry?: ToolDisplayRegistry;\n defaultBodyMode?: ToolBodyMode;\n groupParallelTools?: boolean;\n permissionUiMode?: PermissionUiMode;\n markdownRenderer?: MarkdownRenderer;\n children?: ReactNode;\n}\n\nfunction DebugPanel() {\n const status = useSessionStatus();\n const errors = useInternalErrors();\n if (errors.length === 0) return null;\n return (\n <div className=\"lax-debug-panel\" data-testid=\"lax-debug-panel\">\n <div>status: {status}</div>\n <ul>\n {errors.map((err: ReducerError, i: number) => (\n <li key={`${err.eventIndex}-${i}`}>\n [{err.eventType}] {err.message}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\nexport function MultiAgentSession({\n sessions,\n activeSessionId: controlledActiveId,\n defaultActiveSessionId,\n onActiveSessionChange,\n maxSessions,\n tierOverrides,\n debug = false,\n registry,\n onError,\n virtualized = false,\n virtualizeThreshold,\n interactionBus,\n toolDisplayRegistry,\n defaultBodyMode = 'preview',\n groupParallelTools = false,\n permissionUiMode = 'standalone',\n markdownRenderer,\n children,\n}: MultiAgentSessionProps) {\n const multiStoreRef = useRef<MultiSessionStore | null>(null);\n const bridgeRef = useRef<ReturnType<typeof createActiveSessionBridge> | null>(null);\n\n if (multiStoreRef.current === null) {\n const defaultId =\n defaultActiveSessionId ??\n controlledActiveId ??\n sessions[0]?.sessionId ??\n null;\n multiStoreRef.current = createMultiSessionStore({\n maxSessions,\n tierOverrides,\n debug,\n activeSessionId: defaultId,\n });\n bridgeRef.current = createActiveSessionBridge(multiStoreRef.current);\n for (const cfg of sessions) {\n multiStoreRef.current.getState().ensureSession(cfg.sessionId, cfg.initialEvents);\n }\n }\n\n const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);\n const busRef = useMemo(\n () => interactionBus ?? getNoopInteractionBus(),\n [interactionBus],\n );\n const toolDisplayRef = useMemo(\n () => ({\n registry: toolDisplayRegistry ?? createDefaultToolRegistry(),\n defaultBodyMode,\n }),\n [toolDisplayRegistry, defaultBodyMode],\n );\n const sessionViewRef = useMemo(\n () => ({\n ...DEFAULT_SESSION_VIEW_OPTIONS,\n groupParallelTools,\n permissionUiMode,\n verboseReasoning: debug,\n }),\n [groupParallelTools, permissionUiMode, debug],\n );\n\n useEffect(() => {\n if (controlledActiveId === undefined) return;\n multiStoreRef.current!.getState().setActiveSessionId(controlledActiveId);\n }, [controlledActiveId]);\n\n useEffect(() => {\n if (!onActiveSessionChange) return;\n return multiStoreRef.current!.subscribe((state) => {\n onActiveSessionChange(state.activeSessionId);\n });\n }, [onActiveSessionChange]);\n\n useEffect(() => {\n const multiStore = multiStoreRef.current!;\n const controllers = sessions.map((cfg) => {\n const controller = new AbortController();\n multiStore.getState().ensureSession(cfg.sessionId, cfg.initialEvents);\n void cfg.source.start((event, ctx) => {\n multiStore.getState().applyEvent(cfg.sessionId, event, ctx);\n }, controller.signal).catch((err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error, cfg.sessionId);\n });\n return controller;\n });\n return () => {\n for (const c of controllers) c.abort();\n };\n }, [sessions, onError]);\n\n return (\n <MultiSessionStoreContext.Provider value={multiStoreRef.current!}>\n <SessionStoreContext.Provider value={bridgeRef.current!}>\n <InteractionBusContext.Provider value={busRef}>\n <NodeRegistryContext.Provider value={registryRef}>\n <MarkdownRendererContext.Provider value={markdownRenderer}>\n <ToolDisplayOptionsContext.Provider value={toolDisplayRef}>\n <SessionViewOptionsContext.Provider value={sessionViewRef}>\n <div className=\"lax-agent-session lax-multi-agent-session\" data-testid=\"lax-multi-agent-session\">\n {children ?? (\n <SessionTimeline\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n )}\n {debug ? <DebugPanel /> : null}\n </div>\n </SessionViewOptionsContext.Provider>\n </ToolDisplayOptionsContext.Provider>\n </MarkdownRendererContext.Provider>\n </NodeRegistryContext.Provider>\n </InteractionBusContext.Provider>\n </SessionStoreContext.Provider>\n </MultiSessionStoreContext.Provider>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBM,SACE,KADF;AAfC,IAAM,gBAAgB;AAMtB,SAAS,gBAAgB,EAAE,OAAO,GAAyB;AAChE,QAAM,OAAO,aAAa,QAAQ,WAAW;AAC7C,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,OAAO,KAAK,YAAY,KAAK;AACnC,MAAI,CAAC,KAAM,QAAO;AAElB,SACE,oBAAC,SAAI,WAAU,wBAAuB,eAAa,KAAK,QAAQ,iBAAe,KAAK,SAClF,+BAAC,SAAI,WAAU,8BACb;AAAA,wBAAC,UAAK,WAAU,6BAA4B,eAAY,QACrD,yBACH;AAAA,IACA,oBAAC,UAAK,WAAU,iCAAiC,eAAK,aAAY;AAAA,KACpE,GACF;AAEJ;;;ACdA,SAAgB,QAAQ,SAAS,gBAAgB;AACjD,SAAS,cAAuC;AAChD,OAAO,mBAAmB;AAC1B,OAAO,eAAe;AACtB,SAAS,SAAS,yBAAyB;AAC3C,SAAS,eAAe;AAuFhB,SA6EI,UA7EJ,OAAAA,MA6EI,QAAAC,aA7EJ;AA9ER,IAAM,kBAAkB;AACxB,IAAM,aAAa,oBAAI,IAAqB;AAO5C,IAAM,eAAe;AAErB,SAAS,kBAAkB,GAAoB;AAE7C,SAAO,aAAa,KAAK,EAAE,SAAS,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAAC;AAC/D;AAKA,SAAS,YAAY,SAAyB;AAC5C,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAS,QAAQ,KAAK,OAAO,QAAQ,WAAW,CAAC,IAAK;AAAA,EACxD;AACA,SAAO,KAAK,SAAS,EAAE;AACzB;AAKA,SAAS,YAAY,SAA0B;AAG7C,MAAI,CAAC,kBAAkB,OAAO,GAAG;AAC/B,WAAO,CAAC;AAAA,MACN,MAAM;AAAA,MACN,KAAK;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA,MACR,CAAC;AAAA,IACH,CAAU;AAAA,EACZ;AAEA,QAAM,MAAM,YAAY,OAAO;AAC/B,QAAM,MAAM,WAAW,IAAI,GAAG;AAE9B,MAAI,KAAK;AAEP,eAAW,OAAO,GAAG;AACrB,eAAW,IAAI,KAAK,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,OAAO,MAAM,OAAO;AAEnC,MAAI,WAAW,QAAQ,iBAAiB;AAEtC,UAAM,QAAQ,WAAW,KAAK,EAAE,KAAK,EAAE;AACvC,QAAI,UAAU,OAAW,YAAW,OAAO,KAAK;AAAA,EAClD;AAEA,aAAW,IAAI,KAAK,MAAM;AAC1B,SAAO;AACT;AAKA,IAAM,sBAAsB;AAAA,EAC1B,KAAK,EAAE,MAAM,WAAW,UAAU,GAAG,MAAM,GAAQ;AACjD,UAAM,QAAQ,iBAAiB,KAAK,aAAa,EAAE;AACnD,UAAM,cAAc,OAAO,QAAQ,EAAE,QAAQ,OAAO,EAAE;AACtD,UAAM,SAAS,CAAC;AAEhB,QAAI,CAAC,UAAU,OAAO;AACpB,aACE,gBAAAD,KAAC,aAAU,UAAU,MAAM,CAAC,GAAG,SAAS,aAAa;AAAA,IAEzD;AAEA,WACE,gBAAAA,KAAC,UAAK,WAAU,6BAA6B,GAAG,OAC7C,UACH;AAAA,EAEJ;AAAA,EACA,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,0CAA0C,UAAS;AAAA,EAAO;AAAA,EACvG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,0CAA0C,UAAS;AAAA,EAAO;AAAA,EACvG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,0CAA0C,UAAS;AAAA,EAAO;AAAA,EACvG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,0CAA0C,UAAS;AAAA,EAAO;AAAA,EACvG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,0CAA0C,UAAS;AAAA,EAAO;AAAA,EACvG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,0CAA0C,UAAS;AAAA,EAAO;AAAA,EACvG,EAAE,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,OAAE,WAAU,2BAA2B,UAAS;AAAA,EAAM;AAAA,EACrF,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,uCAAuC,UAAS;AAAA,EAAO;AAAA,EACpG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,uCAAuC,UAAS;AAAA,EAAO;AAAA,EACpG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,oBAAoB,UAAS;AAAA,EAAO;AAAA,EACjF,EAAE,EAAE,UAAU,KAAK,GAAQ;AACzB,WACE,gBAAAA,KAAC,OAAE,MAAY,WAAU,sBAAqB,QAAO,UAAS,KAAI,uBAC/D,UACH;AAAA,EAEJ;AAAA,EACA,WAAW,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,gBAAW,WAAU,4BAA4B,UAAS;AAAA,EAAe;AAAA,EACjH,MAAM,EAAE,SAAS,GAAQ;AACvB,WACE,gBAAAA,KAAC,SAAI,WAAU,+BACb,0BAAAA,KAAC,WAAM,WAAU,uBAAuB,UAAS,GACnD;AAAA,EAEJ;AAAA,EACA,MAAM,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,WAAM,WAAU,uBAAuB,UAAS;AAAA,EAAU;AAAA,EAC7F,MAAM,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,WAAM,WAAU,uBAAuB,UAAS;AAAA,EAAU;AAAA,EAC7F,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,oBAAoB,UAAS;AAAA,EAAO;AAAA,EACjF,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,oBAAoB,UAAS;AAAA,EAAO;AAAA,EACjF,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,oBAAoB,UAAS;AAAA,EAAO;AAAA,EACjF,KAAK;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,oBAAmB;AAAA,EAAI;AAAA,EACnD,OAAO,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,YAAO,WAAU,wBAAwB,UAAS;AAAA,EAAW;AAAA,EACjG,GAAG,EAAE,SAAS,GAAQ;AAAE,WAAO,gBAAAA,KAAC,QAAG,WAAU,oBAAoB,UAAS;AAAA,EAAO;AACnF;AAUA,SAAS,UAAU,EAAE,UAAU,QAAQ,GAAmB;AACxD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,aAAa,YAAY;AAC7B,QAAI;AACF,YAAM,UAAU,UAAU,UAAU,OAAO;AAC3C,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC,SAAS,KAAK;AACZ,cAAQ,MAAM,mBAAmB,GAAG;AAAA,IACtC;AAAA,EACF;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAU,kBACb;AAAA,oBAAAA,MAAC,SAAI,WAAU,0BACb;AAAA,sBAAAD,KAAC,UAAK,WAAU,wBAAwB,sBAAY,QAAO;AAAA,MAC3D,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW,wBAAwB,SAAS,iCAAiC,EAAE;AAAA,UAC/E,SAAS;AAAA,UACT,OAAO,SAAS,6BAAS;AAAA,UAExB,mBACC,gBAAAC,MAAA,YACE;AAAA,4BAAAD,KAAC,SAAI,WAAU,wBAAuB,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAAe,aAAa,GACvG,0BAAAA,KAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,kBAAiB,GACxE;AAAA,YACA,gBAAAA,KAAC,UAAK,gCAAG;AAAA,aACX,IAEA,gBAAAC,MAAA,YACE;AAAA,4BAAAD,KAAC,SAAI,WAAU,wBAAuB,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAAe,aAAa,GACvG,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,eAAc;AAAA,gBACd,gBAAe;AAAA,gBACf,GAAE;AAAA;AAAA,YACJ,GACF;AAAA,YACA,gBAAAA,KAAC,UAAK,0BAAE;AAAA,aACV;AAAA;AAAA,MAEJ;AAAA,OACF;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO;AAAA,QACP,aAAa;AAAA,UACX,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,QACd;AAAA,QACA,iBAAiB;AAAA,QACjB,eAAe;AAAA,QAEd;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;AASA,SAAS,iBAAiB,EAAE,QAAQ,GAA0B;AAC5D,MAAI,CAAC,QAAQ,KAAK,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,QAAQ,MAAM;AAC7B,UAAM,OAAO,YAAY,OAAO;AAGhC,QAAI,CAAC,kBAAkB,OAAO,GAAG;AAC/B,aACE,gBAAAA,KAAC,OAA0B,WAAU,2BAClC,qBADK,KAAK,SAAS,EAAE,CAExB;AAAA,IAEJ;AAGA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QAEC,eAAe,CAAC,SAAS;AAAA,QACzB,YAAY;AAAA,QAEX;AAAA;AAAA,MAJI,KAAK,SAAS,EAAE;AAAA,IAKvB;AAAA,EAEJ,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO,gBAAAA,KAAA,YAAG,oBAAS;AACrB;AAeO,SAAS,kBAAkB,EAAE,SAAS,GAA2B;AAItE;AAGA,QAAM,kBAAkB,OAAO,EAAE;AAGjC,MAAI,CAAC,SAAS,WAAW,gBAAgB,OAAO,GAAG;AACjD,oBAAgB,UAAU;AAAA,EAC5B;AAGA,QAAM,WAAW,gBAAgB,QAAQ;AACzC,QAAM,SAAS,YAAY,SAAS,UAAU,QAAQ,CAAC;AAGvD,MAAI,iBAAiB,OAAO,SAAS;AACrC,SAAO,kBAAkB,KAAK,OAAO,cAAc,EAAG,SAAS,SAAS;AACtE;AAAA,EACF;AAEA,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACvC,eAAW,OAAO,CAAC,EAAG,IAAI;AAAA,EAC5B;AAEA,MAAI,UAAU,GAAG;AACf,oBAAgB,UAAU,SAAS,UAAU,GAAG,WAAW,OAAO;AAAA,EACpE;AAEA,QAAM,eAAe,gBAAgB;AACrC,QAAM,iBAAiB,SAAS,UAAU,aAAa,MAAM;AAE7D,SACE,gBAAAC,MAAC,SAAI,WAAU,gBAEZ;AAAA,oBACC,gBAAAD,KAAC,oBAA6D,SAAS,gBAAhD,UAAU,YAAY,YAAY,CAAC,EAA2B;AAAA,IAGtF,kBACC,gBAAAA,KAAC,oBAAiE,SAAS,kBAApD,YAAY,YAAY,cAAc,CAAC,EAA6B;AAAA,KAE/F;AAEJ;;;ACzSM,SACE,OAAAE,MADF,QAAAC,aAAA;AAPC,SAAS,WAAW,EAAE,OAAO,GAAoB;AACtD,QAAM,OAAO,aAAa,QAAQ,MAAM;AACxC,MAAI,CAAC,KAAM,QAAO;AAGlB,SACE,gBAAAD,KAAC,SAAI,WAAU,mBAAkB,eAAa,KAAK,QACjD,0BAAAC,MAAC,SAAI,WAAU,yBACb;AAAA,oBAAAD,KAAC,UAAK,WAAU,wBAAuB,eAAY,QAChD,yBACH;AAAA,IACA,gBAAAA,KAAC,SAAI,WAAU,+DACb,0BAAAA,KAAC,qBACE,eAAK,aACR,GACF;AAAA,KACF,GACF;AAEJ;;;AChCA,SAAS,WAAW,YAAAE,iBAAgB;AAoF1B,gBAAAC,YAAA;AAlEH,SAAS,aAAa,EAAE,QAAQ,SAAS,UAAU,GAAsB;AAC9E,QAAM,OAAO,aAAa,QAAQ,WAAW;AAC7C,QAAM,EAAE,UAAU,gBAAgB,IAAI,sBAAsB;AAC5D,QAAM,cAAc,sBAAsB;AAC1C,QAAM,oBAAoB,4BAA4B,MAAM,YAAY,EAAE;AAC1E,QAAM,mBAAmB,6BAA6B,aAAa,eAAe;AAClF,QAAM,CAAC,UAAU,WAAW,IAAIC,UAAS,gBAAgB;AAEzD,YAAU,MAAM;AACd,gBAAY,6BAA6B,aAAa,eAAe,CAAC;AAAA,EACxE,GAAG,CAAC,YAAY,aAAa,YAAY,SAAS,eAAe,CAAC;AAElE,MAAI,CAAC,KAAM,QAAO;AAGlB,MAAI,KAAK,OAAQ,QAAO;AAExB,QAAM,UAAU,KAAK;AACrB,QAAM,cAAc,SAAS,eAAe,KAAK;AACjD,QAAM,SAAS,KAAK;AACpB,QAAM,cAAc,QAAQ,WAAW;AACvC,QAAM,uBAAuB,KAAK,kBAAkB,UAAU,KAAK;AACnE,QAAM,WACJ,uBAAuB,EAAE,KAAK,WAAW,aAAa,UAAU;AAElE,QAAM,gBAAgB,gBAAgB,KAAK,UAAU,aAAa,QAAQ;AAC1E,QAAM,QAAQ;AAAA,IACZ,KAAK;AAAA,IACL,SAAS,SAAS,KAAK;AAAA,IACvB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAEA,QAAM,YAA8B;AAAA,IAClC;AAAA,IACA,UAAU,KAAK;AAAA,IACf,QAAQ,KAAK;AAAA,IACb,OAAO,SAAS,SAAS,KAAK;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,UAAU,KAAK,YAAY;AAAA,IAC3B,kBAAkB,KAAK;AAAA,IACvB,kBAAkB,KAAK;AAAA,IACvB;AAAA,IACA,kBAAkB;AAAA,EACpB;AAEA,QAAM,eAAe,QAAQ,OAAO,WAAW;AAC/C,QAAM,iBACJ,YAAY,qBAAqB,gBAAgB,KAAK,WAAW,YAC7D,oBACA;AAEN,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,QAAQ,KAAK;AAAA,MACb;AAAA,MACA,UAAU,KAAK,YAAY;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB,YAAY;AAAA,MAE7B,qBACC,gBAAAA,KAAC,SAAI,WAAU,wBACb,0BAAAA,KAAC,iBAAe,GAAG,WAAW,GAChC,IACE;AAAA;AAAA,EAEN;AAEJ;;;AC/EM,gBAAAE,YAAA;AALC,SAAS,SAAS,EAAE,OAAO,GAAkB;AAClD,QAAM,OAAO,aAAa,QAAQ,MAAM;AACxC,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,gBAAAA,KAAC,aAAQ,WAAU,iBAAgB,eAAa,KAAK,QACnD,0BAAAA,KAAC,aAAQ,WAAU,0BAA0B,eAAK,OAAM,GAC1D;AAEJ;;;ACJI,SACE,OAAAC,MADF,QAAAC,aAAA;AAJG,SAAS,UAAU,EAAE,OAAO,GAAmB;AACpD,QAAM,OAAO,aAAa,QAAQ,OAAO;AACzC,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,gBAAAA,MAAC,SAAI,WAAU,kBAAiB,MAAK,SACnC;AAAA,oBAAAD,KAAC,SAAI,WAAU,2BAA2B,eAAK,SAAQ;AAAA,IACtD,KAAK,YACJ,gBAAAA,KAAC,SAAI,WAAU,wBAAwB,eAAK,WAAU,IACpD;AAAA,KACN;AAEJ;;;ACNM,SACA,OAAAE,MADA,QAAAC,aAAA;AALC,SAAS,YAAY,EAAE,OAAO,GAAqB;AACxD,QAAM,OAAO,aAAa,QAAQ,SAAS;AAC3C,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,gBAAAA,MAAC,SAAI,WAAU,oBACb;AAAA,oBAAAA,MAAC,SAAI,WAAU,0BAAyB;AAAA;AAAA,MAAU,KAAK;AAAA,OAAU;AAAA,IACjE,gBAAAD,KAAC,SAAI,WAAU,0BACZ,eAAK,UAAU,KAAK,SAAS,MAAM,CAAC,GACvC;AAAA,KACF;AAEJ;;;ACjBA,SAAS,YAAAE,iBAAgB;AAkCnB,SACE,OAAAC,MADF,QAAAC,aAAA;AAzBC,SAAS,eAAe,EAAE,OAAO,GAAwB;AAC9D,QAAM,OAAO,aAAa,QAAQ,YAAY;AAC9C,QAAM,MAAM,kBAAkB;AAC9B,QAAM,CAAC,iBAAiB,kBAAkB,IAAIC,UAAS,KAAK;AAE5D,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,UAAU,KAAK,WAAW,aAAa,CAAC;AAE9C,QAAM,UAAU,MAAM;AACpB,SAAK,IAAI,kBAAkB,EAAE,WAAW,KAAK,WAAW,OAAO,KAAK,CAAC;AACrE,uBAAmB,IAAI;AAAA,EACzB;AAEA,QAAM,SAAS,MAAM;AACnB,SAAK,IAAI,kBAAkB,EAAE,WAAW,KAAK,WAAW,OAAO,MAAM,CAAC;AACtE,uBAAmB,IAAI;AAAA,EACzB;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAa,UAAU,YAAY;AAAA,MACnC,mBAAiB,KAAK;AAAA,MAEtB;AAAA,wBAAAA,MAAC,SAAI,WAAU,+BACb;AAAA,0BAAAD,KAAC,UAAK,WAAU,8BAA6B,wBAAU;AAAA,UACvD,gBAAAA,KAAC,UAAK,WAAU,6BAA6B,eAAK,UAAS;AAAA,WAC7D;AAAA,QACA,gBAAAA,KAAC,SAAI,WAAU,gCAAgC,eAAK,SAAQ;AAAA,QAC3D,KAAK,aAAa,KAAK,cAAc,KAAK,UACzC,gBAAAA,KAAC,SAAI,WAAU,+BAA+B,eAAK,WAAU,IAC3D;AAAA,QACH,UACC,gBAAAC,MAAC,SAAI,WAAU,gCACb;AAAA,0BAAAD,KAAC,YAAO,MAAK,UAAS,WAAU,8BAA6B,SAAS,SAAS,mBAE/E;AAAA,UACA,gBAAAA,KAAC,YAAO,MAAK,UAAS,WAAU,6BAA4B,SAAS,QAAQ,kBAE7E;AAAA,WACF,IAEA,gBAAAA,KAAC,SAAI,WAAU,iCAAgC,sBAAQ;AAAA;AAAA;AAAA,EAE3D;AAEJ;;;AChCM,SACE,OAAAG,MADF,QAAAC,aAAA;AAVC,SAAS,eAAe,EAAE,OAAO,GAAwB;AAC9D,QAAM,OAAO,aAAa,QAAQ,cAAc;AAChD,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,WAAW,KAAK,aAAa,SAAS;AAC5C,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAY;AAAA,MACZ,gBAAc;AAAA,MAEd;AAAA,wBAAAA,MAAC,aAAQ,WAAU,6BACjB;AAAA,0BAAAD,KAAC,UAAK,WAAU,0BAAyB,eAAY,QAAO,uBAE5D;AAAA,UACA,gBAAAA,KAAC,UAAK,WAAU,0BAA0B,eAAK,aAAY;AAAA,WAC7D;AAAA,QACC,WACC,gBAAAA,KAAC,QAAG,WAAU,2BACX,eAAK,aAAa,IAAI,CAAC,MACtB,gBAAAA,KAAC,QAAW,WAAU,0BACpB,0BAAAA,KAAC,UAAM,aAAE,KADF,CAET,CACD,GACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;;;AC7BA,IAAM,kBAAkB,oBAAI,IAAwB;AAAA,EAClD,CAAC,QAAQ,UAAU;AAAA,EACnB,CAAC,aAAa,eAAe;AAAA,EAC7B,CAAC,aAAa,YAAY;AAAA,EAC1B,CAAC,QAAQ,QAAQ;AAAA,EACjB,CAAC,SAAS,SAAS;AAAA,EACnB,CAAC,WAAW,WAAW;AAAA,EACvB,CAAC,cAAc,cAAc;AAAA,EAC7B,CAAC,gBAAgB,cAAc;AACjC,CAAC;AAQM,IAAM,eAAN,MAAM,cAAa;AAAA,EACP;AAAA,EAEjB,YAAY,SAAkC;AAC5C,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,OAAO,UAAwB;AAC7B,WAAO,IAAI,cAAa,IAAI,IAAI,eAAe,CAAC;AAAA,EAClD;AAAA,EAEA,SAAS,MAAgC,QAAkC;AACzE,UAAM,OAAO,IAAI,IAAI,KAAK,OAAO;AACjC,SAAK,IAAI,MAAM,MAAM;AACrB,WAAO,IAAI,cAAa,IAAI;AAAA,EAC9B;AAAA,EAEA,SAAS,MAAc,QAAkC;AACvD,WAAO,KAAK,SAAS,MAAM,MAAM;AAAA,EACnC;AAAA,EAEA,IAAI,MAAsC;AACxC,WAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,IAAI,MAAuB;AACzB,WAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,EAC9B;AACF;;;ACvDO,SAAS,wBAAsC;AACpD,SAAO,aAAa,QAAQ;AAC9B;;;ACJA,SAAS,mBAAkC;;;ACCpC,SAAS,yBACd,cACA,YACS;AACT,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,aAAa,IAAI,UAAU;AACpC;AAEO,SAAS,gBACd,cACA,YACM;AACN,MAAI,WAAY,cAAa,IAAI,UAAU;AAC7C;;;ADsBA,IAAM,uBAAuB;AAE7B,SAAS,WAAW,OAAiB,WAA6B;AAChE,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC,OAAO,OAAO,SAAS,GAAG,SAAS;AAC9D;AAEA,SAAS,WACP,MACA,OACA,YACA,SACa;AACb,MAAI;AACF,WAAO,WAAW,MAAM,OAAO,YAAY,OAAO;AAAA,EACpD,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAM,QAAQ,eAAe,QAAQ,IAAI,QAAQ;AACjD,QAAI,YAAY,KAAK,KAAK;AACxB,cAAQ,MAAM,+CAA+C,GAAG;AAAA,IAClE;AACA,UAAM,eAA6B;AAAA,MACjC;AAAA,MACA,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,gBAAgB,CAAC,GAAG,KAAK,gBAAgB,YAAY;AAAA,IACvD;AAAA,EACF;AACF;AAEA,SAAS,cACP,UACA,OACA,aACA,iBAC6D;AAC7D,MAAI,eAAe,EAAE,GAAG,SAAS;AACjC,MAAI,YAAY,CAAC,GAAG,KAAK;AACzB,SAAO,UAAU,SAAS,aAAa;AACrC,UAAM,YAAY,UAAU,KAAK,CAAC,OAAO,OAAO,eAAe,KAAK,UAAU,CAAC;AAC/E,QAAI,CAAC,UAAW;AAChB,UAAM,EAAE,CAAC,SAAS,GAAG,UAAU,GAAG,KAAK,IAAI;AAC3C,mBAAe;AACf,gBAAY,UAAU,OAAO,CAAC,OAAO,OAAO,SAAS;AAAA,EACvD;AACA,SAAO,EAAE,UAAU,cAAc,OAAO,UAAU;AACpD;AAEO,SAAS,wBACd,SACkC;AAClC,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,aAA4B;AAAA,IAChC,eAAe,SAAS;AAAA,IACxB,cAAc,SAAS,UAAU;AAAA,EACnC;AACA,QAAM,aAAa;AAAA,IACjB,eAAe,SAAS;AAAA,IACxB,cAAc,SAAS,UAAU;AAAA,EACnC;AACA,QAAM,gBAAgB,oBAAI,IAAyB;AAEnD,WAAS,WAAW,WAAgC;AAClD,QAAI,MAAM,cAAc,IAAI,SAAS;AACrC,QAAI,CAAC,KAAK;AACR,YAAM,oBAAI,IAAY;AACtB,oBAAc,IAAI,WAAW,GAAG;AAAA,IAClC;AACA,WAAO;AAAA,EACT;AAEA,SAAO,YAAoC,CAAC,KAAK,SAAS;AAAA,IACxD,UAAU,CAAC;AAAA,IACX,iBAAiB,SAAS,mBAAmB;AAAA,IAC7C,OAAO,CAAC;AAAA,IAER,eAAe,WAAW;AACxB,aAAO,IAAI,EAAE,SAAS,SAAS,GAAG;AAAA,IACpC;AAAA,IAEA,cAAc,WAAW,eAAe;AACtC,YAAM,QAAQ,IAAI;AAClB,UAAI,MAAM,SAAS,SAAS,EAAG;AAE/B,YAAM,OACJ,iBAAiB,cAAc,SAAS,IACpC,aAAa,eAAe,UAAU,IACtC,gBAAgB;AACtB,YAAM,QAAsB;AAAA,QAC1B;AAAA,QACA,YAAY,eAAe,UAAU;AAAA,MACvC;AACA,UAAI,QAAQ,WAAW,MAAM,OAAO,SAAS;AAC7C,UAAI,WAAW,EAAE,GAAG,MAAM,UAAU,CAAC,SAAS,GAAG,MAAM;AACvD,OAAC,EAAE,UAAU,MAAM,IAAI,cAAc,UAAU,OAAO,aAAa,MAAM,eAAe;AAExF,UAAI;AAAA,QACF;AAAA,QACA;AAAA,QACA,iBAAiB,MAAM,mBAAmB;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,IAEA,WAAW,WAAW,OAAO,KAAK;AAChC,YAAM,aAAa,KAAK;AACxB,YAAM,OAAO,WAAW,SAAS;AACjC,UAAI,yBAAyB,MAAM,UAAU,EAAG;AAEhD,YAAM,QAAQ,IAAI;AAClB,UAAI,QAAQ,MAAM,SAAS,SAAS;AACpC,UAAI,CAAC,OAAO;AACV,YAAI,EAAE,cAAc,SAAS;AAC7B,gBAAQ,IAAI,EAAE,SAAS,SAAS;AAAA,MAClC;AACA,YAAM,UAAU,WAAW,MAAM,MAAM,OAAO,MAAM,YAAY,UAAU;AAC1E,YAAM,WACJ,aACI,EAAE,GAAG,SAAS,MAAM,EAAE,GAAG,QAAQ,MAAM,aAAa,WAAW,EAAE,IACjE;AACN,YAAM,YAA0B;AAAA,QAC9B,MAAM;AAAA,QACN,YAAY,MAAM,aAAa;AAAA,MACjC;AACA,sBAAgB,MAAM,UAAU;AAChC,UAAI,WAAW,EAAE,GAAG,MAAM,UAAU,CAAC,SAAS,GAAG,UAAU;AAC3D,UAAI,QAAQ,WAAW,MAAM,OAAO,SAAS;AAC7C,OAAC,EAAE,UAAU,MAAM,IAAI,cAAc,UAAU,OAAO,aAAa,MAAM,eAAe;AACxF,UAAI,EAAE,UAAU,MAAM,CAAC;AAAA,IACzB;AAAA,IAEA,YAAY,WAAW,QAAQ;AAC7B,iBAAW,SAAS,QAAQ;AAC1B,YAAI,EAAE,WAAW,WAAW,KAAK;AAAA,MACnC;AAAA,IACF;AAAA,IAEA,mBAAmB,IAAI;AACrB,UAAI,EAAE,iBAAiB,GAAG,CAAC;AAAA,IAC7B;AAAA,IAEA,cAAc,WAAW;AACvB,YAAM,QAAQ,IAAI;AAClB,UAAI,CAAC,MAAM,SAAS,SAAS,EAAG;AAChC,oBAAc,OAAO,SAAS;AAC9B,YAAM,EAAE,CAAC,SAAS,GAAG,UAAU,GAAG,SAAS,IAAI,MAAM;AACrD,YAAM,QAAQ,MAAM,MAAM,OAAO,CAAC,OAAO,OAAO,SAAS;AACzD,YAAM,kBACJ,MAAM,oBAAoB,YACrB,MAAM,MAAM,SAAS,CAAC,KAAK,OAC5B,MAAM;AACZ,UAAI,EAAE,UAAU,OAAO,gBAAgB,CAAC;AAAA,IAC1C;AAAA,IAEA,cAAc,WAAW,QAAQ;AAC/B,YAAM,OAAO,aAAa,QAAQ,UAAU;AAC5C,YAAM,QAAsB,EAAE,MAAM,YAAY,OAAO,OAAO;AAC9D,YAAM,QAAQ,IAAI;AAClB,UAAI,QAAQ,WAAW,MAAM,OAAO,SAAS;AAC7C,UAAI,WAAW,EAAE,GAAG,MAAM,UAAU,CAAC,SAAS,GAAG,MAAM;AACvD,OAAC,EAAE,UAAU,MAAM,IAAI,cAAc,UAAU,OAAO,aAAa,MAAM,eAAe;AACxF,UAAI,EAAE,UAAU,MAAM,CAAC;AAAA,IACzB;AAAA,EACF,EAAE;AACJ;AAKO,SAAS,0BAA0B,YAA4D;AAGpG,QAAM,SAAS,YAAyB,OAAO;AAAA,IAC7C,MAAM,gBAAgB;AAAA,IACtB,YAAY;AAAA,IACZ,WAAW,OAAO,KAAK;AACrB,YAAM,KAAK,WAAW,SAAS,EAAE;AACjC,UAAI,GAAI,YAAW,SAAS,EAAE,WAAW,IAAI,OAAO,GAAG;AAAA,IACzD;AAAA,IACA,YAAY,QAAQ;AAClB,YAAM,KAAK,WAAW,SAAS,EAAE;AACjC,UAAI,GAAI,YAAW,SAAS,EAAE,YAAY,IAAI,MAAM;AAAA,IACtD;AAAA,IACA,QAAQ;AACN,YAAM,KAAK,WAAW,SAAS,EAAE;AACjC,UAAI,GAAI,YAAW,SAAS,EAAE,cAAc,IAAI,CAAC,CAAC;AAAA,IACpD;AAAA,EACF,EAAE;AAEF,QAAM,OAAO,MAAY;AACvB,UAAM,EAAE,iBAAiB,SAAS,IAAI,WAAW,SAAS;AAC1D,UAAM,QAAQ,kBAAkB,SAAS,eAAe,IAAI;AAC5D,WAAO,SAAS;AAAA,MACd,MAAM,OAAO,QAAQ,gBAAgB;AAAA,MACrC,YAAY,OAAO,cAAc;AAAA,IACnC,CAAC;AAAA,EACH;AAEA,aAAW,UAAU,IAAI;AACzB,OAAK;AACL,SAAO;AACT;;;AE/OA,SAAS,aAAAE,YAAW,WAAAC,UAAS,UAAAC,eAA8B;AAsErD,SACA,OAAAC,OADA,QAAAC,aAAA;AANN,SAAS,aAAa;AACpB,QAAM,SAAS,iBAAiB;AAChC,QAAM,SAAS,kBAAkB;AACjC,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SACE,gBAAAA,MAAC,SAAI,WAAU,mBAAkB,eAAY,mBAC3C;AAAA,oBAAAA,MAAC,SAAI;AAAA;AAAA,MAAS;AAAA,OAAO;AAAA,IACrB,gBAAAD,MAAC,QACE,iBAAO,IAAI,CAAC,KAAmB,MAC9B,gBAAAC,MAAC,QAAkC;AAAA;AAAA,MAC/B,IAAI;AAAA,MAAU;AAAA,MAAG,IAAI;AAAA,SADhB,GAAG,IAAI,UAAU,IAAI,CAAC,EAE/B,CACD,GACH;AAAA,KACF;AAEJ;AAEO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,gBAAgBC,QAAiC,IAAI;AAC3D,QAAM,YAAYA,QAA4D,IAAI;AAElF,MAAI,cAAc,YAAY,MAAM;AAClC,UAAM,YACJ,0BACA,sBACA,SAAS,CAAC,GAAG,aACb;AACF,kBAAc,UAAU,wBAAwB;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,IACnB,CAAC;AACD,cAAU,UAAU,0BAA0B,cAAc,OAAO;AACnE,eAAW,OAAO,UAAU;AAC1B,oBAAc,QAAQ,SAAS,EAAE,cAAc,IAAI,WAAW,IAAI,aAAa;AAAA,IACjF;AAAA,EACF;AAEA,QAAM,cAAcC,SAAQ,MAAM,YAAY,sBAAsB,GAAG,CAAC,QAAQ,CAAC;AACjF,QAAM,SAASA;AAAA,IACb,MAAM,kBAAkB,sBAAsB;AAAA,IAC9C,CAAC,cAAc;AAAA,EACjB;AACA,QAAM,iBAAiBA;AAAA,IACrB,OAAO;AAAA,MACL,UAAU,uBAAuB,0BAA0B;AAAA,MAC3D;AAAA,IACF;AAAA,IACA,CAAC,qBAAqB,eAAe;AAAA,EACvC;AACA,QAAM,iBAAiBA;AAAA,IACrB,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,IACpB;AAAA,IACA,CAAC,oBAAoB,kBAAkB,KAAK;AAAA,EAC9C;AAEA,EAAAC,WAAU,MAAM;AACd,QAAI,uBAAuB,OAAW;AACtC,kBAAc,QAAS,SAAS,EAAE,mBAAmB,kBAAkB;AAAA,EACzE,GAAG,CAAC,kBAAkB,CAAC;AAEvB,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,sBAAuB;AAC5B,WAAO,cAAc,QAAS,UAAU,CAAC,UAAU;AACjD,4BAAsB,MAAM,eAAe;AAAA,IAC7C,CAAC;AAAA,EACH,GAAG,CAAC,qBAAqB,CAAC;AAE1B,EAAAA,WAAU,MAAM;AACd,UAAM,aAAa,cAAc;AACjC,UAAM,cAAc,SAAS,IAAI,CAAC,QAAQ;AACxC,YAAM,aAAa,IAAI,gBAAgB;AACvC,iBAAW,SAAS,EAAE,cAAc,IAAI,WAAW,IAAI,aAAa;AACpE,WAAK,IAAI,OAAO,MAAM,CAAC,OAAO,QAAQ;AACpC,mBAAW,SAAS,EAAE,WAAW,IAAI,WAAW,OAAO,GAAG;AAAA,MAC5D,GAAG,WAAW,MAAM,EAAE,MAAM,CAAC,QAAiB;AAC5C,cAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAChE,kBAAU,OAAO,IAAI,SAAS;AAAA,MAChC,CAAC;AACD,aAAO;AAAA,IACT,CAAC;AACD,WAAO,MAAM;AACX,iBAAW,KAAK,YAAa,GAAE,MAAM;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,UAAU,OAAO,CAAC;AAEtB,SACE,gBAAAJ,MAAC,yBAAyB,UAAzB,EAAkC,OAAO,cAAc,SACtD,0BAAAA,MAAC,oBAAoB,UAApB,EAA6B,OAAO,UAAU,SAC7C,0BAAAA,MAAC,sBAAsB,UAAtB,EAA+B,OAAO,QACrC,0BAAAA,MAAC,oBAAoB,UAApB,EAA6B,OAAO,aACnC,0BAAAA,MAAC,wBAAwB,UAAxB,EAAiC,OAAO,kBACvC,0BAAAA,MAAC,0BAA0B,UAA1B,EAAmC,OAAO,gBACzC,0BAAAA,MAAC,0BAA0B,UAA1B,EAAmC,OAAO,gBACzC,0BAAAC,MAAC,SAAI,WAAU,6CAA4C,eAAY,2BACpE;AAAA,gBACC,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,IAED,QAAQ,gBAAAA,MAAC,cAAW,IAAK;AAAA,KAC5B,GACF,GACF,GACF,GACF,GACF,GACF,GACF;AAEJ;","names":["jsx","jsxs","jsx","jsxs","useState","jsx","useState","jsx","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","useState","jsx","jsxs","useEffect","useMemo","useRef","jsx","jsxs","useRef","useMemo","useEffect"]}