@cdoing/opentuicli 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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/context/theme.tsx", "../src/context/sdk.tsx", "../src/components/toast.tsx", "../src/lib/autocomplete.ts", "../src/components/input-area.tsx", "../src/routes/home.tsx", "../src/components/message-list.tsx", "../src/components/permission-prompt.tsx", "../src/components/loading-spinner.tsx", "../src/lib/terminal-title.ts", "../src/lib/history.ts", "../src/lib/context-providers.ts", "../src/routes/session.tsx", "../src/components/status-bar.tsx", "../src/components/session-header.tsx", "../src/components/session-footer.tsx", "../src/components/sidebar.tsx", "../src/components/dialog-model.tsx", "../src/components/dialog-command.tsx", "../src/components/dialog-help.tsx", "../src/components/dialog-theme.tsx", "../src/components/session-browser.tsx", "../src/components/setup-wizard.tsx", "../src/components/dialog-status.tsx", "../src/app.tsx", "../src/index.ts"],
4
+ "sourcesContent": ["/**\n * Theme Context \u2014 Multi-theme system for the TUI\n *\n * Supports 15+ built-in themes inspired by popular editor themes.\n * Each theme has dark and light variants with full color palettes.\n *\n * Detection:\n * 1. OSC 11 escape sequence (queries terminal directly)\n * 2. COLORFGBG environment variable (fallback)\n * 3. Defaults to dark mode\n */\n\nimport { RGBA, rgbToHex, SyntaxStyle } from \"@opentui/core\";\nimport { createContext, useContext, useState, useEffect, useRef, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nexport interface Theme {\n text: RGBA;\n textMuted: RGBA;\n textDim: RGBA;\n primary: RGBA;\n secondary: RGBA;\n success: RGBA;\n error: RGBA;\n warning: RGBA;\n info: RGBA;\n border: RGBA;\n borderFocused: RGBA;\n bg: RGBA;\n bgSubtle: RGBA;\n // Roles\n userText: RGBA;\n assistantText: RGBA;\n systemText: RGBA;\n toolText: RGBA;\n // Tool status\n toolRunning: RGBA;\n toolDone: RGBA;\n toolError: RGBA;\n // Diff\n diffAdd: RGBA;\n diffRemove: RGBA;\n diffHunk: RGBA;\n}\n\n// \u2500\u2500 Theme Definitions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface ThemeDef {\n name: string;\n dark: Theme;\n light: Theme;\n}\n\nfunction t(hex: string): RGBA {\n return RGBA.fromHex(hex);\n}\n\n/** Helper to build a full theme from a minimal palette */\nfunction buildTheme(p: {\n bg: string; bgSubtle: string; text: string; textMuted: string; textDim: string;\n primary: string; secondary: string; success: string; error: string;\n warning: string; info: string; border: string;\n diffAdd?: string; diffRemove?: string;\n}): Theme {\n return {\n text: t(p.text), textMuted: t(p.textMuted), textDim: t(p.textDim),\n primary: t(p.primary), secondary: t(p.secondary),\n success: t(p.success), error: t(p.error), warning: t(p.warning), info: t(p.info),\n border: t(p.border), borderFocused: t(p.primary),\n bg: t(p.bg), bgSubtle: t(p.bgSubtle),\n userText: t(p.success), assistantText: t(p.text),\n systemText: t(p.warning), toolText: t(p.textMuted),\n toolRunning: t(p.warning), toolDone: t(p.success), toolError: t(p.error),\n diffAdd: t(p.diffAdd || p.success), diffRemove: t(p.diffRemove || p.error),\n diffHunk: t(p.info),\n };\n}\n\n// \u2500\u2500 Built-in Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const THEMES: Record<string, ThemeDef> = {\n default: {\n name: \"Default\",\n dark: buildTheme({\n bg: \"#000000\", bgSubtle: \"#111111\", text: \"#e5e7eb\", textMuted: \"#9ca3af\", textDim: \"#6b7280\",\n primary: \"#06b6d4\", secondary: \"#8b5cf6\", success: \"#22c55e\", error: \"#ef4444\",\n warning: \"#eab308\", info: \"#3b82f6\", border: \"#374151\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f3f4f6\", text: \"#1f2937\", textMuted: \"#6b7280\", textDim: \"#9ca3af\",\n primary: \"#0891b2\", secondary: \"#7c3aed\", success: \"#16a34a\", error: \"#dc2626\",\n warning: \"#ca8a04\", info: \"#2563eb\", border: \"#d1d5db\",\n }),\n },\n catppuccin: {\n name: \"Catppuccin\",\n dark: buildTheme({\n bg: \"#1e1e2e\", bgSubtle: \"#313244\", text: \"#cdd6f4\", textMuted: \"#a6adc8\", textDim: \"#6c7086\",\n primary: \"#89b4fa\", secondary: \"#cba6f7\", success: \"#a6e3a1\", error: \"#f38ba8\",\n warning: \"#f9e2af\", info: \"#74c7ec\", border: \"#45475a\",\n }),\n light: buildTheme({\n bg: \"#eff1f5\", bgSubtle: \"#e6e9ef\", text: \"#4c4f69\", textMuted: \"#6c6f85\", textDim: \"#9ca0b0\",\n primary: \"#1e66f5\", secondary: \"#8839ef\", success: \"#40a02b\", error: \"#d20f39\",\n warning: \"#df8e1d\", info: \"#04a5e5\", border: \"#ccd0da\",\n }),\n },\n dracula: {\n name: \"Dracula\",\n dark: buildTheme({\n bg: \"#282a36\", bgSubtle: \"#44475a\", text: \"#f8f8f2\", textMuted: \"#6272a4\", textDim: \"#44475a\",\n primary: \"#bd93f9\", secondary: \"#ff79c6\", success: \"#50fa7b\", error: \"#ff5555\",\n warning: \"#f1fa8c\", info: \"#8be9fd\", border: \"#44475a\",\n }),\n light: buildTheme({\n bg: \"#f8f8f2\", bgSubtle: \"#e6e6e6\", text: \"#282a36\", textMuted: \"#6272a4\", textDim: \"#999999\",\n primary: \"#7c3aed\", secondary: \"#d946ef\", success: \"#16a34a\", error: \"#dc2626\",\n warning: \"#ca8a04\", info: \"#0891b2\", border: \"#d1d5db\",\n }),\n },\n nord: {\n name: \"Nord\",\n dark: buildTheme({\n bg: \"#2e3440\", bgSubtle: \"#3b4252\", text: \"#eceff4\", textMuted: \"#d8dee9\", textDim: \"#4c566a\",\n primary: \"#88c0d0\", secondary: \"#b48ead\", success: \"#a3be8c\", error: \"#bf616a\",\n warning: \"#ebcb8b\", info: \"#81a1c1\", border: \"#434c5e\",\n }),\n light: buildTheme({\n bg: \"#eceff4\", bgSubtle: \"#e5e9f0\", text: \"#2e3440\", textMuted: \"#4c566a\", textDim: \"#7b88a1\",\n primary: \"#5e81ac\", secondary: \"#b48ead\", success: \"#a3be8c\", error: \"#bf616a\",\n warning: \"#ebcb8b\", info: \"#81a1c1\", border: \"#d8dee9\",\n }),\n },\n tokyonight: {\n name: \"Tokyo Night\",\n dark: buildTheme({\n bg: \"#1a1b26\", bgSubtle: \"#24283b\", text: \"#c0caf5\", textMuted: \"#a9b1d6\", textDim: \"#565f89\",\n primary: \"#7aa2f7\", secondary: \"#bb9af7\", success: \"#9ece6a\", error: \"#f7768e\",\n warning: \"#e0af68\", info: \"#7dcfff\", border: \"#3b4261\",\n }),\n light: buildTheme({\n bg: \"#d5d6db\", bgSubtle: \"#cbccd1\", text: \"#343b58\", textMuted: \"#565a6e\", textDim: \"#9699a3\",\n primary: \"#34548a\", secondary: \"#5a4a78\", success: \"#485e30\", error: \"#8c4351\",\n warning: \"#8f5e15\", info: \"#0f4b6e\", border: \"#b4b5b9\",\n }),\n },\n gruvbox: {\n name: \"Gruvbox\",\n dark: buildTheme({\n bg: \"#282828\", bgSubtle: \"#3c3836\", text: \"#ebdbb2\", textMuted: \"#a89984\", textDim: \"#665c54\",\n primary: \"#fabd2f\", secondary: \"#d3869b\", success: \"#b8bb26\", error: \"#fb4934\",\n warning: \"#fe8019\", info: \"#83a598\", border: \"#504945\",\n }),\n light: buildTheme({\n bg: \"#fbf1c7\", bgSubtle: \"#f2e5bc\", text: \"#3c3836\", textMuted: \"#7c6f64\", textDim: \"#a89984\",\n primary: \"#b57614\", secondary: \"#8f3f71\", success: \"#79740e\", error: \"#9d0006\",\n warning: \"#af3a03\", info: \"#427b58\", border: \"#d5c4a1\",\n }),\n },\n rosepine: {\n name: \"Ros\u00E9 Pine\",\n dark: buildTheme({\n bg: \"#191724\", bgSubtle: \"#1f1d2e\", text: \"#e0def4\", textMuted: \"#908caa\", textDim: \"#6e6a86\",\n primary: \"#c4a7e7\", secondary: \"#ebbcba\", success: \"#31748f\", error: \"#eb6f92\",\n warning: \"#f6c177\", info: \"#9ccfd8\", border: \"#26233a\",\n }),\n light: buildTheme({\n bg: \"#faf4ed\", bgSubtle: \"#f2e9e1\", text: \"#575279\", textMuted: \"#797593\", textDim: \"#9893a5\",\n primary: \"#907aa9\", secondary: \"#d7827e\", success: \"#286983\", error: \"#b4637a\",\n warning: \"#ea9d34\", info: \"#56949f\", border: \"#dfdad9\",\n }),\n },\n monokai: {\n name: \"Monokai\",\n dark: buildTheme({\n bg: \"#272822\", bgSubtle: \"#3e3d32\", text: \"#f8f8f2\", textMuted: \"#75715e\", textDim: \"#49483e\",\n primary: \"#66d9ef\", secondary: \"#ae81ff\", success: \"#a6e22e\", error: \"#f92672\",\n warning: \"#e6db74\", info: \"#66d9ef\", border: \"#49483e\",\n }),\n light: buildTheme({\n bg: \"#fafafa\", bgSubtle: \"#f0f0f0\", text: \"#272822\", textMuted: \"#75715e\", textDim: \"#b0b0b0\",\n primary: \"#0096d1\", secondary: \"#7c3aed\", success: \"#629e25\", error: \"#c4265e\",\n warning: \"#b5a21d\", info: \"#0096d1\", border: \"#d0d0d0\",\n }),\n },\n solarized: {\n name: \"Solarized\",\n dark: buildTheme({\n bg: \"#002b36\", bgSubtle: \"#073642\", text: \"#839496\", textMuted: \"#657b83\", textDim: \"#586e75\",\n primary: \"#268bd2\", secondary: \"#6c71c4\", success: \"#859900\", error: \"#dc322f\",\n warning: \"#b58900\", info: \"#2aa198\", border: \"#073642\",\n }),\n light: buildTheme({\n bg: \"#fdf6e3\", bgSubtle: \"#eee8d5\", text: \"#657b83\", textMuted: \"#839496\", textDim: \"#93a1a1\",\n primary: \"#268bd2\", secondary: \"#6c71c4\", success: \"#859900\", error: \"#dc322f\",\n warning: \"#b58900\", info: \"#2aa198\", border: \"#eee8d5\",\n }),\n },\n amoled: {\n name: \"AMOLED\",\n dark: buildTheme({\n bg: \"#000000\", bgSubtle: \"#0a0a0a\", text: \"#ffffff\", textMuted: \"#888888\", textDim: \"#555555\",\n primary: \"#00e5ff\", secondary: \"#e040fb\", success: \"#00e676\", error: \"#ff1744\",\n warning: \"#ffea00\", info: \"#40c4ff\", border: \"#222222\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f5f5f5\", text: \"#000000\", textMuted: \"#666666\", textDim: \"#aaaaaa\",\n primary: \"#0097a7\", secondary: \"#7b1fa2\", success: \"#2e7d32\", error: \"#c62828\",\n warning: \"#f9a825\", info: \"#0277bd\", border: \"#e0e0e0\",\n }),\n },\n github: {\n name: \"GitHub\",\n dark: buildTheme({\n bg: \"#0d1117\", bgSubtle: \"#161b22\", text: \"#e6edf3\", textMuted: \"#8b949e\", textDim: \"#484f58\",\n primary: \"#58a6ff\", secondary: \"#bc8cff\", success: \"#3fb950\", error: \"#f85149\",\n warning: \"#d29922\", info: \"#58a6ff\", border: \"#30363d\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f6f8fa\", text: \"#1f2328\", textMuted: \"#656d76\", textDim: \"#8c959f\",\n primary: \"#0969da\", secondary: \"#8250df\", success: \"#1a7f37\", error: \"#cf222e\",\n warning: \"#9a6700\", info: \"#0969da\", border: \"#d0d7de\",\n }),\n },\n material: {\n name: \"Material\",\n dark: buildTheme({\n bg: \"#263238\", bgSubtle: \"#37474f\", text: \"#eeffff\", textMuted: \"#b0bec5\", textDim: \"#546e7a\",\n primary: \"#82aaff\", secondary: \"#c792ea\", success: \"#c3e88d\", error: \"#ff5370\",\n warning: \"#ffcb6b\", info: \"#89ddff\", border: \"#37474f\",\n }),\n light: buildTheme({\n bg: \"#fafafa\", bgSubtle: \"#eeeeee\", text: \"#90a4ae\", textMuted: \"#546e7a\", textDim: \"#b0bec5\",\n primary: \"#6182b8\", secondary: \"#7c4dff\", success: \"#91b859\", error: \"#e53935\",\n warning: \"#f76d47\", info: \"#39adb5\", border: \"#d0d0d0\",\n }),\n },\n synthwave: {\n name: \"Synthwave '84\",\n dark: buildTheme({\n bg: \"#262335\", bgSubtle: \"#34294f\", text: \"#ffffff\", textMuted: \"#bbbbbb\", textDim: \"#6d5da0\",\n primary: \"#ff7edb\", secondary: \"#36f9f6\", success: \"#72f1b8\", error: \"#fe4450\",\n warning: \"#fede5d\", info: \"#36f9f6\", border: \"#495495\",\n }),\n light: buildTheme({\n bg: \"#f5f0ff\", bgSubtle: \"#e8e0f0\", text: \"#262335\", textMuted: \"#6d5da0\", textDim: \"#a090c0\",\n primary: \"#b03090\", secondary: \"#108888\", success: \"#308050\", error: \"#c03030\",\n warning: \"#a08000\", info: \"#207080\", border: \"#d0c8e0\",\n }),\n },\n everforest: {\n name: \"Everforest\",\n dark: buildTheme({\n bg: \"#2d353b\", bgSubtle: \"#343f44\", text: \"#d3c6aa\", textMuted: \"#859289\", textDim: \"#5c6a72\",\n primary: \"#a7c080\", secondary: \"#d699b6\", success: \"#a7c080\", error: \"#e67e80\",\n warning: \"#dbbc7f\", info: \"#7fbbb3\", border: \"#475258\",\n }),\n light: buildTheme({\n bg: \"#fdf6e3\", bgSubtle: \"#f3efda\", text: \"#5c6a72\", textMuted: \"#829181\", textDim: \"#a6b0a0\",\n primary: \"#8da101\", secondary: \"#df69ba\", success: \"#8da101\", error: \"#f85552\",\n warning: \"#dfa000\", info: \"#35a77c\", border: \"#e0dcc7\",\n }),\n },\n cobalt2: {\n name: \"Cobalt2\",\n dark: buildTheme({\n bg: \"#193549\", bgSubtle: \"#1f4662\", text: \"#ffffff\", textMuted: \"#8db0cc\", textDim: \"#4d7ea0\",\n primary: \"#ffc600\", secondary: \"#ff9d00\", success: \"#3ad900\", error: \"#ff628c\",\n warning: \"#ffc600\", info: \"#80fcff\", border: \"#2a5a7a\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f0f0f0\", text: \"#193549\", textMuted: \"#4d7ea0\", textDim: \"#8db0cc\",\n primary: \"#b88d00\", secondary: \"#cc7a00\", success: \"#2ba600\", error: \"#cc4e70\",\n warning: \"#b88d00\", info: \"#0090a0\", border: \"#d0d0d0\",\n }),\n },\n};\n\n/** Get sorted list of theme IDs */\nexport function getThemeIds(): string[] {\n return Object.keys(THEMES).sort((a, b) => {\n if (a === \"default\") return -1;\n if (b === \"default\") return 1;\n return a.localeCompare(b);\n });\n}\n\n/** Get theme by ID and mode */\nexport function getThemeColors(themeId: string, mode: \"dark\" | \"light\"): Theme {\n const def = THEMES[themeId] || THEMES[\"default\"];\n return mode === \"light\" ? def.light : def.dark;\n}\n\n// \u2500\u2500 Terminal detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction luminance(r: number, g: number, b: number): number {\n const [rs, gs, bs] = [r, g, b].map((c) => {\n const s = c / 255;\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\nfunction queryTerminalBackground(): Promise<{ r: number; g: number; b: number } | null> {\n return new Promise((resolve) => {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n resolve(null);\n return;\n }\n const timeout = setTimeout(() => { cleanup(); resolve(null); }, 500);\n let buf = \"\";\n const onData = (data: Buffer) => {\n buf += data.toString();\n const match = buf.match(\n /\\x1b\\]11;rgb:([0-9a-fA-F]{2,4})\\/([0-9a-fA-F]{2,4})\\/([0-9a-fA-F]{2,4})/\n );\n if (match) {\n cleanup();\n const parse = (hex: string) =>\n hex.length <= 2 ? parseInt(hex, 16) : Math.round((parseInt(hex, 16) / 65535) * 255);\n resolve({ r: parse(match[1]), g: parse(match[2]), b: parse(match[3]) });\n }\n };\n const cleanup = () => {\n clearTimeout(timeout);\n process.stdin.removeListener(\"data\", onData);\n if (wasRaw === false) process.stdin.setRawMode(false);\n };\n const wasRaw = process.stdin.isRaw;\n try { process.stdin.setRawMode(true); } catch { resolve(null); return; }\n process.stdin.on(\"data\", onData);\n process.stdout.write(\"\\x1b]11;?\\x07\");\n });\n}\n\nfunction detectThemeFromEnv(): \"dark\" | \"light\" {\n const bg = process.env.COLORFGBG;\n if (bg) {\n const parts = bg.split(\";\");\n const bgVal = parseInt(parts[parts.length - 1] || \"0\", 10);\n if (bgVal > 8) return \"light\";\n }\n return \"dark\";\n}\n\nlet _detectedMode: \"dark\" | \"light\" | null = null;\n\nexport async function detectTerminalTheme(): Promise<\"dark\" | \"light\"> {\n if (_detectedMode) return _detectedMode;\n const rgb = await queryTerminalBackground();\n if (rgb) {\n const lum = luminance(rgb.r, rgb.g, rgb.b);\n _detectedMode = lum > 0.5 ? \"light\" : \"dark\";\n } else {\n _detectedMode = detectThemeFromEnv();\n }\n return _detectedMode;\n}\n\nexport function setTerminalBackground(color: RGBA): void {\n if (!process.stdout.isTTY) return;\n const hex = rgbToHex(color);\n process.stdout.write(`\\x1b]11;${hex}\\x07`);\n}\n\nexport function restoreTerminalBackground(): void {\n if (!process.stdout.isTTY) return;\n process.stdout.write(\"\\x1b]111;\\x07\");\n}\n\n// \u2500\u2500 Syntax Style Generation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction generateSyntaxStyle(theme: Theme): SyntaxStyle {\n return SyntaxStyle.fromStyles({\n // Default text\n \"default\": { fg: theme.text },\n // Markdown-specific scopes (used by <markdown> component)\n \"markup.heading.1\": { fg: theme.primary, bold: true },\n \"markup.heading.2\": { fg: theme.primary, bold: true },\n \"markup.heading.3\": { fg: theme.info, bold: true },\n \"markup.heading.4\": { fg: theme.info, bold: true },\n \"markup.heading.5\": { fg: theme.info },\n \"markup.heading.6\": { fg: theme.info },\n \"markup.bold\": { bold: true },\n \"markup.italic\": { italic: true },\n \"markup.list\": { fg: theme.warning },\n \"markup.link\": { fg: theme.info, underline: true },\n \"markup.raw\": { fg: theme.warning },\n \"markup.quote\": { fg: theme.textMuted, italic: true },\n // Code block syntax highlighting\n \"keyword\": { fg: theme.secondary, bold: true },\n \"keyword.control\": { fg: theme.secondary, bold: true },\n \"keyword.operator\": { fg: theme.secondary },\n \"string\": { fg: theme.success },\n \"string.quoted\": { fg: theme.success },\n \"comment\": { fg: theme.textDim, italic: true },\n \"comment.line\": { fg: theme.textDim, italic: true },\n \"comment.block\": { fg: theme.textDim, italic: true },\n \"constant\": { fg: theme.warning },\n \"constant.numeric\": { fg: theme.warning },\n \"number\": { fg: theme.warning },\n \"variable\": { fg: theme.text },\n \"variable.parameter\": { fg: theme.text },\n \"function\": { fg: theme.info },\n \"entity.name.function\": { fg: theme.info },\n \"support.function\": { fg: theme.info },\n \"type\": { fg: theme.primary },\n \"entity.name.type\": { fg: theme.primary },\n \"support.type\": { fg: theme.primary },\n \"operator\": { fg: theme.textMuted },\n \"punctuation\": { fg: theme.textMuted },\n });\n}\n\n// \u2500\u2500 Theme Context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ThemeContext = createContext<{\n theme: Theme;\n themeId: string;\n mode: \"dark\" | \"light\";\n syntaxStyle: SyntaxStyle;\n customBg: string | null;\n setThemeId: (id: string) => void;\n setMode: (m: \"dark\" | \"light\") => void;\n setCustomBg: (hex: string | null) => void;\n syncTerminalBg: boolean;\n setSyncTerminalBg: (sync: boolean) => void;\n} | undefined>(undefined);\n\nexport function ThemeProvider(props: {\n mode?: string;\n themeId?: string;\n syncTerminalBg?: boolean;\n detectedMode?: \"dark\" | \"light\";\n children: ReactNode;\n}) {\n const initialMode: \"dark\" | \"light\" =\n props.mode === \"light\" ? \"light\"\n : props.mode === \"auto\" ? (props.detectedMode || \"dark\")\n : \"dark\";\n\n const initialThemeId = props.themeId || \"default\";\n\n const [themeId, setThemeIdState] = useState(initialThemeId);\n const [currentMode, setCurrentMode] = useState<\"dark\" | \"light\">(initialMode);\n const [theme, setTheme] = useState<Theme>(getThemeColors(initialThemeId, initialMode));\n const [syncBg, setSyncBg] = useState(props.syncTerminalBg ?? false);\n const [customBg, setCustomBgState] = useState<string | null>(null);\n\n // Refs to avoid stale closures \u2014 always read current values\n const syncBgRef = useRef(syncBg);\n syncBgRef.current = syncBg;\n const customBgRef = useRef(customBg);\n customBgRef.current = customBg;\n const modeRef = useRef(currentMode);\n modeRef.current = currentMode;\n const themeIdRef = useRef(themeId);\n themeIdRef.current = themeId;\n\n /** Apply terminal background to match theme \u2014 always call after setTheme */\n const applyTerminalBg = (colors: Theme) => {\n if (!syncBgRef.current) return;\n if (customBgRef.current) {\n setTerminalBackground(RGBA.fromHex(customBgRef.current));\n } else {\n setTerminalBackground(colors.bg);\n }\n };\n\n const setThemeId = (id: string) => {\n setThemeIdState(id);\n themeIdRef.current = id;\n const colors = getThemeColors(id, modeRef.current);\n setTheme(colors);\n applyTerminalBg(colors);\n };\n\n const setMode = (m: \"dark\" | \"light\") => {\n setCurrentMode(m);\n modeRef.current = m;\n const colors = getThemeColors(themeIdRef.current, m);\n setTheme(colors);\n applyTerminalBg(colors);\n };\n\n const setCustomBg = (hex: string | null) => {\n setCustomBgState(hex);\n customBgRef.current = hex;\n if (!syncBgRef.current) return;\n if (hex) {\n setTerminalBackground(RGBA.fromHex(hex));\n } else {\n setTerminalBackground(getThemeColors(themeIdRef.current, modeRef.current).bg);\n }\n };\n\n const setSyncTerminalBg = (sync: boolean) => {\n setSyncBg(sync);\n syncBgRef.current = sync;\n if (sync) {\n const colors = getThemeColors(themeIdRef.current, modeRef.current);\n applyTerminalBg(colors);\n } else {\n restoreTerminalBackground();\n }\n };\n\n // Sync terminal bg on mount \u2014 force it immediately\n useEffect(() => {\n if (syncBgRef.current) {\n const colors = getThemeColors(initialThemeId, initialMode);\n applyTerminalBg(colors);\n }\n return () => {\n if (syncBgRef.current) restoreTerminalBackground();\n };\n }, []);\n\n const syntaxStyle = useMemo(() => generateSyntaxStyle(theme), [theme]);\n\n return (\n <ThemeContext.Provider value={{ theme, themeId, mode: currentMode, syntaxStyle, customBg, setThemeId, setMode, setCustomBg, syncTerminalBg: syncBg, setSyncTerminalBg }}>\n {props.children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme() {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error(\"useTheme must be used within ThemeProvider\");\n return ctx;\n}\n", "/**\n * SDK Context \u2014 wraps AgentRunner, ToolRegistry, PermissionManager,\n * and exposes callbacks for runtime model/provider changes and agent rebuild.\n */\n\nimport { createContext, useContext } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { AgentRunner } from \"@cdoing/ai\";\nimport type { ToolRegistry, PermissionManager } from \"@cdoing/core\";\n\nexport interface SDKState {\n agent: AgentRunner;\n registry: ToolRegistry;\n permissionManager: PermissionManager;\n workingDir: string;\n provider: string;\n model: string;\n /** Request a permission decision from the UI */\n requestPermission?: (toolName: string, message: string) => Promise<\"allow\" | \"always\" | \"deny\">;\n /** Rebuild the agent after model/provider change */\n rebuildAgent?: (provider: string, model: string, apiKey?: string) => void;\n /** Change working directory */\n setWorkingDir?: (dir: string) => void;\n}\n\nconst SDKContext = createContext<SDKState | undefined>(undefined);\n\nexport function SDKProvider(props: { value: SDKState; children: ReactNode }) {\n return (\n <SDKContext.Provider value={props.value}>\n {props.children}\n </SDKContext.Provider>\n );\n}\n\nexport function useSDK() {\n const ctx = useContext(SDKContext);\n if (!ctx) throw new Error(\"useSDK must be used within SDKProvider\");\n return ctx;\n}\n", "/**\n * Toast Notification System \u2014 transient notifications for the TUI\n *\n * Provides a ToastProvider context and useToast hook for showing\n * auto-dismissing notifications with type-based styling.\n */\n\nimport { createContext, useContext, useState, useEffect, useCallback, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useTheme } from \"../context/theme\";\nimport type { Theme } from \"../context/theme\";\nimport type { RGBA } from \"@opentui/core\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ToastType = \"info\" | \"success\" | \"warning\" | \"error\";\n\ninterface ToastItem {\n id: number;\n type: ToastType;\n message: string;\n duration: number;\n}\n\ninterface ToastContextValue {\n toast: (type: ToastType, message: string, duration?: number) => void;\n}\n\n// \u2500\u2500 Icons & Colors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TOAST_ICONS: Record<ToastType, string> = {\n info: \"\\u2139\", // i\n success: \"\\u2713\", // checkmark\n warning: \"\\u26A0\", // warning sign\n error: \"\\u2717\", // x mark\n};\n\nfunction getToastColor(type: ToastType, theme: Theme): RGBA {\n switch (type) {\n case \"info\": return theme.info;\n case \"success\": return theme.success;\n case \"warning\": return theme.warning;\n case \"error\": return theme.error;\n }\n}\n\n// \u2500\u2500 Context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\nconst DEFAULT_DURATION = 3000;\nconst MAX_VISIBLE = 3;\n\n// \u2500\u2500 Provider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function ToastProvider(props: { children: ReactNode }) {\n const { theme } = useTheme();\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n const idRef = useRef(0);\n const timersRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());\n\n const removeToast = useCallback((id: number) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n const timer = timersRef.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(id);\n }\n }, []);\n\n const toast = useCallback((type: ToastType, message: string, duration?: number) => {\n const id = ++idRef.current;\n const dur = duration ?? DEFAULT_DURATION;\n const item: ToastItem = { id, type, message, duration: dur };\n\n setToasts((prev) => {\n const next = [...prev, item];\n // Keep only the most recent MAX_VISIBLE toasts\n if (next.length > MAX_VISIBLE) {\n const removed = next.splice(0, next.length - MAX_VISIBLE);\n // Clean up timers for removed toasts\n for (const r of removed) {\n const timer = timersRef.current.get(r.id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(r.id);\n }\n }\n }\n return next;\n });\n\n // Set auto-dismiss timer\n const timer = setTimeout(() => {\n removeToast(id);\n }, dur);\n timersRef.current.set(id, timer);\n }, [removeToast]);\n\n // Clean up all timers on unmount\n useEffect(() => {\n return () => {\n for (const timer of timersRef.current.values()) {\n clearTimeout(timer);\n }\n timersRef.current.clear();\n };\n }, []);\n\n return (\n <ToastContext.Provider value={{ toast }}>\n {props.children}\n {/* Toast overlay \u2014 positioned at the bottom, above status bar */}\n {toasts.length > 0 && (\n <box flexDirection=\"column\" alignItems=\"flex-end\">\n {toasts.map((t) => {\n const color = getToastColor(t.type, theme);\n const icon = TOAST_ICONS[t.type];\n return (\n <box key={t.id} height={1} flexDirection=\"row\" justifyContent=\"flex-end\">\n <text fg={color}>{` ${icon} `}</text>\n <text fg={theme.text}>{t.message}</text>\n <text fg={theme.textDim}>{\" \"}</text>\n </box>\n );\n })}\n </box>\n )}\n </ToastContext.Provider>\n );\n}\n\n// \u2500\u2500 Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within ToastProvider\");\n return ctx;\n}\n", "/**\n * Autocomplete engine \u2014 slash commands, @mentions, path completion, tool subcommands\n *\n * Ported from @cdoing/cli UserInput.tsx logic for the OpenTUI terminal.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n// \u2500\u2500 Slash Commands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SlashCommand {\n name: string;\n description: string;\n}\n\nexport const SLASH_COMMANDS: SlashCommand[] = [\n { name: \"/help\", description: \"Show available commands\" },\n { name: \"/clear\", description: \"Clear chat history\" },\n { name: \"/new\", description: \"Start new conversation\" },\n { name: \"/model\", description: \"Show/change model\" },\n { name: \"/provider\", description: \"Show/change provider\" },\n { name: \"/mode\", description: \"Cycle permission mode\" },\n { name: \"/usage\", description: \"Show token usage & cost\" },\n { name: \"/compact\", description: \"Compress context\" },\n { name: \"/config\", description: \"Show/set configuration\" },\n { name: \"/dir\", description: \"Change working directory\" },\n { name: \"/history\", description: \"Browse past sessions\" },\n { name: \"/ls\", description: \"List conversations\" },\n { name: \"/resume\", description: \"Resume conversation by ID\" },\n { name: \"/view\", description: \"View a conversation\" },\n { name: \"/fork\", description: \"Fork current conversation\" },\n { name: \"/delete\", description: \"Delete a conversation\" },\n { name: \"/plan\", description: \"Toggle plan mode\" },\n { name: \"/tasks\", description: \"Show active tasks\" },\n { name: \"/memory\", description: \"Show agent memory\" },\n { name: \"/permissions\", description: \"Show permission rules\" },\n { name: \"/hooks\", description: \"Show configured hooks\" },\n { name: \"/rules\", description: \"Show project rules\" },\n { name: \"/mcp\", description: \"MCP server management\" },\n { name: \"/context\", description: \"Show context providers\" },\n { name: \"/effort\", description: \"Set effort level\" },\n { name: \"/theme\", description: \"Switch theme\" },\n { name: \"/bg\", description: \"Run in background\" },\n { name: \"/jobs\", description: \"Show background jobs\" },\n { name: \"/login\", description: \"OAuth login\" },\n { name: \"/logout\", description: \"OAuth logout\" },\n { name: \"/setup\", description: \"Run setup wizard\" },\n { name: \"/doctor\", description: \"Check system health\" },\n { name: \"/init\", description: \"Initialize project config\" },\n { name: \"/exit\", description: \"Quit the TUI\" },\n { name: \"/quit\", description: \"Quit the TUI\" },\n { name: \"/btw\", description: \"Ask without adding to history\" },\n { name: \"/auth-status\", description: \"Show authentication status\" },\n { name: \"/queue\", description: \"Show message queue\" },\n];\n\n// \u2500\u2500 @Mention Providers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MentionProvider {\n trigger: string;\n description: string;\n}\n\nexport const MENTION_PROVIDERS: MentionProvider[] = [\n { trigger: \"@terminal\", description: \"Recent terminal output\" },\n { trigger: \"@url\", description: \"Fetch URL content\" },\n { trigger: \"@tree\", description: \"Project file tree\" },\n { trigger: \"@codebase\", description: \"Full codebase context\" },\n { trigger: \"@clip\", description: \"Clipboard content\" },\n { trigger: \"@file\", description: \"Include a file\" },\n];\n\n// \u2500\u2500 Tool Subcommands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TOOL_SUBCOMMANDS: Record<string, string[]> = {\n npm: [\"install\", \"run\", \"test\", \"start\", \"build\", \"init\", \"publish\", \"uninstall\", \"update\", \"ls\", \"audit\", \"ci\"],\n yarn: [\"install\", \"add\", \"remove\", \"run\", \"build\", \"test\", \"start\", \"dev\", \"upgrade\", \"info\", \"why\"],\n pnpm: [\"install\", \"add\", \"remove\", \"run\", \"build\", \"test\", \"dev\", \"update\", \"store\"],\n bun: [\"install\", \"add\", \"remove\", \"run\", \"build\", \"test\", \"dev\", \"init\", \"create\"],\n git: [\"status\", \"add\", \"commit\", \"push\", \"pull\", \"fetch\", \"checkout\", \"branch\", \"merge\", \"rebase\", \"log\", \"diff\", \"stash\", \"reset\", \"clone\", \"remote\", \"tag\", \"cherry-pick\", \"bisect\", \"show\", \"blame\", \"reflog\"],\n docker: [\"build\", \"run\", \"exec\", \"ps\", \"images\", \"pull\", \"push\", \"stop\", \"rm\", \"logs\", \"compose\"],\n python: [\"-m\", \"-c\", \"--version\", \"manage.py\"],\n python3: [\"-m\", \"-c\", \"--version\", \"manage.py\"],\n pip: [\"install\", \"uninstall\", \"freeze\", \"list\", \"show\"],\n cargo: [\"build\", \"run\", \"test\", \"check\", \"clippy\", \"fmt\", \"new\", \"init\", \"add\", \"publish\"],\n go: [\"build\", \"run\", \"test\", \"get\", \"mod\", \"fmt\", \"vet\", \"install\", \"generate\"],\n make: [\"build\", \"test\", \"clean\", \"install\", \"all\"],\n kubectl: [\"get\", \"describe\", \"apply\", \"delete\", \"logs\", \"exec\", \"port-forward\", \"scale\"],\n gh: [\"pr\", \"issue\", \"repo\", \"run\", \"release\", \"api\", \"auth\", \"browse\"],\n turbo: [\"build\", \"dev\", \"test\", \"lint\", \"run\"],\n npx: [\"tsc\", \"ts-node\", \"eslint\", \"prettier\", \"jest\", \"vitest\", \"playwright\"],\n};\n\n// \u2500\u2500 Suggestion Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Suggestion {\n text: string;\n description?: string;\n type: \"command\" | \"mention\" | \"file\" | \"subcommand\";\n}\n\n// \u2500\u2500 Autocomplete Logic \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getCompletions(input: string, workingDir: string): Suggestion[] {\n if (!input) return [];\n\n // Slash commands\n if (input.startsWith(\"/\")) {\n return SLASH_COMMANDS\n .filter((c) => c.name.startsWith(input))\n .map((c) => ({ text: c.name, description: c.description, type: \"command\" as const }));\n }\n\n // @mentions\n if (input.startsWith(\"@\") || input.includes(\" @\")) {\n const atIdx = input.lastIndexOf(\"@\");\n const query = input.substring(atIdx);\n\n const results: Suggestion[] = [];\n\n // Provider matches\n for (const p of MENTION_PROVIDERS) {\n if (p.trigger.startsWith(query)) {\n results.push({ text: p.trigger, description: p.description, type: \"mention\" });\n }\n }\n\n // File matches for @file or bare @\n if (query === \"@\" || query.startsWith(\"@file \") || query.startsWith(\"@f\")) {\n const fileQuery = query.startsWith(\"@file \") ? query.substring(6) : \"\";\n const files = getProjectFiles(workingDir, fileQuery);\n for (const f of files.slice(0, 10)) {\n results.push({ text: `@file ${f}`, description: \"\", type: \"file\" });\n }\n }\n\n return results;\n }\n\n // Tool subcommands (e.g. \"npm \" \u2192 show npm subcommands)\n const parts = input.split(\" \");\n if (parts.length >= 1) {\n const tool = parts[0];\n const subcommands = TOOL_SUBCOMMANDS[tool];\n if (subcommands && parts.length <= 2) {\n const sub = parts[1] || \"\";\n return subcommands\n .filter((s) => s.startsWith(sub))\n .map((s) => ({ text: `${tool} ${s}`, description: \"\", type: \"subcommand\" as const }));\n }\n }\n\n // Path completion for shell commands (cd, ls, cat, etc.)\n if (parts.length >= 2) {\n const pathResults = getPathCompletions(input, workingDir);\n if (pathResults.length > 0) {\n const prefix = parts.slice(0, -1).join(\" \") + \" \";\n return pathResults.map((p) => ({\n text: prefix + p,\n description: p.endsWith(\"/\") ? \"directory\" : \"file\",\n type: \"file\" as const,\n }));\n }\n }\n\n return [];\n}\n\n// \u2500\u2500 Ghost Text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getGhostText(input: string, workingDir: string): string {\n if (!input) return \"\";\n\n // Slash command ghost\n if (input.startsWith(\"/\")) {\n const match = SLASH_COMMANDS.find((c) => c.name.startsWith(input) && c.name !== input);\n return match ? match.name.substring(input.length) : \"\";\n }\n\n // @mention ghost\n const atIdx = input.lastIndexOf(\"@\");\n if (atIdx >= 0 && atIdx === input.length - input.substring(atIdx).length) {\n const query = input.substring(atIdx);\n const match = MENTION_PROVIDERS.find((p) => p.trigger.startsWith(query) && p.trigger !== query);\n return match ? match.trigger.substring(query.length) : \"\";\n }\n\n return \"\";\n}\n\n// \u2500\u2500 Path Completion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getPathCompletions(input: string, workingDir: string): string[] {\n // Detect path context: commands like cd, ls, cat, etc.\n const pathCommands = [\"cd\", \"ls\", \"cat\", \"head\", \"tail\", \"less\", \"more\", \"vim\", \"nano\", \"code\", \"open\", \"rm\", \"cp\", \"mv\", \"mkdir\", \"touch\", \"chmod\"];\n const parts = input.split(\" \");\n if (parts.length < 2) return [];\n\n const cmd = parts[0];\n if (!pathCommands.includes(cmd)) return [];\n\n const partial = parts[parts.length - 1] || \"\";\n return readPathEntries(workingDir, partial);\n}\n\nfunction readPathEntries(workingDir: string, partial: string): string[] {\n try {\n const dir = partial.includes(\"/\")\n ? path.resolve(workingDir, partial.substring(0, partial.lastIndexOf(\"/\") + 1))\n : workingDir;\n const prefix = partial.includes(\"/\") ? partial.substring(partial.lastIndexOf(\"/\") + 1) : partial;\n\n if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) return [];\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n const base = partial.includes(\"/\") ? partial.substring(0, partial.lastIndexOf(\"/\") + 1) : \"\";\n\n return entries\n .filter((e) => !e.name.startsWith(\".\") || partial.startsWith(\".\"))\n .filter((e) => e.name.toLowerCase().startsWith(prefix.toLowerCase()))\n .sort((a, b) => {\n if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;\n return a.name.localeCompare(b.name);\n })\n .slice(0, 20)\n .map((e) => base + e.name + (e.isDirectory() ? \"/\" : \"\"));\n } catch {\n return [];\n }\n}\n\nfunction getProjectFiles(workingDir: string, query: string): string[] {\n const results: string[] = [];\n const lower = query.toLowerCase();\n const skipDirs = new Set([\"node_modules\", \".git\", \"dist\", \"build\", \"__pycache__\", \".cache\", \"coverage\"]);\n\n const walk = (dir: string, rel: string, depth: number) => {\n if (depth > 3 || results.length >= 15) return;\n try {\n const entries = fs.readdirSync(path.join(workingDir, dir), { withFileTypes: true });\n for (const e of entries) {\n if (e.name.startsWith(\".\") || skipDirs.has(e.name)) continue;\n if (results.length >= 15) break;\n const p = rel ? `${rel}/${e.name}` : e.name;\n if (e.isDirectory()) {\n if (!query || p.toLowerCase().includes(lower)) results.push(p + \"/\");\n walk(path.join(dir, e.name), p, depth + 1);\n } else {\n if (!query || p.toLowerCase().includes(lower)) results.push(p);\n }\n }\n } catch { /* skip */ }\n };\n\n walk(\"\", \"\", 0);\n return results;\n}\n", "/**\n * InputArea \u2014 rich input with autocomplete, ghost text, image paste\n *\n * Features:\n * - Slash command autocomplete dropdown (/ prefix)\n * - @mention autocomplete dropdown (@ prefix)\n * - Tool subcommand suggestions (npm, git, etc.)\n * - Ghost text inline completion (Tab/\u2192 to accept)\n * - Ctrl+V paste text or images (macOS clipboard)\n * - Ctrl+U clear line, Ctrl+W delete word\n * - Up/Down navigate suggestions, Enter to select\n * - Escape to close dropdown\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState, useRef, useMemo } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { execSync } from \"child_process\";\nimport { useTheme } from \"../context/theme\";\nimport { getCompletions, getGhostText, type Suggestion } from \"../lib/autocomplete\";\nimport type { ImageAttachment } from \"@cdoing/ai\";\n\nexport interface InputAreaProps {\n onSubmit: (text: string, images?: ImageAttachment[]) => void;\n placeholder?: string;\n disabled?: boolean;\n workingDir: string;\n}\n\nfunction readClipboard(): string {\n try {\n if (process.platform === \"darwin\") return execSync(\"pbpaste\", { encoding: \"utf-8\" });\n try { return execSync(\"xclip -selection clipboard -o\", { encoding: \"utf-8\" }); }\n catch { return execSync(\"xsel --clipboard --output\", { encoding: \"utf-8\" }); }\n } catch { return \"\"; }\n}\n\nfunction readClipboardImage(): ImageAttachment | null {\n if (process.platform !== \"darwin\") return null;\n try {\n const hasImage = execSync(\n `osascript -e 'clipboard info' 2>/dev/null | grep -q \"TIFF\\\\|PNG\\\\|JPEG\" && echo \"yes\" || echo \"no\"`,\n { encoding: \"utf-8\", timeout: 1000 },\n ).trim();\n if (hasImage !== \"yes\") return null;\n const base64 = execSync(\n `osascript -e 'set theImage to the clipboard as \u00ABclass PNGf\u00BB' -e 'return theImage' 2>/dev/null | base64`,\n { encoding: \"utf-8\", timeout: 3000, maxBuffer: 20 * 1024 * 1024 },\n ).trim();\n if (base64 && base64.length > 100) return { data: base64, mimeType: \"image/png\" };\n } catch {}\n return null;\n}\n\nconst MAX_VISIBLE = 6;\n\nexport function InputArea(props: InputAreaProps) {\n const { theme } = useTheme();\n const t = theme;\n const [value, setValue] = useState(\"\");\n const [pendingImages, setPendingImages] = useState<ImageAttachment[]>([]);\n const [selectedIdx, setSelectedIdx] = useState(0);\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const valueRef = useRef(value);\n valueRef.current = value;\n const imageCountRef = useRef(0);\n\n // Compute suggestions based on current input, with a leading \"(none)\" option for path completions\n const suggestions = useMemo(() => {\n if (!value) return [];\n const completions = getCompletions(value, props.workingDir);\n // Add a \"none\" option at the top for file/subcommand completions so user can submit as-is\n if (completions.length > 0 && completions[0].type === \"file\") {\n return [{ text: value, description: \"submit as typed\", type: \"file\" as const }, ...completions];\n }\n return completions;\n }, [value, props.workingDir]);\n\n // Compute ghost text\n const ghost = useMemo(() => {\n if (dropdownOpen && suggestions.length > 0) return \"\";\n return getGhostText(value, props.workingDir);\n }, [value, props.workingDir, dropdownOpen, suggestions.length]);\n\n // Auto-open dropdown when suggestions exist\n const showDropdown = dropdownOpen && suggestions.length > 0;\n\n useKeyboard((key: any) => {\n // Allow typing even when disabled (streaming) \u2014 submit handler decides what to do\n\n // \u2500\u2500 Dropdown navigation \u2500\u2500\n if (showDropdown) {\n if (key.name === \"up\") {\n setSelectedIdx((i) => (i <= 0 ? suggestions.length - 1 : i - 1));\n return;\n }\n if (key.name === \"down\") {\n setSelectedIdx((i) => (i >= suggestions.length - 1 ? 0 : i + 1));\n return;\n }\n if (key.name === \"return\") {\n const s = suggestions[selectedIdx];\n if (s) {\n const text = s.text.trim();\n if (text) {\n // Execute the command directly\n props.onSubmit(text, pendingImages.length > 0 ? [...pendingImages] : undefined);\n setValue(\"\");\n setPendingImages([]);\n }\n setDropdownOpen(false);\n setSelectedIdx(0);\n }\n return;\n }\n if (key.name === \"escape\") {\n setDropdownOpen(false);\n return;\n }\n if (key.name === \"tab\") {\n const s = suggestions[selectedIdx];\n if (s) {\n setValue(s.text + \" \");\n setDropdownOpen(false);\n setSelectedIdx(0);\n }\n return;\n }\n }\n\n // \u2500\u2500 Ghost text accept \u2500\u2500\n if (ghost && (key.name === \"tab\" || key.name === \"right\")) {\n setValue((v) => v + ghost);\n return;\n }\n\n // Ctrl+V \u2014 paste image or text\n if (key.ctrl && key.name === \"v\") {\n const img = readClipboardImage();\n if (img) {\n imageCountRef.current += 1;\n setPendingImages((prev) => [...prev, img]);\n setValue((v) => v + `[Image #${imageCountRef.current}] `);\n return;\n }\n const clip = readClipboard().trim();\n if (clip) {\n const firstLine = clip.split(\"\\n\")[0] || \"\";\n setValue((v) => v + firstLine);\n }\n return;\n }\n\n // Ctrl+U \u2014 clear line\n if (key.ctrl && key.name === \"u\") {\n setValue(\"\");\n setPendingImages([]);\n setDropdownOpen(false);\n return;\n }\n\n // Ctrl+W \u2014 delete last word\n if (key.ctrl && key.name === \"w\") {\n setValue((v) => v.replace(/\\S+\\s*$/, \"\"));\n return;\n }\n\n // Enter \u2014 submit\n if (key.name === \"return\" && !key.shift) {\n const text = valueRef.current.trim();\n if (text || pendingImages.length > 0) {\n props.onSubmit(text || \"Describe this image.\", pendingImages.length > 0 ? [...pendingImages] : undefined);\n setValue(\"\");\n setPendingImages([]);\n setDropdownOpen(false);\n }\n return;\n }\n\n // Backspace\n if (key.name === \"backspace\") {\n setValue((v) => {\n const next = v.slice(0, -1);\n // Re-evaluate dropdown\n if (next.startsWith(\"/\") || next.includes(\"@\") || getCompletions(next, props.workingDir).length > 0) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n } else {\n setDropdownOpen(false);\n }\n return next;\n });\n return;\n }\n\n // Escape\n if (key.name === \"escape\") {\n setDropdownOpen(false);\n return;\n }\n\n // Space\n if (key.name === \"space\") {\n setValue((v) => {\n const next = v + \" \";\n // Close dropdown on space for slash commands, but check for path completions\n if (v.startsWith(\"/\")) {\n setDropdownOpen(false);\n } else if (getCompletions(next, props.workingDir).length > 0) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n }\n return next;\n });\n return;\n }\n\n // Regular character\n if (key.name && key.name.length === 1 && !key.ctrl && !key.meta) {\n setValue((v) => {\n const next = v + key.name;\n // Auto-open dropdown for /, @, and path completions\n if (next.startsWith(\"/\") || next.includes(\"@\")) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n } else if (getCompletions(next, props.workingDir).length > 0) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n }\n return next;\n });\n }\n });\n\n const isSlashCommand = value.startsWith(\"/\");\n\n // Window the suggestions for display\n const windowStart = Math.max(0, Math.min(selectedIdx - Math.floor(MAX_VISIBLE / 2), suggestions.length - MAX_VISIBLE));\n const visibleSuggestions = suggestions.slice(windowStart, windowStart + MAX_VISIBLE);\n const hasAbove = windowStart > 0;\n const hasBelow = windowStart + MAX_VISIBLE < suggestions.length;\n\n return (\n <box flexDirection=\"column\" flexShrink={0}>\n {/* Autocomplete dropdown (above input) */}\n {showDropdown && (\n <box flexDirection=\"column\" paddingX={1}>\n {hasAbove && (\n <box><text fg={t.textDim}>{` \u25B2 ${windowStart} more`}</text></box>\n )}\n {visibleSuggestions.map((s, i) => {\n const realIdx = windowStart + i;\n const isSelected = realIdx === selectedIdx;\n const color = s.type === \"command\" ? t.warning\n : s.type === \"mention\" ? t.info\n : s.type === \"file\" ? t.success\n : t.textMuted;\n return (\n <box key={s.text} flexDirection=\"row\">\n <text fg={isSelected ? t.primary : color} attributes={isSelected ? TextAttributes.BOLD : undefined}>\n {isSelected ? \" \u276F \" : \" \"}\n </text>\n <text fg={isSelected ? t.text : color}>{s.text}</text>\n {s.description ? (\n <text fg={t.textDim}>{` ${s.description}`}</text>\n ) : null}\n </box>\n );\n })}\n {hasBelow && (\n <box><text fg={t.textDim}>{` \u25BC ${suggestions.length - windowStart - MAX_VISIBLE} more`}</text></box>\n )}\n </box>\n )}\n\n {/* Pending images indicator */}\n {pendingImages.length > 0 && (\n <box height={1} paddingX={1}>\n <text fg={t.primary}>\n {` \uD83D\uDDBC ${pendingImages.length} image${pendingImages.length > 1 ? \"s\" : \"\"} attached`}\n </text>\n </box>\n )}\n\n {/* Input box */}\n <box\n height={3}\n borderStyle=\"single\"\n borderColor={t.borderFocused}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingX={1}\n >\n <text\n fg={isSlashCommand ? t.warning : t.primary}\n attributes={TextAttributes.BOLD}\n >\n {isSlashCommand ? \" / \" : \" > \"}\n </text>\n\n {value ? (\n <>\n <text fg={t.text}>{value}</text>\n {ghost ? (\n <text fg={t.textDim}>{ghost}</text>\n ) : (\n <text fg={t.primary}>{\"\u258A\"}</text>\n )}\n </>\n ) : (\n <text fg={t.textDim}>\n {props.placeholder || \"Type a message... (^V paste, / commands, @ context, Tab accept)\"}\n </text>\n )}\n </box>\n </box>\n );\n}\n", "/**\n * Home Route \u2014 landing screen with logo, project info, shortcuts, and quick actions\n *\n * Responsive: adapts layout based on terminal dimensions.\n * - Small terminals (< 60 cols or < 20 rows): compact layout, no logo\n * - Medium terminals: smaller logo, condensed info\n * - Large terminals: full figlet logo, spacious layout\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport { InputArea } from \"../components/input-area\";\nimport type { ImageAttachment } from \"@cdoing/ai\";\n\n// Full figlet logo (ANSI Shadow)\nconst LOGO_FULL = [\n \" \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \",\n \"\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \",\n \"\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\",\n \"\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\",\n \"\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\",\n \" \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \",\n];\n\n// Compact logo for smaller terminals\nconst LOGO_COMPACT = [\n \"\u250C\u2500\u2510\u250C\u2510 \u250C\u2500\u2510\u252C\u250C\u2510\u250C\u250C\u2500\u2510\",\n \"\u2502 \u2502\u2502\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2502\u2502 \u252C\",\n \"\u2514\u2500\u2518\u2514\u2518\u2514\u2500\u2518\u2514\u2500\u2518\u2518\u2514\u2518\u2514\u2500\u2518\",\n];\n\nexport function Home(props: {\n provider: string;\n model: string;\n workingDir: string;\n themeId: string;\n onAction?: (action: string) => void;\n onSubmit?: (text: string, images?: ImageAttachment[]) => void;\n}) {\n const { theme } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n const w = dims.width || 80;\n const h = dims.height || 24;\n\n const shortDir = () => {\n const home = process.env.HOME || \"\";\n const d = props.workingDir;\n return home && d.startsWith(home) ? \"~\" + d.slice(home.length) : d;\n };\n\n const subtitle = \"Multi-provider AI coding assistant\";\n const version = \"v0.1.1\";\n\n // Determine layout size\n const isSmall = w < 60 || h < 20;\n const isMedium = !isSmall && (w < 80 || h < 30);\n\n // Pick logo\n const logo = isSmall ? null : isMedium ? LOGO_COMPACT : LOGO_FULL;\n\n // Build info lines\n const infoLines = [\n [\"Provider\", props.provider],\n [\"Model\", props.model],\n [\"Theme\", props.themeId],\n [\"Directory\", shortDir()],\n ];\n const maxKeyLen = Math.max(...infoLines.map(([k]) => k.length));\n\n // Quick actions\n const actions = [\n { key: \"Enter\", label: \"Send message / start session\", id: \"start\" },\n { key: \"Ctrl+P\", label: \"Switch model\", id: \"model\" },\n { key: \"Ctrl+T\", label: \"Change theme\", id: \"theme\" },\n { key: \"Ctrl+N\", label: \"New session\", id: \"new\" },\n { key: \"Ctrl+S\", label: \"Browse sessions\", id: \"sessions\" },\n { key: \"Ctrl+X\", label: \"Command palette\", id: \"commands\" },\n { key: \"/setup\", label: \"Setup wizard\", id: \"setup\" },\n { key: \"Ctrl+C\", label: \"Quit\", id: \"quit\" },\n ];\n const maxActionKey = Math.max(...actions.map((a) => a.key.length));\n\n return (\n <box flexDirection=\"column\" flexGrow={1} flexShrink={1} overflow=\"hidden\">\n <box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" flexGrow={1}>\n {/* Logo */}\n {logo && logo.map((line, i) => (\n <text key={`logo-${i}`} fg={t.primary} attributes={TextAttributes.BOLD}>\n {line}\n </text>\n ))}\n\n {/* Subtitle + version */}\n <text fg={t.textDim}>\n {subtitle}\n </text>\n <text fg={t.textMuted}>\n {version}\n </text>\n\n <text>{\"\"}</text>\n\n {/* Info section */}\n {infoLines.map(([key, val], i) => {\n const line = `${key.padStart(maxKeyLen)} ${val}`;\n return (\n <text key={`info-${i}`} fg={t.textDim}>\n {line}\n </text>\n );\n })}\n\n <text>{\"\"}</text>\n\n {/* Actions */}\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"Actions\"}\n </text>\n {actions.map((action, i) => {\n const line = `${action.key.padStart(maxActionKey)} ${action.label}`;\n return (\n <text key={`act-${i}`} fg={t.textMuted}>\n {line}\n </text>\n );\n })}\n\n <text>{\"\"}</text>\n\n {/* Footer */}\n <text fg={t.textDim}>\n {\"Powered by @opentui/react + @cdoing/ai\"}\n </text>\n </box>\n\n {/* Input bar at bottom \u2014 user can start typing immediately */}\n {props.onSubmit && (\n <InputArea\n onSubmit={props.onSubmit}\n workingDir={props.workingDir}\n placeholder=\"Start typing to begin a session... (/ commands, @ context)\"\n />\n )}\n </box>\n );\n}\n", "/**\n * MessageList \u2014 renders chat messages with tool calls, streaming, and markdown\n *\n * Uses a custom inline markdown renderer for assistant messages (matching the CLI's\n * RenderMarkdown approach) with OpenTUI's <markdown> component for fenced code blocks.\n * The scrollbox is managed by the parent (session.tsx) to ensure proper flex height\n * calculation (matching OpenCode's pattern).\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme, type Theme } from \"../context/theme\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Message {\n id: string;\n role: \"user\" | \"assistant\" | \"system\" | \"tool\";\n content: string;\n toolName?: string;\n toolStatus?: \"running\" | \"done\" | \"error\";\n isError?: boolean;\n timestamp: number;\n}\n\n// \u2500\u2500 Tool Icons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TOOL_ICONS: Record<string, string> = {\n file_read: \"\uD83D\uDCD6\", file_write: \"\u270F\uFE0F\", file_edit: \"\uD83D\uDD27\", multi_edit: \"\uD83D\uDD27\",\n shell_exec: \"\uD83D\uDCBB\", file_run: \"\u25B6\", glob_search: \"\uD83D\uDD0D\", grep_search: \"\uD83D\uDD0E\",\n codebase_search: \"\uD83D\uDD0E\", web_fetch: \"\uD83C\uDF10\", web_search: \"\uD83D\uDD2E\", sub_agent: \"\uD83E\uDD16\",\n todo: \"\uD83D\uDCCB\", list_dir: \"\uD83D\uDCC1\", view_diff: \"\uD83D\uDCCA\", view_repo_map: \"\uD83D\uDDFA\uFE0F\",\n code_verify: \"\u2705\", system_info: \"\u2139\uFE0F\", ast_edit: \"\uD83C\uDF33\", notebook_edit: \"\uD83D\uDCD3\",\n};\n\n// \u2500\u2500 Inline Markdown Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Strip markdown inline syntax markers: **bold** \u2192 bold, *italic* \u2192 italic, `code` \u2192 code */\nfunction stripInlineMarkdown(text: string): string {\n return text\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"$1\")\n .replace(/(?<!\\w)\\*([^*]+)\\*(?!\\w)/g, \"$1\");\n}\n\n// \u2500\u2500 Custom Markdown Renderer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Renders markdown content using OpenTUI primitives with proper styling.\n// Strips markdown syntax (##, **, *, `, ---) and renders styled text.\n// Uses <markdown> component only for fenced code blocks (syntax highlighting).\n\nfunction RenderMarkdown(props: { text: string; theme: Theme }) {\n const t = props.theme;\n const { syntaxStyle } = useTheme();\n const lines = props.text.split(\"\\n\");\n\n const rendered: React.ReactNode[] = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n // \u2500\u2500 Fenced code block \u2014 use OpenTUI <markdown> for syntax highlighting \u2500\u2500\n if (line.startsWith(\"```\")) {\n const codeLines: string[] = [line];\n i++;\n while (i < lines.length) {\n codeLines.push(lines[i]);\n if (lines[i].startsWith(\"```\")) {\n i++;\n break;\n }\n i++;\n }\n const codeBlock = codeLines.join(\"\\n\");\n rendered.push(\n <box key={`code-${i}`} marginY={0}>\n <markdown\n syntaxStyle={syntaxStyle}\n streaming={false}\n content={codeBlock}\n conceal={true}\n />\n </box>\n );\n continue;\n }\n\n // \u2500\u2500 Headers \u2500\u2500\n if (line.startsWith(\"### \")) {\n rendered.push(\n <text key={i} fg={t.info} attributes={TextAttributes.BOLD}>\n {` \u25B8 ${stripInlineMarkdown(line.slice(4))}`}\n </text>\n );\n i++;\n continue;\n }\n if (line.startsWith(\"## \")) {\n rendered.push(\n <text key={i} fg={t.primary} attributes={TextAttributes.BOLD}>\n {` \u25B8\u25B8 ${stripInlineMarkdown(line.slice(3))}`}\n </text>\n );\n i++;\n continue;\n }\n if (line.startsWith(\"# \")) {\n rendered.push(\n <text key={i} fg={t.primary} attributes={TextAttributes.BOLD}>\n {`\u25B8\u25B8\u25B8 ${stripInlineMarkdown(line.slice(2))}`}\n </text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Horizontal rule \u2500\u2500\n if (/^---+$/.test(line) || /^===+$/.test(line) || /^\\*\\*\\*+$/.test(line)) {\n rendered.push(\n <text key={i} fg={t.textDim}>{\"\u2500\".repeat(40)}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Bullet list \u2500\u2500\n const bulletMatch = line.match(/^(\\s*)[-*] (.*)/);\n if (bulletMatch) {\n const indent = bulletMatch[1] || \"\";\n const content = stripInlineMarkdown(bulletMatch[2]);\n rendered.push(\n <text key={i}>{`${indent}\u25CF ${content}`}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Numbered list \u2500\u2500\n const numMatch = line.match(/^(\\s*)(\\d+)\\. (.*)/);\n if (numMatch) {\n const content = stripInlineMarkdown(numMatch[3]);\n rendered.push(\n <text key={i}>{`${numMatch[1]}${numMatch[2]}. ${content}`}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Blockquote \u2500\u2500\n if (line.startsWith(\"> \")) {\n rendered.push(\n <text key={i} fg={t.textMuted}>{`\u2502 ${stripInlineMarkdown(line.slice(2))}`}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Empty line \u2500\u2500\n if (!line.trim()) {\n rendered.push(<text key={i}>{\" \"}</text>);\n i++;\n continue;\n }\n\n // \u2500\u2500 Plain text \u2014 strip markdown syntax \u2500\u2500\n rendered.push(\n <text key={i}>{stripInlineMarkdown(line)}</text>\n );\n i++;\n }\n\n return <box flexDirection=\"column\">{rendered}</box>;\n}\n\n// \u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction formatTimestamp(ts: number): string {\n const d = new Date(ts);\n let h = d.getHours();\n const m = d.getMinutes();\n const ampm = h >= 12 ? \"PM\" : \"AM\";\n h = h % 12 || 12;\n return `${h}:${m.toString().padStart(2, \"0\")} ${ampm}`;\n}\n\n/**\n * Renders message content only (no scrollbox wrapper).\n * Parent should wrap this in a <scrollbox> for proper flex height.\n */\nexport function MessageList(props: {\n messages: Message[];\n streamingText?: string;\n isStreaming?: boolean;\n showTimestamps?: boolean;\n}) {\n const { theme } = useTheme();\n const t = theme;\n\n return (\n <>\n {/* Empty state */}\n {props.messages.length === 0 && !props.isStreaming && (\n <box paddingX={2} paddingY={1}>\n <text fg={t.textMuted}>\n {\"Type a message to start chatting. Use / for commands, @ for context.\"}\n </text>\n </box>\n )}\n\n {/* Messages */}\n {props.messages.map((msg) => {\n if (msg.role === \"user\") {\n return (\n <box key={msg.id} paddingX={1} paddingY={0} flexDirection=\"row\">\n <text fg={t.userText} attributes={TextAttributes.BOLD}>\n {\"\u276F \"}\n </text>\n <text fg={t.userText} flexGrow={1}>{msg.content}</text>\n {props.showTimestamps && msg.timestamp && (\n <text fg={t.textDim}>{` ${formatTimestamp(msg.timestamp)}`}</text>\n )}\n </box>\n );\n }\n\n if (msg.role === \"assistant\") {\n return (\n <box key={msg.id} paddingLeft={1} marginTop={1} flexShrink={0} flexDirection=\"column\">\n <box flexDirection=\"row\">\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"\u25C6 \"}\n </text>\n {props.showTimestamps && msg.timestamp && (\n <text fg={t.textDim}>{` ${formatTimestamp(msg.timestamp)}`}</text>\n )}\n </box>\n <box paddingLeft={2}>\n <RenderMarkdown text={msg.content.trim()} theme={t} />\n </box>\n </box>\n );\n }\n\n if (msg.role === \"system\") {\n return (\n <box key={msg.id} paddingX={1} flexDirection=\"row\">\n <text fg={t.systemText} flexGrow={1}>{`\u26A1 ${msg.content}`}</text>\n {props.showTimestamps && msg.timestamp && (\n <text fg={t.textDim}>{` ${formatTimestamp(msg.timestamp)}`}</text>\n )}\n </box>\n );\n }\n\n if (msg.role === \"tool\") {\n return (\n <ToolCallRow\n key={msg.id}\n name={msg.toolName || \"unknown\"}\n content={msg.content}\n status={msg.toolStatus || (msg.isError ? \"error\" : \"done\")}\n />\n );\n }\n\n return null;\n })}\n\n {/* Streaming indicator */}\n {props.isStreaming && (\n <box paddingLeft={1} marginTop={1} flexShrink={0} flexDirection=\"column\">\n <box flexDirection=\"row\">\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"\u25C6 \"}\n </text>\n <text fg={t.primary}>{\"\u258A\"}</text>\n </box>\n {(props.streamingText || \"\").trim() && (\n <box paddingLeft={2}>\n <RenderMarkdown text={(props.streamingText || \"\").trim()} theme={t} />\n </box>\n )}\n </box>\n )}\n </>\n );\n}\n\n// \u2500\u2500 Tool Call Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction ToolCallRow(props: {\n name: string;\n content: string;\n status: \"running\" | \"done\" | \"error\";\n}) {\n const { theme } = useTheme();\n const t = theme;\n\n const icon = TOOL_ICONS[props.name] || \"\u2699\uFE0F\";\n const statusIcon = (() => {\n switch (props.status) {\n case \"running\": return \"\u23F3\";\n case \"done\": return \"\u2713\";\n case \"error\": return \"\u2717\";\n }\n })();\n const statusColor = (() => {\n switch (props.status) {\n case \"running\": return t.toolRunning;\n case \"done\": return t.toolDone;\n case \"error\": return t.toolError;\n }\n })();\n\n const shortName = (() => {\n const names: Record<string, string> = {\n file_read: \"Read\", file_write: \"Write\", file_edit: \"Edit\",\n multi_edit: \"MultiEdit\", shell_exec: \"Bash\", glob_search: \"Search files\",\n grep_search: \"Search code\", web_fetch: \"Fetch\", sub_agent: \"Agent\",\n list_dir: \"List dir\", codebase_search: \"Codebase search\",\n };\n return names[props.name] || props.name.replace(/_/g, \" \");\n })();\n\n return (\n <box paddingX={2}>\n <text fg={statusColor}>{`${statusIcon} `}</text>\n <text fg={t.toolText}>{`${icon} ${shortName}`}</text>\n {props.content && (\n <text fg={t.textDim}>{` \u2014 ${trimText(props.content, 60)}`}</text>\n )}\n </box>\n );\n}\n\nfunction trimText(s: string, max: number): string {\n const first = s.split(\"\\n\")[0] || \"\";\n return first.length > max ? first.substring(0, max) + \"\u2026\" : first;\n}\n", "/**\n * PermissionPrompt \u2014 asks user to allow/deny a tool action\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface PermissionPromptProps {\n toolName: string;\n message: string;\n onDecision: (decision: \"allow\" | \"always\" | \"deny\") => void;\n}\n\nconst OPTIONS = [\n { key: \"1\", label: \"Allow once\", value: \"allow\" as const },\n { key: \"2\", label: \"Always allow\", value: \"always\" as const },\n { key: \"3\", label: \"Deny\", value: \"deny\" as const },\n];\n\nexport function PermissionPrompt(props: PermissionPromptProps) {\n const { theme } = useTheme();\n const t = theme;\n const [selected, setSelected] = useState(0);\n\n useKeyboard((key: any) => {\n if (key.name === \"up\" || key.name === \"k\") {\n setSelected((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelected((s) => Math.min(OPTIONS.length - 1, s + 1));\n } else if (key.name === \"return\") {\n props.onDecision(OPTIONS[selected].value);\n } else if (key.name === \"1\") {\n props.onDecision(\"allow\");\n } else if (key.name === \"2\") {\n props.onDecision(\"always\");\n } else if (key.name === \"3\") {\n props.onDecision(\"deny\");\n }\n });\n\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.warning}\n paddingX={1}\n paddingY={0}\n flexDirection=\"column\"\n >\n <text fg={t.warning} attributes={TextAttributes.BOLD}>\n {\"\uD83D\uDD10 Permission Required\"}\n </text>\n <text fg={t.text}>\n {` ${props.toolName}: ${props.message}`}\n </text>\n <text fg={t.textDim}>{\"\"}</text>\n {OPTIONS.map((opt, i) => (\n <box key={opt.key}>\n <text\n fg={selected === i ? t.primary : t.textMuted}\n attributes={selected === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selected === i ? \"\u276F\" : \" \"} [${opt.key}] ${opt.label}`}\n </text>\n </box>\n ))}\n <text fg={t.textDim}>{\"\\n \u2191\u2193 Navigate Enter Select 1-3 Quick pick\"}</text>\n </box>\n );\n}\n", "/**\n * LoadingSpinner \u2014 animated thinking/tool indicator\n */\n\nimport { useState, useEffect } from \"react\";\nimport { useTheme } from \"../context/theme\";\n\nconst FRAMES = [\"\u280B\", \"\u2819\", \"\u2839\", \"\u2838\", \"\u283C\", \"\u2834\", \"\u2826\", \"\u2827\", \"\u2807\", \"\u280F\"];\n\nexport function LoadingSpinner(props: { label?: string }) {\n const { theme } = useTheme();\n const t = theme;\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const interval = setInterval(() => {\n setFrame((f) => (f + 1) % FRAMES.length);\n }, 80);\n return () => clearInterval(interval);\n }, []);\n\n return (\n <box paddingX={1} height={1} flexDirection=\"row\">\n <text fg={t.primary}>{FRAMES[frame]}</text>\n <text fg={t.textMuted}>{` ${props.label || \"Thinking...\"}`}</text>\n </box>\n );\n}\n", "/**\n * Terminal Title \u2014 set/reset the terminal window title via escape sequences\n */\n\nexport function setTerminalTitle(title: string): void {\n if (process.stdout.isTTY) {\n process.stdout.write(`\\x1b]0;${title}\\x07`);\n }\n}\n\nexport function resetTerminalTitle(): void {\n if (process.stdout.isTTY) {\n process.stdout.write(`\\x1b]0;\\x07`);\n }\n}\n", "/**\n * Conversation History Manager for TUI\n *\n * Saves conversations to ~/.cdoing/conversations/ as JSON files.\n * Mirrors the base CLI implementation for full compatibility.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\n\nconst CONV_DIR = path.join(os.homedir(), \".cdoing\", \"conversations\");\n\nexport interface ChatMessage {\n role: \"user\" | \"assistant\" | \"tool\";\n content: string;\n toolName?: string;\n timestamp: number;\n}\n\nexport interface Conversation {\n id: string;\n title: string;\n createdAt: number;\n updatedAt: number;\n provider: string;\n model: string;\n messages: ChatMessage[];\n}\n\nfunction ensureDir(): void {\n if (!fs.existsSync(CONV_DIR)) fs.mkdirSync(CONV_DIR, { recursive: true });\n}\n\nfunction generateId(): string {\n const now = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 6);\n return `${now}-${rand}`;\n}\n\nfunction deriveTitle(message: string): string {\n const clean = message.replace(/\\n/g, \" \").trim();\n return clean.length > 60 ? clean.substring(0, 57) + \"...\" : clean;\n}\n\nexport function createConversation(provider: string, model: string): Conversation {\n ensureDir();\n return {\n id: generateId(),\n title: \"New conversation\",\n createdAt: Date.now(),\n updatedAt: Date.now(),\n provider,\n model,\n messages: [],\n };\n}\n\nexport function addMessage(\n conv: Conversation,\n role: \"user\" | \"assistant\" | \"tool\",\n content: string,\n toolName?: string\n): void {\n conv.messages.push({ role, content, timestamp: Date.now(), toolName });\n conv.updatedAt = Date.now();\n\n if (role === \"user\" && conv.title === \"New conversation\") {\n conv.title = deriveTitle(content);\n }\n\n saveConversation(conv);\n}\n\nexport function saveConversation(conv: Conversation): void {\n ensureDir();\n const filePath = path.join(CONV_DIR, `${conv.id}.json`);\n fs.writeFileSync(filePath, JSON.stringify(conv, null, 2), \"utf-8\");\n}\n\nexport function loadConversation(id: string): Conversation | null {\n // Support partial IDs\n ensureDir();\n const files = fs.readdirSync(CONV_DIR).filter((f) => f.endsWith(\".json\"));\n const match = files.find((f) => f.startsWith(id) || f.replace(\".json\", \"\") === id);\n if (!match) return null;\n\n const filePath = path.join(CONV_DIR, match);\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nexport function listConversations(): Conversation[] {\n ensureDir();\n const files = fs.readdirSync(CONV_DIR).filter((f) => f.endsWith(\".json\"));\n const convs: Conversation[] = [];\n\n for (const file of files) {\n try {\n const data = JSON.parse(fs.readFileSync(path.join(CONV_DIR, file), \"utf-8\"));\n convs.push(data);\n } catch {}\n }\n\n return convs.sort((a, b) => b.updatedAt - a.updatedAt);\n}\n\nexport function loadLastConversation(): Conversation | null {\n const all = listConversations();\n return all.length > 0 ? all[0] : null;\n}\n\nexport function deleteConversation(id: string): boolean {\n ensureDir();\n const files = fs.readdirSync(CONV_DIR).filter((f) => f.endsWith(\".json\"));\n const match = files.find((f) => f.startsWith(id) || f.replace(\".json\", \"\") === id);\n if (match) {\n fs.unlinkSync(path.join(CONV_DIR, match));\n return true;\n }\n return false;\n}\n\nexport function forkConversation(idOrConv: string | Conversation): Conversation | null {\n const original =\n typeof idOrConv === \"string\" ? loadConversation(idOrConv) : idOrConv;\n if (!original) return null;\n\n ensureDir();\n const forked: Conversation = {\n ...original,\n id: generateId(),\n title: `Fork of: ${original.title}`,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messages: original.messages.map((m) => ({ ...m })),\n };\n saveConversation(forked);\n return forked;\n}\n\nexport function updateConversationTitle(id: string, title: string): void {\n const conv = loadConversation(id);\n if (!conv) return;\n conv.title = title.length > 80 ? title.substring(0, 77) + \"...\" : title;\n conv.updatedAt = Date.now();\n saveConversation(conv);\n}\n\nexport function formatRelativeDate(timestamp: number): string {\n const diff = Date.now() - timestamp;\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return \"just now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n if (days < 30) return `${days}d ago`;\n return new Date(timestamp).toLocaleDateString();\n}\n", "/**\n * Context Provider Expansion \u2014 resolves @mentions in user messages\n *\n * Detects @terminal, @url, @tree, @codebase, @clip, @file triggers\n * and expands them into the actual content before sending to the agent.\n */\n\nimport {\n ContextProviderRegistry,\n TerminalContextProvider,\n UrlContextProvider,\n TreeContextProvider,\n CodebaseContextProvider,\n ClipboardContextProvider,\n FileIncludeContextProvider,\n} from \"@cdoing/core\";\n\nlet registry: ContextProviderRegistry | null = null;\nlet terminalProvider: TerminalContextProvider | null = null;\n\nfunction getRegistry(): ContextProviderRegistry {\n if (!registry) {\n registry = new ContextProviderRegistry();\n terminalProvider = new TerminalContextProvider();\n registry.register(terminalProvider);\n registry.register(new UrlContextProvider());\n registry.register(new TreeContextProvider());\n registry.register(new CodebaseContextProvider());\n registry.register(new ClipboardContextProvider());\n registry.register(new FileIncludeContextProvider());\n }\n return registry;\n}\n\n/** Update terminal provider with recent shell output */\nexport function pushTerminalOutput(output: string): void {\n getRegistry();\n if (terminalProvider && typeof (terminalProvider as any).push === \"function\") {\n (terminalProvider as any).push(output);\n }\n}\n\n/** Known @mention triggers */\nconst TRIGGERS = [\"@terminal\", \"@url\", \"@tree\", \"@codebase\", \"@clip\", \"@file\"];\n\n/**\n * Resolve all @mention providers in a message.\n * Returns the expanded message with provider content appended.\n */\nexport async function resolveContextProviders(\n message: string,\n workingDir: string\n): Promise<string> {\n const reg = getRegistry();\n let expandedMessage = message;\n const appendSections: string[] = [];\n\n for (const trigger of TRIGGERS) {\n const idx = expandedMessage.indexOf(trigger);\n if (idx === -1) continue;\n\n // Extract the trigger + argument\n const afterTrigger = expandedMessage.substring(idx + trigger.length);\n const endIdx = afterTrigger.search(/\\s@|\\n|$/);\n const arg = afterTrigger.substring(0, endIdx === -1 ? afterTrigger.length : endIdx).trim();\n\n // Remove trigger from message\n const fullTrigger = trigger + (arg ? \" \" + arg : \"\");\n expandedMessage = expandedMessage.replace(fullTrigger, \"\").trim();\n\n // Resolve\n const providerName = trigger.substring(1); // strip @\n const provider = reg.get(providerName);\n if (!provider) continue;\n\n try {\n const result = await provider.resolve(arg, { workingDir });\n if (result) {\n appendSections.push(`--- ${trigger} ---\\n${result}`);\n }\n } catch {\n // Silently skip failed providers\n }\n }\n\n if (appendSections.length > 0) {\n expandedMessage = expandedMessage + \"\\n\\n\" + appendSections.join(\"\\n\\n\");\n }\n\n return expandedMessage;\n}\n\n/**\n * Check if a message contains any @mention triggers.\n */\nexport function hasContextMentions(message: string): boolean {\n return TRIGGERS.some((t) => message.includes(t));\n}\n", "/**\n * Session Route \u2014 active chat session with full agent integration\n *\n * Wires up the AgentRunner with streaming callbacks to display:\n * - Token-by-token streaming with cursor\n * - Tool call display with status icons\n * - Permission prompts (via SDK context)\n * - Token usage tracking\n * - Full slash command handling\n * - Session persistence (save/resume/fork/delete)\n * - @mention context expansion\n * - Background jobs (/bg, /jobs)\n * - One-shot questions (/btw)\n * - Shell command auto-detection\n * - OAuth status (/auth-status)\n * - /config set support\n */\n\nimport { useState, useRef, useEffect } from \"react\";\nimport { TextAttributes } from \"@opentui/core\";\nimport { useKeyboard } from \"@opentui/react\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { MessageList, type Message } from \"../components/message-list\";\nimport { InputArea } from \"../components/input-area\";\nimport { PermissionPrompt } from \"../components/permission-prompt\";\nimport { LoadingSpinner } from \"../components/loading-spinner\";\nimport { useSDK } from \"../context/sdk\";\nimport { useTheme } from \"../context/theme\";\nimport { useToast } from \"../components/toast\";\nimport { setTerminalTitle } from \"../lib/terminal-title\";\nimport { execSync } from \"child_process\";\nimport type { AgentCallbacks, ImageAttachment } from \"@cdoing/ai\";\nimport {\n createConversation,\n addMessage as addHistoryMessage,\n listConversations,\n loadConversation,\n deleteConversation,\n forkConversation,\n formatRelativeDate,\n type Conversation,\n} from \"../lib/history\";\nimport {\n resolveContextProviders,\n hasContextMentions,\n pushTerminalOutput,\n} from \"../lib/context-providers\";\n\n// \u2500\u2500 Shell Command Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst SHELL_COMMANDS = new Set([\n \"ls\", \"ll\", \"la\", \"pwd\", \"cd\", \"mkdir\", \"rmdir\", \"rm\", \"cp\", \"mv\",\n \"cat\", \"head\", \"tail\", \"touch\", \"echo\", \"env\",\n \"git\", \"npm\", \"yarn\", \"pnpm\", \"npx\", \"node\", \"ts-node\",\n \"python\", \"python3\", \"pip\", \"pip3\",\n \"docker\", \"docker-compose\",\n \"grep\", \"find\", \"which\", \"whereis\",\n \"curl\", \"wget\",\n \"chmod\", \"chown\", \"ln\",\n \"ps\", \"kill\", \"df\", \"du\",\n \"open\", \"code\",\n \"vim\", \"vi\", \"nano\", \"less\", \"more\", \"man\", \"top\", \"htop\",\n]);\n\nfunction detectShellCommand(input: string): string | null {\n const trimmed = input.trim();\n const firstWord = trimmed.split(/\\s+/)[0].toLowerCase();\n return SHELL_COMMANDS.has(firstWord) ? trimmed : null;\n}\n\n// \u2500\u2500 Background Job \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface BackgroundJob {\n id: string;\n prompt: string;\n status: \"running\" | \"done\" | \"error\";\n result?: string;\n error?: string;\n startedAt: number;\n completedAt?: number;\n}\n\n// \u2500\u2500 Interrupt/Queue Prompt \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction InterruptPrompt(props: {\n message: string;\n onInterrupt: () => void;\n onQueue: () => void;\n onCancel: () => void;\n}) {\n const { theme } = useTheme();\n const t = theme;\n const [selected, setSelected] = useState(0);\n const options = [\n { label: \"Interrupt \u2014 stop current response and send new message\", action: props.onInterrupt },\n { label: \"Queue \u2014 wait for current response, then send\", action: props.onQueue },\n { label: \"Cancel \u2014 discard new message\", action: props.onCancel },\n ];\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\") { props.onCancel(); return; }\n if (key.name === \"up\" || key.name === \"k\") { setSelected((s) => Math.max(0, s - 1)); return; }\n if (key.name === \"down\" || key.name === \"j\") { setSelected((s) => Math.min(options.length - 1, s + 1)); return; }\n if (key.name === \"return\") { options[selected].action(); return; }\n // Quick keys\n if (key.sequence === \"1\" || key.sequence === \"i\") { props.onInterrupt(); return; }\n if (key.sequence === \"2\" || key.sequence === \"q\") { props.onQueue(); return; }\n if (key.sequence === \"3\") { props.onCancel(); return; }\n });\n\n const preview = props.message.length > 50 ? props.message.slice(0, 47) + \"...\" : props.message;\n\n return (\n <box flexDirection=\"column\" flexShrink={0} paddingX={1}>\n <text fg={t.warning} attributes={TextAttributes.BOLD}>\n {\" Agent is streaming. What to do with your message?\"}\n </text>\n <text fg={t.textDim}>{` \"${preview}\"`}</text>\n <text>{\"\"}</text>\n {options.map((opt, i) => (\n <text key={i} fg={i === selected ? t.primary : t.textMuted} attributes={i === selected ? TextAttributes.BOLD : undefined}>\n {` ${i === selected ? \"\u276F\" : \" \"} ${i + 1}. ${opt.label}`}\n </text>\n ))}\n <text fg={t.textDim}>{\" \u2191\u2193 Navigate Enter Select i/q/Esc Quick keys\"}</text>\n </box>\n );\n}\n\n// \u2500\u2500 Session View \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function SessionView(props: {\n onStatus: (s: string) => void;\n onTokens: (input: number, output: number) => void;\n onActiveTool: (tool: string | undefined) => void;\n onContextPercent: (pct: number) => void;\n onOpenDialog?: (dialog: string) => void;\n initialMessage?: { text: string; images?: ImageAttachment[] } | null;\n}) {\n const sdk = useSDK();\n const { setMode } = useTheme();\n const { toast } = useToast();\n\n // Set terminal title to indicate active session\n setTerminalTitle(\"cdoing - session\");\n\n const [messages, setMessages] = useState<Message[]>([]);\n const [streamingText, setStreamingText] = useState(\"\");\n const streamingTextRef = useRef(streamingText);\n streamingTextRef.current = streamingText;\n const [isStreaming, setIsStreaming] = useState(false);\n const [activeTool, setActiveTool] = useState<string | undefined>();\n const [pendingPermission, setPendingPermission] = useState<{\n toolName: string;\n message: string;\n resolve: (decision: \"allow\" | \"always\" | \"deny\") => void;\n } | null>(null);\n\n // Interrupt/queue prompt state\n const [pendingInterrupt, setPendingInterrupt] = useState<{\n text: string;\n images?: ImageAttachment[];\n } | null>(null);\n const queuedMessagesRef = useRef<string[]>([]);\n\n const totalInputRef = useRef(0);\n const totalOutputRef = useRef(0);\n const msgIdCounterRef = useRef(0);\n const conversationRef = useRef<Conversation | null>(null);\n const backgroundJobsRef = useRef<BackgroundJob[]>([]);\n const bgIdCounterRef = useRef(0);\n\n // Initialize conversation on first render\n if (!conversationRef.current) {\n conversationRef.current = createConversation(sdk.provider, sdk.model);\n }\n\n const addMessage = (role: Message[\"role\"], content: string, extra?: Partial<Message>) => {\n const msg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role,\n content,\n timestamp: Date.now(),\n ...extra,\n };\n setMessages((prev) => [...prev, msg]);\n\n // Persist to conversation history\n if (conversationRef.current && (role === \"user\" || role === \"assistant\")) {\n addHistoryMessage(conversationRef.current, role, content);\n }\n\n return msg.id;\n };\n\n const updateMessage = (id: string, updates: Partial<Message>) => {\n setMessages((prev) =>\n prev.map((m) => (m.id === id ? { ...m, ...updates } : m))\n );\n };\n\n // \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const loadStoredConfig = (): Record<string, any> => {\n try {\n const configPath = path.join(os.homedir(), \".cdoing\", \"config.json\");\n if (fs.existsSync(configPath)) {\n return JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n return {};\n };\n\n const saveConfigKey = (key: string, value: any): void => {\n const configDir = path.join(os.homedir(), \".cdoing\");\n const configPath = path.join(configDir, \"config.json\");\n let config: Record<string, any> = {};\n try {\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n config[key] = value;\n if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n };\n\n const loadProjectSettings = (): Record<string, any> => {\n try {\n const settingsPath = path.join(sdk.workingDir, \".cdoing\", \"settings.json\");\n if (fs.existsSync(settingsPath)) {\n return JSON.parse(fs.readFileSync(settingsPath, \"utf-8\"));\n }\n const claudePath = path.join(sdk.workingDir, \".claude\", \"settings.json\");\n if (fs.existsSync(claudePath)) {\n return JSON.parse(fs.readFileSync(claudePath, \"utf-8\"));\n }\n } catch {}\n return {};\n };\n\n // \u2500\u2500 Background Jobs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const runBackgroundJob = (prompt: string) => {\n const job: BackgroundJob = {\n id: `bg-${++bgIdCounterRef.current}`,\n prompt,\n status: \"running\",\n startedAt: Date.now(),\n };\n backgroundJobsRef.current = [...backgroundJobsRef.current, job];\n addMessage(\"system\", `Background job ${job.id} started: ${prompt.substring(0, 60)}${prompt.length > 60 ? \"...\" : \"\"}`);\n\n // Run in background with a separate callback set\n let bgResult = \"\";\n const bgCallbacks: AgentCallbacks = {\n onToken: (token) => { bgResult += token; },\n onToolCall: () => {},\n onToolResult: () => {},\n onComplete: () => {\n job.status = \"done\";\n job.result = bgResult.trim();\n job.completedAt = Date.now();\n backgroundJobsRef.current = [...backgroundJobsRef.current];\n addMessage(\"system\", `Background job ${job.id} completed. Use /jobs ${job.id} to see results.`);\n },\n onError: (error) => {\n job.status = \"error\";\n job.error = error.message;\n job.completedAt = Date.now();\n backgroundJobsRef.current = [...backgroundJobsRef.current];\n addMessage(\"system\", `Background job ${job.id} failed: ${error.message}`);\n },\n };\n\n // Fire and forget\n sdk.agent.run(prompt, bgCallbacks).catch((err) => {\n job.status = \"error\";\n job.error = err instanceof Error ? err.message : String(err);\n job.completedAt = Date.now();\n });\n };\n\n // \u2500\u2500 Slash Commands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const handleSlashCommand = (cmd: string) => {\n const [command, ...args] = cmd.split(\" \");\n const arg = args.join(\" \").trim();\n\n switch (command) {\n case \"/clear\":\n setMessages([]);\n sdk.agent.clearHistory();\n addMessage(\"system\", \"Chat cleared.\");\n toast(\"success\", \"Chat cleared\");\n break;\n\n case \"/new\":\n setMessages([]);\n sdk.agent.clearHistory();\n totalInputRef.current = 0;\n totalOutputRef.current = 0;\n props.onTokens(0, 0);\n props.onContextPercent(0);\n conversationRef.current = createConversation(sdk.provider, sdk.model);\n addMessage(\"system\", \"New conversation started.\");\n toast(\"success\", \"New conversation started\");\n break;\n\n case \"/model\": {\n if (arg && sdk.rebuildAgent) {\n sdk.rebuildAgent(sdk.provider, arg);\n addMessage(\"system\", `Model switched to: ${arg}`);\n toast(\"info\", `Model: ${arg}`);\n } else if (arg) {\n addMessage(\"system\", \"Model switching not available.\");\n toast(\"warning\", \"Model switching not available\");\n } else {\n addMessage(\"system\", `Current model: ${sdk.model}`);\n }\n break;\n }\n\n case \"/provider\": {\n if (arg && sdk.rebuildAgent) {\n const { getDefaultModel } = require(\"@cdoing/ai\");\n const defaultModel = getDefaultModel(arg) || sdk.model;\n sdk.rebuildAgent(arg, defaultModel);\n addMessage(\"system\", `Provider switched to: ${arg} (model: ${defaultModel})`);\n toast(\"info\", `Provider: ${arg} (${defaultModel})`);\n } else if (arg) {\n addMessage(\"system\", \"Provider switching not available.\");\n toast(\"warning\", \"Provider switching not available\");\n } else {\n addMessage(\"system\", `Current provider: ${sdk.provider}`);\n }\n break;\n }\n\n case \"/mode\": {\n const currentMode = (sdk.permissionManager as any)?.mode || \"ask\";\n addMessage(\"system\", `Permission mode: ${currentMode}\\nAvailable: ask, auto-edit, auto`);\n break;\n }\n\n case \"/dir\": {\n if (arg) {\n const resolved = path.resolve(sdk.workingDir, arg);\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n if (sdk.setWorkingDir) sdk.setWorkingDir(resolved);\n addMessage(\"system\", `Working directory changed to: ${resolved}`);\n } else {\n addMessage(\"system\", `Directory not found: ${resolved}`);\n }\n } else {\n addMessage(\"system\", `Working directory: ${sdk.workingDir}`);\n }\n break;\n }\n\n case \"/config\": {\n if (arg.startsWith(\"set \")) {\n const setParts = arg.substring(4).trim().split(/\\s+/);\n if (setParts.length >= 2) {\n const [key, ...valParts] = setParts;\n const value = valParts.join(\" \");\n if (key === \"api-key\") {\n const config = loadStoredConfig();\n if (!config.apiKeys) config.apiKeys = {};\n config.apiKeys[sdk.provider] = value;\n saveConfigKey(\"apiKeys\", config.apiKeys);\n addMessage(\"system\", `API key saved for ${sdk.provider}.`);\n } else if (key === \"api-key-helper\") {\n saveConfigKey(\"apiKeyHelper\", value);\n addMessage(\"system\", `API key helper set to: ${value}`);\n } else {\n saveConfigKey(key, value);\n addMessage(\"system\", `Config ${key} set to: ${value}`);\n }\n } else {\n addMessage(\"system\", \"Usage: /config set <key> <value>\");\n }\n } else if (arg === \"show\" || !arg) {\n const config = loadStoredConfig();\n const lines = Object.entries(config)\n .filter(([k]) => k !== \"apiKeys\")\n .map(([k, v]) => ` ${k}: ${typeof v === \"object\" ? JSON.stringify(v) : v}`);\n addMessage(\"system\", lines.length > 0 ? \"Configuration:\\n\" + lines.join(\"\\n\") : \"No configuration found. Run /setup to configure.\");\n } else {\n addMessage(\"system\", \"Usage: /config [show | set <key> <value>]\");\n }\n break;\n }\n\n case \"/theme\": {\n const validModes = [\"dark\", \"light\"] as const;\n if (arg && (validModes as readonly string[]).includes(arg)) {\n setMode(arg as \"dark\" | \"light\");\n addMessage(\"system\", `Theme mode switched to: ${arg}`);\n toast(\"success\", `Mode: ${arg}`);\n } else {\n addMessage(\"system\", \"Usage: /theme dark | light (or Ctrl+T for theme picker)\");\n toast(\"warning\", \"Usage: /theme dark | light\");\n }\n break;\n }\n\n case \"/compact\":\n if ((sdk.agent as any).compressContext) {\n (sdk.agent as any).compressContext();\n addMessage(\"system\", \"Context compressed.\");\n toast(\"success\", \"Context compressed\");\n } else {\n addMessage(\"system\", \"Context compression not available.\");\n toast(\"warning\", \"Context compression not available\");\n }\n break;\n\n case \"/effort\": {\n const levels = [\"low\", \"medium\", \"high\", \"max\"];\n if (arg && levels.includes(arg)) {\n addMessage(\"system\", `Effort level set to: ${arg}`);\n toast(\"info\", `Effort: ${arg}`);\n } else {\n addMessage(\"system\", `Usage: /effort <${levels.join(\"|\")}>`);\n }\n break;\n }\n\n case \"/plan\": {\n if (arg === \"on\") {\n addMessage(\"system\", \"Plan mode enabled. Agent will propose a plan before executing.\");\n } else if (arg === \"off\") {\n addMessage(\"system\", \"Plan mode disabled.\");\n } else if (arg === \"show\") {\n addMessage(\"system\", \"No active plan.\");\n } else if (arg === \"approve\") {\n addMessage(\"system\", \"No plan to approve.\");\n } else if (arg === \"reject\") {\n addMessage(\"system\", \"No plan to reject.\");\n } else {\n addMessage(\"system\", \"Usage: /plan <on|off|show|approve|reject>\");\n }\n break;\n }\n\n case \"/permissions\": {\n const settings = loadProjectSettings();\n const allow = settings?.allow || [];\n const deny = settings?.deny || [];\n const lines: string[] = [\"Permission rules:\"];\n if (deny.length > 0) lines.push(\" Deny: \" + deny.join(\", \"));\n if (allow.length > 0) lines.push(\" Allow: \" + allow.join(\", \"));\n if (deny.length === 0 && allow.length === 0) lines.push(\" No custom rules configured.\");\n addMessage(\"system\", lines.join(\"\\n\"));\n break;\n }\n\n case \"/hooks\": {\n try {\n const hooksPath = path.join(sdk.workingDir, \".cdoing\", \"hooks.json\");\n if (fs.existsSync(hooksPath)) {\n const hooks = JSON.parse(fs.readFileSync(hooksPath, \"utf-8\"));\n const keys = Object.keys(hooks);\n addMessage(\"system\", keys.length > 0\n ? \"Configured hooks:\\n\" + keys.map((k) => ` ${k}: ${JSON.stringify(hooks[k])}`).join(\"\\n\")\n : \"No hooks configured.\");\n } else {\n addMessage(\"system\", \"No hooks file found (.cdoing/hooks.json).\");\n }\n } catch {\n addMessage(\"system\", \"No hooks configured.\");\n }\n break;\n }\n\n case \"/rules\": {\n try {\n const rulesDir = path.join(sdk.workingDir, \".cdoing\", \"rules\");\n if (fs.existsSync(rulesDir)) {\n const files = fs.readdirSync(rulesDir).filter((f: string) => f.endsWith(\".md\"));\n addMessage(\"system\", files.length > 0\n ? \"Project rules:\\n\" + files.map((f: string) => ` ${f}`).join(\"\\n\")\n : \"No rules found in .cdoing/rules/.\");\n } else {\n addMessage(\"system\", \"No rules directory found (.cdoing/rules/).\");\n }\n } catch {\n addMessage(\"system\", \"No rules configured.\");\n }\n break;\n }\n\n case \"/memory\":\n addMessage(\"system\", \"Memory store: not yet implemented in TUI. Coming soon.\");\n break;\n\n case \"/tasks\":\n addMessage(\"system\", \"Task list: not yet implemented in TUI. Coming soon.\");\n break;\n\n case \"/context\":\n addMessage(\"system\", [\n \"Context providers (use @ to invoke):\",\n \" @terminal \u2014 Recent terminal output\",\n \" @url \u2014 Fetch URL content\",\n \" @tree \u2014 Project file tree\",\n \" @codebase \u2014 Full codebase context\",\n \" @clip \u2014 Clipboard content\",\n \" @file \u2014 Include a file\",\n ].join(\"\\n\"));\n break;\n\n case \"/mcp\":\n addMessage(\"system\", \"MCP server management: not yet implemented in TUI. Coming soon.\");\n break;\n\n case \"/history\":\n case \"/ls\": {\n const convs = listConversations().slice(0, 20);\n if (convs.length > 0) {\n const lines = convs.map((c) => {\n const id = c.id.substring(0, 12);\n const date = formatRelativeDate(c.updatedAt);\n const msgCount = c.messages.filter((m) => m.role === \"user\").length;\n return ` ${id} ${date.padEnd(10)} (${msgCount} msgs) ${c.title}`;\n });\n addMessage(\"system\", \"Conversations:\\n\" + lines.join(\"\\n\") + \"\\n\\nUse /resume <id> to continue. Ctrl+S for interactive browser.\");\n } else {\n addMessage(\"system\", \"No saved conversations found.\");\n }\n break;\n }\n\n case \"/resume\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /resume <conversation-id>\");\n break;\n }\n const conv = loadConversation(arg);\n if (!conv) {\n addMessage(\"system\", `Conversation not found: ${arg}`);\n break;\n }\n // Restore conversation\n conversationRef.current = conv;\n setMessages([]);\n sdk.agent.clearHistory();\n totalInputRef.current = 0;\n totalOutputRef.current = 0;\n // Replay messages into UI\n for (const m of conv.messages) {\n if (m.role === \"user\" || m.role === \"assistant\") {\n const msg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role: m.role,\n content: m.content,\n timestamp: m.timestamp,\n };\n setMessages((prev) => [...prev, msg]);\n }\n }\n addMessage(\"system\", `Resumed conversation: ${conv.title}`);\n break;\n }\n\n case \"/view\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /view <conversation-id>\");\n break;\n }\n const conv = loadConversation(arg);\n if (!conv) {\n addMessage(\"system\", `Conversation not found: ${arg}`);\n break;\n }\n const viewMsgs = conv.messages\n .filter((m) => m.role !== \"tool\")\n .slice(-20)\n .map((m) => {\n const prefix = m.role === \"user\" ? \"\u276F\" : \"\u25C6\";\n const content = m.content.length > 100 ? m.content.substring(0, 97) + \"...\" : m.content;\n return ` ${prefix} ${content.replace(/\\n/g, \" \")}`;\n });\n addMessage(\"system\", `Conversation: ${conv.title}\\n\\n${viewMsgs.join(\"\\n\")}`);\n break;\n }\n\n case \"/fork\": {\n const sourceConv = arg ? loadConversation(arg) : conversationRef.current;\n if (!sourceConv) {\n addMessage(\"system\", arg ? `Conversation not found: ${arg}` : \"No active conversation to fork.\");\n break;\n }\n const forked = forkConversation(sourceConv);\n if (forked) {\n addMessage(\"system\", `Forked conversation: ${forked.id.substring(0, 12)} \u2014 \"${forked.title}\"`);\n } else {\n addMessage(\"system\", \"Failed to fork conversation.\");\n }\n break;\n }\n\n case \"/delete\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /delete <conversation-id>\");\n break;\n }\n if (deleteConversation(arg)) {\n addMessage(\"system\", `Conversation deleted: ${arg}`);\n } else {\n addMessage(\"system\", `Conversation not found: ${arg}`);\n }\n break;\n }\n\n case \"/bg\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /bg <prompt>\");\n break;\n }\n runBackgroundJob(arg);\n break;\n }\n\n case \"/jobs\": {\n const jobs = backgroundJobsRef.current;\n if (arg) {\n // Show specific job\n const job = jobs.find((j) => j.id === arg);\n if (job) {\n const elapsed = job.completedAt\n ? `${((job.completedAt - job.startedAt) / 1000).toFixed(1)}s`\n : `${((Date.now() - job.startedAt) / 1000).toFixed(1)}s (running)`;\n const result = job.result\n ? job.result.length > 500 ? job.result.substring(0, 497) + \"...\" : job.result\n : job.error || \"(no output)\";\n addMessage(\"system\", `Job ${job.id} [${job.status}] (${elapsed}):\\n Prompt: ${job.prompt}\\n Result: ${result}`);\n } else {\n addMessage(\"system\", `Job not found: ${arg}`);\n }\n } else if (jobs.length > 0) {\n const lines = jobs.map((j) => {\n const icon = j.status === \"running\" ? \"\u23F3\" : j.status === \"done\" ? \"\u2713\" : \"\u2717\";\n return ` ${icon} ${j.id} ${j.status} ${j.prompt.substring(0, 50)}${j.prompt.length > 50 ? \"...\" : \"\"}`;\n });\n addMessage(\"system\", \"Background jobs:\\n\" + lines.join(\"\\n\"));\n } else {\n addMessage(\"system\", \"No background jobs.\");\n }\n break;\n }\n\n case \"/btw\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /btw <question>\");\n break;\n }\n // Ephemeral question \u2014 don't add to conversation history\n const btwMsg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role: \"user\",\n content: `(btw) ${arg}`,\n timestamp: Date.now(),\n };\n setMessages((prev) => [...prev, btwMsg]);\n setIsStreaming(true);\n setStreamingText(\"\");\n props.onStatus(\"Processing...\");\n\n let btwResult = \"\";\n const btwCallbacks: AgentCallbacks = {\n onToken: (token) => {\n btwResult += token;\n setStreamingText((prev) => prev + token);\n },\n onToolCall: () => {},\n onToolResult: () => {},\n onComplete: () => {\n if (btwResult.trim()) {\n const msg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role: \"assistant\",\n content: btwResult.trim(),\n timestamp: Date.now(),\n };\n setMessages((prev) => [...prev, msg]);\n setStreamingText(\"\");\n }\n setIsStreaming(false);\n props.onStatus(\"Ready\");\n },\n onError: (error) => {\n addMessage(\"system\", `Error: ${error.message}`);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n },\n };\n\n sdk.agent.run(arg, btwCallbacks).catch((err) => {\n addMessage(\"system\", `Error: ${err instanceof Error ? err.message : String(err)}`);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n });\n break;\n }\n\n case \"/login\":\n case \"/setup\":\n if (props.onOpenDialog) {\n props.onOpenDialog(\"setup\");\n } else {\n addMessage(\"system\", \"Setup wizard: configure via ~/.cdoing/config.json or run the base CLI with --login.\");\n }\n break;\n\n case \"/logout\": {\n try {\n const { fullLogout } = require(\"@cdoing/core\");\n const msg = fullLogout(sdk.provider);\n\n // Invalidate the in-memory agent so it can't make further API calls\n sdk.agent.invalidate();\n\n addMessage(\"system\", msg);\n } catch {\n addMessage(\"system\", \"OAuth logout not available.\");\n }\n break;\n }\n\n case \"/auth-status\": {\n const config = loadStoredConfig();\n const lines: string[] = [\"Authentication Status:\", \"\"];\n\n // API keys\n lines.push(\"Stored API keys:\");\n if (config.apiKeys && Object.keys(config.apiKeys).length > 0) {\n for (const [prov, key] of Object.entries(config.apiKeys)) {\n const k = String(key);\n const masked = k.slice(0, 8) + \"...\" + k.slice(-4);\n lines.push(` \u2713 ${prov}: ${masked}`);\n }\n } else {\n lines.push(\" None\");\n }\n\n lines.push(\"\");\n lines.push(\"Environment variables:\");\n const envVars: [string, string | undefined][] = [\n [\"ANTHROPIC_API_KEY\", process.env.ANTHROPIC_API_KEY],\n [\"OPENAI_API_KEY\", process.env.OPENAI_API_KEY],\n [\"GOOGLE_API_KEY\", process.env.GOOGLE_API_KEY],\n ];\n let hasEnvKey = false;\n for (const [name, value] of envVars) {\n if (value) {\n hasEnvKey = true;\n const masked = value.slice(0, 8) + \"...\" + value.slice(-4);\n lines.push(` \u2713 ${name}: ${masked}`);\n }\n }\n if (!hasEnvKey) lines.push(\" None\");\n\n addMessage(\"system\", lines.join(\"\\n\"));\n break;\n }\n\n case \"/doctor\": {\n const checks: string[] = [\"System health check:\"];\n const config = loadStoredConfig();\n const envKey = process.env[`${sdk.provider.toUpperCase()}_API_KEY`];\n checks.push(` Provider: ${sdk.provider} ${config.apiKeys?.[sdk.provider] || envKey ? \"\u2713 API key found\" : \"\u2717 No API key\"}`);\n checks.push(` Model: ${sdk.model}`);\n checks.push(` Working dir: ${sdk.workingDir} ${fs.existsSync(sdk.workingDir) ? \"\u2713\" : \"\u2717\"}`);\n const hasCdoing = fs.existsSync(path.join(sdk.workingDir, \".cdoing\"));\n const hasClaude = fs.existsSync(path.join(sdk.workingDir, \".claude\"));\n checks.push(` Project config: ${hasCdoing ? \".cdoing/ \u2713\" : hasClaude ? \".claude/ \u2713\" : \"\u2717 none\"}`);\n checks.push(` Node: ${process.version}`);\n checks.push(` Platform: ${process.platform} ${process.arch}`);\n\n // Check conversation history\n const convs = listConversations();\n checks.push(` Conversations: ${convs.length} saved`);\n\n // Check background jobs\n const runningJobs = backgroundJobsRef.current.filter((j) => j.status === \"running\");\n if (runningJobs.length > 0) {\n checks.push(` Background jobs: ${runningJobs.length} running`);\n }\n\n addMessage(\"system\", checks.join(\"\\n\"));\n break;\n }\n\n case \"/init\": {\n const cdoingDir = path.join(sdk.workingDir, \".cdoing\");\n if (fs.existsSync(cdoingDir)) {\n addMessage(\"system\", \"Project already initialized (.cdoing/ exists).\");\n } else {\n try {\n fs.mkdirSync(cdoingDir, { recursive: true });\n fs.mkdirSync(path.join(cdoingDir, \"rules\"), { recursive: true });\n fs.writeFileSync(\n path.join(cdoingDir, \"config.md\"),\n \"# Project Configuration\\n\\nDescribe your project here for the AI assistant.\\n\",\n \"utf-8\"\n );\n addMessage(\"system\", \"Project initialized. Created .cdoing/ with config.md and rules/.\");\n } catch (err) {\n addMessage(\"system\", `Failed to initialize: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n break;\n }\n\n case \"/queue\":\n addMessage(\"system\", \"Message queue is empty.\");\n break;\n\n case \"/help\":\n addMessage(\"system\", [\n \"Available commands:\",\n \"\",\n \" Session\",\n \" /clear Clear chat history\",\n \" /new Start new conversation\",\n \" /compact Compress context window\",\n \" /btw <question> Ask without adding to history\",\n \"\",\n \" Configuration\",\n \" /model [name] Show/change model\",\n \" /provider [name] Show/change provider\",\n \" /mode Show permission mode\",\n \" /dir [path] Show/change working directory\",\n \" /config Show configuration\",\n \" /config set k v Set a config value\",\n \" /theme <mode> Switch theme (dark/light/auto)\",\n \" /effort <level> Set effort (low/medium/high/max)\",\n \" /plan <on|off> Toggle plan mode\",\n \"\",\n \" History\",\n \" /history, /ls List saved conversations\",\n \" /resume <id> Resume conversation\",\n \" /view <id> View conversation messages\",\n \" /fork [id] Fork current/specified conversation\",\n \" /delete <id> Delete conversation\",\n \"\",\n \" Background\",\n \" /bg <prompt> Run prompt in background\",\n \" /jobs [id] List/inspect background jobs\",\n \"\",\n \" System\",\n \" /permissions Show permission rules\",\n \" /hooks Show configured hooks\",\n \" /rules Show project rules\",\n \" /context Show context providers\",\n \" /mcp MCP server management\",\n \" /doctor System health check\",\n \" /usage Show token usage\",\n \" /auth-status Show authentication status\",\n \"\",\n \" /setup Run setup wizard\",\n \" /login Open setup wizard\",\n \" /logout Clear OAuth tokens\",\n \" /init Initialize project config\",\n \" /exit Quit\",\n \"\",\n \"Keyboard shortcuts:\",\n \" Ctrl+V Paste text or image\",\n \" Ctrl+U Clear input line\",\n \" Ctrl+W Delete last word\",\n \" Ctrl+N New session\",\n \" Ctrl+P Model picker\",\n \" Ctrl+S Session browser\",\n \" Tab/\u2192 Accept autocomplete\",\n \" \u2191/\u2193 Navigate suggestions\",\n \" Escape Close dropdown\",\n \"\",\n \"Shell: prefix with ! or type commands directly (ls, git, npm, etc.)\",\n \"Context: use @terminal, @url, @tree, @codebase, @clip, @file in messages\",\n ].join(\"\\n\"));\n break;\n\n case \"/usage\":\n addMessage(\"system\", `Tokens: ${totalInputRef.current.toLocaleString()}\u2192${totalOutputRef.current.toLocaleString()} (${(totalInputRef.current + totalOutputRef.current).toLocaleString()} total)`);\n break;\n\n case \"/exit\":\n case \"/quit\":\n process.exit(0);\n break;\n\n default:\n addMessage(\"system\", `Unknown command: ${command}. Type /help for available commands.`);\n toast(\"error\", `Unknown command: ${command}`);\n }\n };\n\n // \u2500\u2500 Shell Commands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const runShellCommand = (shellCmd: string) => {\n addMessage(\"user\", `!${shellCmd}`);\n let output = \"\";\n let errorMsg = \"\";\n try {\n output = execSync(shellCmd, {\n cwd: sdk.workingDir,\n env: { ...process.env },\n encoding: \"utf-8\",\n timeout: 120000,\n maxBuffer: 10 * 1024 * 1024,\n });\n } catch (err: any) {\n if (err.stdout) output = String(err.stdout);\n if (err.stderr) errorMsg = String(err.stderr);\n if (err.status !== undefined && err.status !== 0) {\n errorMsg += `\\n[exited with code ${err.status}]`;\n } else if (!err.stdout && !err.stderr && err.message) {\n errorMsg = err.message;\n }\n }\n const result = (output + (errorMsg ? `\\n${errorMsg}` : \"\")).trim();\n addMessage(\"system\", `$ ${shellCmd}\\n${result || \"(no output)\"}`);\n\n // Push to terminal context provider\n pushTerminalOutput(`$ ${shellCmd}\\n${result}`);\n };\n\n // \u2500\u2500 Interrupt: stop streaming, flush partial, send new message with context \u2500\u2500\n\n const handleInterrupt = (text: string, images?: ImageAttachment[]) => {\n // Capture partial response and interrupt \u2014 adds partial to agent history for context\n const partialResponse = streamingTextRef.current.trim();\n sdk.agent.interrupt(partialResponse);\n\n // Flush partial streaming text as a message\n if (partialResponse) {\n addMessage(\"assistant\", partialResponse + \"\\n\\n*(interrupted)*\");\n setStreamingText(\"\");\n }\n\n setIsStreaming(false);\n props.onStatus(\"Ready\");\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n setPendingInterrupt(null);\n\n // Send the new message \u2014 agent.cancel() calls onComplete which resets state,\n // so we use a small delay to let that settle\n setTimeout(() => {\n doSendMessage(text, images);\n }, 100);\n };\n\n // \u2500\u2500 Queue: add to queue, process after current stream finishes \u2500\u2500\n\n const handleQueue = (text: string) => {\n queuedMessagesRef.current.push(text);\n addMessage(\"system\", `\uD83D\uDCEC Queued message (${queuedMessagesRef.current.length} in queue)`);\n setPendingInterrupt(null);\n };\n\n // \u2500\u2500 Process queued messages after streaming completes \u2500\u2500\n\n const processQueue = () => {\n if (queuedMessagesRef.current.length > 0) {\n const next = queuedMessagesRef.current.shift()!;\n setTimeout(() => doSendMessage(next), 100);\n }\n };\n\n // \u2500\u2500 Send Message \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const sendMessage = async (text: string, images?: ImageAttachment[]) => {\n if (text.startsWith(\"/\")) {\n handleSlashCommand(text);\n return;\n }\n\n // Shell commands always run immediately\n const shellCmd = text.startsWith(\"!\")\n ? text.slice(1).trim()\n : detectShellCommand(text);\n\n if (shellCmd) {\n // Intercept \"cd\" \u2014 execSync runs in a child process, so cd has no effect there\n const shellParts = shellCmd.trim().split(/\\s+/);\n if (shellParts[0] === \"cd\") {\n const target = shellParts.slice(1).join(\" \") || process.env.HOME || \"/\";\n const resolved = path.resolve(sdk.workingDir, target);\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n if (sdk.setWorkingDir) sdk.setWorkingDir(resolved);\n addMessage(\"system\", `Working directory changed to: ${resolved}`);\n } else {\n addMessage(\"system\", `cd: no such directory: ${resolved}`);\n }\n return;\n }\n runShellCommand(shellCmd);\n return;\n }\n\n // If currently streaming, show interrupt/queue prompt\n if (isStreaming) {\n setPendingInterrupt({ text, images });\n return;\n }\n\n await doSendMessage(text, images);\n };\n\n // Auto-send initial message from home screen input\n const initialMessageSentRef = useRef(false);\n useEffect(() => {\n if (props.initialMessage && !initialMessageSentRef.current) {\n initialMessageSentRef.current = true;\n sendMessage(props.initialMessage.text, props.initialMessage.images);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n const doSendMessage = async (text: string, images?: ImageAttachment[]) => {\n // Resolve @mention context providers\n let expandedText = text;\n if (hasContextMentions(text)) {\n try {\n expandedText = await resolveContextProviders(text, sdk.workingDir);\n } catch {\n // If expansion fails, send original text\n }\n }\n\n addMessage(\"user\", text + (images && images.length > 0 ? ` [${images.length} image${images.length > 1 ? \"s\" : \"\"}]` : \"\"));\n setIsStreaming(true);\n setStreamingText(\"\");\n props.onStatus(\"Processing...\");\n\n let currentToolId: string | undefined;\n let turnInput = 0;\n\n const callbacks: AgentCallbacks = {\n onToken: (token) => {\n setStreamingText((prev) => prev + token);\n },\n\n onToolCall: (name, input) => {\n // Flush streaming text to a message\n const current = streamingTextRef.current.trim();\n if (current) {\n addMessage(\"assistant\", current);\n setStreamingText(\"\");\n }\n\n const description = (input as any)?.description || \"\";\n currentToolId = addMessage(\"tool\", description, {\n toolName: name,\n toolStatus: \"running\",\n });\n setActiveTool(name);\n props.onActiveTool(name);\n },\n\n onToolResult: (_name, result, isError) => {\n if (currentToolId) {\n const summary = result.length > 80 ? result.substring(0, 77) + \"...\" : result;\n updateMessage(currentToolId, {\n content: summary,\n toolStatus: isError ? \"error\" : \"done\",\n isError,\n });\n currentToolId = undefined;\n }\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n },\n\n onComplete: () => {\n const current = streamingTextRef.current.trim();\n if (current) {\n addMessage(\"assistant\", current);\n setStreamingText(\"\");\n }\n \n setIsStreaming(false);\n props.onStatus(\"Ready\");\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n props.onTokens(totalInputRef.current, totalOutputRef.current);\n // Process queued messages\n processQueue();\n },\n\n onError: (error) => {\n const current = streamingTextRef.current.trim();\n if (current) {\n addMessage(\"assistant\", current);\n setStreamingText(\"\");\n }\n addMessage(\"system\", `Error: ${error.message}`);\n toast(\"error\", error.message);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n },\n\n onUsage: (usage) => {\n turnInput += usage.inputTokens;\n totalInputRef.current += usage.inputTokens;\n totalOutputRef.current += usage.outputTokens;\n props.onTokens(totalInputRef.current, totalOutputRef.current);\n // Estimate context usage (rough: typical 200k window)\n const pct = Math.min(100, (turnInput / 200000) * 100);\n props.onContextPercent(pct);\n },\n };\n\n try {\n await sdk.agent.run(expandedText, callbacks, images);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n addMessage(\"system\", `Error: ${msg}`);\n toast(\"error\", msg);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n }\n };\n\n return (\n <box flexDirection=\"column\" flexGrow={1} paddingLeft={2} paddingRight={2} paddingTop={1} paddingBottom={1} gap={1}>\n {/* Scrollable message area \u2014 directly in layout for proper flex height (like OpenCode) */}\n <scrollbox\n stickyScroll={true}\n stickyStart=\"bottom\"\n flexGrow={1}\n scrollY={true}\n >\n <MessageList\n messages={messages}\n streamingText={streamingText}\n isStreaming={isStreaming}\n />\n </scrollbox>\n\n {/* Fixed bottom area \u2014 never pushed off screen */}\n <box flexDirection=\"column\" flexShrink={0}>\n {/* Permission prompt overlay */}\n {pendingPermission && (\n <PermissionPrompt\n toolName={pendingPermission.toolName}\n message={pendingPermission.message}\n onDecision={(decision) => {\n pendingPermission.resolve(decision);\n setPendingPermission(null);\n }}\n />\n )}\n\n {/* Interrupt/Queue prompt */}\n {pendingInterrupt && (\n <InterruptPrompt\n message={pendingInterrupt.text}\n onInterrupt={() => handleInterrupt(pendingInterrupt.text, pendingInterrupt.images)}\n onQueue={() => handleQueue(pendingInterrupt.text)}\n onCancel={() => setPendingInterrupt(null)}\n />\n )}\n\n {/* Loading spinner */}\n {isStreaming && !streamingText && !pendingInterrupt && (\n <LoadingSpinner label={activeTool || \"Thinking...\"} />\n )}\n\n {/* Input area */}\n <InputArea\n onSubmit={sendMessage}\n disabled={false}\n placeholder={isStreaming ? \"Type to interrupt or queue...\" : undefined}\n workingDir={sdk.workingDir}\n />\n </box>\n </box>\n );\n}\n", "/**\n * StatusBar \u2014 bottom bar with model info, tokens, context %, keybinds\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface StatusBarProps {\n provider: string;\n model: string;\n mode: string;\n workingDir: string;\n tokens?: { input: number; output: number };\n contextPercent?: number;\n activeTool?: string;\n isProcessing?: boolean;\n}\n\nexport function StatusBar(props: StatusBarProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const home = process.env.HOME || \"\";\n const shortDir = home && props.workingDir.startsWith(home)\n ? \"~\" + props.workingDir.slice(home.length)\n : props.workingDir;\n\n const tokenInfo = props.tokens\n ? ` ${props.tokens.input.toLocaleString()}\u2192${props.tokens.output.toLocaleString()}`\n : \"\";\n\n const pct = props.contextPercent ? Math.round(props.contextPercent) : 0;\n const contextBar = pct > 0 ? ` ctx:${pct}%` : \"\";\n\n return (\n <box height={1} flexDirection=\"row\" justifyContent=\"space-between\">\n <box flexDirection=\"row\">\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {` ${props.provider}`}\n </text>\n <text fg={t.textMuted}>{`/${props.model}`}</text>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.warning}>{props.mode}</text>\n {tokenInfo && (\n <>\n <text fg={t.textDim}>{\" \u2502\"}</text>\n <text fg={t.textMuted}>{tokenInfo}</text>\n </>\n )}\n {contextBar && (\n <>\n <text fg={t.textDim}>{\" \u2502\"}</text>\n <text fg={pct > 75 ? t.warning : t.textMuted}>{contextBar}</text>\n </>\n )}\n {props.activeTool && (\n <>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.toolRunning}>{`\u23F3 ${props.activeTool}`}</text>\n </>\n )}\n {props.isProcessing && !props.activeTool && (\n <>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.primary}>{\"thinking...\"}</text>\n </>\n )}\n </box>\n <box flexDirection=\"row\">\n <text fg={t.textDim}>{shortDir}</text>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.textMuted}>{\"^N:New ^P:Model ^C:Quit\"}</text>\n </box>\n </box>\n );\n}\n", "/**\n * SessionHeader \u2014 top-line session info bar.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface SessionHeaderProps {\n title: string;\n provider: string;\n model: string;\n tokens?: { input: number; output: number };\n contextPercent?: number;\n status: string;\n}\n\nexport function SessionHeader(props: SessionHeaderProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const inTok = props.tokens ? props.tokens.input.toLocaleString() : \"0\";\n const outTok = props.tokens ? props.tokens.output.toLocaleString() : \"0\";\n const pct = props.contextPercent ? Math.round(props.contextPercent) : 0;\n const pctColor = pct > 75 ? t.error : pct > 50 ? t.warning : t.success;\n const statusColor = props.status === \"Error\" ? t.error\n : props.status === \"Processing...\" ? t.warning : t.success;\n\n const left = ` \u25C6 ${props.title || \"Session\"} \u2502 ${props.provider}/${props.model} \u2502 ${inTok}\u2192${outTok} tokens`;\n\n return (\n <box height={1} flexDirection=\"row\">\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{left}</text>\n <text fg={t.border}>{\" \u2502 \"}</text>\n <text fg={pctColor}>{`${pct}%`}</text>\n <box flexGrow={1} />\n <text fg={statusColor}>{`${props.status} `}</text>\n </box>\n );\n}\n", "/**\n * SessionFooter \u2014 bottom status line with directory and shortcut hints.\n */\n\nimport { useTheme } from \"../context/theme\";\n\nexport interface SessionFooterProps {\n workingDir: string;\n isProcessing: boolean;\n}\n\nexport function SessionFooter(props: SessionFooterProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const home = process.env.HOME || \"\";\n const shortDir = home && props.workingDir.startsWith(home)\n ? \"~\" + props.workingDir.slice(home.length)\n : props.workingDir;\n\n const shortcuts = \"^N:New ^P:Model ^T:Theme ^S:Sessions ^B:Sidebar\";\n\n return (\n <box height={1} flexDirection=\"row\">\n <text fg={t.textDim}>{` ${shortDir}`}</text>\n <box flexGrow={1} />\n <text fg={t.textMuted}>{`${shortcuts} `}</text>\n </box>\n );\n}\n", "/**\n * Sidebar \u2014 collapsible right panel with sections.\n * Uses single text per line to avoid layout concatenation issues.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme } from \"../context/theme\";\n\nconst W = 34; // content width (inside the border)\n\nexport interface SidebarProps {\n provider: string;\n model: string;\n workingDir: string;\n tokens?: { input: number; output: number };\n contextPercent?: number;\n activeTool?: string;\n status: string;\n sessionTitle?: string;\n themeId?: string;\n modifiedFiles?: Array<{ path: string; additions: number; deletions: number }>;\n}\n\nfunction trunc(str: string, max: number): string {\n return str.length > max ? str.slice(0, max - 1) + \"\u2026\" : str;\n}\n\nfunction bar(pct: number, len: number): string {\n const filled = Math.round((pct / 100) * len);\n return \"\u2588\".repeat(filled) + \"\u2591\".repeat(len - filled);\n}\n\nexport function Sidebar(props: SidebarProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const home = process.env.HOME || \"\";\n const dir = home && props.workingDir.startsWith(home)\n ? \"~\" + props.workingDir.slice(home.length) : props.workingDir;\n\n const pct = props.contextPercent ? Math.round(props.contextPercent) : 0;\n const pctColor = pct > 75 ? t.error : pct > 50 ? t.warning : t.success;\n const inTok = props.tokens ? props.tokens.input.toLocaleString() : \"0\";\n const outTok = props.tokens ? props.tokens.output.toLocaleString() : \"0\";\n const statusColor = props.status === \"Error\" ? t.error\n : props.status === \"Processing...\" ? t.warning : t.success;\n\n // Each line is a single string rendered in one <text> to avoid concatenation issues\n const lines: Array<{ text: string; fg: any; bold?: boolean }> = [];\n\n const sep = () => lines.push({ text: \"\u2502\", fg: t.border });\n const header = (title: string) => {\n lines.push({ text: `\u2502 ${title}`, fg: t.primary, bold: true });\n };\n const row = (label: string, value: string, fg?: any) => {\n const padded = label ? `\u2502 ${label.padEnd(10)} ${trunc(value, W - 14)}` : `\u2502 ${trunc(value, W - 4)}`;\n lines.push({ text: padded, fg: fg || t.text });\n };\n const shortcut = (key: string, label: string) => {\n lines.push({ text: `\u2502 ${key.padEnd(10)} ${label}`, fg: t.textDim });\n };\n\n // \u2500\u2500 Session \u2500\u2500\n header(\"Session\");\n row(\"\", props.sessionTitle || \"New Session\");\n row(\"Dir\", trunc(dir, W - 14));\n row(\"Provider\", props.provider);\n row(\"Model\", props.model);\n if (props.themeId) row(\"Theme\", props.themeId);\n sep();\n\n // \u2500\u2500 Context \u2500\u2500\n header(\"Context\");\n row(\"Input\", `${inTok} tokens`);\n row(\"Output\", `${outTok} tokens`);\n lines.push({ text: `\u2502 ${bar(pct, 16)} ${pct}%`, fg: pctColor });\n sep();\n\n // \u2500\u2500 Activity \u2500\u2500\n header(\"Activity\");\n lines.push({ text: `\u2502 Status ${props.status}`, fg: statusColor });\n if (props.activeTool) {\n lines.push({ text: `\u2502 Tool ${trunc(props.activeTool, W - 14)}`, fg: t.toolRunning });\n }\n sep();\n\n // \u2500\u2500 Modified Files \u2500\u2500\n if (props.modifiedFiles && props.modifiedFiles.length > 0) {\n header(`Files (${props.modifiedFiles.length})`);\n for (const f of props.modifiedFiles.slice(0, 6)) {\n const name = f.path.split(\"/\").pop() || f.path;\n const diff = (f.additions > 0 ? ` +${f.additions}` : \"\") + (f.deletions > 0 ? ` -${f.deletions}` : \"\");\n lines.push({ text: `\u2502 ${trunc(name, W - 12)}${diff}`, fg: t.text });\n }\n if (props.modifiedFiles.length > 6) {\n lines.push({ text: `\u2502 \u2026 ${props.modifiedFiles.length - 6} more`, fg: t.textDim });\n }\n sep();\n }\n\n // \u2500\u2500 Shortcuts \u2500\u2500\n header(\"Shortcuts\");\n shortcut(\"Ctrl+B\", \"Sidebar\");\n shortcut(\"Ctrl+N\", \"New session\");\n shortcut(\"Ctrl+P\", \"Model\");\n shortcut(\"Ctrl+T\", \"Theme\");\n shortcut(\"Ctrl+S\", \"Sessions\");\n shortcut(\"Ctrl+X\", \"Commands\");\n shortcut(\"F1\", \"Help\");\n\n return (\n <box width={W + 2} flexDirection=\"column\">\n <box flexDirection=\"column\" flexGrow={1}>\n {lines.map((line, i) => (\n <text\n key={i}\n fg={line.fg}\n attributes={line.bold ? TextAttributes.BOLD : undefined}\n >\n {line.text}\n </text>\n ))}\n {/* Fill remaining space with border */}\n <box flexGrow={1}>\n <text fg={t.border}>{\"\u2502\"}</text>\n </box>\n </box>\n </box>\n );\n}\n", "/**\n * DialogModel \u2014 model picker dialog (Ctrl+P)\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface ModelOption {\n id: string;\n name: string;\n hint?: string;\n}\n\nconst MODELS: Record<string, ModelOption[]> = {\n anthropic: [\n { id: \"claude-sonnet-4-6\", name: \"Claude Sonnet 4.6\", hint: \"fast & smart\" },\n { id: \"claude-opus-4-6\", name: \"Claude Opus 4.6\", hint: \"most capable\" },\n { id: \"claude-haiku-4-5\", name: \"Claude Haiku 4.5\", hint: \"fastest\" },\n ],\n openai: [\n { id: \"gpt-4o\", name: \"GPT-4o\", hint: \"recommended\" },\n { id: \"gpt-4o-mini\", name: \"GPT-4o mini\", hint: \"fastest\" },\n { id: \"o3\", name: \"o3\", hint: \"reasoning\" },\n ],\n google: [\n { id: \"gemini-2.0-flash\", name: \"Gemini 2.0 Flash\", hint: \"fast\" },\n { id: \"gemini-2.5-pro\", name: \"Gemini 2.5 Pro\", hint: \"most capable\" },\n ],\n};\n\nexport function DialogModel(props: {\n provider: string;\n currentModel: string;\n onSelect: (model: string) => void;\n onClose: () => void;\n}) {\n const { theme } = useTheme();\n const t = theme;\n const models = MODELS[props.provider] || [];\n const [selected, setSelected] = useState(\n Math.max(0, models.findIndex((m) => m.id === props.currentModel))\n );\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\" || (key.ctrl && key.name === \"c\")) {\n props.onClose();\n } else if (key.name === \"up\" || key.name === \"k\") {\n setSelected((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelected((s) => Math.min(models.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const m = models[selected];\n if (m) props.onSelect(m.id);\n }\n });\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top=\"30%\"\n left=\"20%\"\n width=\"60%\"\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\" Select Model\"}\n </text>\n <text fg={t.textDim}>{` Provider: ${props.provider}`}</text>\n <text fg={t.textDim}>{\"\"}</text>\n {models.map((model, i) => (\n <box key={model.id}>\n <text\n fg={i === selected ? t.primary : t.text}\n attributes={i === selected ? TextAttributes.BOLD : undefined}\n >\n {` ${i === selected ? \"\u276F\" : \" \"} ${model.name}`}\n </text>\n <text fg={t.textDim}>{model.hint ? ` ${model.hint}` : \"\"}</text>\n <text fg={model.id === props.currentModel ? t.success : t.textDim}>\n {model.id === props.currentModel ? \" \u25CF\" : \"\"}\n </text>\n </box>\n ))}\n <text fg={t.textDim}>{\"\\n \u2191\u2193 Navigate Enter Select Esc Close\"}</text>\n </box>\n );\n}\n", "/**\n * DialogCommand \u2014 command palette dialog (Ctrl+X)\n *\n * A centered modal with all available commands grouped by category,\n * fuzzy search/filtering, keyboard shortcuts, and vim-style navigation.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState, useMemo, type ReactNode } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\n// \u2500\u2500 Command Definition \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Command {\n id: string;\n label: string;\n shortcut?: string;\n category: string;\n}\n\nconst COMMANDS: Command[] = [\n // Session\n { id: \"session:new\", label: \"New Session\", shortcut: \"Ctrl+N\", category: \"Session\" },\n { id: \"session:browse\", label: \"Browse Sessions\", shortcut: \"Ctrl+S\", category: \"Session\" },\n { id: \"session:clear\", label: \"Clear History\", shortcut: \"\", category: \"Session\" },\n\n // Model & Provider\n { id: \"model:switch\", label: \"Switch Model\", shortcut: \"Ctrl+P\", category: \"Model\" },\n\n // Theme & Appearance\n { id: \"theme:picker\", label: \"Browse Themes\", shortcut: \"Ctrl+T\", category: \"Appearance\" },\n { id: \"theme:dark\", label: \"Dark Mode\", shortcut: \"\", category: \"Appearance\" },\n { id: \"theme:light\", label: \"Light Mode\", shortcut: \"\", category: \"Appearance\" },\n { id: \"display:sidebar\", label: \"Toggle Sidebar\", shortcut: \"Ctrl+B\", category: \"Appearance\" },\n\n // System\n { id: \"system:status\", label: \"System Status\", shortcut: \"\", category: \"System\" },\n { id: \"system:help\", label: \"Help\", shortcut: \"F1\", category: \"System\" },\n { id: \"system:doctor\", label: \"Doctor\", shortcut: \"\", category: \"System\" },\n { id: \"system:setup\", label: \"Setup Wizard\", shortcut: \"\", category: \"System\" },\n { id: \"system:exit\", label: \"Exit\", shortcut: \"Ctrl+C\", category: \"System\" },\n];\n\n// \u2500\u2500 Fuzzy Match \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction fuzzyMatch(query: string, text: string): boolean {\n if (!query) return true;\n const lower = text.toLowerCase();\n const q = query.toLowerCase();\n let qi = 0;\n for (let i = 0; i < lower.length && qi < q.length; i++) {\n if (lower[i] === q[qi]) qi++;\n }\n return qi === q.length;\n}\n\n// \u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function DialogCommand(props: {\n onSelect: (commandId: string) => void;\n onClose: () => void;\n}) {\n const { theme } = useTheme();\n const t = theme;\n const [query, setQuery] = useState(\"\");\n const [selected, setSelected] = useState(0);\n\n // Filter commands by fuzzy search across label and category\n const filtered = useMemo(() => {\n return COMMANDS.filter(\n (cmd) => fuzzyMatch(query, cmd.label) || fuzzyMatch(query, cmd.category)\n );\n }, [query]);\n\n // Group filtered commands by category, preserving order\n const groups = useMemo(() => {\n const map = new Map<string, Command[]>();\n for (const cmd of filtered) {\n const list = map.get(cmd.category);\n if (list) {\n list.push(cmd);\n } else {\n map.set(cmd.category, [cmd]);\n }\n }\n return map;\n }, [filtered]);\n\n // Flat list for index-based navigation\n const flatList = filtered;\n\n // Clamp selected when list shrinks\n const clampedSelected = Math.min(selected, Math.max(0, flatList.length - 1));\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\") {\n props.onClose();\n return;\n }\n\n if (key.name === \"return\") {\n const cmd = flatList[clampedSelected];\n if (cmd) props.onSelect(cmd.id);\n return;\n }\n\n if (key.name === \"up\" || (key.name === \"k\" && !query)) {\n setSelected((s) => Math.max(0, s - 1));\n return;\n }\n\n if (key.name === \"down\" || (key.name === \"j\" && !query)) {\n setSelected((s) => Math.min(flatList.length - 1, s + 1));\n return;\n }\n\n // Backspace\n if (key.name === \"backspace\") {\n setQuery((q) => q.slice(0, -1));\n setSelected(0);\n return;\n }\n\n // Printable character \u2014 append to query\n if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setQuery((q) => q + key.sequence);\n setSelected(0);\n }\n });\n\n // Build rows: category headers + command items\n let flatIndex = 0;\n const rows: ReactNode[] = [];\n\n for (const [category, cmds] of groups) {\n // Category header\n rows.push(\n <text key={`cat-${category}`} fg={t.secondary} attributes={TextAttributes.BOLD}>\n {` ${category}`}\n </text>\n );\n\n for (const cmd of cmds) {\n const isSel = flatIndex === clampedSelected;\n const shortcutText = cmd.shortcut ? ` ${cmd.shortcut}` : \"\";\n rows.push(\n <box key={cmd.id} flexDirection=\"row\">\n <text\n fg={isSel ? t.primary : t.text}\n attributes={isSel ? TextAttributes.BOLD : undefined}\n >\n {` ${isSel ? \">\" : \" \"} ${cmd.label}`}\n </text>\n <text fg={t.textDim}>{shortcutText}</text>\n </box>\n );\n flatIndex++;\n }\n\n // Spacer between groups\n rows.push(\n <text key={`spacer-${category}`} fg={t.textDim}>{\"\"}</text>\n );\n }\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top=\"15%\"\n left=\"15%\"\n width=\"70%\"\n >\n {/* Title */}\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\" Command Palette\"}\n </text>\n <text fg={t.textDim}>{\"\"}</text>\n\n {/* Search input */}\n <box flexDirection=\"row\">\n <text fg={t.textMuted}>{\" > \"}</text>\n <text fg={t.text}>{query || \"\"}</text>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"_\"}</text>\n </box>\n <text fg={t.textDim}>{\"\"}</text>\n\n {/* Command list */}\n {flatList.length > 0 ? (\n rows\n ) : (\n <text fg={t.textDim}>{\" No matching commands\"}</text>\n )}\n\n {/* Footer */}\n <text fg={t.textDim}>{\" \u2191\u2193/jk Navigate Enter Select Esc Close\"}</text>\n </box>\n );\n}\n", "/**\n * DialogHelp \u2014 help dialog showing keyboard shortcuts, slash commands, and @mentions\n *\n * Opens as a centered scrollable modal. Navigate with Up/Down/PgUp/PgDn,\n * close with Esc or q.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\n// \u2500\u2500 Content Sections \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface HelpEntry {\n key: string;\n description: string;\n}\n\nconst KEYBOARD_SHORTCUTS: HelpEntry[] = [\n { key: \"Ctrl+N\", description: \"New session\" },\n { key: \"Ctrl+P\", description: \"Switch model\" },\n { key: \"Ctrl+S\", description: \"Browse sessions\" },\n { key: \"Ctrl+X\", description: \"Command palette\" },\n { key: \"F1\", description: \"Show this help\" },\n { key: \"Ctrl+V\", description: \"Paste text or image\" },\n { key: \"Ctrl+U\", description: \"Clear input line\" },\n { key: \"Ctrl+W\", description: \"Delete last word\" },\n { key: \"Tab / ->\", description: \"Accept autocomplete\" },\n { key: \"Up / Down\", description: \"Navigate suggestions\" },\n { key: \"Escape\", description: \"Close dialog / dropdown\" },\n { key: \"Ctrl+C\", description: \"Quit\" },\n];\n\nconst SLASH_COMMANDS: HelpEntry[] = [\n { key: \"/help\", description: \"Show help\" },\n { key: \"/clear\", description: \"Clear chat history\" },\n { key: \"/new\", description: \"Start new conversation\" },\n { key: \"/compact\", description: \"Compress context window\" },\n { key: \"/btw <question>\", description: \"Ask without adding to history\" },\n { key: \"/model [name]\", description: \"Show/change model\" },\n { key: \"/provider [name]\", description: \"Show/change provider\" },\n { key: \"/mode\", description: \"Show permission mode\" },\n { key: \"/dir [path]\", description: \"Show/change working directory\" },\n { key: \"/config\", description: \"Show configuration\" },\n { key: \"/config set k v\", description: \"Set a config value\" },\n { key: \"/theme <mode>\", description: \"Switch theme (dark/light/auto)\" },\n { key: \"/effort <level>\", description: \"Set effort level\" },\n { key: \"/plan <on|off>\", description: \"Toggle plan mode\" },\n { key: \"/history\", description: \"List saved conversations\" },\n { key: \"/resume <id>\", description: \"Resume conversation\" },\n { key: \"/view <id>\", description: \"View conversation messages\" },\n { key: \"/fork [id]\", description: \"Fork conversation\" },\n { key: \"/delete <id>\", description: \"Delete conversation\" },\n { key: \"/bg <prompt>\", description: \"Run prompt in background\" },\n { key: \"/jobs [id]\", description: \"List/inspect background jobs\" },\n { key: \"/permissions\", description: \"Show permission rules\" },\n { key: \"/hooks\", description: \"Show configured hooks\" },\n { key: \"/rules\", description: \"Show project rules\" },\n { key: \"/context\", description: \"Show context providers\" },\n { key: \"/mcp\", description: \"MCP server management\" },\n { key: \"/doctor\", description: \"System health check\" },\n { key: \"/usage\", description: \"Show token usage\" },\n { key: \"/auth-status\", description: \"Show authentication status\" },\n { key: \"/setup\", description: \"Run setup wizard\" },\n { key: \"/login\", description: \"Open setup wizard\" },\n { key: \"/logout\", description: \"Clear OAuth tokens\" },\n { key: \"/init\", description: \"Initialize project config\" },\n { key: \"/exit\", description: \"Quit\" },\n];\n\nconst AT_MENTIONS: HelpEntry[] = [\n { key: \"@terminal\", description: \"Recent terminal output\" },\n { key: \"@url\", description: \"Fetch URL content\" },\n { key: \"@tree\", description: \"Directory tree\" },\n { key: \"@codebase\", description: \"Search codebase\" },\n { key: \"@clip\", description: \"Clipboard contents\" },\n { key: \"@file\", description: \"Include file\" },\n];\n\n// \u2500\u2500 Build Lines \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface HelpLine {\n type: \"header\" | \"entry\" | \"blank\";\n text?: string;\n key?: string;\n description?: string;\n}\n\nfunction buildLines(): HelpLine[] {\n const lines: HelpLine[] = [];\n\n lines.push({ type: \"header\", text: \"Keyboard Shortcuts\" });\n lines.push({ type: \"blank\" });\n for (const entry of KEYBOARD_SHORTCUTS) {\n lines.push({ type: \"entry\", key: entry.key, description: entry.description });\n }\n\n lines.push({ type: \"blank\" });\n lines.push({ type: \"header\", text: \"Slash Commands\" });\n lines.push({ type: \"blank\" });\n for (const entry of SLASH_COMMANDS) {\n lines.push({ type: \"entry\", key: entry.key, description: entry.description });\n }\n\n lines.push({ type: \"blank\" });\n lines.push({ type: \"header\", text: \"@Mentions\" });\n lines.push({ type: \"blank\" });\n for (const entry of AT_MENTIONS) {\n lines.push({ type: \"entry\", key: entry.key, description: entry.description });\n }\n\n return lines;\n}\n\nconst ALL_LINES = buildLines();\nconst PAGE_SIZE = 15;\n\n// \u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function DialogHelp(props: {\n onClose: () => void;\n}) {\n const { theme } = useTheme();\n const t = theme;\n const [scrollOffset, setScrollOffset] = useState(0);\n\n const maxOffset = Math.max(0, ALL_LINES.length - PAGE_SIZE);\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\" || key.name === \"q\") {\n props.onClose();\n return;\n }\n\n if (key.name === \"up\" || key.name === \"k\") {\n setScrollOffset((s) => Math.max(0, s - 1));\n return;\n }\n\n if (key.name === \"down\" || key.name === \"j\") {\n setScrollOffset((s) => Math.min(maxOffset, s + 1));\n return;\n }\n\n if (key.name === \"pageup\") {\n setScrollOffset((s) => Math.max(0, s - PAGE_SIZE));\n return;\n }\n\n if (key.name === \"pagedown\") {\n setScrollOffset((s) => Math.min(maxOffset, s + PAGE_SIZE));\n return;\n }\n\n // Home / End\n if (key.name === \"home\") {\n setScrollOffset(0);\n return;\n }\n if (key.name === \"end\") {\n setScrollOffset(maxOffset);\n return;\n }\n });\n\n const visibleLines = ALL_LINES.slice(scrollOffset, scrollOffset + PAGE_SIZE);\n const keyColWidth = 20;\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n paddingX={2}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top=\"10%\"\n left=\"15%\"\n width=\"70%\"\n height=\"80%\"\n >\n {/* Title */}\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\" Help\"}\n </text>\n <text fg={t.textDim}>{\"\"}</text>\n\n {/* Scrollable content */}\n {visibleLines.map((line, i) => {\n if (line.type === \"blank\") {\n return <text key={`line-${scrollOffset + i}`} fg={t.textDim}>{\"\"}</text>;\n }\n\n if (line.type === \"header\") {\n return (\n <text\n key={`line-${scrollOffset + i}`}\n fg={t.primary}\n attributes={TextAttributes.BOLD}\n >\n {` ${line.text}`}\n </text>\n );\n }\n\n // entry\n const paddedKey = (line.key || \"\").padEnd(keyColWidth);\n return (\n <box key={`line-${scrollOffset + i}`} flexDirection=\"row\">\n <text fg={t.secondary}>{` ${paddedKey}`}</text>\n <text fg={t.textMuted}>{line.description || \"\"}</text>\n </box>\n );\n })}\n\n {/* Scroll indicator */}\n <text fg={t.textDim}>{\"\"}</text>\n <text fg={t.textDim}>\n {` ${scrollOffset > 0 ? \"...\" : \" \"} ${scrollOffset + 1}-${Math.min(scrollOffset + PAGE_SIZE, ALL_LINES.length)} of ${ALL_LINES.length} ${scrollOffset < maxOffset ? \"...\" : \" \"}`}\n </text>\n\n {/* Footer */}\n <text fg={t.textDim}>{\" Up/Down/j/k Scroll PgUp/PgDn Page Esc/q Close\"}</text>\n </box>\n );\n}\n", "/**\n * DialogTheme \u2014 theme picker dialog (Ctrl+T)\n *\n * Three sections navigable with Tab:\n * 1. Appearance \u2014 Dark / Light mode toggle\n * 2. Custom Background \u2014 type a hex color for terminal bg (or clear to use theme default)\n * 3. Color Themes \u2014 browse / search built-in themes with live preview\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState, useMemo } from \"react\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme, THEMES, getThemeIds } from \"../context/theme\";\n\ntype Section = \"mode\" | \"custombg\" | \"themes\";\nconst SECTIONS: Section[] = [\"mode\", \"custombg\", \"themes\"];\n\nexport function DialogTheme(props: {\n onClose: () => void;\n}) {\n const { theme, themeId, mode, customBg, setThemeId, setMode, setCustomBg } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n\n const initialThemeId = themeId;\n const initialMode = mode;\n const initialCustomBg = customBg;\n const themeIds = getThemeIds();\n\n const [section, setSection] = useState<Section>(\"mode\");\n const [modeSelected, setModeSelected] = useState<number>(mode === \"dark\" ? 0 : 1);\n const [bgInput, setBgInput] = useState(customBg || \"\");\n const [query, setQuery] = useState(\"\");\n const [selected, setSelected] = useState(\n Math.max(0, themeIds.indexOf(themeId))\n );\n\n const filtered = useMemo(() => {\n if (!query) return themeIds;\n const q = query.toLowerCase();\n return themeIds.filter((id) => {\n const def = THEMES[id];\n return id.toLowerCase().includes(q) || def.name.toLowerCase().includes(q);\n });\n }, [query, themeIds]);\n\n const clampedSelected = Math.min(selected, Math.max(0, filtered.length - 1));\n\n const maxVisible = Math.max(5, Math.min(filtered.length, (dims.height || 24) - 18));\n const scrollOffset = Math.max(0, clampedSelected - maxVisible + 3);\n const visibleItems = filtered.slice(scrollOffset, scrollOffset + maxVisible);\n\n const modeOptions: Array<{ id: \"dark\" | \"light\"; label: string }> = [\n { id: \"dark\", label: \"Dark Mode\" },\n { id: \"light\", label: \"Light Mode\" },\n ];\n\n const nextSection = () => {\n setSection((s) => {\n const idx = SECTIONS.indexOf(s);\n return SECTIONS[(idx + 1) % SECTIONS.length];\n });\n };\n\n const isValidHex = (s: string): boolean => /^#[0-9a-fA-F]{6}$/.test(s);\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\") {\n setThemeId(initialThemeId);\n setMode(initialMode);\n setCustomBg(initialCustomBg);\n props.onClose();\n return;\n }\n\n if (key.name === \"tab\") {\n nextSection();\n return;\n }\n\n // \u2500\u2500 Mode section \u2500\u2500\n if (section === \"mode\") {\n if (key.name === \"up\" || key.name === \"k\") {\n setModeSelected((s) => Math.max(0, s - 1));\n return;\n }\n if (key.name === \"down\" || key.name === \"j\") {\n setModeSelected((s) => Math.min(modeOptions.length - 1, s + 1));\n return;\n }\n if (key.name === \"return\") {\n setMode(modeOptions[modeSelected].id);\n nextSection();\n return;\n }\n return;\n }\n\n // \u2500\u2500 Custom BG section \u2500\u2500\n if (section === \"custombg\") {\n if (key.name === \"return\") {\n if (bgInput === \"\" || bgInput === \"none\") {\n setCustomBg(null);\n } else if (isValidHex(bgInput)) {\n setCustomBg(bgInput);\n }\n nextSection();\n return;\n }\n if (key.name === \"backspace\") {\n setBgInput((s) => s.slice(0, -1));\n return;\n }\n if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setBgInput((s) => {\n const next = s + key.sequence;\n // Live preview if valid hex\n if (isValidHex(next)) {\n setCustomBg(next);\n }\n return next;\n });\n return;\n }\n return;\n }\n\n // \u2500\u2500 Themes section \u2500\u2500\n if (key.name === \"return\") {\n props.onClose();\n return;\n }\n\n if (key.name === \"up\" || (key.name === \"k\" && !query)) {\n setSelected((s) => {\n const next = Math.max(0, s - 1);\n const id = filtered[next];\n if (id) setThemeId(id);\n return next;\n });\n return;\n }\n\n if (key.name === \"down\" || (key.name === \"j\" && !query)) {\n setSelected((s) => {\n const next = Math.min(filtered.length - 1, s + 1);\n const id = filtered[next];\n if (id) setThemeId(id);\n return next;\n });\n return;\n }\n\n if (key.name === \"backspace\") {\n setQuery((q) => q.slice(0, -1));\n setSelected(0);\n return;\n }\n\n if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setQuery((q) => {\n const newQ = q + key.sequence;\n const q2 = newQ.toLowerCase();\n const first = themeIds.find((id) => {\n const def = THEMES[id];\n return id.toLowerCase().includes(q2) || def.name.toLowerCase().includes(q2);\n });\n if (first) setThemeId(first);\n return newQ;\n });\n setSelected(0);\n }\n });\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top=\"10%\"\n left=\"20%\"\n width=\"60%\"\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\" Themes\"}\n </text>\n <text fg={t.textDim}>\n {` Mode: ${mode} \u2022 ${filtered.length} themes${customBg ? ` \u2022 BG: ${customBg}` : \"\"}`}\n </text>\n <text>{\"\"}</text>\n\n {/* \u2500\u2500 Appearance \u2500\u2500 */}\n <text\n fg={section === \"mode\" ? t.primary : t.textDim}\n attributes={section === \"mode\" ? TextAttributes.BOLD : undefined}\n >\n {\" Appearance\"}\n </text>\n {modeOptions.map((opt, i) => {\n const isSel = section === \"mode\" && i === modeSelected;\n const isActive = opt.id === mode;\n return (\n <box key={opt.id} flexDirection=\"row\">\n <text\n fg={isSel ? t.primary : t.text}\n attributes={isSel ? TextAttributes.BOLD : undefined}\n >\n {` ${isSel ? \">\" : \" \"} ${opt.label}`}\n </text>\n {isActive && <text fg={t.success}>{\" *\"}</text>}\n </box>\n );\n })}\n <text>{\"\"}</text>\n\n {/* \u2500\u2500 Custom Background \u2500\u2500 */}\n <text\n fg={section === \"custombg\" ? t.primary : t.textDim}\n attributes={section === \"custombg\" ? TextAttributes.BOLD : undefined}\n >\n {\" Custom Background\"}\n </text>\n <box flexDirection=\"row\">\n <text fg={t.textMuted}>{\" Hex: \"}</text>\n {section === \"custombg\" ? (\n <>\n <text fg={isValidHex(bgInput) ? t.success : t.text}>{bgInput || \"\"}</text>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"_\"}</text>\n </>\n ) : (\n <text fg={customBg ? t.success : t.textDim}>{customBg || \"(theme default)\"}</text>\n )}\n </box>\n {section === \"custombg\" && (\n <text fg={t.textDim}>{\" Type #rrggbb hex, empty to clear. Enter to apply.\"}</text>\n )}\n <text>{\"\"}</text>\n\n {/* \u2500\u2500 Color Themes \u2500\u2500 */}\n <text\n fg={section === \"themes\" ? t.primary : t.textDim}\n attributes={section === \"themes\" ? TextAttributes.BOLD : undefined}\n >\n {\" Color Themes\"}\n </text>\n\n {section === \"themes\" && (\n <box flexDirection=\"row\">\n <text fg={t.textMuted}>{\" > \"}</text>\n <text fg={t.text}>{query || \"\"}</text>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"_\"}</text>\n </box>\n )}\n\n {visibleItems.length > 0 ? (\n visibleItems.map((id) => {\n const def = THEMES[id];\n const idx = filtered.indexOf(id);\n const isSel = section === \"themes\" && idx === clampedSelected;\n const isCurrent = id === themeId;\n\n return (\n <box key={id} flexDirection=\"row\">\n <text\n fg={isSel ? t.primary : t.text}\n attributes={isSel ? TextAttributes.BOLD : undefined}\n >\n {` ${isSel ? \">\" : \" \"} ${def.name}`}\n </text>\n <text fg={t.textDim}>{` ${id}`}</text>\n {isCurrent && <text fg={t.success}>{\" *\"}</text>}\n </box>\n );\n })\n ) : (\n <text fg={t.textDim}>{\" No matching themes\"}</text>\n )}\n\n {filtered.length > maxVisible && (\n <text fg={t.textDim}>\n {` ... ${filtered.length - maxVisible} more`}\n </text>\n )}\n\n <text>{\"\"}</text>\n <text fg={t.textDim}>{\" Tab Switch section Up/Down Navigate Enter Select Esc Cancel\"}</text>\n </box>\n );\n}\n", "/**\n * SessionBrowser \u2014 Interactive TUI overlay for browsing saved conversations\n *\n * Features:\n * - Arrow keys to navigate\n * - Enter to resume a conversation\n * - d to delete, f to fork, v to view\n * - Escape to close\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState, useMemo } from \"react\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport {\n listConversations,\n deleteConversation,\n forkConversation,\n formatRelativeDate,\n type Conversation,\n} from \"../lib/history\";\n\nexport interface SessionBrowserProps {\n onResume: (conv: Conversation) => void;\n onClose: () => void;\n}\n\nexport function SessionBrowser(props: SessionBrowserProps) {\n const { theme } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n\n const [conversations, setConversations] = useState(() => listConversations());\n const [selected, setSelected] = useState(0);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [viewMode, setViewMode] = useState(false);\n const [viewScroll, setViewScroll] = useState(0);\n\n const maxVisible = Math.max(5, Math.floor((dims.height || 20) - 10));\n\n const scrollOffset = useMemo(() => {\n if (selected < maxVisible) return 0;\n return selected - maxVisible + 1;\n }, [selected, maxVisible]);\n\n const visibleConvs = conversations.slice(scrollOffset, scrollOffset + maxVisible);\n\n useKeyboard((key: any) => {\n if (viewMode) {\n // View mode controls\n if (key.name === \"escape\" || key.name === \"q\") {\n setViewMode(false);\n setViewScroll(0);\n } else if (key.name === \"up\" || key.name === \"k\") {\n setViewScroll((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n const conv = conversations[selected];\n if (conv) {\n const msgs = conv.messages.filter((m) => m.role !== \"tool\");\n setViewScroll((s) => Math.min(msgs.length - 1, s + 1));\n }\n } else if (key.name === \"return\") {\n const conv = conversations[selected];\n if (conv) props.onResume(conv);\n }\n return;\n }\n\n if (confirmDelete) {\n if (key.name === \"y\") {\n const conv = conversations[selected];\n if (conv) {\n deleteConversation(conv.id);\n const updated = listConversations();\n setConversations(updated);\n setSelected((s) => Math.min(s, updated.length - 1));\n }\n setConfirmDelete(false);\n } else {\n setConfirmDelete(false);\n }\n return;\n }\n\n if (key.name === \"escape\" || key.name === \"q\") {\n props.onClose();\n } else if (key.name === \"up\" || key.name === \"k\") {\n setSelected((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelected((s) => Math.min(conversations.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const conv = conversations[selected];\n if (conv) props.onResume(conv);\n } else if (key.name === \"d\") {\n if (conversations.length > 0) setConfirmDelete(true);\n } else if (key.name === \"f\") {\n const conv = conversations[selected];\n if (conv) {\n const forked = forkConversation(conv);\n if (forked) {\n setConversations(listConversations());\n }\n }\n } else if (key.name === \"v\") {\n if (conversations.length > 0) {\n setViewMode(true);\n setViewScroll(0);\n }\n }\n });\n\n if (conversations.length === 0) {\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n paddingX={2}\n paddingY={1}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"Sessions\"}\n </text>\n <text fg={t.textDim}>{\"\\nNo saved conversations.\\n\"}</text>\n <text fg={t.textMuted}>{\"Esc Close\"}</text>\n </box>\n );\n }\n\n // View mode \u2014 show messages from selected conversation\n if (viewMode) {\n const conv = conversations[selected];\n const msgs = conv ? conv.messages.filter((m) => m.role !== \"tool\") : [];\n const visibleMsgs = msgs.slice(viewScroll, viewScroll + maxVisible);\n const total = msgs.length;\n\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n paddingX={1}\n paddingY={0}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {`Viewing: ${conv?.title || \"Untitled\"}`}\n </text>\n <text fg={t.textDim}>\n {`${viewScroll + 1}\u2013${Math.min(viewScroll + maxVisible, total)} of ${total} messages`}\n </text>\n <text>{\"\"}</text>\n {visibleMsgs.map((m, i) => {\n const prefix = m.role === \"user\" ? \"\u276F\" : \"\u25C6\";\n const color = m.role === \"user\" ? t.success : t.text;\n const content = m.content.length > 120 ? m.content.substring(0, 117) + \"...\" : m.content;\n return (\n <text key={`view-${viewScroll + i}`} fg={color}>\n {` ${prefix} ${content.replace(/\\n/g, \" \")}`}\n </text>\n );\n })}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" \u2191\u2193 Scroll Enter Resume Esc Back\"}</text>\n </box>\n );\n }\n\n // List mode\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n paddingX={1}\n paddingY={0}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"Sessions\"}\n </text>\n <text fg={t.textDim}>\n {`${conversations.length} conversation${conversations.length !== 1 ? \"s\" : \"\"}`}\n </text>\n <text>{\"\"}</text>\n {visibleConvs.map((conv, i) => {\n const idx = scrollOffset + i;\n const isSelected = idx === selected;\n const date = formatRelativeDate(conv.updatedAt);\n const msgCount = conv.messages.filter((m) => m.role === \"user\").length;\n const title = conv.title.length > 40 ? conv.title.substring(0, 37) + \"...\" : conv.title;\n\n return (\n <box key={conv.id} flexDirection=\"row\">\n <text\n fg={isSelected ? t.primary : t.textMuted}\n attributes={isSelected ? TextAttributes.BOLD : undefined}\n >\n {` ${isSelected ? \"\u276F\" : \" \"} ${title}`}\n </text>\n <text fg={t.textDim}>\n {` ${date} (${msgCount} msgs)`}\n </text>\n </box>\n );\n })}\n {confirmDelete && (\n <box>\n <text>{\"\"}</text>\n <text fg={t.warning} attributes={TextAttributes.BOLD}>\n {` Delete \"${conversations[selected]?.title}\"? (y/n)`}\n </text>\n </box>\n )}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" \u2191\u2193 Navigate Enter Resume v View d Delete f Fork Esc Close\"}</text>\n </box>\n );\n}\n", "/**\n * SetupWizard \u2014 Interactive setup overlay for configuring provider, model, API key, or OAuth\n *\n * Steps:\n * 1. Select provider\n * 2. Select auth method (API key or OAuth \u2014 Anthropic only)\n * 3. Select model\n * 4. Enter API key / OAuth code\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { execSync } from \"child_process\";\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState, useRef, useEffect } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface SetupWizardProps {\n onComplete: (config: { provider: string; model: string; apiKey?: string; oauthToken?: string }) => void;\n onClose: () => void;\n}\n\nconst PROVIDERS = [\n { id: \"anthropic\", name: \"Anthropic (Claude)\", hint: \"Claude Sonnet, Opus, Haiku\" },\n { id: \"openai\", name: \"OpenAI\", hint: \"GPT-4o, o3\" },\n { id: \"google\", name: \"Google AI\", hint: \"Gemini 2.0 Flash, 2.5 Pro\" },\n { id: \"ollama\", name: \"Ollama (Local)\", hint: \"No API key needed\" },\n];\n\nconst AUTH_METHODS = [\n { id: \"apikey\", name: \"API Key\", hint: \"all models available - console.anthropic.com\" },\n { id: \"oauth\", name: \"OAuth\", hint: \"Claude Pro/Max - opens browser\" },\n];\n\nconst MODELS: Record<string, { id: string; name: string; hint?: string }[]> = {\n anthropic: [\n { id: \"claude-sonnet-4-6\", name: \"Claude Sonnet 4.6\", hint: \"recommended - fast & smart\" },\n { id: \"claude-opus-4-6\", name: \"Claude Opus 4.6\", hint: \"most capable\" },\n { id: \"claude-haiku-4-5-20251001\", name: \"Claude Haiku 4.5\", hint: \"fastest\" },\n ],\n openai: [\n { id: \"gpt-4o\", name: \"GPT-4o\", hint: \"recommended\" },\n { id: \"gpt-4o-mini\", name: \"GPT-4o mini\", hint: \"fastest\" },\n { id: \"o3\", name: \"o3\", hint: \"reasoning\" },\n ],\n google: [\n { id: \"gemini-2.0-flash\", name: \"Gemini 2.0 Flash\", hint: \"recommended\" },\n { id: \"gemini-2.5-pro\", name: \"Gemini 2.5 Pro\", hint: \"most capable\" },\n ],\n ollama: [\n { id: \"llama3.1\", name: \"Llama 3.1\", hint: \"general purpose\" },\n { id: \"codellama\", name: \"Code Llama\", hint: \"code-focused\" },\n { id: \"mistral\", name: \"Mistral\", hint: \"fast & capable\" },\n ],\n};\n\nconst OAUTH_MODELS = [\n { id: \"claude-haiku-4-5\", name: \"Claude Haiku 4.5\", hint: \"only model supported with OAuth\" },\n];\n\nconst ENV_VARS: Record<string, string> = {\n anthropic: \"ANTHROPIC_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n google: \"GOOGLE_API_KEY\",\n};\n\nconst KEY_URLS: Record<string, string> = {\n anthropic: \"https://console.anthropic.com/settings/keys\",\n openai: \"https://platform.openai.com/api-keys\",\n google: \"https://aistudio.google.com/apikey\",\n};\n\ntype Step = \"provider\" | \"auth-method\" | \"model\" | \"apikey\" | \"oauth-paste\" | \"oauth-exchanging\";\n\nfunction openBrowser(url: string): void {\n try {\n const cmd = process.platform === \"darwin\" ? `open \"${url}\"`\n : process.platform === \"win32\" ? `start \"\" \"${url}\"`\n : `xdg-open \"${url}\"`;\n execSync(cmd, { stdio: \"ignore\", timeout: 3000 });\n } catch { /* browser open is best-effort */ }\n}\n\nexport function SetupWizard(props: SetupWizardProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const [step, setStep] = useState<Step>(\"provider\");\n const [selectedProvider, setSelectedProvider] = useState(0);\n const [selectedAuth, setSelectedAuth] = useState(0);\n const [selectedModel, setSelectedModel] = useState(0);\n const [authMethod, setAuthMethod] = useState<\"apikey\" | \"oauth\">(\"apikey\");\n const [chosenProviderId, setChosenProviderId] = useState(\"anthropic\");\n const [chosenModelId, setChosenModelId] = useState(\"\");\n const [apiKeyInput, setApiKeyInput] = useState(\"\");\n const [showKey, setShowKey] = useState(false);\n const [error, setError] = useState(\"\");\n\n // OAuth state\n const [oauthUrl, setOauthUrl] = useState(\"\");\n const [oauthVerifier, setOauthVerifier] = useState(\"\");\n const [oauthCodeInput, setOauthCodeInput] = useState(\"\");\n const [showCode, setShowCode] = useState(false);\n const [oauthError, setOauthError] = useState(\"\");\n const exchangingRef = useRef(false);\n\n const provider = PROVIDERS[selectedProvider];\n const models = authMethod === \"oauth\" ? OAUTH_MODELS : (MODELS[chosenProviderId] || []);\n\n // Generate OAuth URL when entering oauth-paste step\n useEffect(() => {\n if (step !== \"oauth-paste\") return;\n try {\n const { generateOAuthUrl } = require(\"@cdoing/core\");\n const { url, codeVerifier } = generateOAuthUrl(chosenProviderId);\n setOauthUrl(url);\n setOauthVerifier(codeVerifier);\n setOauthCodeInput(\"\");\n setOauthError(\"\");\n openBrowser(url);\n } catch {\n setOauthError(\"OAuth not available. Install @cdoing/core with OAuth support.\");\n }\n }, [step, chosenProviderId]);\n\n useKeyboard((key: any) => {\n // Escape \u2014 go back or close\n if (key.name === \"escape\") {\n if (step === \"oauth-paste\" || step === \"oauth-exchanging\") {\n setStep(\"model\");\n setOauthError(\"\");\n } else if (step === \"apikey\") {\n setStep(\"model\");\n setError(\"\");\n } else if (step === \"model\") {\n setStep(chosenProviderId === \"anthropic\" ? \"auth-method\" : \"provider\");\n } else if (step === \"auth-method\") {\n setStep(\"provider\");\n } else {\n props.onClose();\n }\n return;\n }\n\n // \u2500\u2500 Step 1: Provider \u2500\u2500\n if (step === \"provider\") {\n if (key.name === \"up\" || key.name === \"k\") {\n setSelectedProvider((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelectedProvider((s) => Math.min(PROVIDERS.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const p = PROVIDERS[selectedProvider];\n setChosenProviderId(p.id);\n setSelectedModel(0);\n if (p.id === \"anthropic\") {\n setSelectedAuth(0);\n setStep(\"auth-method\");\n } else {\n setAuthMethod(\"apikey\");\n setStep(\"model\");\n }\n }\n return;\n }\n\n // \u2500\u2500 Step 2: Auth method (Anthropic only) \u2500\u2500\n if (step === \"auth-method\") {\n if (key.name === \"up\" || key.name === \"k\") {\n setSelectedAuth((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelectedAuth((s) => Math.min(AUTH_METHODS.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const auth = AUTH_METHODS[selectedAuth].id as \"apikey\" | \"oauth\";\n setAuthMethod(auth);\n setSelectedModel(0);\n setStep(\"model\");\n }\n return;\n }\n\n // \u2500\u2500 Step 3: Model \u2500\u2500\n if (step === \"model\") {\n if (key.name === \"up\" || key.name === \"k\") {\n setSelectedModel((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelectedModel((s) => Math.min(models.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const m = models[selectedModel];\n setChosenModelId(m.id);\n if (chosenProviderId === \"ollama\") {\n saveAndComplete(chosenProviderId, m.id, undefined);\n } else if (authMethod === \"oauth\") {\n exchangingRef.current = false;\n setStep(\"oauth-paste\");\n } else {\n setStep(\"apikey\");\n setApiKeyInput(\"\");\n setError(\"\");\n }\n }\n return;\n }\n\n // \u2500\u2500 Step 4a: API key \u2500\u2500\n if (step === \"apikey\") {\n if (key.name === \"return\") {\n if (!apiKeyInput.trim()) {\n setError(\"API key cannot be empty\");\n return;\n }\n saveAndComplete(chosenProviderId, chosenModelId, apiKeyInput.trim());\n } else if (key.ctrl && key.name === \"s\") {\n setShowKey((s) => !s);\n } else if (key.name === \"backspace\") {\n setApiKeyInput((s) => s.slice(0, -1));\n setError(\"\");\n } else if (key.ctrl && key.name === \"u\") {\n setApiKeyInput(\"\");\n setError(\"\");\n } else if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setApiKeyInput((s) => s + key.sequence);\n setError(\"\");\n }\n return;\n }\n\n // \u2500\u2500 Step 4b: OAuth code paste \u2500\u2500\n if (step === \"oauth-paste\") {\n if (key.name === \"return\") {\n const code = oauthCodeInput.trim();\n if (!code || exchangingRef.current) return;\n exchangingRef.current = true;\n setStep(\"oauth-exchanging\");\n try {\n const { exchangeOAuthCode } = require(\"@cdoing/core\");\n exchangeOAuthCode(code, oauthVerifier, chosenProviderId)\n .then((tokens: any) => {\n saveAndComplete(chosenProviderId, chosenModelId, undefined);\n props.onComplete({\n provider: chosenProviderId,\n model: chosenModelId,\n oauthToken: tokens.access_token,\n });\n })\n .catch((err: Error) => {\n exchangingRef.current = false;\n setOauthError(err.message);\n setStep(\"oauth-paste\");\n });\n } catch {\n exchangingRef.current = false;\n setOauthError(\"OAuth exchange failed\");\n setStep(\"oauth-paste\");\n }\n return;\n }\n if (key.ctrl && key.name === \"s\") {\n setShowCode((s) => !s);\n } else if (key.name === \"backspace\") {\n setOauthCodeInput((s) => s.slice(0, -1));\n setOauthError(\"\");\n } else if (key.ctrl && key.name === \"u\") {\n setOauthCodeInput(\"\");\n setOauthError(\"\");\n } else if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setOauthCodeInput((s) => s + key.sequence);\n setOauthError(\"\");\n }\n return;\n }\n });\n\n const saveAndComplete = (prov: string, model: string, apiKey?: string) => {\n const configDir = path.join(os.homedir(), \".cdoing\");\n const configPath = path.join(configDir, \"config.json\");\n\n let config: Record<string, any> = {};\n try {\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n\n config.provider = prov;\n config.model = model;\n if (apiKey) {\n if (!config.apiKeys) config.apiKeys = {};\n config.apiKeys[prov] = apiKey;\n }\n\n if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n props.onComplete({ provider: prov, model, apiKey });\n };\n\n // Step numbers for display\n const isAnthropic = chosenProviderId === \"anthropic\";\n const total = isAnthropic ? 4 : chosenProviderId === \"ollama\" ? 2 : 3;\n const stepLabel = (s: Step): string => {\n switch (s) {\n case \"provider\": return `1/${total}`;\n case \"auth-method\": return \"2/4\";\n case \"model\": return isAnthropic ? \"3/4\" : chosenProviderId === \"ollama\" ? \"2/2\" : \"2/3\";\n case \"apikey\": return isAnthropic ? \"4/4\" : \"3/3\";\n case \"oauth-paste\": return \"4/4\";\n case \"oauth-exchanging\": return \"4/4\";\n default: return \"\";\n }\n };\n\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n paddingX={2}\n paddingY={1}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"Setup Wizard\"}\n </text>\n <text>{\"\"}</text>\n\n {/* Step 1: Provider */}\n {step === \"provider\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"provider\")}: Select Provider`}\n </text>\n <text>{\"\"}</text>\n {PROVIDERS.map((p, i) => (\n <text\n key={p.id}\n fg={selectedProvider === i ? t.primary : t.textMuted}\n attributes={selectedProvider === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selectedProvider === i ? \">\" : \" \"} ${p.name} ${selectedProvider === i ? p.hint : \"\"}`}\n </text>\n ))}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Up/Down Navigate Enter Select Esc Cancel\"}</text>\n </box>\n )}\n\n {/* Step 2: Auth method (Anthropic only) */}\n {step === \"auth-method\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"auth-method\")}: How do you want to authenticate?`}\n </text>\n <text>{\"\"}</text>\n {AUTH_METHODS.map((a, i) => (\n <text\n key={a.id}\n fg={selectedAuth === i ? t.primary : t.textMuted}\n attributes={selectedAuth === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selectedAuth === i ? \">\" : \" \"} ${a.name} ${selectedAuth === i ? a.hint : \"\"}`}\n </text>\n ))}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Up/Down Navigate Enter Select Esc Back\"}</text>\n </box>\n )}\n\n {/* Step 3: Model */}\n {step === \"model\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {authMethod === \"oauth\"\n ? `Step ${stepLabel(\"model\")}: Select Model (OAuth supports Haiku only)`\n : `Step ${stepLabel(\"model\")}: Select Model (${provider.name})`}\n </text>\n <text>{\"\"}</text>\n {models.map((m, i) => (\n <text\n key={m.id}\n fg={selectedModel === i ? t.primary : t.textMuted}\n attributes={selectedModel === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selectedModel === i ? \">\" : \" \"} ${m.name}${m.hint ? ` ${m.hint}` : \"\"}`}\n </text>\n ))}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Up/Down Navigate Enter Select Esc Back\"}</text>\n </box>\n )}\n\n {/* Step 4a: API key */}\n {step === \"apikey\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"apikey\")}: Enter API Key`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.textDim}>\n {` Provider: ${chosenProviderId} Model: ${chosenModelId}`}\n </text>\n {KEY_URLS[chosenProviderId] && (\n <text fg={t.textDim}>\n {` Get a key: ${KEY_URLS[chosenProviderId]}`}\n </text>\n )}\n <text fg={t.textDim}>\n {` Environment variable: ${ENV_VARS[chosenProviderId] || \"N/A\"}`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.text}>\n {` > ${showKey ? apiKeyInput : apiKeyInput.replace(/./g, \"*\")}|`}\n </text>\n {error && (\n <text fg={t.error}>{`\\n ${error}`}</text>\n )}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Enter Save Ctrl+S Toggle visibility Ctrl+U Clear Esc Back\"}</text>\n </box>\n )}\n\n {/* Step 4b: OAuth paste */}\n {step === \"oauth-paste\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"oauth-paste\")}: OAuth Login`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.text}>{\" 1. Browser opening to Claude login...\"}</text>\n {oauthUrl ? (\n <text fg={t.textDim}>{` If it didn't open: ${oauthUrl.substring(0, 70)}...`}</text>\n ) : null}\n <text fg={t.text}>{\" 2. Approve -> you'll land on a page with a code in the URL\"}</text>\n <text fg={t.text}>{\" 3. Copy the code= value from the URL and paste below\"}</text>\n {oauthError ? (\n <>\n <text>{\"\"}</text>\n <text fg={t.error}>{` Error: ${oauthError}`}</text>\n </>\n ) : null}\n <text>{\"\"}</text>\n <text fg={t.text}>\n {` Code: ${showCode ? oauthCodeInput : oauthCodeInput.replace(/./g, \"*\")}|`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Paste code then Enter Ctrl+S Toggle visible Esc Cancel\"}</text>\n </box>\n )}\n\n {/* Step 4b: OAuth exchanging */}\n {step === \"oauth-exchanging\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"oauth-exchanging\")}: OAuth Login`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.warning}>{\" Exchanging code for tokens...\"}</text>\n </box>\n )}\n </box>\n );\n}\n", "/**\n * DialogStatus \u2014 system status dialog showing provider, tools, config info.\n * Scrollable overlay with sections for Provider, System, and Tools.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState } from \"react\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport { useSDK } from \"../context/sdk\";\n\nexport function DialogStatus(props: { onClose: () => void }) {\n const { theme } = useTheme();\n const t = theme;\n const sdk = useSDK();\n const dims = useTerminalDimensions();\n const [scrollOffset, setScrollOffset] = useState(0);\n\n // Gather status info\n const allTools = sdk.registry.getAll ? sdk.registry.getAll() : [];\n const toolNames = Array.isArray(allTools)\n ? allTools.map((tool: any) =>\n tool.definition?.name || tool.name || \"unknown\"\n )\n : [];\n\n const sections: Array<{ title: string; rows: Array<[string, string]> }> = [\n {\n title: \"Provider\",\n rows: [\n [\"Provider\", sdk.provider],\n [\"Model\", sdk.model],\n [\"Directory\", sdk.workingDir],\n ],\n },\n {\n title: \"System\",\n rows: [\n [\"Node\", process.version],\n [\"Platform\", `${process.platform} ${process.arch}`],\n [\n \"Terminal\",\n process.env.TERM_PROGRAM || process.env.TERM || \"unknown\",\n ],\n [\"Shell\", process.env.SHELL || \"unknown\"],\n ],\n },\n {\n title: `Tools (${toolNames.length})`,\n rows: toolNames.slice(0, 20).map((name: string) => [\"\\u2022\", name]),\n },\n ];\n\n // Build flat lines for scrolling\n const lines: Array<{\n type: \"header\" | \"row\";\n text: string;\n value?: string;\n }> = [];\n for (const section of sections) {\n lines.push({ type: \"header\", text: section.title });\n for (const [label, value] of section.rows) {\n lines.push({ type: \"row\", text: label, value });\n }\n lines.push({ type: \"row\", text: \"\", value: \"\" }); // spacer\n }\n\n const maxVisible = Math.max(5, (dims.height || 24) - 10);\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\" || key.name === \"q\") props.onClose();\n if (key.name === \"up\" || key.name === \"k\")\n setScrollOffset((s) => Math.max(0, s - 1));\n if (key.name === \"down\" || key.name === \"j\")\n setScrollOffset((s) => Math.min(lines.length - maxVisible, s + 1));\n });\n\n const visible = lines.slice(scrollOffset, scrollOffset + maxVisible);\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top=\"10%\"\n left=\"15%\"\n width=\"70%\"\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\" System Status\"}\n </text>\n <text>{\"\"}</text>\n {visible.map((line, i) => {\n if (line.type === \"header\") {\n return (\n <text\n key={`h-${i}`}\n fg={t.secondary}\n attributes={TextAttributes.BOLD}\n >\n {` ${line.text}`}\n </text>\n );\n }\n if (!line.text && !line.value) return <text key={`s-${i}`}>{\"\"}</text>;\n return (\n <box key={`r-${i}`} flexDirection=\"row\">\n <text fg={t.textMuted}>{` ${line.text}`}</text>\n {line.value && <text fg={t.text}>{` ${line.value}`}</text>}\n </box>\n );\n })}\n <text>{\"\"}</text>\n <text fg={t.textDim}>\n {\" \\u2191\\u2193 Scroll Esc Close\"}\n </text>\n </box>\n );\n}\n", "/**\n * Main TUI Application \u2014 OpenTUI + React\n *\n * Full-featured terminal UI with:\n * - Agent integration (streaming, tool calls, permissions)\n * - Permission prompt wiring (real UI prompts, not auto-allow)\n * - Runtime model/provider switching with agent rebuild\n * - Session browser overlay (Ctrl+S)\n * - Setup wizard overlay (/setup)\n * - Keyboard-driven navigation\n * - Model picker dialog (Ctrl+P)\n * - Theme support (dark/light/auto)\n * - Status bar with token counts and context %\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { createRoot, useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { createCliRenderer, TextAttributes } from \"@opentui/core\";\nimport { useState, useRef, useCallback } from \"react\";\nimport {\n ToolRegistry,\n PermissionManager,\n PermissionMode,\n registerAllTools,\n} from \"@cdoing/core\";\nimport { AgentRunner, getDefaultModel, getApiKeyEnvVar } from \"@cdoing/ai\";\nimport type { ModelConfig } from \"@cdoing/ai\";\n\nimport { ThemeProvider, useTheme, detectTerminalTheme, restoreTerminalBackground, getThemeColors, setTerminalBackground } from \"./context/theme\";\nimport { SDKProvider } from \"./context/sdk\";\nimport { ToastProvider } from \"./components/toast\";\nimport { Home } from \"./routes/home\";\nimport { SessionView } from \"./routes/session\";\nimport { StatusBar } from \"./components/status-bar\";\nimport { SessionHeader } from \"./components/session-header\";\nimport { SessionFooter } from \"./components/session-footer\";\nimport { Sidebar } from \"./components/sidebar\";\nimport { DialogModel } from \"./components/dialog-model\";\nimport { DialogCommand } from \"./components/dialog-command\";\nimport { DialogHelp } from \"./components/dialog-help\";\nimport { DialogTheme } from \"./components/dialog-theme\";\nimport { SessionBrowser } from \"./components/session-browser\";\nimport { SetupWizard } from \"./components/setup-wizard\";\nimport { DialogStatus } from \"./components/dialog-status\";\nimport { setTerminalTitle, resetTerminalTitle } from \"./lib/terminal-title\";\nimport type { Conversation } from \"./lib/history\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface TUIOptions {\n prompt?: string;\n provider: string;\n model?: string;\n apiKey?: string;\n baseUrl?: string;\n workingDir: string;\n mode: string;\n resume?: string;\n continue?: boolean;\n theme: string;\n}\n\n// \u2500\u2500 App Shell \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype Route = \"home\" | \"session\";\ntype Dialog = \"none\" | \"model\" | \"command\" | \"sessions\" | \"setup\" | \"help\" | \"theme\" | \"status\";\n\nfunction AppShell(props: {\n options: TUIOptions;\n agent: AgentRunner;\n registry: ToolRegistry;\n permissionManager: PermissionManager;\n}) {\n const dims = useTerminalDimensions();\n const { theme, themeId, setMode, setThemeId } = useTheme();\n const t = theme;\n\n const [route, setRoute] = useState<Route>(props.options.prompt ? \"session\" : \"home\");\n const [dialog, setDialog] = useState<Dialog>(\"none\");\n const [status, setStatus] = useState(\"Ready\");\n const [provider, setProvider] = useState(props.options.provider);\n const [model, setModel] = useState(props.options.model || getDefaultModel(props.options.provider) || \"default\");\n const [workingDir, setWorkingDir] = useState(props.options.workingDir);\n const [tokens, setTokens] = useState<{ input: number; output: number } | undefined>();\n const [contextPercent, setContextPercent] = useState(0);\n const [activeTool, setActiveTool] = useState<string | undefined>();\n const [showSidebar, setShowSidebar] = useState(true);\n\n // Mutable refs for agent rebuild\n const agentRef = useRef(props.agent);\n const registryRef = useRef(props.registry);\n const pmRef = useRef(props.permissionManager);\n\n // Initial message from home screen input\n const initialMessageRef = useRef<{ text: string; images?: import(\"@cdoing/ai\").ImageAttachment[] } | null>(null);\n\n // \u2500\u2500 Permission prompt bridge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Store a pending permission resolve callback that the UI can call\n const permissionResolveRef = useRef<((decision: \"allow\" | \"always\" | \"deny\") => void) | null>(null);\n const [pendingPermission, setPendingPermission] = useState<{\n toolName: string;\n message: string;\n } | null>(null);\n\n // Wire PermissionManager to show UI prompt\n const requestPermission = useCallback((toolName: string, message: string): Promise<\"allow\" | \"always\" | \"deny\"> => {\n return new Promise((resolve) => {\n permissionResolveRef.current = resolve;\n setPendingPermission({ toolName, message });\n });\n }, []);\n\n // Set up the prompt function on the permission manager\n pmRef.current.setPromptFn(async (toolName: string, message: string) => {\n const decision = await requestPermission(toolName, message);\n return decision === \"always\" ? \"allow\" : decision;\n });\n\n // \u2500\u2500 Agent Rebuild \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const rebuildAgent = useCallback((newProvider: string, newModel: string, apiKey?: string) => {\n // Resolve API key\n // If apiKey is explicitly \"\" (empty string), it means logout \u2014 skip all fallbacks\n let resolvedKey = apiKey;\n if (apiKey === undefined) {\n const envVar = getApiKeyEnvVar(newProvider);\n if (process.env[envVar]) {\n resolvedKey = process.env[envVar];\n } else {\n try {\n const configPath = path.join(os.homedir(), \".cdoing\", \"config.json\");\n if (fs.existsSync(configPath)) {\n const config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n resolvedKey = config.apiKeys?.[newProvider];\n }\n } catch {}\n }\n }\n\n const modelConfig: Partial<ModelConfig> = {\n provider: newProvider,\n model: newModel,\n apiKey: resolvedKey || undefined,\n baseURL: props.options.baseUrl || undefined,\n temperature: 0,\n maxTokens: 8096,\n };\n\n const newAgent = new AgentRunner(modelConfig, registryRef.current, pmRef.current);\n agentRef.current = newAgent;\n setProvider(newProvider);\n setModel(newModel);\n }, [props.options.baseUrl]);\n\n // \u2500\u2500 Working Directory Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const handleSetWorkingDir = useCallback((dir: string) => {\n setWorkingDir(dir);\n }, []);\n\n // \u2500\u2500 Global Keyboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n useKeyboard((key: any) => {\n // Don't intercept keys when a dialog is open (except escape)\n if (dialog !== \"none\" && key.name !== \"escape\") return;\n\n // Ctrl+C \u2014 graceful quit\n if (key.ctrl && key.name === \"c\") {\n const cleanup = (globalThis as any).__cdoingCleanup;\n if (cleanup) cleanup();\n else process.exit(0);\n }\n // Ctrl+N \u2014 new session\n if (key.ctrl && key.name === \"n\") {\n setRoute(\"session\");\n setStatus(\"Ready\");\n }\n // Ctrl+P \u2014 model picker\n if (key.ctrl && key.name === \"p\") {\n setDialog((d) => (d === \"model\" ? \"none\" : \"model\"));\n }\n // Ctrl+S \u2014 session browser\n if (key.ctrl && key.name === \"s\") {\n setDialog((d) => (d === \"sessions\" ? \"none\" : \"sessions\"));\n }\n // Ctrl+B \u2014 toggle sidebar\n if (key.ctrl && key.name === \"b\") {\n setShowSidebar((s) => !s);\n }\n // Ctrl+T \u2014 theme picker\n if (key.ctrl && key.name === \"t\") {\n setDialog((d) => (d === \"theme\" ? \"none\" : \"theme\"));\n }\n // Ctrl+X \u2014 command palette\n if (key.ctrl && key.name === \"x\") {\n setDialog((d) => (d === \"command\" ? \"none\" : \"command\"));\n }\n // F1 \u2014 help dialog\n if (key.name === \"f1\") {\n setDialog((d) => (d === \"help\" ? \"none\" : \"help\"));\n }\n // Escape \u2014 close any dialog\n if (key.name === \"escape\") {\n setDialog(\"none\");\n }\n }, {});\n\n // \u2500\u2500 Session Resume Handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const handleResumeSession = useCallback((_conv: Conversation) => {\n // TODO: restore conversation messages into agent history\n setRoute(\"session\");\n setDialog(\"none\");\n setStatus(\"Ready\");\n }, []);\n\n return (\n <box width={dims.width} height={dims.height} flexDirection=\"column\">\n {/* Header bar */}\n <box height={1} flexDirection=\"row\" paddingX={1} flexShrink={0}>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"cdoing\"}</text>\n <text fg={t.border}>{\" \u2502 \"}</text>\n <text fg={t.textMuted}>{model}</text>\n <text fg={t.border}>{\" \u2502 \"}</text>\n <text fg={status === \"Error\" ? t.error : status === \"Processing...\" ? t.warning : t.success}>\n {status}\n </text>\n </box>\n\n {/* Session header (only in session route) */}\n {route === \"session\" && (\n <SessionHeader\n title=\"Session\"\n provider={provider}\n model={model}\n tokens={tokens}\n contextPercent={contextPercent}\n status={status}\n />\n )}\n\n {/* Separator */}\n <box height={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2500\".repeat(Math.max(dims.width, 40))}</text>\n </box>\n\n {/* Main content area with optional sidebar */}\n <box flexDirection=\"row\" flexGrow={1}>\n <SDKProvider\n value={{\n agent: agentRef.current,\n registry: registryRef.current,\n permissionManager: pmRef.current,\n workingDir,\n provider,\n model,\n requestPermission,\n rebuildAgent,\n setWorkingDir: handleSetWorkingDir,\n }}\n >\n <box flexGrow={1} flexDirection=\"column\">\n {dialog === \"sessions\" ? (\n <SessionBrowser\n onResume={handleResumeSession}\n onClose={() => setDialog(\"none\")}\n />\n ) : dialog === \"setup\" ? (\n <SetupWizard\n onComplete={(config) => {\n rebuildAgent(config.provider, config.model, config.apiKey);\n setDialog(\"none\");\n }}\n onClose={() => setDialog(\"none\")}\n />\n ) : route === \"home\" ? (\n <Home\n provider={provider}\n model={model}\n workingDir={workingDir}\n themeId={themeId}\n onSubmit={(text, images) => {\n initialMessageRef.current = { text, images };\n setRoute(\"session\");\n }}\n />\n ) : (\n <SessionView\n onStatus={setStatus}\n onTokens={(i, o) => setTokens({ input: i, output: o })}\n onActiveTool={setActiveTool}\n onContextPercent={setContextPercent}\n onOpenDialog={(d) => setDialog(d as Dialog)}\n initialMessage={initialMessageRef.current}\n />\n )}\n </box>\n </SDKProvider>\n\n {/* Sidebar (right panel) */}\n {showSidebar && (\n <Sidebar\n provider={provider}\n model={model}\n workingDir={workingDir}\n tokens={tokens}\n contextPercent={contextPercent}\n activeTool={activeTool}\n status={status}\n themeId={themeId}\n />\n )}\n </box>\n\n {/* Separator */}\n <box height={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2500\".repeat(Math.max(dims.width, 40))}</text>\n </box>\n\n {/* Footer: session footer in session route, status bar always */}\n {route === \"session\" ? (\n <SessionFooter\n workingDir={workingDir}\n isProcessing={status === \"Processing...\"}\n />\n ) : (\n <StatusBar\n provider={provider}\n model={model}\n mode={props.options.mode}\n workingDir={workingDir}\n tokens={tokens}\n contextPercent={contextPercent}\n activeTool={activeTool}\n isProcessing={status === \"Processing...\"}\n />\n )}\n\n {/* Model picker dialog (overlay) */}\n {dialog === \"model\" && (\n <DialogModel\n provider={provider}\n currentModel={model}\n onSelect={(m) => {\n rebuildAgent(provider, m);\n setDialog(\"none\");\n }}\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Command palette dialog (overlay) */}\n {dialog === \"command\" && (\n <DialogCommand\n onSelect={(commandId) => {\n setDialog(\"none\");\n switch (commandId) {\n // Session\n case \"session:new\":\n setRoute(\"session\");\n setStatus(\"Ready\");\n break;\n case \"session:browse\":\n setDialog(\"sessions\");\n break;\n case \"session:clear\":\n setRoute(\"session\");\n setStatus(\"Ready\");\n break;\n // Model\n case \"model:switch\":\n setDialog(\"model\");\n break;\n // Theme\n case \"theme:dark\":\n setMode(\"dark\");\n break;\n case \"theme:light\":\n setMode(\"light\");\n break;\n case \"theme:picker\":\n setDialog(\"theme\");\n break;\n // Display\n case \"display:sidebar\":\n setShowSidebar((s) => !s);\n break;\n case \"display:timestamps\":\n case \"display:thinking\":\n // Display toggles \u2014 extend as needed\n break;\n // System\n case \"system:status\":\n setDialog(\"status\");\n break;\n case \"system:help\":\n setDialog(\"help\");\n break;\n case \"system:doctor\":\n setStatus(\"Doctor\");\n break;\n case \"system:setup\":\n setDialog(\"setup\");\n break;\n case \"system:exit\": {\n const exit = (globalThis as any).__cdoingCleanup;\n if (exit) exit();\n else process.exit(0);\n break;\n }\n }\n }}\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Help dialog (overlay) */}\n {dialog === \"help\" && (\n <DialogHelp\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Theme picker dialog (overlay) */}\n {dialog === \"theme\" && (\n <DialogTheme\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Status dialog (overlay) */}\n {dialog === \"status\" && (\n <DialogStatus onClose={() => setDialog(\"none\")} />\n )}\n </box>\n );\n}\n\n// \u2500\u2500 Entry Point \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function startTUI(options: TUIOptions): Promise<void> {\n // Initialize core services\n const registry = new ToolRegistry();\n const permMode = options.mode === \"auto\" ? PermissionMode.BYPASS\n : options.mode === \"auto-edit\" ? PermissionMode.ACCEPT_EDITS\n : PermissionMode.DEFAULT;\n const pm = new PermissionManager(permMode, options.workingDir);\n\n // Permission prompt will be wired up via React state in AppShell\n // Set a temporary default \u2014 will be overridden once React mounts\n pm.setPromptFn(async (_toolName, _message) => {\n return \"allow\";\n });\n\n await registerAllTools(registry, {\n workingDir: options.workingDir,\n permissionManager: pm,\n });\n\n // Resolve API key: flag \u2192 env var \u2192 stored config (~/.cdoing/config.json)\n let resolvedApiKey = options.apiKey;\n let resolvedProvider = options.provider;\n let resolvedModel = options.model;\n let resolvedBaseUrl = options.baseUrl;\n\n if (!resolvedApiKey) {\n // Load stored config\n const configPath = path.join(os.homedir(), \".cdoing\", \"config.json\");\n let storedConfig: Record<string, any> = {};\n try {\n if (fs.existsSync(configPath)) {\n storedConfig = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n\n // Apply stored provider/model/baseUrl if not set via flags\n if (resolvedProvider === \"anthropic\" && storedConfig.provider) {\n resolvedProvider = storedConfig.provider;\n }\n if (!resolvedModel && storedConfig.model) {\n resolvedModel = storedConfig.model;\n }\n if (!resolvedBaseUrl && storedConfig.baseUrl) {\n resolvedBaseUrl = storedConfig.baseUrl;\n }\n\n // Check env var\n const envVar = getApiKeyEnvVar(resolvedProvider);\n if (process.env[envVar]) {\n resolvedApiKey = process.env[envVar];\n }\n // Check stored API keys\n else if (storedConfig.apiKeys?.[resolvedProvider]) {\n resolvedApiKey = storedConfig.apiKeys[resolvedProvider];\n }\n }\n\n // Build model config\n const modelConfig: Partial<ModelConfig> = {\n provider: resolvedProvider,\n model: resolvedModel || undefined,\n apiKey: resolvedApiKey || undefined,\n baseURL: resolvedBaseUrl || undefined,\n temperature: 0,\n maxTokens: 8096,\n };\n\n // Create agent\n const agent = new AgentRunner(modelConfig, registry, pm);\n\n // Detect terminal background color before rendering (async OSC 11 query)\n let detectedMode: \"dark\" | \"light\" | undefined;\n if (options.theme === \"auto\") {\n detectedMode = await detectTerminalTheme();\n }\n\n // Set terminal background BEFORE clearing so it fills the entire screen\n const resolvedMode: \"dark\" | \"light\" = options.theme === \"light\" ? \"light\"\n : options.theme === \"auto\" ? (detectedMode || \"dark\")\n : \"dark\";\n const initialColors = getThemeColors(\"default\", resolvedMode);\n setTerminalBackground(initialColors.bg);\n\n console.clear();\n\n // Set terminal title on mount\n setTerminalTitle(\"cdoing\");\n\n const renderer = await createCliRenderer({\n useMouse: true,\n exitOnCtrlC: false,\n });\n const root = createRoot(renderer);\n root.render(\n <ThemeProvider mode={options.theme} detectedMode={detectedMode} syncTerminalBg>\n <ToastProvider>\n <AppShell\n options={{ ...options, provider: resolvedProvider, model: resolvedModel || undefined }}\n agent={agent}\n registry={registry}\n permissionManager={pm}\n />\n </ToastProvider>\n </ThemeProvider>\n );\n\n // Graceful cleanup: unmount React, destroy renderer, restore terminal\n let isCleaningUp = false;\n const cleanup = () => {\n if (isCleaningUp) return;\n isCleaningUp = true;\n try { root.unmount(); } catch {}\n try { renderer.destroy(); } catch {}\n resetTerminalTitle();\n restoreTerminalBackground();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Expose cleanup globally so the keyboard handler can use it\n (globalThis as any).__cdoingCleanup = cleanup;\n\n // Keep alive\n await new Promise(() => {});\n}\n", "/**\n * cdoing-tui \u2014 OpenTUI-based terminal interface for cdoing agent\n *\n * This is the advanced TUI (like opencode) using @opentui/react for\n * a rich, interactive terminal experience with:\n * - Split panes (chat + file preview)\n * - Dialog system (model picker, session list, command palette)\n * - Theme support\n * - Keyboard-driven navigation\n *\n * The existing @cdoing/cli uses Ink (React) for a simpler TUI.\n * This package provides the opencode-style experience.\n */\n\nimport { Command } from \"commander\";\nimport { getDefaultModel, getRegisteredProviders } from \"@cdoing/ai\";\n\nconst program = new Command();\n\nprogram\n .name(\"cdoing-tui\")\n .description(\"OpenTUI-based terminal interface for cdoing agent\")\n .version(\"0.1.0\")\n .option(\"-m, --model <model>\", \"Model name\")\n .option(\"-p, --provider <provider>\", \"AI provider\", \"anthropic\")\n .option(\"--api-key <key>\", \"API key\")\n .option(\"--base-url <url>\", \"Base URL for custom providers\")\n .option(\"-d, --dir <directory>\", \"Working directory\", process.cwd())\n .option(\"--mode <mode>\", \"Permission mode: ask, auto-edit, auto\", \"ask\")\n .option(\"-r, --resume <id>\", \"Resume conversation by ID\")\n .option(\"-c, --continue\", \"Continue most recent conversation\")\n .option(\"--theme <theme>\", \"Theme: dark, light, auto\", \"dark\")\n .argument(\"[prompt]\", \"Initial prompt\")\n .action(async (prompt, opts) => {\n const { startTUI } = await import(\"./app\");\n await startTUI({\n prompt,\n provider: opts.provider,\n model: opts.model || getDefaultModel(opts.provider),\n apiKey: opts.apiKey,\n baseUrl: opts.baseUrl,\n workingDir: opts.dir,\n mode: opts.mode,\n resume: opts.resume,\n continue: opts.continue,\n theme: opts.theme,\n });\n });\n\nprogram.parse();\n"],
5
+ "mappings": "0XAYA,OAAS,QAAAA,GAAM,YAAAC,GAAU,eAAAC,OAAmB,gBAC5C,OAAS,iBAAAC,GAAe,cAAAC,GAAY,YAAAC,GAAU,aAAAC,GAAW,UAAAC,GAAQ,WAAAC,OAAe,QA4f5E,cAAAC,OAAA,6BApdJ,SAASC,EAAEC,EAAmB,CAC5B,OAAOX,GAAK,QAAQW,CAAG,CACzB,CAGA,SAASC,EAAWC,EAKV,CACR,MAAO,CACL,KAAMH,EAAEG,EAAE,IAAI,EAAG,UAAWH,EAAEG,EAAE,SAAS,EAAG,QAASH,EAAEG,EAAE,OAAO,EAChE,QAASH,EAAEG,EAAE,OAAO,EAAG,UAAWH,EAAEG,EAAE,SAAS,EAC/C,QAASH,EAAEG,EAAE,OAAO,EAAG,MAAOH,EAAEG,EAAE,KAAK,EAAG,QAASH,EAAEG,EAAE,OAAO,EAAG,KAAMH,EAAEG,EAAE,IAAI,EAC/E,OAAQH,EAAEG,EAAE,MAAM,EAAG,cAAeH,EAAEG,EAAE,OAAO,EAC/C,GAAIH,EAAEG,EAAE,EAAE,EAAG,SAAUH,EAAEG,EAAE,QAAQ,EACnC,SAAUH,EAAEG,EAAE,OAAO,EAAG,cAAeH,EAAEG,EAAE,IAAI,EAC/C,WAAYH,EAAEG,EAAE,OAAO,EAAG,SAAUH,EAAEG,EAAE,SAAS,EACjD,YAAaH,EAAEG,EAAE,OAAO,EAAG,SAAUH,EAAEG,EAAE,OAAO,EAAG,UAAWH,EAAEG,EAAE,KAAK,EACvE,QAASH,EAAEG,EAAE,SAAWA,EAAE,OAAO,EAAG,WAAYH,EAAEG,EAAE,YAAcA,EAAE,KAAK,EACzE,SAAUH,EAAEG,EAAE,IAAI,CACpB,CACF,CA2MO,SAASC,IAAwB,CACtC,OAAO,OAAO,KAAKC,EAAM,EAAE,KAAK,CAACC,EAAGC,IAC9BD,IAAM,UAAkB,GACxBC,IAAM,UAAkB,EACrBD,EAAE,cAAcC,CAAC,CACzB,CACH,CAGO,SAASC,GAAeC,EAAiBC,EAA+B,CAC7E,IAAMC,EAAMN,GAAOI,CAAO,GAAKJ,GAAO,QACtC,OAAOK,IAAS,QAAUC,EAAI,MAAQA,EAAI,IAC5C,CAIA,SAASC,GAAUC,EAAWC,EAAWP,EAAmB,CAC1D,GAAM,CAACQ,EAAIC,EAAIC,CAAE,EAAI,CAACJ,EAAGC,EAAGP,CAAC,EAAE,IAAKW,GAAM,CACxC,IAAMC,EAAID,EAAI,IACd,OAAOC,GAAK,OAAUA,EAAI,MAAQ,KAAK,KAAKA,EAAI,MAAS,MAAO,GAAG,CACrE,CAAC,EACD,MAAO,OAASJ,EAAK,MAASC,EAAK,MAASC,CAC9C,CAEA,SAASG,IAA+E,CACtF,OAAO,IAAI,QAASC,GAAY,CAC9B,GAAI,CAAC,QAAQ,MAAM,OAAS,CAAC,QAAQ,OAAO,MAAO,CACjDA,EAAQ,IAAI,EACZ,MACF,CACA,IAAMC,EAAU,WAAW,IAAM,CAAEC,EAAQ,EAAGF,EAAQ,IAAI,CAAG,EAAG,GAAG,EAC/DG,EAAM,GACJC,EAAUC,GAAiB,CAC/BF,GAAOE,EAAK,SAAS,EACrB,IAAMC,EAAQH,EAAI,MAChB,yEACF,EACA,GAAIG,EAAO,CACTJ,EAAQ,EACR,IAAMK,EAAS3B,GACbA,EAAI,QAAU,EAAI,SAASA,EAAK,EAAE,EAAI,KAAK,MAAO,SAASA,EAAK,EAAE,EAAI,MAAS,GAAG,EACpFoB,EAAQ,CAAE,EAAGO,EAAMD,EAAM,CAAC,CAAC,EAAG,EAAGC,EAAMD,EAAM,CAAC,CAAC,EAAG,EAAGC,EAAMD,EAAM,CAAC,CAAC,CAAE,CAAC,CACxE,CACF,EACMJ,EAAU,IAAM,CACpB,aAAaD,CAAO,EACpB,QAAQ,MAAM,eAAe,OAAQG,CAAM,EACvCI,IAAW,IAAO,QAAQ,MAAM,WAAW,EAAK,CACtD,EACMA,EAAS,QAAQ,MAAM,MAC7B,GAAI,CAAE,QAAQ,MAAM,WAAW,EAAI,CAAG,MAAQ,CAAER,EAAQ,IAAI,EAAG,MAAQ,CACvE,QAAQ,MAAM,GAAG,OAAQI,CAAM,EAC/B,QAAQ,OAAO,MAAM,eAAe,CACtC,CAAC,CACH,CAEA,SAASK,IAAuC,CAC9C,IAAMC,EAAK,QAAQ,IAAI,UACvB,GAAIA,EAAI,CACN,IAAMC,EAAQD,EAAG,MAAM,GAAG,EAE1B,GADc,SAASC,EAAMA,EAAM,OAAS,CAAC,GAAK,IAAK,EAAE,EAC7C,EAAG,MAAO,OACxB,CACA,MAAO,MACT,CAIA,eAAsBC,IAAiD,CACrE,GAAIC,GAAe,OAAOA,GAC1B,IAAMC,EAAM,MAAMf,GAAwB,EAC1C,OAAIe,EAEFD,GADYtB,GAAUuB,EAAI,EAAGA,EAAI,EAAGA,EAAI,CAAC,EACnB,GAAM,QAAU,OAEtCD,GAAgBJ,GAAmB,EAE9BI,EACT,CAEO,SAASE,GAAsBC,EAAmB,CACvD,GAAI,CAAC,QAAQ,OAAO,MAAO,OAC3B,IAAMpC,EAAMV,GAAS8C,CAAK,EAC1B,QAAQ,OAAO,MAAM,WAAWpC,CAAG,MAAM,CAC3C,CAEO,SAASqC,IAAkC,CAC3C,QAAQ,OAAO,OACpB,QAAQ,OAAO,MAAM,eAAe,CACtC,CAIA,SAASC,GAAoBC,EAA2B,CACtD,OAAOhD,GAAY,WAAW,CAE5B,QAAW,CAAE,GAAIgD,EAAM,IAAK,EAE5B,mBAAoB,CAAE,GAAIA,EAAM,QAAS,KAAM,EAAK,EACpD,mBAAoB,CAAE,GAAIA,EAAM,QAAS,KAAM,EAAK,EACpD,mBAAoB,CAAE,GAAIA,EAAM,KAAM,KAAM,EAAK,EACjD,mBAAoB,CAAE,GAAIA,EAAM,KAAM,KAAM,EAAK,EACjD,mBAAoB,CAAE,GAAIA,EAAM,IAAK,EACrC,mBAAoB,CAAE,GAAIA,EAAM,IAAK,EACrC,cAAe,CAAE,KAAM,EAAK,EAC5B,gBAAiB,CAAE,OAAQ,EAAK,EAChC,cAAe,CAAE,GAAIA,EAAM,OAAQ,EACnC,cAAe,CAAE,GAAIA,EAAM,KAAM,UAAW,EAAK,EACjD,aAAc,CAAE,GAAIA,EAAM,OAAQ,EAClC,eAAgB,CAAE,GAAIA,EAAM,UAAW,OAAQ,EAAK,EAEpD,QAAW,CAAE,GAAIA,EAAM,UAAW,KAAM,EAAK,EAC7C,kBAAmB,CAAE,GAAIA,EAAM,UAAW,KAAM,EAAK,EACrD,mBAAoB,CAAE,GAAIA,EAAM,SAAU,EAC1C,OAAU,CAAE,GAAIA,EAAM,OAAQ,EAC9B,gBAAiB,CAAE,GAAIA,EAAM,OAAQ,EACrC,QAAW,CAAE,GAAIA,EAAM,QAAS,OAAQ,EAAK,EAC7C,eAAgB,CAAE,GAAIA,EAAM,QAAS,OAAQ,EAAK,EAClD,gBAAiB,CAAE,GAAIA,EAAM,QAAS,OAAQ,EAAK,EACnD,SAAY,CAAE,GAAIA,EAAM,OAAQ,EAChC,mBAAoB,CAAE,GAAIA,EAAM,OAAQ,EACxC,OAAU,CAAE,GAAIA,EAAM,OAAQ,EAC9B,SAAY,CAAE,GAAIA,EAAM,IAAK,EAC7B,qBAAsB,CAAE,GAAIA,EAAM,IAAK,EACvC,SAAY,CAAE,GAAIA,EAAM,IAAK,EAC7B,uBAAwB,CAAE,GAAIA,EAAM,IAAK,EACzC,mBAAoB,CAAE,GAAIA,EAAM,IAAK,EACrC,KAAQ,CAAE,GAAIA,EAAM,OAAQ,EAC5B,mBAAoB,CAAE,GAAIA,EAAM,OAAQ,EACxC,eAAgB,CAAE,GAAIA,EAAM,OAAQ,EACpC,SAAY,CAAE,GAAIA,EAAM,SAAU,EAClC,YAAe,CAAE,GAAIA,EAAM,SAAU,CACvC,CAAC,CACH,CAiBO,SAASC,GAAcC,EAM3B,CACD,IAAMC,EACJD,EAAM,OAAS,QAAU,QACrBA,EAAM,OAAS,QAAUA,EAAM,cAAgB,OAG/CE,EAAiBF,EAAM,SAAW,UAElC,CAACjC,EAASoC,CAAe,EAAIlD,GAASiD,CAAc,EACpD,CAACE,EAAaC,CAAc,EAAIpD,GAA2BgD,CAAW,EACtE,CAACH,EAAOQ,CAAQ,EAAIrD,GAAgBa,GAAeoC,EAAgBD,CAAW,CAAC,EAC/E,CAACM,EAAQC,CAAS,EAAIvD,GAAS+C,EAAM,gBAAkB,EAAK,EAC5D,CAACS,EAAUC,CAAgB,EAAIzD,GAAwB,IAAI,EAG3D0D,EAAYxD,GAAOoD,CAAM,EAC/BI,EAAU,QAAUJ,EACpB,IAAMK,EAAczD,GAAOsD,CAAQ,EACnCG,EAAY,QAAUH,EACtB,IAAMI,EAAU1D,GAAOiD,CAAW,EAClCS,EAAQ,QAAUT,EAClB,IAAMU,EAAa3D,GAAOY,CAAO,EACjC+C,EAAW,QAAU/C,EAGrB,IAAMgD,EAAmBC,GAAkB,CACpCL,EAAU,UACXC,EAAY,QACdlB,GAAsB9C,GAAK,QAAQgE,EAAY,OAAO,CAAC,EAEvDlB,GAAsBsB,EAAO,EAAE,EAEnC,EAEMC,EAAcC,GAAe,CACjCf,EAAgBe,CAAE,EAClBJ,EAAW,QAAUI,EACrB,IAAMF,EAASlD,GAAeoD,EAAIL,EAAQ,OAAO,EACjDP,EAASU,CAAM,EACfD,EAAgBC,CAAM,CACxB,EAEMG,EAAWC,GAAwB,CACvCf,EAAee,CAAC,EAChBP,EAAQ,QAAUO,EAClB,IAAMJ,EAASlD,GAAegD,EAAW,QAASM,CAAC,EACnDd,EAASU,CAAM,EACfD,EAAgBC,CAAM,CACxB,EAEMK,EAAe9D,GAAuB,CAC1CmD,EAAiBnD,CAAG,EACpBqD,EAAY,QAAUrD,EACjBoD,EAAU,SAEbjB,GADEnC,EACoBX,GAAK,QAAQW,CAAG,EAEhBO,GAAegD,EAAW,QAASD,EAAQ,OAAO,EAAE,EAFnC,CAI3C,EAEMS,EAAqBC,GAAkB,CAG3C,GAFAf,EAAUe,CAAI,EACdZ,EAAU,QAAUY,EAChBA,EAAM,CACR,IAAMP,EAASlD,GAAegD,EAAW,QAASD,EAAQ,OAAO,EACjEE,EAAgBC,CAAM,CACxB,MACEpB,GAA0B,CAE9B,EAGA1C,GAAU,IAAM,CACd,GAAIyD,EAAU,QAAS,CACrB,IAAMK,EAASlD,GAAeoC,EAAgBD,CAAW,EACzDc,EAAgBC,CAAM,CACxB,CACA,MAAO,IAAM,CACPL,EAAU,SAASf,GAA0B,CACnD,CACF,EAAG,CAAC,CAAC,EAEL,IAAM4B,EAAcpE,GAAQ,IAAMyC,GAAoBC,CAAK,EAAG,CAACA,CAAK,CAAC,EAErE,OACEzC,GAACoE,GAAa,SAAb,CAAsB,MAAO,CAAE,MAAA3B,EAAO,QAAA/B,EAAS,KAAMqC,EAAa,YAAAoB,EAAa,SAAAf,EAAU,WAAAQ,EAAY,QAAAE,EAAS,YAAAE,EAAa,eAAgBd,EAAQ,kBAAAe,CAAkB,EACnK,SAAAtB,EAAM,SACT,CAEJ,CAEO,SAAS0B,GAAW,CACzB,IAAMC,EAAM3E,GAAWyE,EAAY,EACnC,GAAI,CAACE,EAAK,MAAM,IAAI,MAAM,4CAA4C,EACtE,OAAOA,CACT,CAnhBA,IAgFahE,GAyQT6B,GAuEEiC,GAhaNG,EAAAC,EAAA,kBAgFalE,GAAmC,CAC9C,QAAS,CACP,KAAM,UACN,KAAMH,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,WAAY,CACV,KAAM,aACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,QAAS,CACP,KAAM,UACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,KAAM,CACJ,KAAM,OACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,WAAY,CACV,KAAM,cACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,QAAS,CACP,KAAM,UACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,SAAU,CACR,KAAM,eACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,QAAS,CACP,KAAM,UACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,UAAW,CACT,KAAM,YACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,OAAQ,CACN,KAAM,SACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,OAAQ,CACN,KAAM,SACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,SAAU,CACR,KAAM,WACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,UAAW,CACT,KAAM,gBACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,WAAY,CACV,KAAM,aACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,EACA,QAAS,CACP,KAAM,UACN,KAAMA,EAAW,CACf,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,EACD,MAAOA,EAAW,CAChB,GAAI,UAAW,SAAU,UAAW,KAAM,UAAW,UAAW,UAAW,QAAS,UACpF,QAAS,UAAW,UAAW,UAAW,QAAS,UAAW,MAAO,UACrE,QAAS,UAAW,KAAM,UAAW,OAAQ,SAC/C,CAAC,CACH,CACF,EAqEIgC,GAAyC,KAuEvCiC,GAAe1E,GAWN,MAAS,ICtaxB,OAAS,iBAAA+E,GAAe,cAAAC,OAAkB,QAwBtC,cAAAC,OAAA,6BAFG,SAASC,GAAYC,EAAiD,CAC3E,OACEF,GAACG,GAAW,SAAX,CAAoB,MAAOD,EAAM,MAC/B,SAAAA,EAAM,SACT,CAEJ,CAEO,SAASE,IAAS,CACvB,IAAMC,EAAMN,GAAWI,EAAU,EACjC,GAAI,CAACE,EAAK,MAAM,IAAI,MAAM,wCAAwC,EAClE,OAAOA,CACT,CAvCA,IAyBMF,GAzBNG,GAAAC,EAAA,kBAyBMJ,GAAaL,GAAoC,MAAS,IClBhE,OAAS,iBAAAU,GAAe,cAAAC,GAAY,YAAAC,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QAgHtE,OACE,OAAAC,GADF,QAAAC,OAAA,6BAlFd,SAASC,GAAcC,EAAiBC,EAAoB,CAC1D,OAAQD,EAAM,CACZ,IAAK,OAAW,OAAOC,EAAM,KAC7B,IAAK,UAAW,OAAOA,EAAM,QAC7B,IAAK,UAAW,OAAOA,EAAM,QAC7B,IAAK,QAAW,OAAOA,EAAM,KAC/B,CACF,CAWO,SAASC,GAAcC,EAAgC,CAC5D,GAAM,CAAE,MAAAF,CAAM,EAAIG,EAAS,EACrB,CAACC,EAAQC,CAAS,EAAIb,GAAsB,CAAC,CAAC,EAC9Cc,EAAQX,GAAO,CAAC,EAChBY,EAAYZ,GAAmD,IAAI,GAAK,EAExEa,EAAcd,GAAae,GAAe,CAC9CJ,EAAWK,GAASA,EAAK,OAAQC,GAAMA,EAAE,KAAOF,CAAE,CAAC,EACnD,IAAMG,EAAQL,EAAU,QAAQ,IAAIE,CAAE,EAClCG,IACF,aAAaA,CAAK,EAClBL,EAAU,QAAQ,OAAOE,CAAE,EAE/B,EAAG,CAAC,CAAC,EAECI,EAAQnB,GAAY,CAACK,EAAiBe,EAAiBC,IAAsB,CACjF,IAAMN,EAAK,EAAEH,EAAM,QACbU,EAAMD,GAAYE,GAClBC,EAAkB,CAAE,GAAAT,EAAI,KAAAV,EAAM,QAAAe,EAAS,SAAUE,CAAI,EAE3DX,EAAWK,GAAS,CAClB,IAAMS,EAAO,CAAC,GAAGT,EAAMQ,CAAI,EAE3B,GAAIC,EAAK,OAASC,GAAa,CAC7B,IAAMC,EAAUF,EAAK,OAAO,EAAGA,EAAK,OAASC,EAAW,EAExD,QAAWE,KAAKD,EAAS,CACvB,IAAMT,EAAQL,EAAU,QAAQ,IAAIe,EAAE,EAAE,EACpCV,IACF,aAAaA,CAAK,EAClBL,EAAU,QAAQ,OAAOe,EAAE,EAAE,EAEjC,CACF,CACA,OAAOH,CACT,CAAC,EAGD,IAAMP,EAAQ,WAAW,IAAM,CAC7BJ,EAAYC,CAAE,CAChB,EAAGO,CAAG,EACNT,EAAU,QAAQ,IAAIE,EAAIG,CAAK,CACjC,EAAG,CAACJ,CAAW,CAAC,EAGhB,OAAAf,GAAU,IACD,IAAM,CACX,QAAWmB,KAASL,EAAU,QAAQ,OAAO,EAC3C,aAAaK,CAAK,EAEpBL,EAAU,QAAQ,MAAM,CAC1B,EACC,CAAC,CAAC,EAGHV,GAAC0B,GAAa,SAAb,CAAsB,MAAO,CAAE,MAAAV,CAAM,EACnC,UAAAX,EAAM,SAENE,EAAO,OAAS,GACfR,GAAC,OAAI,cAAc,SAAS,WAAW,WACpC,SAAAQ,EAAO,IAAKO,GAAM,CACjB,IAAMa,EAAQ1B,GAAca,EAAE,KAAMX,CAAK,EACnCyB,EAAOC,GAAYf,EAAE,IAAI,EAC/B,OACEd,GAAC,OAAe,OAAQ,EAAG,cAAc,MAAM,eAAe,WAC5D,UAAAD,GAAC,QAAK,GAAI4B,EAAQ,aAAIC,CAAI,IAAI,EAC9B7B,GAAC,QAAK,GAAII,EAAM,KAAO,SAAAW,EAAE,QAAQ,EACjCf,GAAC,QAAK,GAAII,EAAM,QAAU,aAAI,IAHtBW,EAAE,EAIZ,CAEJ,CAAC,EACH,GAEJ,CAEJ,CAIO,SAASgB,IAA8B,CAC5C,IAAMC,EAAMrC,GAAWgC,EAAY,EACnC,GAAI,CAACK,EAAK,MAAM,IAAI,MAAM,4CAA4C,EACtE,OAAOA,CACT,CA1IA,IA8BMF,GAkBAH,GAEAN,GACAG,GAnDNS,GAAAC,EAAA,kBASAC,IAqBML,GAAyC,CAC7C,KAAM,SACN,QAAS,SACT,QAAS,SACT,MAAO,QACT,EAaMH,GAAejC,GAA6C,MAAS,EAErE2B,GAAmB,IACnBG,GAAc,IC7CpB,UAAYY,OAAQ,KACpB,UAAYC,OAAU,OAiGf,SAASC,GAAeC,EAAeC,EAAkC,CAC9E,GAAI,CAACD,EAAO,MAAO,CAAC,EAGpB,GAAIA,EAAM,WAAW,GAAG,EACtB,OAAOE,GACJ,OAAQC,GAAMA,EAAE,KAAK,WAAWH,CAAK,CAAC,EACtC,IAAKG,IAAO,CAAE,KAAMA,EAAE,KAAM,YAAaA,EAAE,YAAa,KAAM,SAAmB,EAAE,EAIxF,GAAIH,EAAM,WAAW,GAAG,GAAKA,EAAM,SAAS,IAAI,EAAG,CACjD,IAAMI,EAAQJ,EAAM,YAAY,GAAG,EAC7BK,EAAQL,EAAM,UAAUI,CAAK,EAE7BE,EAAwB,CAAC,EAG/B,QAAWC,KAAKC,GACVD,EAAE,QAAQ,WAAWF,CAAK,GAC5BC,EAAQ,KAAK,CAAE,KAAMC,EAAE,QAAS,YAAaA,EAAE,YAAa,KAAM,SAAU,CAAC,EAKjF,GAAIF,IAAU,KAAOA,EAAM,WAAW,QAAQ,GAAKA,EAAM,WAAW,IAAI,EAAG,CACzE,IAAMI,EAAYJ,EAAM,WAAW,QAAQ,EAAIA,EAAM,UAAU,CAAC,EAAI,GAC9DK,EAAQC,GAAgBV,EAAYQ,CAAS,EACnD,QAAWG,KAAKF,EAAM,MAAM,EAAG,EAAE,EAC/BJ,EAAQ,KAAK,CAAE,KAAM,SAASM,CAAC,GAAI,YAAa,GAAI,KAAM,MAAO,CAAC,CAEtE,CAEA,OAAON,CACT,CAGA,IAAMO,EAAQb,EAAM,MAAM,GAAG,EAC7B,GAAIa,EAAM,QAAU,EAAG,CACrB,IAAMC,EAAOD,EAAM,CAAC,EACdE,EAAcC,GAAiBF,CAAI,EACzC,GAAIC,GAAeF,EAAM,QAAU,EAAG,CACpC,IAAMI,EAAMJ,EAAM,CAAC,GAAK,GACxB,OAAOE,EACJ,OAAQG,GAAMA,EAAE,WAAWD,CAAG,CAAC,EAC/B,IAAKC,IAAO,CAAE,KAAM,GAAGJ,CAAI,IAAII,CAAC,GAAI,YAAa,GAAI,KAAM,YAAsB,EAAE,CACxF,CACF,CAGA,GAAIL,EAAM,QAAU,EAAG,CACrB,IAAMM,EAAcC,GAAmBpB,EAAOC,CAAU,EACxD,GAAIkB,EAAY,OAAS,EAAG,CAC1B,IAAME,EAASR,EAAM,MAAM,EAAG,EAAE,EAAE,KAAK,GAAG,EAAI,IAC9C,OAAOM,EAAY,IAAKZ,IAAO,CAC7B,KAAMc,EAASd,EACf,YAAaA,EAAE,SAAS,GAAG,EAAI,YAAc,OAC7C,KAAM,MACR,EAAE,CACJ,CACF,CAEA,MAAO,CAAC,CACV,CAIO,SAASe,GAAatB,EAAeC,EAA4B,CACtE,GAAI,CAACD,EAAO,MAAO,GAGnB,GAAIA,EAAM,WAAW,GAAG,EAAG,CACzB,IAAMuB,EAAQrB,GAAe,KAAMC,GAAMA,EAAE,KAAK,WAAWH,CAAK,GAAKG,EAAE,OAASH,CAAK,EACrF,OAAOuB,EAAQA,EAAM,KAAK,UAAUvB,EAAM,MAAM,EAAI,EACtD,CAGA,IAAMI,EAAQJ,EAAM,YAAY,GAAG,EACnC,GAAII,GAAS,GAAKA,IAAUJ,EAAM,OAASA,EAAM,UAAUI,CAAK,EAAE,OAAQ,CACxE,IAAMC,EAAQL,EAAM,UAAUI,CAAK,EAC7BmB,EAAQf,GAAkB,KAAMD,GAAMA,EAAE,QAAQ,WAAWF,CAAK,GAAKE,EAAE,UAAYF,CAAK,EAC9F,OAAOkB,EAAQA,EAAM,QAAQ,UAAUlB,EAAM,MAAM,EAAI,EACzD,CAEA,MAAO,EACT,CAIO,SAASe,GAAmBpB,EAAeC,EAA8B,CAE9E,IAAMuB,EAAe,CAAC,KAAM,KAAM,MAAO,OAAQ,OAAQ,OAAQ,OAAQ,MAAO,OAAQ,OAAQ,OAAQ,KAAM,KAAM,KAAM,QAAS,QAAS,OAAO,EAC7IX,EAAQb,EAAM,MAAM,GAAG,EAC7B,GAAIa,EAAM,OAAS,EAAG,MAAO,CAAC,EAE9B,IAAMY,EAAMZ,EAAM,CAAC,EACnB,GAAI,CAACW,EAAa,SAASC,CAAG,EAAG,MAAO,CAAC,EAEzC,IAAMC,EAAUb,EAAMA,EAAM,OAAS,CAAC,GAAK,GAC3C,OAAOc,GAAgB1B,EAAYyB,CAAO,CAC5C,CAEA,SAASC,GAAgB1B,EAAoByB,EAA2B,CACtE,GAAI,CACF,IAAME,EAAMF,EAAQ,SAAS,GAAG,EACvB,WAAQzB,EAAYyB,EAAQ,UAAU,EAAGA,EAAQ,YAAY,GAAG,EAAI,CAAC,CAAC,EAC3EzB,EACEoB,EAASK,EAAQ,SAAS,GAAG,EAAIA,EAAQ,UAAUA,EAAQ,YAAY,GAAG,EAAI,CAAC,EAAIA,EAEzF,GAAI,CAAI,cAAWE,CAAG,GAAK,CAAI,YAASA,CAAG,EAAE,YAAY,EAAG,MAAO,CAAC,EAEpE,IAAMC,EAAa,eAAYD,EAAK,CAAE,cAAe,EAAK,CAAC,EACrDE,EAAOJ,EAAQ,SAAS,GAAG,EAAIA,EAAQ,UAAU,EAAGA,EAAQ,YAAY,GAAG,EAAI,CAAC,EAAI,GAE1F,OAAOG,EACJ,OAAQE,GAAM,CAACA,EAAE,KAAK,WAAW,GAAG,GAAKL,EAAQ,WAAW,GAAG,CAAC,EAChE,OAAQK,GAAMA,EAAE,KAAK,YAAY,EAAE,WAAWV,EAAO,YAAY,CAAC,CAAC,EACnE,KAAK,CAACW,EAAGC,IACJD,EAAE,YAAY,IAAMC,EAAE,YAAY,EAAUD,EAAE,YAAY,EAAI,GAAK,EAChEA,EAAE,KAAK,cAAcC,EAAE,IAAI,CACnC,EACA,MAAM,EAAG,EAAE,EACX,IAAKF,GAAMD,EAAOC,EAAE,MAAQA,EAAE,YAAY,EAAI,IAAM,GAAG,CAC5D,MAAQ,CACN,MAAO,CAAC,CACV,CACF,CAEA,SAASpB,GAAgBV,EAAoBI,EAAyB,CACpE,IAAMC,EAAoB,CAAC,EACrB4B,EAAQ7B,EAAM,YAAY,EAC1B8B,EAAW,IAAI,IAAI,CAAC,eAAgB,OAAQ,OAAQ,QAAS,cAAe,SAAU,UAAU,CAAC,EAEjGC,EAAO,CAACR,EAAaS,EAAaC,IAAkB,CACxD,GAAI,EAAAA,EAAQ,GAAKhC,EAAQ,QAAU,IACnC,GAAI,CACF,IAAMuB,EAAa,eAAiB,QAAK5B,EAAY2B,CAAG,EAAG,CAAE,cAAe,EAAK,CAAC,EAClF,QAAWG,KAAKF,EAAS,CACvB,GAAIE,EAAE,KAAK,WAAW,GAAG,GAAKI,EAAS,IAAIJ,EAAE,IAAI,EAAG,SACpD,GAAIzB,EAAQ,QAAU,GAAI,MAC1B,IAAMC,EAAI8B,EAAM,GAAGA,CAAG,IAAIN,EAAE,IAAI,GAAKA,EAAE,KACnCA,EAAE,YAAY,IACZ,CAAC1B,GAASE,EAAE,YAAY,EAAE,SAAS2B,CAAK,IAAG5B,EAAQ,KAAKC,EAAI,GAAG,EACnE6B,EAAU,QAAKR,EAAKG,EAAE,IAAI,EAAGxB,EAAG+B,EAAQ,CAAC,IAErC,CAACjC,GAASE,EAAE,YAAY,EAAE,SAAS2B,CAAK,IAAG5B,EAAQ,KAAKC,CAAC,CAEjE,CACF,MAAQ,CAAa,CACvB,EAEA,OAAA6B,EAAK,GAAI,GAAI,CAAC,EACP9B,CACT,CAjQA,IAgBaJ,GAgDAM,GAWPQ,GA3ENuB,GAAAC,EAAA,kBAgBatC,GAAiC,CAC5C,CAAE,KAAM,QAAS,YAAa,yBAA0B,EACxD,CAAE,KAAM,SAAU,YAAa,oBAAqB,EACpD,CAAE,KAAM,OAAQ,YAAa,wBAAyB,EACtD,CAAE,KAAM,SAAU,YAAa,mBAAoB,EACnD,CAAE,KAAM,YAAa,YAAa,sBAAuB,EACzD,CAAE,KAAM,QAAS,YAAa,uBAAwB,EACtD,CAAE,KAAM,SAAU,YAAa,yBAA0B,EACzD,CAAE,KAAM,WAAY,YAAa,kBAAmB,EACpD,CAAE,KAAM,UAAW,YAAa,wBAAyB,EACzD,CAAE,KAAM,OAAQ,YAAa,0BAA2B,EACxD,CAAE,KAAM,WAAY,YAAa,sBAAuB,EACxD,CAAE,KAAM,MAAO,YAAa,oBAAqB,EACjD,CAAE,KAAM,UAAW,YAAa,2BAA4B,EAC5D,CAAE,KAAM,QAAS,YAAa,qBAAsB,EACpD,CAAE,KAAM,QAAS,YAAa,2BAA4B,EAC1D,CAAE,KAAM,UAAW,YAAa,uBAAwB,EACxD,CAAE,KAAM,QAAS,YAAa,kBAAmB,EACjD,CAAE,KAAM,SAAU,YAAa,mBAAoB,EACnD,CAAE,KAAM,UAAW,YAAa,mBAAoB,EACpD,CAAE,KAAM,eAAgB,YAAa,uBAAwB,EAC7D,CAAE,KAAM,SAAU,YAAa,uBAAwB,EACvD,CAAE,KAAM,SAAU,YAAa,oBAAqB,EACpD,CAAE,KAAM,OAAQ,YAAa,uBAAwB,EACrD,CAAE,KAAM,WAAY,YAAa,wBAAyB,EAC1D,CAAE,KAAM,UAAW,YAAa,kBAAmB,EACnD,CAAE,KAAM,SAAU,YAAa,cAAe,EAC9C,CAAE,KAAM,MAAO,YAAa,mBAAoB,EAChD,CAAE,KAAM,QAAS,YAAa,sBAAuB,EACrD,CAAE,KAAM,SAAU,YAAa,aAAc,EAC7C,CAAE,KAAM,UAAW,YAAa,cAAe,EAC/C,CAAE,KAAM,SAAU,YAAa,kBAAmB,EAClD,CAAE,KAAM,UAAW,YAAa,qBAAsB,EACtD,CAAE,KAAM,QAAS,YAAa,2BAA4B,EAC1D,CAAE,KAAM,QAAS,YAAa,cAAe,EAC7C,CAAE,KAAM,QAAS,YAAa,cAAe,EAC7C,CAAE,KAAM,OAAQ,YAAa,+BAAgC,EAC7D,CAAE,KAAM,eAAgB,YAAa,4BAA6B,EAClE,CAAE,KAAM,SAAU,YAAa,oBAAqB,CACtD,EASaM,GAAuC,CAClD,CAAE,QAAS,YAAa,YAAa,wBAAyB,EAC9D,CAAE,QAAS,OAAQ,YAAa,mBAAoB,EACpD,CAAE,QAAS,QAAS,YAAa,mBAAoB,EACrD,CAAE,QAAS,YAAa,YAAa,uBAAwB,EAC7D,CAAE,QAAS,QAAS,YAAa,mBAAoB,EACrD,CAAE,QAAS,QAAS,YAAa,gBAAiB,CACpD,EAIMQ,GAA6C,CACjD,IAAK,CAAC,UAAW,MAAO,OAAQ,QAAS,QAAS,OAAQ,UAAW,YAAa,SAAU,KAAM,QAAS,IAAI,EAC/G,KAAM,CAAC,UAAW,MAAO,SAAU,MAAO,QAAS,OAAQ,QAAS,MAAO,UAAW,OAAQ,KAAK,EACnG,KAAM,CAAC,UAAW,MAAO,SAAU,MAAO,QAAS,OAAQ,MAAO,SAAU,OAAO,EACnF,IAAK,CAAC,UAAW,MAAO,SAAU,MAAO,QAAS,OAAQ,MAAO,OAAQ,QAAQ,EACjF,IAAK,CAAC,SAAU,MAAO,SAAU,OAAQ,OAAQ,QAAS,WAAY,SAAU,QAAS,SAAU,MAAO,OAAQ,QAAS,QAAS,QAAS,SAAU,MAAO,cAAe,SAAU,OAAQ,QAAS,QAAQ,EAChN,OAAQ,CAAC,QAAS,MAAO,OAAQ,KAAM,SAAU,OAAQ,OAAQ,OAAQ,KAAM,OAAQ,SAAS,EAChG,OAAQ,CAAC,KAAM,KAAM,YAAa,WAAW,EAC7C,QAAS,CAAC,KAAM,KAAM,YAAa,WAAW,EAC9C,IAAK,CAAC,UAAW,YAAa,SAAU,OAAQ,MAAM,EACtD,MAAO,CAAC,QAAS,MAAO,OAAQ,QAAS,SAAU,MAAO,MAAO,OAAQ,MAAO,SAAS,EACzF,GAAI,CAAC,QAAS,MAAO,OAAQ,MAAO,MAAO,MAAO,MAAO,UAAW,UAAU,EAC9E,KAAM,CAAC,QAAS,OAAQ,QAAS,UAAW,KAAK,EACjD,QAAS,CAAC,MAAO,WAAY,QAAS,SAAU,OAAQ,OAAQ,eAAgB,OAAO,EACvF,GAAI,CAAC,KAAM,QAAS,OAAQ,MAAO,UAAW,MAAO,OAAQ,QAAQ,EACrE,MAAO,CAAC,QAAS,MAAO,OAAQ,OAAQ,KAAK,EAC7C,IAAK,CAAC,MAAO,UAAW,SAAU,WAAY,OAAQ,SAAU,YAAY,CAC9E,IC9EA,OAAS,kBAAAyB,OAAsB,gBAC/B,OAAS,YAAAC,GAAU,UAAAC,GAAQ,WAAAC,OAAe,QAC1C,OAAS,eAAAC,OAAmB,iBAC5B,OAAS,YAAAC,OAAgB,gBAuOR,OAqDP,YAAAC,GArDO,OAAAC,GAUH,QAAAC,OAVG,6BA3NjB,SAASC,IAAwB,CAC/B,GAAI,CACF,GAAI,QAAQ,WAAa,SAAU,OAAOJ,GAAS,UAAW,CAAE,SAAU,OAAQ,CAAC,EACnF,GAAI,CAAE,OAAOA,GAAS,gCAAiC,CAAE,SAAU,OAAQ,CAAC,CAAG,MACzE,CAAE,OAAOA,GAAS,4BAA6B,CAAE,SAAU,OAAQ,CAAC,CAAG,CAC/E,MAAQ,CAAE,MAAO,EAAI,CACvB,CAEA,SAASK,IAA6C,CACpD,GAAI,QAAQ,WAAa,SAAU,OAAO,KAC1C,GAAI,CAKF,GAJiBL,GACf,qGACA,CAAE,SAAU,QAAS,QAAS,GAAK,CACrC,EAAE,KAAK,IACU,MAAO,OAAO,KAC/B,IAAMM,EAASN,GACb,+GACA,CAAE,SAAU,QAAS,QAAS,IAAM,UAAW,GAAK,KAAO,IAAK,CAClE,EAAE,KAAK,EACP,GAAIM,GAAUA,EAAO,OAAS,IAAK,MAAO,CAAE,KAAMA,EAAQ,SAAU,WAAY,CAClF,MAAQ,CAAC,CACT,OAAO,IACT,CAIO,SAASC,GAAUC,EAAuB,CAC/C,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJ,CAACE,EAAOC,CAAQ,EAAIhB,GAAS,EAAE,EAC/B,CAACiB,EAAeC,CAAgB,EAAIlB,GAA4B,CAAC,CAAC,EAClE,CAACmB,EAAaC,CAAc,EAAIpB,GAAS,CAAC,EAC1C,CAACqB,EAAcC,CAAe,EAAItB,GAAS,EAAK,EAChDuB,EAAWtB,GAAOc,CAAK,EAC7BQ,EAAS,QAAUR,EACnB,IAAMS,EAAgBvB,GAAO,CAAC,EAGxBwB,EAAcvB,GAAQ,IAAM,CAChC,GAAI,CAACa,EAAO,MAAO,CAAC,EACpB,IAAMW,EAAcC,GAAeZ,EAAOH,EAAM,UAAU,EAE1D,OAAIc,EAAY,OAAS,GAAKA,EAAY,CAAC,EAAE,OAAS,OAC7C,CAAC,CAAE,KAAMX,EAAO,YAAa,kBAAmB,KAAM,MAAgB,EAAG,GAAGW,CAAW,EAEzFA,CACT,EAAG,CAACX,EAAOH,EAAM,UAAU,CAAC,EAGtBgB,EAAQ1B,GAAQ,IAChBmB,GAAgBI,EAAY,OAAS,EAAU,GAC5CI,GAAad,EAAOH,EAAM,UAAU,EAC1C,CAACG,EAAOH,EAAM,WAAYS,EAAcI,EAAY,MAAM,CAAC,EAGxDK,EAAeT,GAAgBI,EAAY,OAAS,EAE1DtB,GAAa4B,GAAa,CAIxB,GAAID,EAAc,CAChB,GAAIC,EAAI,OAAS,KAAM,CACrBX,EAAgBY,GAAOA,GAAK,EAAIP,EAAY,OAAS,EAAIO,EAAI,CAAE,EAC/D,MACF,CACA,GAAID,EAAI,OAAS,OAAQ,CACvBX,EAAgBY,GAAOA,GAAKP,EAAY,OAAS,EAAI,EAAIO,EAAI,CAAE,EAC/D,MACF,CACA,GAAID,EAAI,OAAS,SAAU,CACzB,IAAME,EAAIR,EAAYN,CAAW,EACjC,GAAIc,EAAG,CACL,IAAMC,EAAOD,EAAE,KAAK,KAAK,EACrBC,IAEFtB,EAAM,SAASsB,EAAMjB,EAAc,OAAS,EAAI,CAAC,GAAGA,CAAa,EAAI,MAAS,EAC9ED,EAAS,EAAE,EACXE,EAAiB,CAAC,CAAC,GAErBI,EAAgB,EAAK,EACrBF,EAAe,CAAC,CAClB,CACA,MACF,CACA,GAAIW,EAAI,OAAS,SAAU,CACzBT,EAAgB,EAAK,EACrB,MACF,CACA,GAAIS,EAAI,OAAS,MAAO,CACtB,IAAME,EAAIR,EAAYN,CAAW,EAC7Bc,IACFjB,EAASiB,EAAE,KAAO,GAAG,EACrBX,EAAgB,EAAK,EACrBF,EAAe,CAAC,GAElB,MACF,CACF,CAGA,GAAIQ,IAAUG,EAAI,OAAS,OAASA,EAAI,OAAS,SAAU,CACzDf,EAAUmB,GAAMA,EAAIP,CAAK,EACzB,MACF,CAGA,GAAIG,EAAI,MAAQA,EAAI,OAAS,IAAK,CAChC,IAAMK,EAAM3B,GAAmB,EAC/B,GAAI2B,EAAK,CACPZ,EAAc,SAAW,EACzBN,EAAkBmB,GAAS,CAAC,GAAGA,EAAMD,CAAG,CAAC,EACzCpB,EAAUmB,GAAMA,EAAI,WAAWX,EAAc,OAAO,IAAI,EACxD,MACF,CACA,IAAMc,EAAO9B,GAAc,EAAE,KAAK,EAClC,GAAI8B,EAAM,CACR,IAAMC,EAAYD,EAAK,MAAM;AAAA,CAAI,EAAE,CAAC,GAAK,GACzCtB,EAAUmB,GAAMA,EAAII,CAAS,CAC/B,CACA,MACF,CAGA,GAAIR,EAAI,MAAQA,EAAI,OAAS,IAAK,CAChCf,EAAS,EAAE,EACXE,EAAiB,CAAC,CAAC,EACnBI,EAAgB,EAAK,EACrB,MACF,CAGA,GAAIS,EAAI,MAAQA,EAAI,OAAS,IAAK,CAChCf,EAAUmB,GAAMA,EAAE,QAAQ,UAAW,EAAE,CAAC,EACxC,MACF,CAGA,GAAIJ,EAAI,OAAS,UAAY,CAACA,EAAI,MAAO,CACvC,IAAMG,EAAOX,EAAS,QAAQ,KAAK,GAC/BW,GAAQjB,EAAc,OAAS,KACjCL,EAAM,SAASsB,GAAQ,uBAAwBjB,EAAc,OAAS,EAAI,CAAC,GAAGA,CAAa,EAAI,MAAS,EACxGD,EAAS,EAAE,EACXE,EAAiB,CAAC,CAAC,EACnBI,EAAgB,EAAK,GAEvB,MACF,CAGA,GAAIS,EAAI,OAAS,YAAa,CAC5Bf,EAAUmB,GAAM,CACd,IAAMK,EAAOL,EAAE,MAAM,EAAG,EAAE,EAE1B,OAAIK,EAAK,WAAW,GAAG,GAAKA,EAAK,SAAS,GAAG,GAAKb,GAAea,EAAM5B,EAAM,UAAU,EAAE,OAAS,GAChGU,EAAgB,EAAI,EACpBF,EAAe,CAAC,GAEhBE,EAAgB,EAAK,EAEhBkB,CACT,CAAC,EACD,MACF,CAGA,GAAIT,EAAI,OAAS,SAAU,CACzBT,EAAgB,EAAK,EACrB,MACF,CAGA,GAAIS,EAAI,OAAS,QAAS,CACxBf,EAAUmB,GAAM,CACd,IAAMK,EAAOL,EAAI,IAEjB,OAAIA,EAAE,WAAW,GAAG,EAClBb,EAAgB,EAAK,EACZK,GAAea,EAAM5B,EAAM,UAAU,EAAE,OAAS,IACzDU,EAAgB,EAAI,EACpBF,EAAe,CAAC,GAEXoB,CACT,CAAC,EACD,MACF,CAGIT,EAAI,MAAQA,EAAI,KAAK,SAAW,GAAK,CAACA,EAAI,MAAQ,CAACA,EAAI,MACzDf,EAAUmB,GAAM,CACd,IAAMK,EAAOL,EAAIJ,EAAI,KAErB,OAAIS,EAAK,WAAW,GAAG,GAAKA,EAAK,SAAS,GAAG,GAGlCb,GAAea,EAAM5B,EAAM,UAAU,EAAE,OAAS,KACzDU,EAAgB,EAAI,EACpBF,EAAe,CAAC,GAEXoB,CACT,CAAC,CAEL,CAAC,EAED,IAAMC,EAAiB1B,EAAM,WAAW,GAAG,EAGrC2B,EAAc,KAAK,IAAI,EAAG,KAAK,IAAIvB,EAAc,KAAK,MAAMwB,GAAc,CAAC,EAAGlB,EAAY,OAASkB,EAAW,CAAC,EAC/GC,EAAqBnB,EAAY,MAAMiB,EAAaA,EAAcC,EAAW,EAC7EE,EAAWH,EAAc,EACzBI,EAAWJ,EAAcC,GAAclB,EAAY,OAEzD,OACElB,GAAC,OAAI,cAAc,SAAS,WAAY,EAErC,UAAAuB,GACCvB,GAAC,OAAI,cAAc,SAAS,SAAU,EACnC,UAAAsC,GACCvC,GAAC,OAAI,SAAAA,GAAC,QAAK,GAAI,EAAE,QAAU,qBAAOoC,CAAW,QAAQ,EAAO,EAE7DE,EAAmB,IAAI,CAACX,EAAGD,IAAM,CAEhC,IAAMe,EADUL,EAAcV,IACCb,EACzB6B,EAAQf,EAAE,OAAS,UAAY,EAAE,QACnCA,EAAE,OAAS,UAAY,EAAE,KACzBA,EAAE,OAAS,OAAS,EAAE,QACtB,EAAE,UACN,OACE1B,GAAC,OAAiB,cAAc,MAC9B,UAAAD,GAAC,QAAK,GAAIyC,EAAa,EAAE,QAAUC,EAAO,WAAYD,EAAahD,GAAe,KAAO,OACtF,SAAAgD,EAAa,WAAQ,MACxB,EACAzC,GAAC,QAAK,GAAIyC,EAAa,EAAE,KAAOC,EAAQ,SAAAf,EAAE,KAAK,EAC9CA,EAAE,YACD3B,GAAC,QAAK,GAAI,EAAE,QAAU,cAAK2B,EAAE,WAAW,GAAG,EACzC,OAPIA,EAAE,IAQZ,CAEJ,CAAC,EACAa,GACCxC,GAAC,OAAI,SAAAA,GAAC,QAAK,GAAI,EAAE,QAAU,qBAAOmB,EAAY,OAASiB,EAAcC,EAAW,QAAQ,EAAO,GAEnG,EAID1B,EAAc,OAAS,GACtBX,GAAC,OAAI,OAAQ,EAAG,SAAU,EACxB,SAAAA,GAAC,QAAK,GAAI,EAAE,QACT,wBAAQW,EAAc,MAAM,SAASA,EAAc,OAAS,EAAI,IAAM,EAAE,YAC3E,EACF,EAIFV,GAAC,OACC,OAAQ,EACR,YAAY,SACZ,YAAa,EAAE,cACf,cAAc,MACd,WAAW,SACX,SAAU,EAEV,UAAAD,GAAC,QACC,GAAImC,EAAiB,EAAE,QAAU,EAAE,QACnC,WAAY1C,GAAe,KAE1B,SAAA0C,EAAiB,MAAQ,MAC5B,EAEC1B,EACCR,GAAAF,GAAA,CACE,UAAAC,GAAC,QAAK,GAAI,EAAE,KAAO,SAAAS,EAAM,EACxBa,EACCtB,GAAC,QAAK,GAAI,EAAE,QAAU,SAAAsB,EAAM,EAE5BtB,GAAC,QAAK,GAAI,EAAE,QAAU,kBAAI,GAE9B,EAEAA,GAAC,QAAK,GAAI,EAAE,QACT,SAAAM,EAAM,aAAe,kEACxB,GAEJ,GACF,CAEJ,CA7TA,IAsDM+B,GAtDNM,GAAAC,EAAA,kBAkBAC,IACAC,KAmCMT,GAAc,IC7CpB,OAAS,kBAAAU,OAAsB,gBAC/B,OAAS,yBAAAC,OAA6B,iBA4EhC,OAGI,OAAAC,GAHJ,QAAAC,OAAA,6BAtDC,SAASC,GAAKC,EAOlB,CACD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJE,EAAOP,GAAsB,EAC7BQ,EAAID,EAAK,OAAS,GAClBE,EAAIF,EAAK,QAAU,GAEnBG,EAAW,IAAM,CACrB,IAAMC,EAAO,QAAQ,IAAI,MAAQ,GAC3BC,EAAIR,EAAM,WAChB,OAAOO,GAAQC,EAAE,WAAWD,CAAI,EAAI,IAAMC,EAAE,MAAMD,EAAK,MAAM,EAAIC,CACnE,EAEMC,EAAW,qCACXC,EAAU,SAGVC,EAAUP,EAAI,IAAMC,EAAI,GACxBO,EAAW,CAACD,IAAYP,EAAI,IAAMC,EAAI,IAGtCQ,EAAOF,EAAU,KAAOC,EAAWE,GAAeC,GAGlDC,EAAY,CAChB,CAAC,WAAYhB,EAAM,QAAQ,EAC3B,CAAC,QAASA,EAAM,KAAK,EACrB,CAAC,QAASA,EAAM,OAAO,EACvB,CAAC,YAAaM,EAAS,CAAC,CAC1B,EACMW,EAAY,KAAK,IAAI,GAAGD,EAAU,IAAI,CAAC,CAACE,CAAC,IAAMA,EAAE,MAAM,CAAC,EAGxDC,EAAU,CACd,CAAE,IAAK,QAAS,MAAO,+BAAgC,GAAI,OAAQ,EACnE,CAAE,IAAK,SAAU,MAAO,eAAgB,GAAI,OAAQ,EACpD,CAAE,IAAK,SAAU,MAAO,eAAgB,GAAI,OAAQ,EACpD,CAAE,IAAK,SAAU,MAAO,cAAe,GAAI,KAAM,EACjD,CAAE,IAAK,SAAU,MAAO,kBAAmB,GAAI,UAAW,EAC1D,CAAE,IAAK,SAAU,MAAO,kBAAmB,GAAI,UAAW,EAC1D,CAAE,IAAK,SAAU,MAAO,eAAgB,GAAI,OAAQ,EACpD,CAAE,IAAK,SAAU,MAAO,OAAQ,GAAI,MAAO,CAC7C,EACMC,EAAe,KAAK,IAAI,GAAGD,EAAQ,IAAKE,GAAMA,EAAE,IAAI,MAAM,CAAC,EAEjE,OACEvB,GAAC,OAAI,cAAc,SAAS,SAAU,EAAG,WAAY,EAAG,SAAS,SAC/D,UAAAA,GAAC,OAAI,cAAc,SAAS,WAAW,SAAS,eAAe,SAAS,SAAU,EAE/E,UAAAe,GAAQA,EAAK,IAAI,CAACS,EAAMC,IACvB1B,GAAC,QAAuB,GAAI,EAAE,QAAS,WAAYF,GAAe,KAC/D,SAAA2B,GADQ,QAAQC,CAAC,EAEpB,CACD,EAGD1B,GAAC,QAAK,GAAI,EAAE,QACT,SAAAY,EACH,EACAZ,GAAC,QAAK,GAAI,EAAE,UACT,SAAAa,EACH,EAEAb,GAAC,QAAM,YAAG,EAGTmB,EAAU,IAAI,CAAC,CAACQ,EAAKC,CAAG,EAAGF,IAAM,CAChC,IAAMD,EAAO,GAAGE,EAAI,SAASP,CAAS,CAAC,KAAKQ,CAAG,GAC/C,OACE5B,GAAC,QAAuB,GAAI,EAAE,QAC3B,SAAAyB,GADQ,QAAQC,CAAC,EAEpB,CAEJ,CAAC,EAED1B,GAAC,QAAM,YAAG,EAGVA,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYF,GAAe,KAC7C,mBACH,EACCwB,EAAQ,IAAI,CAACO,EAAQH,IAAM,CAC1B,IAAMD,EAAO,GAAGI,EAAO,IAAI,SAASN,CAAY,CAAC,MAAMM,EAAO,KAAK,GACnE,OACE7B,GAAC,QAAsB,GAAI,EAAE,UAC1B,SAAAyB,GADQ,OAAOC,CAAC,EAEnB,CAEJ,CAAC,EAED1B,GAAC,QAAM,YAAG,EAGVA,GAAC,QAAK,GAAI,EAAE,QACT,kDACH,GACF,EAGCG,EAAM,UACLH,GAAC8B,GAAA,CACC,SAAU3B,EAAM,SAChB,WAAYA,EAAM,WAClB,YAAY,6DACd,GAEJ,CAEJ,CAnJA,IAgBMe,GAUAD,GA1BNc,GAAAC,EAAA,kBAWAC,IACAC,KAIMhB,GAAY,CAChB,gPACA,8QACA,4NACA,4NACA,wRACA,oPACF,EAGMD,GAAe,CACnB,8FACA,qFACA,wGACF,ICrBA,OAAS,kBAAAkB,OAAsB,gBAkErB,OA2HN,YAAAC,GA3HM,OAAAC,EAyIE,QAAAC,OAzIF,6BAtCV,SAASC,GAAoBC,EAAsB,CACjD,OAAOA,EACJ,QAAQ,aAAc,IAAI,EAC1B,QAAQ,mBAAoB,IAAI,EAChC,QAAQ,4BAA6B,IAAI,CAC9C,CAOA,SAASC,GAAeC,EAAuC,CAC7D,IAAMC,EAAID,EAAM,MACV,CAAE,YAAAE,CAAY,EAAIC,EAAS,EAC3BC,EAAQJ,EAAM,KAAK,MAAM;AAAA,CAAI,EAE7BK,EAA8B,CAAC,EACjCC,EAAI,EAER,KAAOA,EAAIF,EAAM,QAAQ,CACvB,IAAMG,EAAOH,EAAME,CAAC,EAGpB,GAAIC,EAAK,WAAW,KAAK,EAAG,CAC1B,IAAMC,EAAsB,CAACD,CAAI,EAEjC,IADAD,IACOA,EAAIF,EAAM,QAAQ,CAEvB,GADAI,EAAU,KAAKJ,EAAME,CAAC,CAAC,EACnBF,EAAME,CAAC,EAAE,WAAW,KAAK,EAAG,CAC9BA,IACA,KACF,CACAA,GACF,CACA,IAAMG,EAAYD,EAAU,KAAK;AAAA,CAAI,EACrCH,EAAS,KACPV,EAAC,OAAsB,QAAS,EAC9B,SAAAA,EAAC,YACC,YAAaO,EACb,UAAW,GACX,QAASO,EACT,QAAS,GACX,GANQ,QAAQH,CAAC,EAOnB,CACF,EACA,QACF,CAGA,GAAIC,EAAK,WAAW,MAAM,EAAG,CAC3BF,EAAS,KACPV,EAAC,QAAa,GAAIM,EAAE,KAAM,WAAYR,GAAe,KAClD,qBAAOI,GAAoBU,EAAK,MAAM,CAAC,CAAC,CAAC,IADjCD,CAEX,CACF,EACAA,IACA,QACF,CACA,GAAIC,EAAK,WAAW,KAAK,EAAG,CAC1BF,EAAS,KACPV,EAAC,QAAa,GAAIM,EAAE,QAAS,WAAYR,GAAe,KACrD,0BAAOI,GAAoBU,EAAK,MAAM,CAAC,CAAC,CAAC,IADjCD,CAEX,CACF,EACAA,IACA,QACF,CACA,GAAIC,EAAK,WAAW,IAAI,EAAG,CACzBF,EAAS,KACPV,EAAC,QAAa,GAAIM,EAAE,QAAS,WAAYR,GAAe,KACrD,+BAAOI,GAAoBU,EAAK,MAAM,CAAC,CAAC,CAAC,IADjCD,CAEX,CACF,EACAA,IACA,QACF,CAGA,GAAI,SAAS,KAAKC,CAAI,GAAK,SAAS,KAAKA,CAAI,GAAK,YAAY,KAAKA,CAAI,EAAG,CACxEF,EAAS,KACPV,EAAC,QAAa,GAAIM,EAAE,QAAU,kBAAI,OAAO,EAAE,GAAhCK,CAAkC,CAC/C,EACAA,IACA,QACF,CAGA,IAAMI,EAAcH,EAAK,MAAM,iBAAiB,EAChD,GAAIG,EAAa,CACf,IAAMC,EAASD,EAAY,CAAC,GAAK,GAC3BE,EAAUf,GAAoBa,EAAY,CAAC,CAAC,EAClDL,EAAS,KACPV,EAAC,QAAc,YAAGgB,CAAM,UAAKC,CAAO,IAAzBN,CAA4B,CACzC,EACAA,IACA,QACF,CAGA,IAAMO,EAAWN,EAAK,MAAM,oBAAoB,EAChD,GAAIM,EAAU,CACZ,IAAMD,EAAUf,GAAoBgB,EAAS,CAAC,CAAC,EAC/CR,EAAS,KACPV,EAAC,QAAc,YAAGkB,EAAS,CAAC,CAAC,GAAGA,EAAS,CAAC,CAAC,KAAKD,CAAO,IAA5CN,CAA+C,CAC5D,EACAA,IACA,QACF,CAGA,GAAIC,EAAK,WAAW,IAAI,EAAG,CACzBF,EAAS,KACPV,EAAC,QAAa,GAAIM,EAAE,UAAY,mBAAKJ,GAAoBU,EAAK,MAAM,CAAC,CAAC,CAAC,IAA5DD,CAA+D,CAC5E,EACAA,IACA,QACF,CAGA,GAAI,CAACC,EAAK,KAAK,EAAG,CAChBF,EAAS,KAAKV,EAAC,QAAc,cAAJW,CAAQ,CAAO,EACxCA,IACA,QACF,CAGAD,EAAS,KACPV,EAAC,QAAc,SAAAE,GAAoBU,CAAI,GAA5BD,CAA8B,CAC3C,EACAA,GACF,CAEA,OAAOX,EAAC,OAAI,cAAc,SAAU,SAAAU,EAAS,CAC/C,CAIA,SAASS,GAAgBC,EAAoB,CAC3C,IAAMC,EAAI,IAAI,KAAKD,CAAE,EACjBE,EAAID,EAAE,SAAS,EACbE,EAAIF,EAAE,WAAW,EACjBG,EAAOF,GAAK,GAAK,KAAO,KAC9B,OAAAA,EAAIA,EAAI,IAAM,GACP,GAAGA,CAAC,IAAIC,EAAE,SAAS,EAAE,SAAS,EAAG,GAAG,CAAC,IAAIC,CAAI,EACtD,CAMO,SAASC,GAAYpB,EAKzB,CACD,GAAM,CAAE,MAAAqB,CAAM,EAAIlB,EAAS,EACrB,EAAIkB,EAEV,OACEzB,GAAAF,GAAA,CAEG,UAAAM,EAAM,SAAS,SAAW,GAAK,CAACA,EAAM,aACrCL,EAAC,OAAI,SAAU,EAAG,SAAU,EAC1B,SAAAA,EAAC,QAAK,GAAI,EAAE,UACT,gFACH,EACF,EAIDK,EAAM,SAAS,IAAKsB,GACfA,EAAI,OAAS,OAEb1B,GAAC,OAAiB,SAAU,EAAG,SAAU,EAAG,cAAc,MACxD,UAAAD,EAAC,QAAK,GAAI,EAAE,SAAU,WAAYF,GAAe,KAC9C,mBACH,EACAE,EAAC,QAAK,GAAI,EAAE,SAAU,SAAU,EAAI,SAAA2B,EAAI,QAAQ,EAC/CtB,EAAM,gBAAkBsB,EAAI,WAC3B3B,EAAC,QAAK,GAAI,EAAE,QAAU,cAAKmB,GAAgBQ,EAAI,SAAS,CAAC,GAAG,IANtDA,EAAI,EAQd,EAIAA,EAAI,OAAS,YAEb1B,GAAC,OAAiB,YAAa,EAAG,UAAW,EAAG,WAAY,EAAG,cAAc,SAC3E,UAAAA,GAAC,OAAI,cAAc,MACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYF,GAAe,KAC7C,mBACH,EACCO,EAAM,gBAAkBsB,EAAI,WAC3B3B,EAAC,QAAK,GAAI,EAAE,QAAU,cAAKmB,GAAgBQ,EAAI,SAAS,CAAC,GAAG,GAEhE,EACA3B,EAAC,OAAI,YAAa,EAChB,SAAAA,EAACI,GAAA,CAAe,KAAMuB,EAAI,QAAQ,KAAK,EAAG,MAAO,EAAG,EACtD,IAXQA,EAAI,EAYd,EAIAA,EAAI,OAAS,SAEb1B,GAAC,OAAiB,SAAU,EAAG,cAAc,MAC3C,UAAAD,EAAC,QAAK,GAAI,EAAE,WAAY,SAAU,EAAI,mBAAK2B,EAAI,OAAO,GAAG,EACxDtB,EAAM,gBAAkBsB,EAAI,WAC3B3B,EAAC,QAAK,GAAI,EAAE,QAAU,cAAKmB,GAAgBQ,EAAI,SAAS,CAAC,GAAG,IAHtDA,EAAI,EAKd,EAIAA,EAAI,OAAS,OAEb3B,EAAC4B,GAAA,CAEC,KAAMD,EAAI,UAAY,UACtB,QAASA,EAAI,QACb,OAAQA,EAAI,aAAeA,EAAI,QAAU,QAAU,SAH9CA,EAAI,EAIX,EAIG,IACR,EAGAtB,EAAM,aACLJ,GAAC,OAAI,YAAa,EAAG,UAAW,EAAG,WAAY,EAAG,cAAc,SAC9D,UAAAA,GAAC,OAAI,cAAc,MACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYF,GAAe,KAC7C,mBACH,EACAE,EAAC,QAAK,GAAI,EAAE,QAAU,kBAAI,GAC5B,GACEK,EAAM,eAAiB,IAAI,KAAK,GAChCL,EAAC,OAAI,YAAa,EAChB,SAAAA,EAACI,GAAA,CAAe,MAAOC,EAAM,eAAiB,IAAI,KAAK,EAAG,MAAO,EAAG,EACtE,GAEJ,GAEJ,CAEJ,CAIA,SAASuB,GAAYvB,EAIlB,CACD,GAAM,CAAE,MAAAqB,CAAM,EAAIlB,EAAS,EACrB,EAAIkB,EAEJG,EAAOC,GAAWzB,EAAM,IAAI,GAAK,eACjC0B,GAAc,IAAM,CACxB,OAAQ1B,EAAM,OAAQ,CACpB,IAAK,UAAW,MAAO,SACvB,IAAK,OAAQ,MAAO,SACpB,IAAK,QAAS,MAAO,QACvB,CACF,GAAG,EACG2B,GAAe,IAAM,CACzB,OAAQ3B,EAAM,OAAQ,CACpB,IAAK,UAAW,OAAO,EAAE,YACzB,IAAK,OAAQ,OAAO,EAAE,SACtB,IAAK,QAAS,OAAO,EAAE,SACzB,CACF,GAAG,EAEG4B,EACkC,CACpC,UAAW,OAAQ,WAAY,QAAS,UAAW,OACnD,WAAY,YAAa,WAAY,OAAQ,YAAa,eAC1D,YAAa,cAAe,UAAW,QAAS,UAAW,QAC3D,SAAU,WAAY,gBAAiB,iBACzC,EACa5B,EAAM,IAAI,GAAKA,EAAM,KAAK,QAAQ,KAAM,GAAG,EAG1D,OACEJ,GAAC,OAAI,SAAU,EACb,UAAAD,EAAC,QAAK,GAAIgC,EAAc,YAAGD,CAAU,IAAI,EACzC/B,EAAC,QAAK,GAAI,EAAE,SAAW,YAAG6B,CAAI,IAAII,CAAS,GAAG,EAC7C5B,EAAM,SACLL,EAAC,QAAK,GAAI,EAAE,QAAU,oBAAMkC,GAAS7B,EAAM,QAAS,EAAE,CAAC,GAAG,GAE9D,CAEJ,CAEA,SAAS6B,GAASC,EAAWC,EAAqB,CAChD,IAAMC,EAAQF,EAAE,MAAM;AAAA,CAAI,EAAE,CAAC,GAAK,GAClC,OAAOE,EAAM,OAASD,EAAMC,EAAM,UAAU,EAAGD,CAAG,EAAI,SAAMC,CAC9D,CAjVA,IA0BMP,GA1BNQ,GAAAC,EAAA,kBAUAC,IAgBMV,GAAqC,CACzC,UAAW,YAAM,WAAY,eAAM,UAAW,YAAM,WAAY,YAChE,WAAY,YAAM,SAAU,SAAK,YAAa,YAAM,YAAa,YACjE,gBAAiB,YAAM,UAAW,YAAM,WAAY,YAAM,UAAW,YACrE,KAAM,YAAM,SAAU,YAAM,UAAW,YAAM,cAAe,kBAC5D,YAAa,SAAK,YAAa,eAAM,SAAU,YAAM,cAAe,WACtE,IC5BA,OAAS,kBAAAW,OAAsB,gBAC/B,OAAS,YAAAC,OAAgB,QACzB,OAAS,eAAAC,OAAmB,iBAqCxB,OAOE,OAAAC,GAPF,QAAAC,OAAA,6BAtBG,SAASC,GAAiBC,EAA8B,CAC7D,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJ,CAACE,EAAUC,CAAW,EAAIT,GAAS,CAAC,EAE1C,OAAAC,GAAaS,GAAa,CACpBA,EAAI,OAAS,MAAQA,EAAI,OAAS,IACpCD,EAAaE,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,EAC5BD,EAAI,OAAS,QAAUA,EAAI,OAAS,IAC7CD,EAAaE,GAAM,KAAK,IAAIC,GAAQ,OAAS,EAAGD,EAAI,CAAC,CAAC,EAC7CD,EAAI,OAAS,SACtBL,EAAM,WAAWO,GAAQJ,CAAQ,EAAE,KAAK,EAC/BE,EAAI,OAAS,IACtBL,EAAM,WAAW,OAAO,EACfK,EAAI,OAAS,IACtBL,EAAM,WAAW,QAAQ,EAChBK,EAAI,OAAS,KACtBL,EAAM,WAAW,MAAM,CAE3B,CAAC,EAGCF,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SAEd,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYH,GAAe,KAC7C,yCACH,EACAG,GAAC,QAAK,GAAI,EAAE,KACT,cAAKG,EAAM,QAAQ,KAAKA,EAAM,OAAO,GACxC,EACAH,GAAC,QAAK,GAAI,EAAE,QAAU,YAAG,EACxBU,GAAQ,IAAI,CAACC,EAAK,IACjBX,GAAC,OACC,SAAAA,GAAC,QACC,GAAIM,IAAa,EAAI,EAAE,QAAU,EAAE,UACnC,WAAYA,IAAa,EAAIT,GAAe,KAAO,OAElD,cAAKS,IAAa,EAAI,SAAM,GAAG,KAAKK,EAAI,GAAG,KAAKA,EAAI,KAAK,GAC5D,GANQA,EAAI,GAOd,CACD,EACDX,GAAC,QAAK,GAAI,EAAE,QAAU;AAAA,uDAAgD,GACxE,CAEJ,CAtEA,IAeMU,GAfNE,GAAAC,EAAA,kBAOAC,IAQMJ,GAAU,CACd,CAAE,IAAK,IAAK,MAAO,aAAc,MAAO,OAAiB,EACzD,CAAE,IAAK,IAAK,MAAO,eAAgB,MAAO,QAAkB,EAC5D,CAAE,IAAK,IAAK,MAAO,OAAQ,MAAO,MAAgB,CACpD,ICfA,OAAS,YAAAK,GAAU,aAAAC,OAAiB,QAkBhC,OACE,OAAAC,GADF,QAAAC,OAAA,6BAbG,SAASC,GAAeC,EAA2B,CACxD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJ,CAACE,EAAOC,CAAQ,EAAIT,GAAS,CAAC,EAEpC,OAAAC,GAAU,IAAM,CACd,IAAMS,EAAW,YAAY,IAAM,CACjCD,EAAUE,IAAOA,EAAI,GAAKC,GAAO,MAAM,CACzC,EAAG,EAAE,EACL,MAAO,IAAM,cAAcF,CAAQ,CACrC,EAAG,CAAC,CAAC,EAGHP,GAAC,OAAI,SAAU,EAAG,OAAQ,EAAG,cAAc,MACzC,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAU,SAAAU,GAAOJ,CAAK,EAAE,EACpCN,GAAC,QAAK,GAAI,EAAE,UAAY,aAAIG,EAAM,OAAS,aAAa,GAAG,GAC7D,CAEJ,CA3BA,IAOMO,GAPNC,GAAAC,EAAA,kBAKAC,IAEMH,GAAS,CAAC,SAAK,SAAK,SAAK,SAAK,SAAK,SAAK,SAAK,SAAK,SAAK,QAAG,ICHzD,SAASI,GAAiBC,EAAqB,CAChD,QAAQ,OAAO,OACjB,QAAQ,OAAO,MAAM,UAAUA,CAAK,MAAM,CAE9C,CAEO,SAASC,IAA2B,CACrC,QAAQ,OAAO,OACjB,QAAQ,OAAO,MAAM,aAAa,CAEtC,CAdA,IAAAC,GAAAC,EAAA,oBCOA,UAAYC,MAAQ,KACpB,UAAYC,OAAU,OACtB,UAAYC,OAAQ,KAqBpB,SAASC,IAAkB,CACjB,aAAWC,EAAQ,GAAM,YAAUA,GAAU,CAAE,UAAW,EAAK,CAAC,CAC1E,CAEA,SAASC,IAAqB,CAC5B,IAAMC,EAAM,KAAK,IAAI,EAAE,SAAS,EAAE,EAC5BC,EAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,EAClD,MAAO,GAAGD,CAAG,IAAIC,CAAI,EACvB,CAEA,SAASC,GAAYC,EAAyB,CAC5C,IAAMC,EAAQD,EAAQ,QAAQ,MAAO,GAAG,EAAE,KAAK,EAC/C,OAAOC,EAAM,OAAS,GAAKA,EAAM,UAAU,EAAG,EAAE,EAAI,MAAQA,CAC9D,CAEO,SAASC,GAAmBC,EAAkBC,EAA6B,CAChF,OAAAV,GAAU,EACH,CACL,GAAIE,GAAW,EACf,MAAO,mBACP,UAAW,KAAK,IAAI,EACpB,UAAW,KAAK,IAAI,EACpB,SAAAO,EACA,MAAAC,EACA,SAAU,CAAC,CACb,CACF,CAEO,SAASC,GACdC,EACAC,EACAC,EACAC,EACM,CACNH,EAAK,SAAS,KAAK,CAAE,KAAAC,EAAM,QAAAC,EAAS,UAAW,KAAK,IAAI,EAAG,SAAAC,CAAS,CAAC,EACrEH,EAAK,UAAY,KAAK,IAAI,EAEtBC,IAAS,QAAUD,EAAK,QAAU,qBACpCA,EAAK,MAAQP,GAAYS,CAAO,GAGlCE,GAAiBJ,CAAI,CACvB,CAEO,SAASI,GAAiBJ,EAA0B,CACzDZ,GAAU,EACV,IAAMiB,EAAgB,QAAKhB,GAAU,GAAGW,EAAK,EAAE,OAAO,EACnD,gBAAcK,EAAU,KAAK,UAAUL,EAAM,KAAM,CAAC,EAAG,OAAO,CACnE,CAEO,SAASM,GAAiBC,EAAiC,CAEhEnB,GAAU,EAEV,IAAMoB,EADW,cAAYnB,EAAQ,EAAE,OAAQoB,GAAMA,EAAE,SAAS,OAAO,CAAC,EACpD,KAAMA,GAAMA,EAAE,WAAWF,CAAE,GAAKE,EAAE,QAAQ,QAAS,EAAE,IAAMF,CAAE,EACjF,GAAI,CAACC,EAAO,OAAO,KAEnB,IAAMH,EAAgB,QAAKhB,GAAUmB,CAAK,EAC1C,GAAI,CACF,OAAO,KAAK,MAAS,eAAaH,EAAU,OAAO,CAAC,CACtD,MAAQ,CACN,OAAO,IACT,CACF,CAEO,SAASK,IAAoC,CAClDtB,GAAU,EACV,IAAMuB,EAAW,cAAYtB,EAAQ,EAAE,OAAQoB,GAAMA,EAAE,SAAS,OAAO,CAAC,EAClEG,EAAwB,CAAC,EAE/B,QAAWC,KAAQF,EACjB,GAAI,CACF,IAAMG,EAAO,KAAK,MAAS,eAAkB,QAAKzB,GAAUwB,CAAI,EAAG,OAAO,CAAC,EAC3ED,EAAM,KAAKE,CAAI,CACjB,MAAQ,CAAC,CAGX,OAAOF,EAAM,KAAK,CAACG,EAAGC,IAAMA,EAAE,UAAYD,EAAE,SAAS,CACvD,CAOO,SAASE,GAAmBV,EAAqB,CACtDnB,GAAU,EAEV,IAAMoB,EADW,cAAYnB,EAAQ,EAAE,OAAQoB,GAAMA,EAAE,SAAS,OAAO,CAAC,EACpD,KAAMA,GAAMA,EAAE,WAAWF,CAAE,GAAKE,EAAE,QAAQ,QAAS,EAAE,IAAMF,CAAE,EACjF,OAAIC,GACC,aAAgB,QAAKnB,GAAUmB,CAAK,CAAC,EACjC,IAEF,EACT,CAEO,SAASU,GAAiBC,EAAsD,CACrF,IAAMC,EACJ,OAAOD,GAAa,SAAWb,GAAiBa,CAAQ,EAAIA,EAC9D,GAAI,CAACC,EAAU,OAAO,KAEtBhC,GAAU,EACV,IAAMiC,EAAuB,CAC3B,GAAGD,EACH,GAAI9B,GAAW,EACf,MAAO,YAAY8B,EAAS,KAAK,GACjC,UAAW,KAAK,IAAI,EACpB,UAAW,KAAK,IAAI,EACpB,SAAUA,EAAS,SAAS,IAAKE,IAAO,CAAE,GAAGA,CAAE,EAAE,CACnD,EACA,OAAAlB,GAAiBiB,CAAM,EAChBA,CACT,CAUO,SAASE,GAAmBC,EAA2B,CAC5D,IAAMC,EAAO,KAAK,IAAI,EAAID,EACpBE,EAAU,KAAK,MAAMD,EAAO,GAAI,EACtC,GAAIC,EAAU,GAAI,MAAO,WACzB,IAAMC,EAAU,KAAK,MAAMD,EAAU,EAAE,EACvC,GAAIC,EAAU,GAAI,MAAO,GAAGA,CAAO,QACnC,IAAMC,EAAQ,KAAK,MAAMD,EAAU,EAAE,EACrC,GAAIC,EAAQ,GAAI,MAAO,GAAGA,CAAK,QAC/B,IAAMC,EAAO,KAAK,MAAMD,EAAQ,EAAE,EAClC,OAAIC,EAAO,GAAW,GAAGA,CAAI,QACtB,IAAI,KAAKL,CAAS,EAAE,mBAAmB,CAChD,CAnKA,IAWMnC,GAXNyC,GAAAC,EAAA,kBAWM1C,GAAgB,QAAQ,WAAQ,EAAG,UAAW,eAAe,ICJnE,OACE,2BAAA2C,GACA,2BAAAC,GACA,sBAAAC,GACA,uBAAAC,GACA,2BAAAC,GACA,4BAAAC,GACA,8BAAAC,OACK,eAKP,SAASC,IAAuC,CAC9C,OAAKC,KACHA,GAAW,IAAIR,GACfS,GAAmB,IAAIR,GACvBO,GAAS,SAASC,EAAgB,EAClCD,GAAS,SAAS,IAAIN,EAAoB,EAC1CM,GAAS,SAAS,IAAIL,EAAqB,EAC3CK,GAAS,SAAS,IAAIJ,EAAyB,EAC/CI,GAAS,SAAS,IAAIH,EAA0B,EAChDG,GAAS,SAAS,IAAIF,EAA4B,GAE7CE,EACT,CAGO,SAASE,GAAmBC,EAAsB,CACvDJ,GAAY,EACRE,IAAoB,OAAQA,GAAyB,MAAS,YAC/DA,GAAyB,KAAKE,CAAM,CAEzC,CASA,eAAsBC,GACpBC,EACAC,EACiB,CACjB,IAAMC,EAAMR,GAAY,EACpBS,EAAkBH,EAChBI,EAA2B,CAAC,EAElC,QAAWC,KAAWC,GAAU,CAC9B,IAAMC,EAAMJ,EAAgB,QAAQE,CAAO,EAC3C,GAAIE,IAAQ,GAAI,SAGhB,IAAMC,EAAeL,EAAgB,UAAUI,EAAMF,EAAQ,MAAM,EAC7DI,EAASD,EAAa,OAAO,UAAU,EACvCE,EAAMF,EAAa,UAAU,EAAGC,IAAW,GAAKD,EAAa,OAASC,CAAM,EAAE,KAAK,EAGnFE,EAAcN,GAAWK,EAAM,IAAMA,EAAM,IACjDP,EAAkBA,EAAgB,QAAQQ,EAAa,EAAE,EAAE,KAAK,EAGhE,IAAMC,EAAeP,EAAQ,UAAU,CAAC,EAClCQ,EAAWX,EAAI,IAAIU,CAAY,EACrC,GAAKC,EAEL,GAAI,CACF,IAAMC,EAAS,MAAMD,EAAS,QAAQH,EAAK,CAAE,WAAAT,CAAW,CAAC,EACrDa,GACFV,EAAe,KAAK,OAAOC,CAAO;AAAA,EAASS,CAAM,EAAE,CAEvD,MAAQ,CAER,CACF,CAEA,OAAIV,EAAe,OAAS,IAC1BD,EAAkBA,EAAkB;AAAA;AAAA,EAASC,EAAe,KAAK;AAAA;AAAA,CAAM,GAGlED,CACT,CAKO,SAASY,GAAmBf,EAA0B,CAC3D,OAAOM,GAAS,KAAMU,GAAMhB,EAAQ,SAASgB,CAAC,CAAC,CACjD,CAjGA,IAiBIrB,GACAC,GAyBEU,GA3CNW,GAAAC,EAAA,kBAiBIvB,GAA2C,KAC3CC,GAAmD,KAyBjDU,GAAW,CAAC,YAAa,OAAQ,QAAS,YAAa,QAAS,OAAO,ICzB7E,OAAS,YAAAa,GAAU,UAAAC,GAAQ,aAAAC,OAAiB,QAC5C,OAAS,kBAAAC,OAAsB,gBAC/B,OAAS,eAAAC,OAAmB,iBAC5B,UAAYC,MAAQ,KACpB,UAAYC,MAAU,OACtB,UAAYC,OAAQ,KASpB,OAAS,YAAAC,OAAgB,gBAmFrB,OACE,OAAAC,GADF,QAAAC,OAAA,6BAjDJ,SAASC,GAAmBC,EAA8B,CACxD,IAAMC,EAAUD,EAAM,KAAK,EACrBE,EAAYD,EAAQ,MAAM,KAAK,EAAE,CAAC,EAAE,YAAY,EACtD,OAAOE,GAAe,IAAID,CAAS,EAAID,EAAU,IACnD,CAgBA,SAASG,GAAgBC,EAKtB,CACD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJ,CAACE,EAAUC,CAAW,EAAIrB,GAAS,CAAC,EACpCsB,EAAU,CACd,CAAE,MAAO,8DAA0D,OAAQL,EAAM,WAAY,EAC7F,CAAE,MAAO,oDAAgD,OAAQA,EAAM,OAAQ,EAC/E,CAAE,MAAO,oCAAgC,OAAQA,EAAM,QAAS,CAClE,EAEAb,GAAamB,GAAa,CACxB,GAAIA,EAAI,OAAS,SAAU,CAAEN,EAAM,SAAS,EAAG,MAAQ,CACvD,GAAIM,EAAI,OAAS,MAAQA,EAAI,OAAS,IAAK,CAAEF,EAAaG,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,EAAG,MAAQ,CAC7F,GAAID,EAAI,OAAS,QAAUA,EAAI,OAAS,IAAK,CAAEF,EAAaG,GAAM,KAAK,IAAIF,EAAQ,OAAS,EAAGE,EAAI,CAAC,CAAC,EAAG,MAAQ,CAChH,GAAID,EAAI,OAAS,SAAU,CAAED,EAAQF,CAAQ,EAAE,OAAO,EAAG,MAAQ,CAEjE,GAAIG,EAAI,WAAa,KAAOA,EAAI,WAAa,IAAK,CAAEN,EAAM,YAAY,EAAG,MAAQ,CACjF,GAAIM,EAAI,WAAa,KAAOA,EAAI,WAAa,IAAK,CAAEN,EAAM,QAAQ,EAAG,MAAQ,CAC7E,GAAIM,EAAI,WAAa,IAAK,CAAEN,EAAM,SAAS,EAAG,MAAQ,CACxD,CAAC,EAED,IAAMQ,EAAUR,EAAM,QAAQ,OAAS,GAAKA,EAAM,QAAQ,MAAM,EAAG,EAAE,EAAI,MAAQA,EAAM,QAEvF,OACEP,GAAC,OAAI,cAAc,SAAS,WAAY,EAAG,SAAU,EACnD,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYN,GAAe,KAC7C,+DACH,EACAM,GAAC,QAAK,GAAI,EAAE,QAAU,eAAMgB,CAAO,IAAI,EACvChB,GAAC,QAAM,YAAG,EACTa,EAAQ,IAAI,CAACI,EAAKC,IACjBlB,GAAC,QAAa,GAAIkB,IAAMP,EAAW,EAAE,QAAU,EAAE,UAAW,WAAYO,IAAMP,EAAWjB,GAAe,KAAO,OAC5G,cAAKwB,IAAMP,EAAW,SAAM,GAAG,IAAIO,EAAI,CAAC,KAAKD,EAAI,KAAK,IAD9CC,CAEX,CACD,EACDlB,GAAC,QAAK,GAAI,EAAE,QAAU,qEAAkD,GAC1E,CAEJ,CAIO,SAASmB,GAAYX,EAOzB,CACD,IAAMY,EAAMC,GAAO,EACb,CAAE,QAAAC,CAAQ,EAAIZ,EAAS,EACvB,CAAE,MAAAa,CAAM,EAAIC,GAAS,EAG3BC,GAAiB,kBAAkB,EAEnC,GAAM,CAACC,EAAUC,CAAW,EAAIpC,GAAoB,CAAC,CAAC,EAChD,CAACqC,EAAeC,CAAgB,EAAItC,GAAS,EAAE,EAC/CuC,EAAmBtC,GAAOoC,CAAa,EAC7CE,EAAiB,QAAUF,EAC3B,GAAM,CAACG,EAAaC,CAAc,EAAIzC,GAAS,EAAK,EAC9C,CAAC0C,EAAYC,CAAa,EAAI3C,GAA6B,EAC3D,CAAC4C,EAAmBC,CAAoB,EAAI7C,GAIxC,IAAI,EAGR,CAAC8C,EAAkBC,CAAmB,EAAI/C,GAGtC,IAAI,EACRgD,EAAoB/C,GAAiB,CAAC,CAAC,EAEvCgD,EAAgBhD,GAAO,CAAC,EACxBiD,EAAiBjD,GAAO,CAAC,EACzBkD,EAAkBlD,GAAO,CAAC,EAC1BmD,EAAkBnD,GAA4B,IAAI,EAClDoD,EAAoBpD,GAAwB,CAAC,CAAC,EAC9CqD,EAAiBrD,GAAO,CAAC,EAG1BmD,EAAgB,UACnBA,EAAgB,QAAUG,GAAmB1B,EAAI,SAAUA,EAAI,KAAK,GAGtE,IAAM2B,EAAa,CAACC,EAAuBC,EAAiBC,IAA6B,CACvF,IAAMC,EAAe,CACnB,GAAI,OAAO,EAAET,EAAgB,OAAO,GACpC,KAAAM,EACA,QAAAC,EACA,UAAW,KAAK,IAAI,EACpB,GAAGC,CACL,EACA,OAAAvB,EAAayB,GAAS,CAAC,GAAGA,EAAMD,CAAG,CAAC,EAGhCR,EAAgB,UAAYK,IAAS,QAAUA,IAAS,cAC1DD,GAAkBJ,EAAgB,QAASK,EAAMC,CAAO,EAGnDE,EAAI,EACb,EAEME,EAAgB,CAACC,EAAYC,IAA8B,CAC/D5B,EAAayB,GACXA,EAAK,IAAKI,GAAOA,EAAE,KAAOF,EAAK,CAAE,GAAGE,EAAG,GAAGD,CAAQ,EAAIC,CAAE,CAC1D,CACF,EAIMC,GAAmB,IAA2B,CAClD,GAAI,CACF,IAAMC,EAAkB,OAAQ,WAAQ,EAAG,UAAW,aAAa,EACnE,GAAO,aAAWA,CAAU,EAC1B,OAAO,KAAK,MAAS,eAAaA,EAAY,OAAO,CAAC,CAE1D,MAAQ,CAAC,CACT,MAAO,CAAC,CACV,EAEMC,GAAgB,CAAC7C,EAAa8C,IAAqB,CACvD,IAAMC,EAAiB,OAAQ,WAAQ,EAAG,SAAS,EAC7CH,EAAkB,OAAKG,EAAW,aAAa,EACjDC,EAA8B,CAAC,EACnC,GAAI,CACK,aAAWJ,CAAU,IAC1BI,EAAS,KAAK,MAAS,eAAaJ,EAAY,OAAO,CAAC,EAE5D,MAAQ,CAAC,CACTI,EAAOhD,CAAG,EAAI8C,EACN,aAAWC,CAAS,GAAM,YAAUA,EAAW,CAAE,UAAW,EAAK,CAAC,EACvE,gBAAcH,EAAY,KAAK,UAAUI,EAAQ,KAAM,CAAC,EAAG,OAAO,CACvE,EAEMC,GAAsB,IAA2B,CACrD,GAAI,CACF,IAAMC,EAAoB,OAAK5C,EAAI,WAAY,UAAW,eAAe,EACzE,GAAO,aAAW4C,CAAY,EAC5B,OAAO,KAAK,MAAS,eAAaA,EAAc,OAAO,CAAC,EAE1D,IAAMC,EAAkB,OAAK7C,EAAI,WAAY,UAAW,eAAe,EACvE,GAAO,aAAW6C,CAAU,EAC1B,OAAO,KAAK,MAAS,eAAaA,EAAY,OAAO,CAAC,CAE1D,MAAQ,CAAC,CACT,MAAO,CAAC,CACV,EAIMC,GAAoBC,GAAmB,CAC3C,IAAMC,EAAqB,CACzB,GAAI,MAAM,EAAEvB,EAAe,OAAO,GAClC,OAAAsB,EACA,OAAQ,UACR,UAAW,KAAK,IAAI,CACtB,EACAvB,EAAkB,QAAU,CAAC,GAAGA,EAAkB,QAASwB,CAAG,EAC9DrB,EAAW,SAAU,kBAAkBqB,EAAI,EAAE,aAAaD,EAAO,UAAU,EAAG,EAAE,CAAC,GAAGA,EAAO,OAAS,GAAK,MAAQ,EAAE,EAAE,EAGrH,IAAIE,EAAW,GACTC,EAA8B,CAClC,QAAUC,GAAU,CAAEF,GAAYE,CAAO,EACzC,WAAY,IAAM,CAAC,EACnB,aAAc,IAAM,CAAC,EACrB,WAAY,IAAM,CAChBH,EAAI,OAAS,OACbA,EAAI,OAASC,EAAS,KAAK,EAC3BD,EAAI,YAAc,KAAK,IAAI,EAC3BxB,EAAkB,QAAU,CAAC,GAAGA,EAAkB,OAAO,EACzDG,EAAW,SAAU,kBAAkBqB,EAAI,EAAE,yBAAyBA,EAAI,EAAE,kBAAkB,CAChG,EACA,QAAUI,GAAU,CAClBJ,EAAI,OAAS,QACbA,EAAI,MAAQI,EAAM,QAClBJ,EAAI,YAAc,KAAK,IAAI,EAC3BxB,EAAkB,QAAU,CAAC,GAAGA,EAAkB,OAAO,EACzDG,EAAW,SAAU,kBAAkBqB,EAAI,EAAE,YAAYI,EAAM,OAAO,EAAE,CAC1E,CACF,EAGApD,EAAI,MAAM,IAAI+C,EAAQG,CAAW,EAAE,MAAOG,GAAQ,CAChDL,EAAI,OAAS,QACbA,EAAI,MAAQK,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,EAC3DL,EAAI,YAAc,KAAK,IAAI,CAC7B,CAAC,CACH,EAIMM,GAAsBC,GAAgB,CAC1C,GAAM,CAACC,EAAS,GAAGC,CAAI,EAAIF,EAAI,MAAM,GAAG,EAClCG,EAAMD,EAAK,KAAK,GAAG,EAAE,KAAK,EAEhC,OAAQD,EAAS,CACf,IAAK,SACHjD,EAAY,CAAC,CAAC,EACdP,EAAI,MAAM,aAAa,EACvB2B,EAAW,SAAU,eAAe,EACpCxB,EAAM,UAAW,cAAc,EAC/B,MAEF,IAAK,OACHI,EAAY,CAAC,CAAC,EACdP,EAAI,MAAM,aAAa,EACvBoB,EAAc,QAAU,EACxBC,EAAe,QAAU,EACzBjC,EAAM,SAAS,EAAG,CAAC,EACnBA,EAAM,iBAAiB,CAAC,EACxBmC,EAAgB,QAAUG,GAAmB1B,EAAI,SAAUA,EAAI,KAAK,EACpE2B,EAAW,SAAU,2BAA2B,EAChDxB,EAAM,UAAW,0BAA0B,EAC3C,MAEF,IAAK,SAAU,CACTuD,GAAO1D,EAAI,cACbA,EAAI,aAAaA,EAAI,SAAU0D,CAAG,EAClC/B,EAAW,SAAU,sBAAsB+B,CAAG,EAAE,EAChDvD,EAAM,OAAQ,UAAUuD,CAAG,EAAE,GACpBA,GACT/B,EAAW,SAAU,gCAAgC,EACrDxB,EAAM,UAAW,+BAA+B,GAEhDwB,EAAW,SAAU,kBAAkB3B,EAAI,KAAK,EAAE,EAEpD,KACF,CAEA,IAAK,YAAa,CAChB,GAAI0D,GAAO1D,EAAI,aAAc,CAC3B,GAAM,CAAE,gBAAA2D,CAAgB,EAAI,GAAQ,YAAY,EAC1CC,EAAeD,EAAgBD,CAAG,GAAK1D,EAAI,MACjDA,EAAI,aAAa0D,EAAKE,CAAY,EAClCjC,EAAW,SAAU,yBAAyB+B,CAAG,YAAYE,CAAY,GAAG,EAC5EzD,EAAM,OAAQ,aAAauD,CAAG,KAAKE,CAAY,GAAG,CACpD,MAAWF,GACT/B,EAAW,SAAU,mCAAmC,EACxDxB,EAAM,UAAW,kCAAkC,GAEnDwB,EAAW,SAAU,qBAAqB3B,EAAI,QAAQ,EAAE,EAE1D,KACF,CAEA,IAAK,QAAS,CACZ,IAAM6D,EAAe7D,EAAI,mBAA2B,MAAQ,MAC5D2B,EAAW,SAAU,oBAAoBkC,CAAW;AAAA,gCAAmC,EACvF,KACF,CAEA,IAAK,OAAQ,CACX,GAAIH,EAAK,CACP,IAAMI,EAAgB,UAAQ9D,EAAI,WAAY0D,CAAG,EAC1C,aAAWI,CAAQ,GAAQ,WAASA,CAAQ,EAAE,YAAY,GAC3D9D,EAAI,eAAeA,EAAI,cAAc8D,CAAQ,EACjDnC,EAAW,SAAU,iCAAiCmC,CAAQ,EAAE,GAEhEnC,EAAW,SAAU,wBAAwBmC,CAAQ,EAAE,CAE3D,MACEnC,EAAW,SAAU,sBAAsB3B,EAAI,UAAU,EAAE,EAE7D,KACF,CAEA,IAAK,UAAW,CACd,GAAI0D,EAAI,WAAW,MAAM,EAAG,CAC1B,IAAMK,EAAWL,EAAI,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,EACpD,GAAIK,EAAS,QAAU,EAAG,CACxB,GAAM,CAACrE,EAAK,GAAGsE,CAAQ,EAAID,EACrBvB,EAAQwB,EAAS,KAAK,GAAG,EAC/B,GAAItE,IAAQ,UAAW,CACrB,IAAMgD,EAASL,GAAiB,EAC3BK,EAAO,UAASA,EAAO,QAAU,CAAC,GACvCA,EAAO,QAAQ1C,EAAI,QAAQ,EAAIwC,EAC/BD,GAAc,UAAWG,EAAO,OAAO,EACvCf,EAAW,SAAU,qBAAqB3B,EAAI,QAAQ,GAAG,CAC3D,MAAWN,IAAQ,kBACjB6C,GAAc,eAAgBC,CAAK,EACnCb,EAAW,SAAU,0BAA0Ba,CAAK,EAAE,IAEtDD,GAAc7C,EAAK8C,CAAK,EACxBb,EAAW,SAAU,UAAUjC,CAAG,YAAY8C,CAAK,EAAE,EAEzD,MACEb,EAAW,SAAU,kCAAkC,CAE3D,SAAW+B,IAAQ,QAAU,CAACA,EAAK,CACjC,IAAMhB,EAASL,GAAiB,EAC1B4B,EAAQ,OAAO,QAAQvB,CAAM,EAChC,OAAO,CAAC,CAACwB,CAAC,IAAMA,IAAM,SAAS,EAC/B,IAAI,CAAC,CAACA,EAAGC,CAAC,IAAM,KAAKD,CAAC,KAAK,OAAOC,GAAM,SAAW,KAAK,UAAUA,CAAC,EAAIA,CAAC,EAAE,EAC7ExC,EAAW,SAAUsC,EAAM,OAAS,EAAI;AAAA,EAAqBA,EAAM,KAAK;AAAA,CAAI,EAAI,kDAAkD,CACpI,MACEtC,EAAW,SAAU,2CAA2C,EAElE,KACF,CAEA,IAAK,SAAU,CAET+B,GADe,CAAC,OAAQ,OAAO,EACU,SAASA,CAAG,GACvDxD,EAAQwD,CAAuB,EAC/B/B,EAAW,SAAU,2BAA2B+B,CAAG,EAAE,EACrDvD,EAAM,UAAW,SAASuD,CAAG,EAAE,IAE/B/B,EAAW,SAAU,0DAA0D,EAC/ExB,EAAM,UAAW,4BAA4B,GAE/C,KACF,CAEA,IAAK,WACEH,EAAI,MAAc,iBACpBA,EAAI,MAAc,gBAAgB,EACnC2B,EAAW,SAAU,qBAAqB,EAC1CxB,EAAM,UAAW,oBAAoB,IAErCwB,EAAW,SAAU,oCAAoC,EACzDxB,EAAM,UAAW,mCAAmC,GAEtD,MAEF,IAAK,UAAW,CACd,IAAMiE,EAAS,CAAC,MAAO,SAAU,OAAQ,KAAK,EAC1CV,GAAOU,EAAO,SAASV,CAAG,GAC5B/B,EAAW,SAAU,wBAAwB+B,CAAG,EAAE,EAClDvD,EAAM,OAAQ,WAAWuD,CAAG,EAAE,GAE9B/B,EAAW,SAAU,mBAAmByC,EAAO,KAAK,GAAG,CAAC,GAAG,EAE7D,KACF,CAEA,IAAK,QAAS,CACRV,IAAQ,KACV/B,EAAW,SAAU,gEAAgE,EAC5E+B,IAAQ,MACjB/B,EAAW,SAAU,qBAAqB,EACjC+B,IAAQ,OACjB/B,EAAW,SAAU,iBAAiB,EAC7B+B,IAAQ,UACjB/B,EAAW,SAAU,qBAAqB,EACjC+B,IAAQ,SACjB/B,EAAW,SAAU,oBAAoB,EAEzCA,EAAW,SAAU,2CAA2C,EAElE,KACF,CAEA,IAAK,eAAgB,CACnB,IAAM0C,EAAW1B,GAAoB,EAC/B2B,EAAQD,GAAU,OAAS,CAAC,EAC5BE,EAAOF,GAAU,MAAQ,CAAC,EAC1BJ,EAAkB,CAAC,mBAAmB,EACxCM,EAAK,OAAS,GAAGN,EAAM,KAAK,WAAaM,EAAK,KAAK,IAAI,CAAC,EACxDD,EAAM,OAAS,GAAGL,EAAM,KAAK,YAAcK,EAAM,KAAK,IAAI,CAAC,EAC3DC,EAAK,SAAW,GAAKD,EAAM,SAAW,GAAGL,EAAM,KAAK,+BAA+B,EACvFtC,EAAW,SAAUsC,EAAM,KAAK;AAAA,CAAI,CAAC,EACrC,KACF,CAEA,IAAK,SAAU,CACb,GAAI,CACF,IAAMO,EAAiB,OAAKxE,EAAI,WAAY,UAAW,YAAY,EACnE,GAAO,aAAWwE,CAAS,EAAG,CAC5B,IAAMC,EAAQ,KAAK,MAAS,eAAaD,EAAW,OAAO,CAAC,EACtDE,EAAO,OAAO,KAAKD,CAAK,EAC9B9C,EAAW,SAAU+C,EAAK,OAAS,EAC/B;AAAA,EAAwBA,EAAK,IAAK,GAAM,KAAK,CAAC,KAAK,KAAK,UAAUD,EAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI,EACxF,sBAAsB,CAC5B,MACE9C,EAAW,SAAU,2CAA2C,CAEpE,MAAQ,CACNA,EAAW,SAAU,sBAAsB,CAC7C,CACA,KACF,CAEA,IAAK,SAAU,CACb,GAAI,CACF,IAAMgD,EAAgB,OAAK3E,EAAI,WAAY,UAAW,OAAO,EAC7D,GAAO,aAAW2E,CAAQ,EAAG,CAC3B,IAAMC,EAAW,cAAYD,CAAQ,EAAE,OAAQE,GAAcA,EAAE,SAAS,KAAK,CAAC,EAC9ElD,EAAW,SAAUiD,EAAM,OAAS,EAChC;AAAA,EAAqBA,EAAM,IAAKC,GAAc,KAAKA,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI,EACjE,mCAAmC,CACzC,MACElD,EAAW,SAAU,4CAA4C,CAErE,MAAQ,CACNA,EAAW,SAAU,sBAAsB,CAC7C,CACA,KACF,CAEA,IAAK,UACHA,EAAW,SAAU,wDAAwD,EAC7E,MAEF,IAAK,SACHA,EAAW,SAAU,qDAAqD,EAC1E,MAEF,IAAK,WACHA,EAAW,SAAU,CACnB,uCACA,6CACA,wCACA,wCACA,4CACA,wCACA,oCACF,EAAE,KAAK;AAAA,CAAI,CAAC,EACZ,MAEF,IAAK,OACHA,EAAW,SAAU,iEAAiE,EACtF,MAEF,IAAK,WACL,IAAK,MAAO,CACV,IAAMmD,EAAQC,GAAkB,EAAE,MAAM,EAAG,EAAE,EAC7C,GAAID,EAAM,OAAS,EAAG,CACpB,IAAMb,EAAQa,EAAM,IAAKE,GAAM,CAC7B,IAAM9C,EAAK8C,EAAE,GAAG,UAAU,EAAG,EAAE,EACzBC,EAAOC,GAAmBF,EAAE,SAAS,EACrCG,GAAWH,EAAE,SAAS,OAAQ5C,IAAMA,GAAE,OAAS,MAAM,EAAE,OAC7D,MAAO,KAAKF,CAAE,KAAK+C,EAAK,OAAO,EAAE,CAAC,MAAME,EAAQ,WAAWH,EAAE,KAAK,EACpE,CAAC,EACDrD,EAAW,SAAU;AAAA,EAAqBsC,EAAM,KAAK;AAAA,CAAI,EAAI;AAAA;AAAA,8DAAmE,CAClI,MACEtC,EAAW,SAAU,+BAA+B,EAEtD,KACF,CAEA,IAAK,UAAW,CACd,GAAI,CAAC+B,EAAK,CACR/B,EAAW,SAAU,kCAAkC,EACvD,KACF,CACA,IAAMyD,EAAOC,GAAiB3B,CAAG,EACjC,GAAI,CAAC0B,EAAM,CACTzD,EAAW,SAAU,2BAA2B+B,CAAG,EAAE,EACrD,KACF,CAEAnC,EAAgB,QAAU6D,EAC1B7E,EAAY,CAAC,CAAC,EACdP,EAAI,MAAM,aAAa,EACvBoB,EAAc,QAAU,EACxBC,EAAe,QAAU,EAEzB,QAAWe,KAAKgD,EAAK,SACnB,GAAIhD,EAAE,OAAS,QAAUA,EAAE,OAAS,YAAa,CAC/C,IAAML,EAAe,CACnB,GAAI,OAAO,EAAET,EAAgB,OAAO,GACpC,KAAMc,EAAE,KACR,QAASA,EAAE,QACX,UAAWA,EAAE,SACf,EACA7B,EAAayB,GAAS,CAAC,GAAGA,EAAMD,CAAG,CAAC,CACtC,CAEFJ,EAAW,SAAU,yBAAyByD,EAAK,KAAK,EAAE,EAC1D,KACF,CAEA,IAAK,QAAS,CACZ,GAAI,CAAC1B,EAAK,CACR/B,EAAW,SAAU,gCAAgC,EACrD,KACF,CACA,IAAMyD,EAAOC,GAAiB3B,CAAG,EACjC,GAAI,CAAC0B,EAAM,CACTzD,EAAW,SAAU,2BAA2B+B,CAAG,EAAE,EACrD,KACF,CACA,IAAM4B,EAAWF,EAAK,SACnB,OAAQhD,GAAMA,EAAE,OAAS,MAAM,EAC/B,MAAM,GAAG,EACT,IAAKA,GAAM,CACV,IAAMmD,EAASnD,EAAE,OAAS,OAAS,SAAM,SACnCP,EAAUO,EAAE,QAAQ,OAAS,IAAMA,EAAE,QAAQ,UAAU,EAAG,EAAE,EAAI,MAAQA,EAAE,QAChF,MAAO,KAAKmD,CAAM,IAAI1D,EAAQ,QAAQ,MAAO,GAAG,CAAC,EACnD,CAAC,EACHF,EAAW,SAAU,iBAAiByD,EAAK,KAAK;AAAA;AAAA,EAAOE,EAAS,KAAK;AAAA,CAAI,CAAC,EAAE,EAC5E,KACF,CAEA,IAAK,QAAS,CACZ,IAAME,EAAa9B,EAAM2B,GAAiB3B,CAAG,EAAInC,EAAgB,QACjE,GAAI,CAACiE,EAAY,CACf7D,EAAW,SAAU+B,EAAM,2BAA2BA,CAAG,GAAK,iCAAiC,EAC/F,KACF,CACA,IAAM+B,EAASC,GAAiBF,CAAU,EACtCC,EACF9D,EAAW,SAAU,wBAAwB8D,EAAO,GAAG,UAAU,EAAG,EAAE,CAAC,YAAOA,EAAO,KAAK,GAAG,EAE7F9D,EAAW,SAAU,8BAA8B,EAErD,KACF,CAEA,IAAK,UAAW,CACd,GAAI,CAAC+B,EAAK,CACR/B,EAAW,SAAU,kCAAkC,EACvD,KACF,CACIgE,GAAmBjC,CAAG,EACxB/B,EAAW,SAAU,yBAAyB+B,CAAG,EAAE,EAEnD/B,EAAW,SAAU,2BAA2B+B,CAAG,EAAE,EAEvD,KACF,CAEA,IAAK,MAAO,CACV,GAAI,CAACA,EAAK,CACR/B,EAAW,SAAU,qBAAqB,EAC1C,KACF,CACAmB,GAAiBY,CAAG,EACpB,KACF,CAEA,IAAK,QAAS,CACZ,IAAMkC,EAAOpE,EAAkB,QAC/B,GAAIkC,EAAK,CAEP,IAAMV,EAAM4C,EAAK,KAAMC,GAAMA,EAAE,KAAOnC,CAAG,EACzC,GAAIV,EAAK,CACP,IAAM8C,EAAU9C,EAAI,YAChB,KAAKA,EAAI,YAAcA,EAAI,WAAa,KAAM,QAAQ,CAAC,CAAC,IACxD,KAAK,KAAK,IAAI,EAAIA,EAAI,WAAa,KAAM,QAAQ,CAAC,CAAC,cACjD+C,EAAS/C,EAAI,OACfA,EAAI,OAAO,OAAS,IAAMA,EAAI,OAAO,UAAU,EAAG,GAAG,EAAI,MAAQA,EAAI,OACrEA,EAAI,OAAS,cACjBrB,EAAW,SAAU,OAAOqB,EAAI,EAAE,KAAKA,EAAI,MAAM,MAAM8C,CAAO;AAAA,YAAiB9C,EAAI,MAAM;AAAA,YAAe+C,CAAM,EAAE,CAClH,MACEpE,EAAW,SAAU,kBAAkB+B,CAAG,EAAE,CAEhD,SAAWkC,EAAK,OAAS,EAAG,CAC1B,IAAM3B,EAAQ2B,EAAK,IAAKC,GAEf,KADMA,EAAE,SAAW,UAAY,SAAMA,EAAE,SAAW,OAAS,SAAM,QACxD,IAAIA,EAAE,EAAE,KAAKA,EAAE,MAAM,KAAKA,EAAE,OAAO,UAAU,EAAG,EAAE,CAAC,GAAGA,EAAE,OAAO,OAAS,GAAK,MAAQ,EAAE,EACxG,EACDlE,EAAW,SAAU;AAAA,EAAuBsC,EAAM,KAAK;AAAA,CAAI,CAAC,CAC9D,MACEtC,EAAW,SAAU,qBAAqB,EAE5C,KACF,CAEA,IAAK,OAAQ,CACX,GAAI,CAAC+B,EAAK,CACR/B,EAAW,SAAU,wBAAwB,EAC7C,KACF,CAEA,IAAMqE,EAAkB,CACtB,GAAI,OAAO,EAAE1E,EAAgB,OAAO,GACpC,KAAM,OACN,QAAS,SAASoC,CAAG,GACrB,UAAW,KAAK,IAAI,CACtB,EACAnD,EAAayB,GAAS,CAAC,GAAGA,EAAMgE,CAAM,CAAC,EACvCpF,EAAe,EAAI,EACnBH,EAAiB,EAAE,EACnBrB,EAAM,SAAS,eAAe,EAE9B,IAAI6G,EAAY,GACVC,EAA+B,CACnC,QAAU/C,GAAU,CAClB8C,GAAa9C,EACb1C,EAAkBuB,GAASA,EAAOmB,CAAK,CACzC,EACA,WAAY,IAAM,CAAC,EACnB,aAAc,IAAM,CAAC,EACrB,WAAY,IAAM,CAChB,GAAI8C,EAAU,KAAK,EAAG,CACpB,IAAMlE,EAAe,CACnB,GAAI,OAAO,EAAET,EAAgB,OAAO,GACpC,KAAM,YACN,QAAS2E,EAAU,KAAK,EACxB,UAAW,KAAK,IAAI,CACtB,EACA1F,EAAayB,GAAS,CAAC,GAAGA,EAAMD,CAAG,CAAC,EACpCtB,EAAiB,EAAE,CACrB,CACAG,EAAe,EAAK,EACpBxB,EAAM,SAAS,OAAO,CACxB,EACA,QAAUgE,GAAU,CAClBzB,EAAW,SAAU,UAAUyB,EAAM,OAAO,EAAE,EAC9CxC,EAAe,EAAK,EACpBxB,EAAM,SAAS,OAAO,CACxB,CACF,EAEAY,EAAI,MAAM,IAAI0D,EAAKwC,CAAY,EAAE,MAAO7C,GAAQ,CAC9C1B,EAAW,SAAU,UAAU0B,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,EAAE,EACjFzC,EAAe,EAAK,EACpBxB,EAAM,SAAS,OAAO,CACxB,CAAC,EACD,KACF,CAEA,IAAK,SACL,IAAK,SACCA,EAAM,aACRA,EAAM,aAAa,OAAO,EAE1BuC,EAAW,SAAU,qFAAqF,EAE5G,MAEF,IAAK,UAAW,CACd,GAAI,CACF,GAAM,CAAE,WAAAwE,CAAW,EAAI,GAAQ,cAAc,EACvCpE,EAAMoE,EAAWnG,EAAI,QAAQ,EAGnCA,EAAI,MAAM,WAAW,EAErB2B,EAAW,SAAUI,CAAG,CAC1B,MAAQ,CACNJ,EAAW,SAAU,6BAA6B,CACpD,CACA,KACF,CAEA,IAAK,eAAgB,CACnB,IAAMe,EAASL,GAAiB,EAC1B4B,EAAkB,CAAC,yBAA0B,EAAE,EAIrD,GADAA,EAAM,KAAK,kBAAkB,EACzBvB,EAAO,SAAW,OAAO,KAAKA,EAAO,OAAO,EAAE,OAAS,EACzD,OAAW,CAAC0D,EAAM1G,EAAG,IAAK,OAAO,QAAQgD,EAAO,OAAO,EAAG,CACxD,IAAMwB,GAAI,OAAOxE,EAAG,EACd2G,GAASnC,GAAE,MAAM,EAAG,CAAC,EAAI,MAAQA,GAAE,MAAM,EAAE,EACjDD,EAAM,KAAK,YAAOmC,CAAI,KAAKC,EAAM,EAAE,CACrC,MAEApC,EAAM,KAAK,QAAQ,EAGrBA,EAAM,KAAK,EAAE,EACbA,EAAM,KAAK,wBAAwB,EACnC,IAAMqC,EAA0C,CAC9C,CAAC,oBAAqB,QAAQ,IAAI,iBAAiB,EACnD,CAAC,iBAAkB,QAAQ,IAAI,cAAc,EAC7C,CAAC,iBAAkB,QAAQ,IAAI,cAAc,CAC/C,EACIC,EAAY,GAChB,OAAW,CAACC,EAAMhE,EAAK,IAAK8D,EAC1B,GAAI9D,GAAO,CACT+D,EAAY,GACZ,IAAMF,GAAS7D,GAAM,MAAM,EAAG,CAAC,EAAI,MAAQA,GAAM,MAAM,EAAE,EACzDyB,EAAM,KAAK,YAAOuC,CAAI,KAAKH,EAAM,EAAE,CACrC,CAEGE,GAAWtC,EAAM,KAAK,QAAQ,EAEnCtC,EAAW,SAAUsC,EAAM,KAAK;AAAA,CAAI,CAAC,EACrC,KACF,CAEA,IAAK,UAAW,CACd,IAAMwC,EAAmB,CAAC,sBAAsB,EAC1C/D,EAASL,GAAiB,EAC1BqE,EAAS,QAAQ,IAAI,GAAG1G,EAAI,SAAS,YAAY,CAAC,UAAU,EAClEyG,EAAO,KAAK,eAAezG,EAAI,QAAQ,IAAI0C,EAAO,UAAU1C,EAAI,QAAQ,GAAK0G,EAAS,uBAAoB,mBAAc,EAAE,EAC1HD,EAAO,KAAK,YAAYzG,EAAI,KAAK,EAAE,EACnCyG,EAAO,KAAK,kBAAkBzG,EAAI,UAAU,IAAO,aAAWA,EAAI,UAAU,EAAI,SAAM,QAAG,EAAE,EAC3F,IAAM2G,EAAe,aAAgB,OAAK3G,EAAI,WAAY,SAAS,CAAC,EAC9D4G,EAAe,aAAgB,OAAK5G,EAAI,WAAY,SAAS,CAAC,EACpEyG,EAAO,KAAK,qBAAqBE,EAAY,kBAAeC,EAAY,kBAAe,aAAQ,EAAE,EACjGH,EAAO,KAAK,WAAW,QAAQ,OAAO,EAAE,EACxCA,EAAO,KAAK,eAAe,QAAQ,QAAQ,IAAI,QAAQ,IAAI,EAAE,EAG7D,IAAM3B,GAAQC,GAAkB,EAChC0B,EAAO,KAAK,oBAAoB3B,GAAM,MAAM,QAAQ,EAGpD,IAAM+B,GAAcrF,EAAkB,QAAQ,OAAQqE,IAAMA,GAAE,SAAW,SAAS,EAC9EgB,GAAY,OAAS,GACvBJ,EAAO,KAAK,sBAAsBI,GAAY,MAAM,UAAU,EAGhElF,EAAW,SAAU8E,EAAO,KAAK;AAAA,CAAI,CAAC,EACtC,KACF,CAEA,IAAK,QAAS,CACZ,IAAMK,EAAiB,OAAK9G,EAAI,WAAY,SAAS,EACrD,GAAO,aAAW8G,CAAS,EACzBnF,EAAW,SAAU,gDAAgD,MAErE,IAAI,CACC,YAAUmF,EAAW,CAAE,UAAW,EAAK,CAAC,EACxC,YAAe,OAAKA,EAAW,OAAO,EAAG,CAAE,UAAW,EAAK,CAAC,EAC5D,gBACI,OAAKA,EAAW,WAAW,EAChC;AAAA;AAAA;AAAA,EACA,OACF,EACAnF,EAAW,SAAU,kEAAkE,CACzF,OAAS0B,EAAK,CACZ1B,EAAW,SAAU,yBAAyB0B,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,EAAE,CAClG,CAEF,KACF,CAEA,IAAK,SACH1B,EAAW,SAAU,yBAAyB,EAC9C,MAEF,IAAK,QACHA,EAAW,SAAU,CACnB,sBACA,GACA,YACA,wCACA,4CACA,6CACA,mDACA,GACA,kBACA,uCACA,0CACA,0CACA,mDACA,wCACA,wCACA,oDACA,sDACA,sCACA,GACA,YACA,8CACA,yCACA,gDACA,yDACA,yCACA,GACA,eACA,8CACA,kDACA,GACA,WACA,2CACA,2CACA,wCACA,4CACA,2CACA,yCACA,sCACA,gDACA,GACA,sCACA,uCACA,wCACA,+CACA,0BACA,GACA,sBACA,kCACA,+BACA,+BACA,0BACA,2BACA,8BACA,uCACA,6CACA,6BACA,GACA,sEACA,0EACF,EAAE,KAAK;AAAA,CAAI,CAAC,EACZ,MAEF,IAAK,SACHA,EAAW,SAAU,WAAWP,EAAc,QAAQ,eAAe,CAAC,SAAIC,EAAe,QAAQ,eAAe,CAAC,MAAMD,EAAc,QAAUC,EAAe,SAAS,eAAe,CAAC,SAAS,EAChM,MAEF,IAAK,QACL,IAAK,QACH,QAAQ,KAAK,CAAC,EACd,MAEF,QACEM,EAAW,SAAU,oBAAoB6B,CAAO,sCAAsC,EACtFrD,EAAM,QAAS,oBAAoBqD,CAAO,EAAE,CAChD,CACF,EAIMuD,GAAmBC,GAAqB,CAC5CrF,EAAW,OAAQ,IAAIqF,CAAQ,EAAE,EACjC,IAAIC,EAAS,GACTC,EAAW,GACf,GAAI,CACFD,EAAStI,GAASqI,EAAU,CAC1B,IAAKhH,EAAI,WACT,IAAK,CAAE,GAAG,QAAQ,GAAI,EACtB,SAAU,QACV,QAAS,KACT,UAAW,GAAK,KAAO,IACzB,CAAC,CACH,OAASqD,EAAU,CACbA,EAAI,SAAQ4D,EAAS,OAAO5D,EAAI,MAAM,GACtCA,EAAI,SAAQ6D,EAAW,OAAO7D,EAAI,MAAM,GACxCA,EAAI,SAAW,QAAaA,EAAI,SAAW,EAC7C6D,GAAY;AAAA,oBAAuB7D,EAAI,MAAM,IACpC,CAACA,EAAI,QAAU,CAACA,EAAI,QAAUA,EAAI,UAC3C6D,EAAW7D,EAAI,QAEnB,CACA,IAAM0C,GAAUkB,GAAUC,EAAW;AAAA,EAAKA,CAAQ,GAAK,KAAK,KAAK,EACjEvF,EAAW,SAAU,KAAKqF,CAAQ;AAAA,EAAKjB,GAAU,aAAa,EAAE,EAGhEoB,GAAmB,KAAKH,CAAQ;AAAA,EAAKjB,CAAM,EAAE,CAC/C,EAIMqB,EAAkB,CAACC,EAAcC,IAA+B,CAEpE,IAAMC,EAAkB7G,EAAiB,QAAQ,KAAK,EACtDV,EAAI,MAAM,UAAUuH,CAAe,EAG/BA,IACF5F,EAAW,YAAa4F,EAAkB;AAAA;AAAA,gBAAqB,EAC/D9G,EAAiB,EAAE,GAGrBG,EAAe,EAAK,EACpBxB,EAAM,SAAS,OAAO,EACtB0B,EAAc,MAAS,EACvB1B,EAAM,aAAa,MAAS,EAC5B8B,EAAoB,IAAI,EAIxB,WAAW,IAAM,CACfsG,GAAcH,EAAMC,CAAM,CAC5B,EAAG,GAAG,CACR,EAIMG,EAAeJ,GAAiB,CACpClG,EAAkB,QAAQ,KAAKkG,CAAI,EACnC1F,EAAW,SAAU,6BAAsBR,EAAkB,QAAQ,MAAM,YAAY,EACvFD,EAAoB,IAAI,CAC1B,EAIMwG,EAAe,IAAM,CACzB,GAAIvG,EAAkB,QAAQ,OAAS,EAAG,CACxC,IAAMwG,EAAOxG,EAAkB,QAAQ,MAAM,EAC7C,WAAW,IAAMqG,GAAcG,CAAI,EAAG,GAAG,CAC3C,CACF,EAIMC,EAAc,MAAOP,EAAcC,IAA+B,CACtE,GAAID,EAAK,WAAW,GAAG,EAAG,CACxB/D,GAAmB+D,CAAI,EACvB,MACF,CAGA,IAAML,EAAWK,EAAK,WAAW,GAAG,EAChCA,EAAK,MAAM,CAAC,EAAE,KAAK,EACnBvI,GAAmBuI,CAAI,EAE3B,GAAIL,EAAU,CAEZ,IAAMa,EAAab,EAAS,KAAK,EAAE,MAAM,KAAK,EAC9C,GAAIa,EAAW,CAAC,IAAM,KAAM,CAC1B,IAAMC,EAASD,EAAW,MAAM,CAAC,EAAE,KAAK,GAAG,GAAK,QAAQ,IAAI,MAAQ,IAC9D/D,EAAgB,UAAQ9D,EAAI,WAAY8H,CAAM,EAC7C,aAAWhE,CAAQ,GAAQ,WAASA,CAAQ,EAAE,YAAY,GAC3D9D,EAAI,eAAeA,EAAI,cAAc8D,CAAQ,EACjDnC,EAAW,SAAU,iCAAiCmC,CAAQ,EAAE,GAEhEnC,EAAW,SAAU,0BAA0BmC,CAAQ,EAAE,EAE3D,MACF,CACAiD,GAAgBC,CAAQ,EACxB,MACF,CAGA,GAAIrG,EAAa,CACfO,EAAoB,CAAE,KAAAmG,EAAM,OAAAC,CAAO,CAAC,EACpC,MACF,CAEA,MAAME,GAAcH,EAAMC,CAAM,CAClC,EAGMS,GAAwB3J,GAAO,EAAK,EAC1CC,GAAU,IAAM,CACVe,EAAM,gBAAkB,CAAC2I,GAAsB,UACjDA,GAAsB,QAAU,GAChCH,EAAYxI,EAAM,eAAe,KAAMA,EAAM,eAAe,MAAM,EAEtE,EAAG,CAAC,CAAC,EAEL,IAAMoI,GAAgB,MAAOH,EAAcC,IAA+B,CAExE,IAAIU,EAAeX,EACnB,GAAIY,GAAmBZ,CAAI,EACzB,GAAI,CACFW,EAAe,MAAME,GAAwBb,EAAMrH,EAAI,UAAU,CACnE,MAAQ,CAER,CAGF2B,EAAW,OAAQ0F,GAAQC,GAAUA,EAAO,OAAS,EAAI,KAAKA,EAAO,MAAM,SAASA,EAAO,OAAS,EAAI,IAAM,EAAE,IAAM,GAAG,EACzH1G,EAAe,EAAI,EACnBH,EAAiB,EAAE,EACnBrB,EAAM,SAAS,eAAe,EAE9B,IAAI+I,EACAC,EAAY,EAEVC,EAA4B,CAChC,QAAUlF,GAAU,CAClB1C,EAAkBuB,GAASA,EAAOmB,CAAK,CACzC,EAEA,WAAY,CAACqD,EAAMzH,IAAU,CAE3B,IAAMuJ,EAAU5H,EAAiB,QAAQ,KAAK,EAC1C4H,IACF3G,EAAW,YAAa2G,CAAO,EAC/B7H,EAAiB,EAAE,GAGrB,IAAM8H,GAAexJ,GAAe,aAAe,GACnDoJ,EAAgBxG,EAAW,OAAQ4G,GAAa,CAC9C,SAAU/B,EACV,WAAY,SACd,CAAC,EACD1F,EAAc0F,CAAI,EAClBpH,EAAM,aAAaoH,CAAI,CACzB,EAEA,aAAc,CAACgC,EAAOzC,EAAQ0C,IAAY,CACxC,GAAIN,EAAe,CACjB,IAAMO,GAAU3C,EAAO,OAAS,GAAKA,EAAO,UAAU,EAAG,EAAE,EAAI,MAAQA,EACvE9D,EAAckG,EAAe,CAC3B,QAASO,GACT,WAAYD,EAAU,QAAU,OAChC,QAAAA,CACF,CAAC,EACDN,EAAgB,MAClB,CACArH,EAAc,MAAS,EACvB1B,EAAM,aAAa,MAAS,CAC9B,EAEA,WAAY,IAAM,CAChB,IAAMkJ,EAAU5H,EAAiB,QAAQ,KAAK,EAC1C4H,IACF3G,EAAW,YAAa2G,CAAO,EAC/B7H,EAAiB,EAAE,GAGrBG,EAAe,EAAK,EACpBxB,EAAM,SAAS,OAAO,EACtB0B,EAAc,MAAS,EACvB1B,EAAM,aAAa,MAAS,EAC5BA,EAAM,SAASgC,EAAc,QAASC,EAAe,OAAO,EAE5DqG,EAAa,CACf,EAEA,QAAUtE,GAAU,CAClB,IAAMkF,EAAU5H,EAAiB,QAAQ,KAAK,EAC1C4H,IACF3G,EAAW,YAAa2G,CAAO,EAC/B7H,EAAiB,EAAE,GAErBkB,EAAW,SAAU,UAAUyB,EAAM,OAAO,EAAE,EAC9CjD,EAAM,QAASiD,EAAM,OAAO,EAC5BxC,EAAe,EAAK,EACpBxB,EAAM,SAAS,OAAO,EACtB0B,EAAc,MAAS,EACvB1B,EAAM,aAAa,MAAS,CAC9B,EAEA,QAAUuJ,GAAU,CAClBP,GAAaO,EAAM,YACnBvH,EAAc,SAAWuH,EAAM,YAC/BtH,EAAe,SAAWsH,EAAM,aAChCvJ,EAAM,SAASgC,EAAc,QAASC,EAAe,OAAO,EAE5D,IAAMuH,EAAM,KAAK,IAAI,IAAMR,EAAY,IAAU,GAAG,EACpDhJ,EAAM,iBAAiBwJ,CAAG,CAC5B,CACF,EAEA,GAAI,CACF,MAAM5I,EAAI,MAAM,IAAIgI,EAAcK,EAAWf,CAAM,CACrD,OAASjE,EAAK,CACZ,IAAMtB,EAAMsB,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,EAC3D1B,EAAW,SAAU,UAAUI,CAAG,EAAE,EACpC5B,EAAM,QAAS4B,CAAG,EAClBnB,EAAe,EAAK,EACpBxB,EAAM,SAAS,OAAO,CACxB,CACF,EAEA,OACEP,GAAC,OAAI,cAAc,SAAS,SAAU,EAAG,YAAa,EAAG,aAAc,EAAG,WAAY,EAAG,cAAe,EAAG,IAAK,EAE9G,UAAAD,GAAC,aACC,aAAc,GACd,YAAY,SACZ,SAAU,EACV,QAAS,GAET,SAAAA,GAACiK,GAAA,CACC,SAAUvI,EACV,cAAeE,EACf,YAAaG,EACf,EACF,EAGA9B,GAAC,OAAI,cAAc,SAAS,WAAY,EAErC,UAAAkC,GACCnC,GAACkK,GAAA,CACC,SAAU/H,EAAkB,SAC5B,QAASA,EAAkB,QAC3B,WAAagI,GAAa,CACxBhI,EAAkB,QAAQgI,CAAQ,EAClC/H,EAAqB,IAAI,CAC3B,EACF,EAIDC,GACCrC,GAACO,GAAA,CACC,QAAS8B,EAAiB,KAC1B,YAAa,IAAMmG,EAAgBnG,EAAiB,KAAMA,EAAiB,MAAM,EACjF,QAAS,IAAMwG,EAAYxG,EAAiB,IAAI,EAChD,SAAU,IAAMC,EAAoB,IAAI,EAC1C,EAIDP,GAAe,CAACH,GAAiB,CAACS,GACjCrC,GAACoK,GAAA,CAAe,MAAOnI,GAAc,cAAe,EAItDjC,GAACqK,GAAA,CACC,SAAUrB,EACV,SAAU,GACV,YAAajH,EAAc,gCAAkC,OAC7D,WAAYX,EAAI,WAClB,GACF,GACF,CAEJ,CAjqCA,IAoDMd,GApDNgK,GAAAC,EAAA,kBAwBAC,KACAC,KACAC,KACAC,KACAC,KACAC,IACAC,KACAC,KAGAC,KAUAC,KAQM3K,GAAiB,IAAI,IAAI,CAC7B,KAAM,KAAM,KAAM,MAAO,KAAM,QAAS,QAAS,KAAM,KAAM,KAC7D,MAAO,OAAQ,OAAQ,QAAS,OAAQ,MACxC,MAAO,MAAO,OAAQ,OAAQ,MAAO,OAAQ,UAC7C,SAAU,UAAW,MAAO,OAC5B,SAAU,iBACV,OAAQ,OAAQ,QAAS,UACzB,OAAQ,OACR,QAAS,QAAS,KAClB,KAAM,OAAQ,KAAM,KACpB,OAAQ,OACR,MAAO,KAAM,OAAQ,OAAQ,OAAQ,MAAO,MAAO,MACrD,CAAC,IC5DD,OAAS,kBAAA4K,OAAsB,gBAiCvB,OAOE,YAAAC,GAPF,OAAAC,EAOE,QAAAC,OAPF,6BAnBD,SAASC,GAAUC,EAAuB,CAC/C,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EAEJE,EAAO,QAAQ,IAAI,MAAQ,GAC3BC,EAAWD,GAAQH,EAAM,WAAW,WAAWG,CAAI,EACrD,IAAMH,EAAM,WAAW,MAAMG,EAAK,MAAM,EACxCH,EAAM,WAEJK,EAAYL,EAAM,OACpB,IAAIA,EAAM,OAAO,MAAM,eAAe,CAAC,SAAIA,EAAM,OAAO,OAAO,eAAe,CAAC,GAC/E,GAEEM,EAAMN,EAAM,eAAiB,KAAK,MAAMA,EAAM,cAAc,EAAI,EAChEO,EAAaD,EAAM,EAAI,QAAQA,CAAG,IAAM,GAE9C,OACER,GAAC,OAAI,OAAQ,EAAG,cAAc,MAAM,eAAe,gBACjD,UAAAA,GAAC,OAAI,cAAc,MACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYF,GAAe,KAC7C,aAAIK,EAAM,QAAQ,GACrB,EACAH,EAAC,QAAK,GAAI,EAAE,UAAY,aAAIG,EAAM,KAAK,GAAG,EAC1CH,EAAC,QAAK,GAAI,EAAE,QAAU,oBAAM,EAC5BA,EAAC,QAAK,GAAI,EAAE,QAAU,SAAAG,EAAM,KAAK,EAChCK,GACCP,GAAAF,GAAA,CACE,UAAAC,EAAC,QAAK,GAAI,EAAE,QAAU,mBAAK,EAC3BA,EAAC,QAAK,GAAI,EAAE,UAAY,SAAAQ,EAAU,GACpC,EAEDE,GACCT,GAAAF,GAAA,CACE,UAAAC,EAAC,QAAK,GAAI,EAAE,QAAU,mBAAK,EAC3BA,EAAC,QAAK,GAAIS,EAAM,GAAK,EAAE,QAAU,EAAE,UAAY,SAAAC,EAAW,GAC5D,EAEDP,EAAM,YACLF,GAAAF,GAAA,CACE,UAAAC,EAAC,QAAK,GAAI,EAAE,QAAU,oBAAM,EAC5BA,EAAC,QAAK,GAAI,EAAE,YAAc,mBAAKG,EAAM,UAAU,GAAG,GACpD,EAEDA,EAAM,cAAgB,CAACA,EAAM,YAC5BF,GAAAF,GAAA,CACE,UAAAC,EAAC,QAAK,GAAI,EAAE,QAAU,oBAAM,EAC5BA,EAAC,QAAK,GAAI,EAAE,QAAU,uBAAc,GACtC,GAEJ,EACAC,GAAC,OAAI,cAAc,MACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAU,SAAAO,EAAS,EAC/BP,EAAC,QAAK,GAAI,EAAE,QAAU,oBAAM,EAC5BA,EAAC,QAAK,GAAI,EAAE,UAAY,mCAA0B,GACpD,GACF,CAEJ,CA3EA,IAAAW,GAAAC,EAAA,kBAKAC,MCDA,OAAS,kBAAAC,OAAsB,gBA0B3B,OACE,OAAAC,GADF,QAAAC,OAAA,6BAdG,SAASC,GAAcC,EAA2B,CACvD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EAEJE,EAAQH,EAAM,OAASA,EAAM,OAAO,MAAM,eAAe,EAAI,IAC7DI,EAASJ,EAAM,OAASA,EAAM,OAAO,OAAO,eAAe,EAAI,IAC/DK,EAAML,EAAM,eAAiB,KAAK,MAAMA,EAAM,cAAc,EAAI,EAChEM,EAAWD,EAAM,GAAK,EAAE,MAAQA,EAAM,GAAK,EAAE,QAAU,EAAE,QACzDE,EAAcP,EAAM,SAAW,QAAU,EAAE,MAC7CA,EAAM,SAAW,gBAAkB,EAAE,QAAU,EAAE,QAE/CQ,EAAO,WAAMR,EAAM,OAAS,SAAS,WAAMA,EAAM,QAAQ,IAAIA,EAAM,KAAK,WAAMG,CAAK,SAAIC,CAAM,UAEnG,OACEN,GAAC,OAAI,OAAQ,EAAG,cAAc,MAC5B,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYD,GAAe,KAAO,SAAAY,EAAK,EAC5DX,GAAC,QAAK,GAAI,EAAE,OAAS,oBAAM,EAC3BA,GAAC,QAAK,GAAIS,EAAW,YAAGD,CAAG,IAAI,EAC/BR,GAAC,OAAI,SAAU,EAAG,EAClBA,GAAC,QAAK,GAAIU,EAAc,YAAGP,EAAM,MAAM,IAAI,GAC7C,CAEJ,CAtCA,IAAAS,GAAAC,EAAA,kBAKAC,MCkBI,OACE,OAAAC,GADF,QAAAC,OAAA,6BAZG,SAASC,GAAcC,EAA2B,CACvD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EAEJE,EAAO,QAAQ,IAAI,MAAQ,GAC3BC,EAAWD,GAAQH,EAAM,WAAW,WAAWG,CAAI,EACrD,IAAMH,EAAM,WAAW,MAAMG,EAAK,MAAM,EACxCH,EAAM,WAIV,OACEF,GAAC,OAAI,OAAQ,EAAG,cAAc,MAC5B,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAU,aAAIO,CAAQ,GAAG,EACrCP,GAAC,OAAI,SAAU,EAAG,EAClBA,GAAC,QAAK,GAAI,EAAE,UAAY,gEAAgB,GAC1C,CAEJ,CA7BA,IAAAQ,GAAAC,EAAA,kBAIAC,MCCA,OAAS,kBAAAC,OAAsB,gBA2GzB,OAEI,OAAAC,GAFJ,QAAAC,OAAA,6BAzFN,SAASC,GAAMC,EAAaC,EAAqB,CAC/C,OAAOD,EAAI,OAASC,EAAMD,EAAI,MAAM,EAAGC,EAAM,CAAC,EAAI,SAAMD,CAC1D,CAEA,SAASE,GAAIC,EAAaC,EAAqB,CAC7C,IAAMC,EAAS,KAAK,MAAOF,EAAM,IAAOC,CAAG,EAC3C,MAAO,SAAI,OAAOC,CAAM,EAAI,SAAI,OAAOD,EAAMC,CAAM,CACrD,CAEO,SAASC,GAAQC,EAAqB,CAC3C,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EAEJE,EAAO,QAAQ,IAAI,MAAQ,GAC3BC,EAAMD,GAAQH,EAAM,WAAW,WAAWG,CAAI,EAChD,IAAMH,EAAM,WAAW,MAAMG,EAAK,MAAM,EAAIH,EAAM,WAEhDJ,EAAMI,EAAM,eAAiB,KAAK,MAAMA,EAAM,cAAc,EAAI,EAChEK,EAAWT,EAAM,GAAK,EAAE,MAAQA,EAAM,GAAK,EAAE,QAAU,EAAE,QACzDU,EAAQN,EAAM,OAASA,EAAM,OAAO,MAAM,eAAe,EAAI,IAC7DO,EAASP,EAAM,OAASA,EAAM,OAAO,OAAO,eAAe,EAAI,IAC/DQ,EAAcR,EAAM,SAAW,QAAU,EAAE,MAC7CA,EAAM,SAAW,gBAAkB,EAAE,QAAU,EAAE,QAG/CS,EAA0D,CAAC,EAE3DC,EAAM,IAAMD,EAAM,KAAK,CAAE,KAAM,SAAK,GAAI,EAAE,MAAO,CAAC,EAClDE,EAAUC,GAAkB,CAChCH,EAAM,KAAK,CAAE,KAAM,UAAKG,CAAK,GAAI,GAAI,EAAE,QAAS,KAAM,EAAK,CAAC,CAC9D,EACMC,EAAM,CAACC,EAAeC,EAAeC,IAAa,CACtD,IAAMC,EAASH,EAAQ,YAAOA,EAAM,OAAO,EAAE,CAAC,IAAItB,GAAMuB,EAAOG,GAAI,EAAE,CAAC,GAAK,YAAO1B,GAAMuB,EAAOG,GAAI,CAAC,CAAC,GACrGT,EAAM,KAAK,CAAE,KAAMQ,EAAQ,GAAID,GAAM,EAAE,IAAK,CAAC,CAC/C,EACMG,EAAW,CAACC,EAAaN,IAAkB,CAC/CL,EAAM,KAAK,CAAE,KAAM,YAAOW,EAAI,OAAO,EAAE,CAAC,IAAIN,CAAK,GAAI,GAAI,EAAE,OAAQ,CAAC,CACtE,EA2BA,GAxBAH,EAAO,SAAS,EAChBE,EAAI,GAAIb,EAAM,cAAgB,aAAa,EAC3Ca,EAAI,MAAOrB,GAAMY,EAAKc,GAAI,EAAE,CAAC,EAC7BL,EAAI,WAAYb,EAAM,QAAQ,EAC9Ba,EAAI,QAASb,EAAM,KAAK,EACpBA,EAAM,SAASa,EAAI,QAASb,EAAM,OAAO,EAC7CU,EAAI,EAGJC,EAAO,SAAS,EAChBE,EAAI,QAAS,GAAGP,CAAK,SAAS,EAC9BO,EAAI,SAAU,GAAGN,CAAM,SAAS,EAChCE,EAAM,KAAK,CAAE,KAAM,YAAOd,GAAIC,EAAK,EAAE,CAAC,IAAIA,CAAG,IAAK,GAAIS,CAAS,CAAC,EAChEK,EAAI,EAGJC,EAAO,UAAU,EACjBF,EAAM,KAAK,CAAE,KAAM,uBAAkBT,EAAM,MAAM,GAAI,GAAIQ,CAAY,CAAC,EAClER,EAAM,YACRS,EAAM,KAAK,CAAE,KAAM,uBAAkBjB,GAAMQ,EAAM,WAAYkB,GAAI,EAAE,CAAC,GAAI,GAAI,EAAE,WAAY,CAAC,EAE7FR,EAAI,EAGAV,EAAM,eAAiBA,EAAM,cAAc,OAAS,EAAG,CACzDW,EAAO,UAAUX,EAAM,cAAc,MAAM,GAAG,EAC9C,QAAWqB,KAAKrB,EAAM,cAAc,MAAM,EAAG,CAAC,EAAG,CAC/C,IAAMsB,EAAOD,EAAE,KAAK,MAAM,GAAG,EAAE,IAAI,GAAKA,EAAE,KACpCE,GAAQF,EAAE,UAAY,EAAI,KAAKA,EAAE,SAAS,GAAK,KAAOA,EAAE,UAAY,EAAI,KAAKA,EAAE,SAAS,GAAK,IACnGZ,EAAM,KAAK,CAAE,KAAM,YAAOjB,GAAM8B,EAAMJ,GAAI,EAAE,CAAC,GAAGK,CAAI,GAAI,GAAI,EAAE,IAAK,CAAC,CACtE,CACIvB,EAAM,cAAc,OAAS,GAC/BS,EAAM,KAAK,CAAE,KAAM,mBAAST,EAAM,cAAc,OAAS,CAAC,QAAS,GAAI,EAAE,OAAQ,CAAC,EAEpFU,EAAI,CACN,CAGA,OAAAC,EAAO,WAAW,EAClBQ,EAAS,SAAU,SAAS,EAC5BA,EAAS,SAAU,aAAa,EAChCA,EAAS,SAAU,OAAO,EAC1BA,EAAS,SAAU,OAAO,EAC1BA,EAAS,SAAU,UAAU,EAC7BA,EAAS,SAAU,UAAU,EAC7BA,EAAS,KAAM,MAAM,EAGnB7B,GAAC,OAAI,MAAO4B,GAAI,EAAG,cAAc,SAC/B,SAAA3B,GAAC,OAAI,cAAc,SAAS,SAAU,EACnC,UAAAkB,EAAM,IAAI,CAACe,EAAMC,IAChBnC,GAAC,QAEC,GAAIkC,EAAK,GACT,WAAYA,EAAK,KAAOnC,GAAe,KAAO,OAE7C,SAAAmC,EAAK,MAJDC,CAKP,CACD,EAEDnC,GAAC,OAAI,SAAU,EACb,SAAAA,GAAC,QAAK,GAAI,EAAE,OAAS,kBAAI,EAC3B,GACF,EACF,CAEJ,CAjIA,IAQM4B,GARNQ,GAAAC,EAAA,kBAMAC,IAEMV,GAAI,KCJV,OAAS,kBAAAW,OAAsB,gBAC/B,OAAS,YAAAC,OAAgB,QACzB,OAAS,eAAAC,OAAmB,iBAgEtB,cAAAC,GAME,QAAAC,OANF,6BAtCC,SAASC,GAAYC,EAKzB,CACD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJE,EAASC,GAAOJ,EAAM,QAAQ,GAAK,CAAC,EACpC,CAACK,EAAUC,CAAW,EAAIX,GAC9B,KAAK,IAAI,EAAGQ,EAAO,UAAWI,GAAMA,EAAE,KAAOP,EAAM,YAAY,CAAC,CAClE,EAEA,OAAAJ,GAAaY,GAAa,CACxB,GAAIA,EAAI,OAAS,UAAaA,EAAI,MAAQA,EAAI,OAAS,IACrDR,EAAM,QAAQ,UACLQ,EAAI,OAAS,MAAQA,EAAI,OAAS,IAC3CF,EAAaG,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,UAC5BD,EAAI,OAAS,QAAUA,EAAI,OAAS,IAC7CF,EAAaG,GAAM,KAAK,IAAIN,EAAO,OAAS,EAAGM,EAAI,CAAC,CAAC,UAC5CD,EAAI,OAAS,SAAU,CAChC,IAAMD,EAAIJ,EAAOE,CAAQ,EACrBE,GAAGP,EAAM,SAASO,EAAE,EAAE,CAC5B,CACF,CAAC,EAGCT,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAS,WACT,IAAI,MACJ,KAAK,MACL,MAAM,MAEN,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYH,GAAe,KAC7C,0BACH,EACAG,GAAC,QAAK,GAAI,EAAE,QAAU,wBAAeG,EAAM,QAAQ,GAAG,EACtDH,GAAC,QAAK,GAAI,EAAE,QAAU,YAAG,EACxBM,EAAO,IAAI,CAACO,EAAOC,IAClBb,GAAC,OACC,UAAAD,GAAC,QACC,GAAIc,IAAMN,EAAW,EAAE,QAAU,EAAE,KACnC,WAAYM,IAAMN,EAAWX,GAAe,KAAO,OAElD,cAAKiB,IAAMN,EAAW,SAAM,GAAG,IAAIK,EAAM,IAAI,GAChD,EACAb,GAAC,QAAK,GAAI,EAAE,QAAU,SAAAa,EAAM,KAAO,KAAKA,EAAM,IAAI,GAAK,GAAG,EAC1Db,GAAC,QAAK,GAAIa,EAAM,KAAOV,EAAM,aAAe,EAAE,QAAU,EAAE,QACvD,SAAAU,EAAM,KAAOV,EAAM,aAAe,UAAO,GAC5C,IAVQU,EAAM,EAWhB,CACD,EACDb,GAAC,QAAK,GAAI,EAAE,QAAU;AAAA,kDAA2C,GACnE,CAEJ,CA5FA,IAeMO,GAfNQ,GAAAC,EAAA,kBAOAC,IAQMV,GAAwC,CAC5C,UAAW,CACT,CAAE,GAAI,oBAAqB,KAAM,oBAAqB,KAAM,cAAe,EAC3E,CAAE,GAAI,kBAAmB,KAAM,kBAAmB,KAAM,cAAe,EACvE,CAAE,GAAI,mBAAoB,KAAM,mBAAoB,KAAM,SAAU,CACtE,EACA,OAAQ,CACN,CAAE,GAAI,SAAU,KAAM,SAAU,KAAM,aAAc,EACpD,CAAE,GAAI,cAAe,KAAM,cAAe,KAAM,SAAU,EAC1D,CAAE,GAAI,KAAM,KAAM,KAAM,KAAM,WAAY,CAC5C,EACA,OAAQ,CACN,CAAE,GAAI,mBAAoB,KAAM,mBAAoB,KAAM,MAAO,EACjE,CAAE,GAAI,iBAAkB,KAAM,iBAAkB,KAAM,cAAe,CACvE,CACF,ICvBA,OAAS,kBAAAW,OAAsB,gBAC/B,OAAS,YAAAC,GAAU,WAAAC,OAA+B,QAClD,OAAS,eAAAC,OAAmB,iBAiItB,cAAAC,GASE,QAAAC,OATF,6BA5FN,SAASC,GAAWC,EAAeC,EAAuB,CACxD,GAAI,CAACD,EAAO,MAAO,GACnB,IAAME,EAAQD,EAAK,YAAY,EACzBE,EAAIH,EAAM,YAAY,EACxBI,EAAK,EACT,QAASC,EAAI,EAAGA,EAAIH,EAAM,QAAUE,EAAKD,EAAE,OAAQE,IAC7CH,EAAMG,CAAC,IAAMF,EAAEC,CAAE,GAAGA,IAE1B,OAAOA,IAAOD,EAAE,MAClB,CAIO,SAASG,GAAcC,EAG3B,CACD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJ,CAACR,EAAOU,CAAQ,EAAIhB,GAAS,EAAE,EAC/B,CAACiB,EAAUC,CAAW,EAAIlB,GAAS,CAAC,EAGpCmB,EAAWlB,GAAQ,IAChBmB,GAAS,OACbC,GAAQhB,GAAWC,EAAOe,EAAI,KAAK,GAAKhB,GAAWC,EAAOe,EAAI,QAAQ,CACzE,EACC,CAACf,CAAK,CAAC,EAGJgB,EAASrB,GAAQ,IAAM,CAC3B,IAAMsB,EAAM,IAAI,IAChB,QAAWF,KAAOF,EAAU,CAC1B,IAAMK,EAAOD,EAAI,IAAIF,EAAI,QAAQ,EAC7BG,EACFA,EAAK,KAAKH,CAAG,EAEbE,EAAI,IAAIF,EAAI,SAAU,CAACA,CAAG,CAAC,CAE/B,CACA,OAAOE,CACT,EAAG,CAACJ,CAAQ,CAAC,EAGPM,EAAWN,EAGXO,EAAkB,KAAK,IAAIT,EAAU,KAAK,IAAI,EAAGQ,EAAS,OAAS,CAAC,CAAC,EAE3EvB,GAAayB,GAAa,CACxB,GAAIA,EAAI,OAAS,SAAU,CACzBd,EAAM,QAAQ,EACd,MACF,CAEA,GAAIc,EAAI,OAAS,SAAU,CACzB,IAAMN,EAAMI,EAASC,CAAe,EAChCL,GAAKR,EAAM,SAASQ,EAAI,EAAE,EAC9B,MACF,CAEA,GAAIM,EAAI,OAAS,MAASA,EAAI,OAAS,KAAO,CAACrB,EAAQ,CACrDY,EAAaU,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,EACrC,MACF,CAEA,GAAID,EAAI,OAAS,QAAWA,EAAI,OAAS,KAAO,CAACrB,EAAQ,CACvDY,EAAaU,GAAM,KAAK,IAAIH,EAAS,OAAS,EAAGG,EAAI,CAAC,CAAC,EACvD,MACF,CAGA,GAAID,EAAI,OAAS,YAAa,CAC5BX,EAAUP,GAAMA,EAAE,MAAM,EAAG,EAAE,CAAC,EAC9BS,EAAY,CAAC,EACb,MACF,CAGIS,EAAI,UAAYA,EAAI,SAAS,SAAW,GAAK,CAACA,EAAI,MAAQ,CAACA,EAAI,OACjEX,EAAUP,GAAMA,EAAIkB,EAAI,QAAQ,EAChCT,EAAY,CAAC,EAEjB,CAAC,EAGD,IAAIW,EAAY,EACVC,EAAoB,CAAC,EAE3B,OAAW,CAACC,EAAUC,CAAI,IAAKV,EAAQ,CAErCQ,EAAK,KACH3B,GAAC,QAA6B,GAAI,EAAE,UAAW,WAAYJ,GAAe,KACvE,cAAKgC,CAAQ,IADL,OAAOA,CAAQ,EAE1B,CACF,EAEA,QAAWV,KAAOW,EAAM,CACtB,IAAMC,EAAQJ,IAAcH,EACtBQ,EAAeb,EAAI,SAAW,KAAKA,EAAI,QAAQ,GAAK,GAC1DS,EAAK,KACH1B,GAAC,OAAiB,cAAc,MAC9B,UAAAD,GAAC,QACC,GAAI8B,EAAQ,EAAE,QAAU,EAAE,KAC1B,WAAYA,EAAQlC,GAAe,KAAO,OAEzC,gBAAOkC,EAAQ,IAAM,GAAG,IAAIZ,EAAI,KAAK,GACxC,EACAlB,GAAC,QAAK,GAAI,EAAE,QAAU,SAAA+B,EAAa,IAP3Bb,EAAI,EAQd,CACF,EACAQ,GACF,CAGAC,EAAK,KACH3B,GAAC,QAAgC,GAAI,EAAE,QAAU,aAAtC,UAAU4B,CAAQ,EAAuB,CACtD,CACF,CAEA,OACE3B,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAS,WACT,IAAI,MACJ,KAAK,MACL,MAAM,MAGN,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYJ,GAAe,KAC7C,6BACH,EACAI,GAAC,QAAK,GAAI,EAAE,QAAU,YAAG,EAGzBC,GAAC,OAAI,cAAc,MACjB,UAAAD,GAAC,QAAK,GAAI,EAAE,UAAY,gBAAO,EAC/BA,GAAC,QAAK,GAAI,EAAE,KAAO,SAAAG,GAAS,GAAG,EAC/BH,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYJ,GAAe,KAAO,aAAI,GAC7D,EACAI,GAAC,QAAK,GAAI,EAAE,QAAU,YAAG,EAGxBsB,EAAS,OAAS,EACjBK,EAEA3B,GAAC,QAAK,GAAI,EAAE,QAAU,kCAAyB,EAIjDA,GAAC,QAAK,GAAI,EAAE,QAAU,+DAA4C,GACpE,CAEJ,CA3MA,IAqBMiB,GArBNe,GAAAC,EAAA,kBAUAC,IAWMjB,GAAsB,CAE1B,CAAE,GAAI,cAAe,MAAO,cAAe,SAAU,SAAU,SAAU,SAAU,EACnF,CAAE,GAAI,iBAAkB,MAAO,kBAAmB,SAAU,SAAU,SAAU,SAAU,EAC1F,CAAE,GAAI,gBAAiB,MAAO,gBAAiB,SAAU,GAAI,SAAU,SAAU,EAGjF,CAAE,GAAI,eAAgB,MAAO,eAAgB,SAAU,SAAU,SAAU,OAAQ,EAGnF,CAAE,GAAI,eAAgB,MAAO,gBAAiB,SAAU,SAAU,SAAU,YAAa,EACzF,CAAE,GAAI,aAAc,MAAO,YAAa,SAAU,GAAI,SAAU,YAAa,EAC7E,CAAE,GAAI,cAAe,MAAO,aAAc,SAAU,GAAI,SAAU,YAAa,EAC/E,CAAE,GAAI,kBAAmB,MAAO,iBAAkB,SAAU,SAAU,SAAU,YAAa,EAG7F,CAAE,GAAI,gBAAiB,MAAO,gBAAiB,SAAU,GAAI,SAAU,QAAS,EAChF,CAAE,GAAI,cAAe,MAAO,OAAQ,SAAU,KAAM,SAAU,QAAS,EACvE,CAAE,GAAI,gBAAiB,MAAO,SAAU,SAAU,GAAI,SAAU,QAAS,EACzE,CAAE,GAAI,eAAgB,MAAO,eAAgB,SAAU,GAAI,SAAU,QAAS,EAC9E,CAAE,GAAI,cAAe,MAAO,OAAQ,SAAU,SAAU,SAAU,QAAS,CAC7E,ICnCA,OAAS,kBAAAkB,OAAsB,gBAC/B,OAAS,YAAAC,OAAgB,QACzB,OAAS,eAAAC,OAAmB,iBA8KtB,cAAAC,GA0BI,QAAAC,OA1BJ,6BA9FN,SAASC,IAAyB,CAChC,IAAMC,EAAoB,CAAC,EAE3BA,EAAM,KAAK,CAAE,KAAM,SAAU,KAAM,oBAAqB,CAAC,EACzDA,EAAM,KAAK,CAAE,KAAM,OAAQ,CAAC,EAC5B,QAAWC,KAASC,GAClBF,EAAM,KAAK,CAAE,KAAM,QAAS,IAAKC,EAAM,IAAK,YAAaA,EAAM,WAAY,CAAC,EAG9ED,EAAM,KAAK,CAAE,KAAM,OAAQ,CAAC,EAC5BA,EAAM,KAAK,CAAE,KAAM,SAAU,KAAM,gBAAiB,CAAC,EACrDA,EAAM,KAAK,CAAE,KAAM,OAAQ,CAAC,EAC5B,QAAWC,KAASE,GAClBH,EAAM,KAAK,CAAE,KAAM,QAAS,IAAKC,EAAM,IAAK,YAAaA,EAAM,WAAY,CAAC,EAG9ED,EAAM,KAAK,CAAE,KAAM,OAAQ,CAAC,EAC5BA,EAAM,KAAK,CAAE,KAAM,SAAU,KAAM,WAAY,CAAC,EAChDA,EAAM,KAAK,CAAE,KAAM,OAAQ,CAAC,EAC5B,QAAWC,KAASG,GAClBJ,EAAM,KAAK,CAAE,KAAM,QAAS,IAAKC,EAAM,IAAK,YAAaA,EAAM,WAAY,CAAC,EAG9E,OAAOD,CACT,CAOO,SAASK,GAAWC,EAExB,CACD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJ,CAACE,EAAcC,CAAe,EAAIf,GAAS,CAAC,EAE5CgB,EAAY,KAAK,IAAI,EAAGC,GAAU,OAASC,EAAS,EAE1DjB,GAAakB,GAAa,CACxB,GAAIA,EAAI,OAAS,UAAYA,EAAI,OAAS,IAAK,CAC7CR,EAAM,QAAQ,EACd,MACF,CAEA,GAAIQ,EAAI,OAAS,MAAQA,EAAI,OAAS,IAAK,CACzCJ,EAAiBK,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,EACzC,MACF,CAEA,GAAID,EAAI,OAAS,QAAUA,EAAI,OAAS,IAAK,CAC3CJ,EAAiBK,GAAM,KAAK,IAAIJ,EAAWI,EAAI,CAAC,CAAC,EACjD,MACF,CAEA,GAAID,EAAI,OAAS,SAAU,CACzBJ,EAAiBK,GAAM,KAAK,IAAI,EAAGA,EAAIF,EAAS,CAAC,EACjD,MACF,CAEA,GAAIC,EAAI,OAAS,WAAY,CAC3BJ,EAAiBK,GAAM,KAAK,IAAIJ,EAAWI,EAAIF,EAAS,CAAC,EACzD,MACF,CAGA,GAAIC,EAAI,OAAS,OAAQ,CACvBJ,EAAgB,CAAC,EACjB,MACF,CACA,GAAII,EAAI,OAAS,MAAO,CACtBJ,EAAgBC,CAAS,EACzB,MACF,CACF,CAAC,EAED,IAAMK,EAAeJ,GAAU,MAAMH,EAAcA,EAAeI,EAAS,EACrEI,EAAc,GAEpB,OACEnB,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAS,WACT,IAAI,MACJ,KAAK,MACL,MAAM,MACN,OAAO,MAGP,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYH,GAAe,KAC7C,kBACH,EACAG,GAAC,QAAK,GAAI,EAAE,QAAU,YAAG,EAGxBmB,EAAa,IAAI,CAACE,EAAMC,IAAM,CAC7B,GAAID,EAAK,OAAS,QAChB,OAAOrB,GAAC,QAAsC,GAAI,EAAE,QAAU,aAA5C,QAAQY,EAAeU,CAAC,EAAuB,EAGnE,GAAID,EAAK,OAAS,SAChB,OACErB,GAAC,QAEC,GAAI,EAAE,QACN,WAAYH,GAAe,KAE1B,cAAKwB,EAAK,IAAI,IAJV,QAAQT,EAAeU,CAAC,EAK/B,EAKJ,IAAMC,GAAaF,EAAK,KAAO,IAAI,OAAOD,CAAW,EACrD,OACEnB,GAAC,OAAqC,cAAc,MAClD,UAAAD,GAAC,QAAK,GAAI,EAAE,UAAY,gBAAOuB,CAAS,GAAG,EAC3CvB,GAAC,QAAK,GAAI,EAAE,UAAY,SAAAqB,EAAK,aAAe,GAAG,IAFvC,QAAQT,EAAeU,CAAC,EAGlC,CAEJ,CAAC,EAGDtB,GAAC,QAAK,GAAI,EAAE,QAAU,YAAG,EACzBA,GAAC,QAAK,GAAI,EAAE,QACT,cAAKY,EAAe,EAAI,MAAQ,KAAK,IAAIA,EAAe,CAAC,IAAI,KAAK,IAAIA,EAAeI,GAAWD,GAAU,MAAM,CAAC,OAAOA,GAAU,MAAM,IAAIH,EAAeE,EAAY,MAAQ,KAAK,GACvL,EAGAd,GAAC,QAAK,GAAI,EAAE,QAAU,6DAAoD,GAC5E,CAEJ,CAlOA,IAmBMK,GAeAC,GAqCAC,GA4CAQ,GACAC,GApHNQ,GAAAC,EAAA,kBAUAC,IASMrB,GAAkC,CACtC,CAAE,IAAK,SAAU,YAAa,aAAc,EAC5C,CAAE,IAAK,SAAU,YAAa,cAAe,EAC7C,CAAE,IAAK,SAAU,YAAa,iBAAkB,EAChD,CAAE,IAAK,SAAU,YAAa,iBAAkB,EAChD,CAAE,IAAK,KAAM,YAAa,gBAAiB,EAC3C,CAAE,IAAK,SAAU,YAAa,qBAAsB,EACpD,CAAE,IAAK,SAAU,YAAa,kBAAmB,EACjD,CAAE,IAAK,SAAU,YAAa,kBAAmB,EACjD,CAAE,IAAK,WAAY,YAAa,qBAAsB,EACtD,CAAE,IAAK,YAAa,YAAa,sBAAuB,EACxD,CAAE,IAAK,SAAU,YAAa,yBAA0B,EACxD,CAAE,IAAK,SAAU,YAAa,MAAO,CACvC,EAEMC,GAA8B,CAClC,CAAE,IAAK,QAAS,YAAa,WAAY,EACzC,CAAE,IAAK,SAAU,YAAa,oBAAqB,EACnD,CAAE,IAAK,OAAQ,YAAa,wBAAyB,EACrD,CAAE,IAAK,WAAY,YAAa,yBAA0B,EAC1D,CAAE,IAAK,kBAAmB,YAAa,+BAAgC,EACvE,CAAE,IAAK,gBAAiB,YAAa,mBAAoB,EACzD,CAAE,IAAK,mBAAoB,YAAa,sBAAuB,EAC/D,CAAE,IAAK,QAAS,YAAa,sBAAuB,EACpD,CAAE,IAAK,cAAe,YAAa,+BAAgC,EACnE,CAAE,IAAK,UAAW,YAAa,oBAAqB,EACpD,CAAE,IAAK,kBAAmB,YAAa,oBAAqB,EAC5D,CAAE,IAAK,gBAAiB,YAAa,gCAAiC,EACtE,CAAE,IAAK,kBAAmB,YAAa,kBAAmB,EAC1D,CAAE,IAAK,iBAAkB,YAAa,kBAAmB,EACzD,CAAE,IAAK,WAAY,YAAa,0BAA2B,EAC3D,CAAE,IAAK,eAAgB,YAAa,qBAAsB,EAC1D,CAAE,IAAK,aAAc,YAAa,4BAA6B,EAC/D,CAAE,IAAK,aAAc,YAAa,mBAAoB,EACtD,CAAE,IAAK,eAAgB,YAAa,qBAAsB,EAC1D,CAAE,IAAK,eAAgB,YAAa,0BAA2B,EAC/D,CAAE,IAAK,aAAc,YAAa,8BAA+B,EACjE,CAAE,IAAK,eAAgB,YAAa,uBAAwB,EAC5D,CAAE,IAAK,SAAU,YAAa,uBAAwB,EACtD,CAAE,IAAK,SAAU,YAAa,oBAAqB,EACnD,CAAE,IAAK,WAAY,YAAa,wBAAyB,EACzD,CAAE,IAAK,OAAQ,YAAa,uBAAwB,EACpD,CAAE,IAAK,UAAW,YAAa,qBAAsB,EACrD,CAAE,IAAK,SAAU,YAAa,kBAAmB,EACjD,CAAE,IAAK,eAAgB,YAAa,4BAA6B,EACjE,CAAE,IAAK,SAAU,YAAa,kBAAmB,EACjD,CAAE,IAAK,SAAU,YAAa,mBAAoB,EAClD,CAAE,IAAK,UAAW,YAAa,oBAAqB,EACpD,CAAE,IAAK,QAAS,YAAa,2BAA4B,EACzD,CAAE,IAAK,QAAS,YAAa,MAAO,CACtC,EAEMC,GAA2B,CAC/B,CAAE,IAAK,YAAa,YAAa,wBAAyB,EAC1D,CAAE,IAAK,OAAQ,YAAa,mBAAoB,EAChD,CAAE,IAAK,QAAS,YAAa,gBAAiB,EAC9C,CAAE,IAAK,YAAa,YAAa,iBAAkB,EACnD,CAAE,IAAK,QAAS,YAAa,oBAAqB,EAClD,CAAE,IAAK,QAAS,YAAa,cAAe,CAC9C,EAqCMQ,GAAYb,GAAW,EACvBc,GAAY,KC3GlB,OAAS,kBAAAW,OAAsB,gBAC/B,OAAS,YAAAC,GAAU,WAAAC,OAAe,QAClC,OAAS,eAAAC,GAAa,yBAAAC,OAA6B,iBA+K7C,OA0CI,YAAAC,GA1CJ,OAAAC,EAmBI,QAAAC,OAnBJ,6BAzKC,SAASC,GAAYC,EAEzB,CACD,GAAM,CAAE,MAAAC,EAAO,QAAAC,EAAS,KAAAC,EAAM,SAAAC,EAAU,WAAAC,EAAY,QAAAC,EAAS,YAAAC,CAAY,EAAIC,EAAS,EAChFC,EAAIR,EACJS,EAAOf,GAAsB,EAE7BgB,EAAiBT,EACjBU,EAAcT,EACdU,EAAkBT,EAClBU,EAAWC,GAAY,EAEvB,CAACC,EAASC,CAAU,EAAIzB,GAAkB,MAAM,EAChD,CAAC0B,EAAcC,CAAe,EAAI3B,GAAiBW,IAAS,OAAS,EAAI,CAAC,EAC1E,CAACiB,EAASC,CAAU,EAAI7B,GAASY,GAAY,EAAE,EAC/C,CAACkB,EAAOC,CAAQ,EAAI/B,GAAS,EAAE,EAC/B,CAACgC,EAAUC,CAAW,EAAIjC,GAC9B,KAAK,IAAI,EAAGsB,EAAS,QAAQZ,CAAO,CAAC,CACvC,EAEMwB,EAAWjC,GAAQ,IAAM,CAC7B,GAAI,CAAC6B,EAAO,OAAOR,EACnB,IAAMa,EAAIL,EAAM,YAAY,EAC5B,OAAOR,EAAS,OAAQc,GAAO,CAC7B,IAAMC,EAAMC,GAAOF,CAAE,EACrB,OAAOA,EAAG,YAAY,EAAE,SAASD,CAAC,GAAKE,EAAI,KAAK,YAAY,EAAE,SAASF,CAAC,CAC1E,CAAC,CACH,EAAG,CAACL,EAAOR,CAAQ,CAAC,EAEdiB,EAAkB,KAAK,IAAIP,EAAU,KAAK,IAAI,EAAGE,EAAS,OAAS,CAAC,CAAC,EAErEM,GAAa,KAAK,IAAI,EAAG,KAAK,IAAIN,EAAS,QAAShB,EAAK,QAAU,IAAM,EAAE,CAAC,EAC5EuB,GAAe,KAAK,IAAI,EAAGF,EAAkBC,GAAa,CAAC,EAC3DE,GAAeR,EAAS,MAAMO,GAAcA,GAAeD,EAAU,EAErEG,GAA8D,CAClE,CAAE,GAAI,OAAQ,MAAO,WAAY,EACjC,CAAE,GAAI,QAAS,MAAO,YAAa,CACrC,EAEMC,GAAc,IAAM,CACxBnB,EAAYoB,GAAM,CAChB,IAAMC,EAAMC,GAAS,QAAQF,CAAC,EAC9B,OAAOE,IAAUD,EAAM,GAAKC,GAAS,MAAM,CAC7C,CAAC,CACH,EAEMC,GAAcH,GAAuB,oBAAoB,KAAKA,CAAC,EAErE,OAAA3C,GAAa+C,GAAa,CACxB,GAAIA,EAAI,OAAS,SAAU,CACzBpC,EAAWM,CAAc,EACzBL,EAAQM,CAAW,EACnBL,EAAYM,CAAe,EAC3Bb,EAAM,QAAQ,EACd,MACF,CAEA,GAAIyC,EAAI,OAAS,MAAO,CACtBL,GAAY,EACZ,MACF,CAGA,GAAIpB,IAAY,OAAQ,CACtB,GAAIyB,EAAI,OAAS,MAAQA,EAAI,OAAS,IAAK,CACzCtB,EAAiBkB,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,EACzC,MACF,CACA,GAAII,EAAI,OAAS,QAAUA,EAAI,OAAS,IAAK,CAC3CtB,EAAiBkB,GAAM,KAAK,IAAIF,GAAY,OAAS,EAAGE,EAAI,CAAC,CAAC,EAC9D,MACF,CACA,GAAII,EAAI,OAAS,SAAU,CACzBnC,EAAQ6B,GAAYjB,CAAY,EAAE,EAAE,EACpCkB,GAAY,EACZ,MACF,CACA,MACF,CAGA,GAAIpB,IAAY,WAAY,CAC1B,GAAIyB,EAAI,OAAS,SAAU,CACrBrB,IAAY,IAAMA,IAAY,OAChCb,EAAY,IAAI,EACPiC,GAAWpB,CAAO,GAC3Bb,EAAYa,CAAO,EAErBgB,GAAY,EACZ,MACF,CACA,GAAIK,EAAI,OAAS,YAAa,CAC5BpB,EAAYgB,GAAMA,EAAE,MAAM,EAAG,EAAE,CAAC,EAChC,MACF,CACA,GAAII,EAAI,UAAYA,EAAI,SAAS,SAAW,GAAK,CAACA,EAAI,MAAQ,CAACA,EAAI,KAAM,CACvEpB,EAAYgB,GAAM,CAChB,IAAMK,EAAOL,EAAII,EAAI,SAErB,OAAID,GAAWE,CAAI,GACjBnC,EAAYmC,CAAI,EAEXA,CACT,CAAC,EACD,MACF,CACA,MACF,CAGA,GAAID,EAAI,OAAS,SAAU,CACzBzC,EAAM,QAAQ,EACd,MACF,CAEA,GAAIyC,EAAI,OAAS,MAASA,EAAI,OAAS,KAAO,CAACnB,EAAQ,CACrDG,EAAaY,GAAM,CACjB,IAAMK,EAAO,KAAK,IAAI,EAAGL,EAAI,CAAC,EACxBT,EAAKF,EAASgB,CAAI,EACxB,OAAId,GAAIvB,EAAWuB,CAAE,EACdc,CACT,CAAC,EACD,MACF,CAEA,GAAID,EAAI,OAAS,QAAWA,EAAI,OAAS,KAAO,CAACnB,EAAQ,CACvDG,EAAaY,GAAM,CACjB,IAAMK,EAAO,KAAK,IAAIhB,EAAS,OAAS,EAAGW,EAAI,CAAC,EAC1CT,EAAKF,EAASgB,CAAI,EACxB,OAAId,GAAIvB,EAAWuB,CAAE,EACdc,CACT,CAAC,EACD,MACF,CAEA,GAAID,EAAI,OAAS,YAAa,CAC5BlB,EAAUI,GAAMA,EAAE,MAAM,EAAG,EAAE,CAAC,EAC9BF,EAAY,CAAC,EACb,MACF,CAEIgB,EAAI,UAAYA,EAAI,SAAS,SAAW,GAAK,CAACA,EAAI,MAAQ,CAACA,EAAI,OACjElB,EAAUI,GAAM,CACd,IAAMgB,EAAOhB,EAAIc,EAAI,SACfG,EAAKD,EAAK,YAAY,EACtBE,GAAQ/B,EAAS,KAAMc,IAAO,CAClC,IAAMC,EAAMC,GAAOF,EAAE,EACrB,OAAOA,GAAG,YAAY,EAAE,SAASgB,CAAE,GAAKf,EAAI,KAAK,YAAY,EAAE,SAASe,CAAE,CAC5E,CAAC,EACD,OAAIC,IAAOxC,EAAWwC,EAAK,EACpBF,CACT,CAAC,EACDlB,EAAY,CAAC,EAEjB,CAAC,EAGC3B,GAAC,OACC,YAAY,SACZ,YAAaW,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAS,WACT,IAAI,MACJ,KAAK,MACL,MAAM,MAEN,UAAAZ,EAAC,QAAK,GAAIY,EAAE,QAAS,WAAYlB,GAAe,KAC7C,oBACH,EACAM,EAAC,QAAK,GAAIY,EAAE,QACT,oBAAWN,CAAI,aAAQuB,EAAS,MAAM,UAAUtB,EAAW,iBAAYA,CAAQ,GAAK,EAAE,GACzF,EACAP,EAAC,QAAM,YAAG,EAGVA,EAAC,QACC,GAAImB,IAAY,OAASP,EAAE,QAAUA,EAAE,QACvC,WAAYO,IAAY,OAASzB,GAAe,KAAO,OAEtD,wBACH,EACC4C,GAAY,IAAI,CAACW,EAAKC,IAAM,CAC3B,IAAMC,EAAQhC,IAAY,QAAU+B,IAAM7B,EACpC+B,EAAWH,EAAI,KAAO3C,EAC5B,OACEL,GAAC,OAAiB,cAAc,MAC9B,UAAAD,EAAC,QACC,GAAImD,EAAQvC,EAAE,QAAUA,EAAE,KAC1B,WAAYuC,EAAQzD,GAAe,KAAO,OAEzC,gBAAOyD,EAAQ,IAAM,GAAG,IAAIF,EAAI,KAAK,GACxC,EACCG,GAAYpD,EAAC,QAAK,GAAIY,EAAE,QAAU,cAAK,IAPhCqC,EAAI,EAQd,CAEJ,CAAC,EACDjD,EAAC,QAAM,YAAG,EAGVA,EAAC,QACC,GAAImB,IAAY,WAAaP,EAAE,QAAUA,EAAE,QAC3C,WAAYO,IAAY,WAAazB,GAAe,KAAO,OAE1D,+BACH,EACAO,GAAC,OAAI,cAAc,MACjB,UAAAD,EAAC,QAAK,GAAIY,EAAE,UAAY,qBAAY,EACnCO,IAAY,WACXlB,GAAAF,GAAA,CACE,UAAAC,EAAC,QAAK,GAAI2C,GAAWpB,CAAO,EAAIX,EAAE,QAAUA,EAAE,KAAO,SAAAW,GAAW,GAAG,EACnEvB,EAAC,QAAK,GAAIY,EAAE,QAAS,WAAYlB,GAAe,KAAO,aAAI,GAC7D,EAEAM,EAAC,QAAK,GAAIO,EAAWK,EAAE,QAAUA,EAAE,QAAU,SAAAL,GAAY,kBAAkB,GAE/E,EACCY,IAAY,YACXnB,EAAC,QAAK,GAAIY,EAAE,QAAU,iEAAwD,EAEhFZ,EAAC,QAAM,YAAG,EAGVA,EAAC,QACC,GAAImB,IAAY,SAAWP,EAAE,QAAUA,EAAE,QACzC,WAAYO,IAAY,SAAWzB,GAAe,KAAO,OAExD,0BACH,EAECyB,IAAY,UACXlB,GAAC,OAAI,cAAc,MACjB,UAAAD,EAAC,QAAK,GAAIY,EAAE,UAAY,kBAAS,EACjCZ,EAAC,QAAK,GAAIY,EAAE,KAAO,SAAAa,GAAS,GAAG,EAC/BzB,EAAC,QAAK,GAAIY,EAAE,QAAS,WAAYlB,GAAe,KAAO,aAAI,GAC7D,EAGD2C,GAAa,OAAS,EACrBA,GAAa,IAAKN,GAAO,CACvB,IAAMC,EAAMC,GAAOF,CAAE,EACfU,EAAMZ,EAAS,QAAQE,CAAE,EACzBoB,EAAQhC,IAAY,UAAYsB,IAAQP,EACxCmB,GAAYtB,IAAO1B,EAEzB,OACEJ,GAAC,OAAa,cAAc,MAC1B,UAAAD,EAAC,QACC,GAAImD,EAAQvC,EAAE,QAAUA,EAAE,KAC1B,WAAYuC,EAAQzD,GAAe,KAAO,OAEzC,gBAAOyD,EAAQ,IAAM,GAAG,IAAInB,EAAI,IAAI,GACvC,EACAhC,EAAC,QAAK,GAAIY,EAAE,QAAU,cAAKmB,CAAE,GAAG,EAC/BsB,IAAarD,EAAC,QAAK,GAAIY,EAAE,QAAU,cAAK,IARjCmB,CASV,CAEJ,CAAC,EAED/B,EAAC,QAAK,GAAIY,EAAE,QAAU,kCAAyB,EAGhDiB,EAAS,OAASM,IACjBnC,EAAC,QAAK,GAAIY,EAAE,QACT,oBAAWiB,EAAS,OAASM,EAAU,QAC1C,EAGFnC,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAIY,EAAE,QAAU,4EAAmE,GAC3F,CAEJ,CAnSA,IAeM8B,GAfNY,GAAAC,EAAA,kBAYAC,IAGMd,GAAsB,CAAC,OAAQ,WAAY,QAAQ,ICLzD,OAAS,kBAAAe,OAAsB,gBAC/B,OAAS,YAAAC,GAAU,WAAAC,OAAe,QAClC,OAAS,eAAAC,GAAa,yBAAAC,OAA6B,iBAqG7C,OAQE,OAAAC,EARF,QAAAC,OAAA,6BAtFC,SAASC,GAAeC,EAA4B,CACzD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJE,EAAOP,GAAsB,EAE7B,CAACQ,EAAeC,CAAgB,EAAIZ,GAAS,IAAMa,GAAkB,CAAC,EACtE,CAACC,EAAUC,CAAW,EAAIf,GAAS,CAAC,EACpC,CAACgB,EAAeC,CAAgB,EAAIjB,GAAS,EAAK,EAClD,CAACkB,EAAUC,CAAW,EAAInB,GAAS,EAAK,EACxC,CAACoB,EAAYC,CAAa,EAAIrB,GAAS,CAAC,EAExCsB,EAAa,KAAK,IAAI,EAAG,KAAK,OAAOZ,EAAK,QAAU,IAAM,EAAE,CAAC,EAE7Da,EAAetB,GAAQ,IACvBa,EAAWQ,EAAmB,EAC3BR,EAAWQ,EAAa,EAC9B,CAACR,EAAUQ,CAAU,CAAC,EAEnBE,EAAeb,EAAc,MAAMY,EAAcA,EAAeD,CAAU,EAkEhF,GAhEApB,GAAauB,GAAa,CACxB,GAAIP,EAAU,CAEZ,GAAIO,EAAI,OAAS,UAAYA,EAAI,OAAS,IACxCN,EAAY,EAAK,EACjBE,EAAc,CAAC,UACNI,EAAI,OAAS,MAAQA,EAAI,OAAS,IAC3CJ,EAAeK,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,UAC9BD,EAAI,OAAS,QAAUA,EAAI,OAAS,IAAK,CAClD,IAAME,EAAOhB,EAAcG,CAAQ,EACnC,GAAIa,EAAM,CACR,IAAMC,EAAOD,EAAK,SAAS,OAAQE,GAAMA,EAAE,OAAS,MAAM,EAC1DR,EAAeK,GAAM,KAAK,IAAIE,EAAK,OAAS,EAAGF,EAAI,CAAC,CAAC,CACvD,CACF,SAAWD,EAAI,OAAS,SAAU,CAChC,IAAME,EAAOhB,EAAcG,CAAQ,EAC/Ba,GAAMpB,EAAM,SAASoB,CAAI,CAC/B,CACA,MACF,CAEA,GAAIX,EAAe,CACjB,GAAIS,EAAI,OAAS,IAAK,CACpB,IAAME,EAAOhB,EAAcG,CAAQ,EACnC,GAAIa,EAAM,CACRG,GAAmBH,EAAK,EAAE,EAC1B,IAAMI,EAAUlB,GAAkB,EAClCD,EAAiBmB,CAAO,EACxBhB,EAAaW,GAAM,KAAK,IAAIA,EAAGK,EAAQ,OAAS,CAAC,CAAC,CACpD,CACAd,EAAiB,EAAK,CACxB,MACEA,EAAiB,EAAK,EAExB,MACF,CAEA,GAAIQ,EAAI,OAAS,UAAYA,EAAI,OAAS,IACxClB,EAAM,QAAQ,UACLkB,EAAI,OAAS,MAAQA,EAAI,OAAS,IAC3CV,EAAaW,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,UAC5BD,EAAI,OAAS,QAAUA,EAAI,OAAS,IAC7CV,EAAaW,GAAM,KAAK,IAAIf,EAAc,OAAS,EAAGe,EAAI,CAAC,CAAC,UACnDD,EAAI,OAAS,SAAU,CAChC,IAAME,EAAOhB,EAAcG,CAAQ,EAC/Ba,GAAMpB,EAAM,SAASoB,CAAI,CAC/B,SAAWF,EAAI,OAAS,IAClBd,EAAc,OAAS,GAAGM,EAAiB,EAAI,UAC1CQ,EAAI,OAAS,IAAK,CAC3B,IAAME,EAAOhB,EAAcG,CAAQ,EAC/Ba,GACaK,GAAiBL,CAAI,GAElCf,EAAiBC,GAAkB,CAAC,CAG1C,MAAWY,EAAI,OAAS,KAClBd,EAAc,OAAS,IACzBQ,EAAY,EAAI,EAChBE,EAAc,CAAC,EAGrB,CAAC,EAEGV,EAAc,SAAW,EAC3B,OACEN,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAU,EAEV,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYL,GAAe,KAC7C,oBACH,EACAK,EAAC,QAAK,GAAI,EAAE,QAAU;AAAA;AAAA,EAA8B,EACpDA,EAAC,QAAK,GAAI,EAAE,UAAY,sBAAa,GACvC,EAKJ,GAAIc,EAAU,CACZ,IAAMS,EAAOhB,EAAcG,CAAQ,EAC7Bc,EAAOD,EAAOA,EAAK,SAAS,OAAQE,GAAMA,EAAE,OAAS,MAAM,EAAI,CAAC,EAChEI,EAAcL,EAAK,MAAMR,EAAYA,EAAaE,CAAU,EAC5DY,EAAQN,EAAK,OAEnB,OACEvB,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAU,EAEV,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYL,GAAe,KAC7C,qBAAY4B,GAAM,OAAS,UAAU,GACxC,EACAvB,EAAC,QAAK,GAAI,EAAE,QACT,YAAGgB,EAAa,CAAC,SAAI,KAAK,IAAIA,EAAaE,EAAYY,CAAK,CAAC,OAAOA,CAAK,YAC5E,EACA9B,EAAC,QAAM,YAAG,EACT6B,EAAY,IAAI,CAACJ,EAAGM,IAAM,CACzB,IAAMC,EAASP,EAAE,OAAS,OAAS,SAAM,SACnCQ,EAAQR,EAAE,OAAS,OAAS,EAAE,QAAU,EAAE,KAC1CS,EAAUT,EAAE,QAAQ,OAAS,IAAMA,EAAE,QAAQ,UAAU,EAAG,GAAG,EAAI,MAAQA,EAAE,QACjF,OACEzB,EAAC,QAAoC,GAAIiC,EACtC,cAAKD,CAAM,IAAIE,EAAQ,QAAQ,MAAO,GAAG,CAAC,IADlC,QAAQlB,EAAae,CAAC,EAEjC,CAEJ,CAAC,EACD/B,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,UAAY,yDAAsC,GAChE,CAEJ,CAGA,OACEC,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAU,EAEV,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYL,GAAe,KAC7C,oBACH,EACAK,EAAC,QAAK,GAAI,EAAE,QACT,YAAGO,EAAc,MAAM,gBAAgBA,EAAc,SAAW,EAAI,IAAM,EAAE,GAC/E,EACAP,EAAC,QAAM,YAAG,EACToB,EAAa,IAAI,CAACG,EAAMQ,IAAM,CAE7B,IAAMI,EADMhB,EAAeY,IACArB,EACrB0B,EAAOC,GAAmBd,EAAK,SAAS,EACxCe,EAAWf,EAAK,SAAS,OAAQE,GAAMA,EAAE,OAAS,MAAM,EAAE,OAC1Dc,EAAQhB,EAAK,MAAM,OAAS,GAAKA,EAAK,MAAM,UAAU,EAAG,EAAE,EAAI,MAAQA,EAAK,MAElF,OACEtB,GAAC,OAAkB,cAAc,MAC/B,UAAAD,EAAC,QACC,GAAImC,EAAa,EAAE,QAAU,EAAE,UAC/B,WAAYA,EAAaxC,GAAe,KAAO,OAE9C,cAAKwC,EAAa,SAAM,GAAG,IAAII,CAAK,GACvC,EACAvC,EAAC,QAAK,GAAI,EAAE,QACT,cAAKoC,CAAI,MAAME,CAAQ,SAC1B,IATQf,EAAK,EAUf,CAEJ,CAAC,EACAX,GACCX,GAAC,OACC,UAAAD,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYL,GAAe,KAC7C,sBAAaY,EAAcG,CAAQ,GAAG,KAAK,WAC9C,GACF,EAEFV,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,UAAY,sFAAmE,GAC7F,CAEJ,CA3NA,IAAAwC,GAAAC,EAAA,kBAaAC,IACAC,OCJA,UAAYC,OAAQ,KACpB,UAAYC,OAAU,OACtB,UAAYC,OAAQ,KACpB,OAAS,YAAAC,OAAgB,gBACzB,OAAS,kBAAAC,OAAsB,gBAC/B,OAAS,YAAAC,EAAU,UAAAC,GAAQ,aAAAC,OAAiB,QAC5C,OAAS,eAAAC,OAAmB,iBAkTtB,OAkHM,YAAAC,GAlHN,OAAAC,EAOE,QAAAC,OAPF,6BAtPN,SAASC,GAAYC,EAAmB,CACtC,GAAI,CACF,IAAMC,EAAM,QAAQ,WAAa,SAAW,SAASD,CAAG,IACpD,QAAQ,WAAa,QAAU,aAAaA,CAAG,IAC/C,aAAaA,CAAG,IACpBV,GAASW,EAAK,CAAE,MAAO,SAAU,QAAS,GAAK,CAAC,CAClD,MAAQ,CAAoC,CAC9C,CAEO,SAASC,GAAYC,EAAyB,CACnD,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EAEJ,CAACE,EAAMC,CAAO,EAAIf,EAAe,UAAU,EAC3C,CAACgB,EAAkBC,CAAmB,EAAIjB,EAAS,CAAC,EACpD,CAACkB,EAAcC,CAAe,EAAInB,EAAS,CAAC,EAC5C,CAACoB,EAAeC,CAAgB,EAAIrB,EAAS,CAAC,EAC9C,CAACsB,EAAYC,CAAa,EAAIvB,EAA6B,QAAQ,EACnE,CAACwB,EAAkBC,CAAmB,EAAIzB,EAAS,WAAW,EAC9D,CAAC0B,EAAeC,CAAgB,EAAI3B,EAAS,EAAE,EAC/C,CAAC4B,EAAaC,CAAc,EAAI7B,EAAS,EAAE,EAC3C,CAAC8B,EAASC,CAAU,EAAI/B,EAAS,EAAK,EACtC,CAACgC,EAAOC,CAAQ,EAAIjC,EAAS,EAAE,EAG/B,CAACkC,EAAUC,CAAW,EAAInC,EAAS,EAAE,EACrC,CAACoC,EAAeC,EAAgB,EAAIrC,EAAS,EAAE,EAC/C,CAACsC,GAAgBC,EAAiB,EAAIvC,EAAS,EAAE,EACjD,CAACwC,GAAUC,EAAW,EAAIzC,EAAS,EAAK,EACxC,CAAC0C,GAAYC,CAAa,EAAI3C,EAAS,EAAE,EACzC4C,EAAgB3C,GAAO,EAAK,EAE5B4C,EAAWC,GAAU9B,CAAgB,EACrC+B,EAASzB,IAAe,QAAU0B,GAAgBC,GAAOzB,CAAgB,GAAK,CAAC,EAGrFtB,GAAU,IAAM,CACd,GAAIY,IAAS,cACb,GAAI,CACF,GAAM,CAAE,iBAAAoC,CAAiB,EAAI,GAAQ,cAAc,EAC7C,CAAE,IAAA1C,EAAK,aAAA2C,CAAa,EAAID,EAAiB1B,CAAgB,EAC/DW,EAAY3B,CAAG,EACf6B,GAAiBc,CAAY,EAC7BZ,GAAkB,EAAE,EACpBI,EAAc,EAAE,EAChBpC,GAAYC,CAAG,CACjB,MAAQ,CACNmC,EAAc,+DAA+D,CAC/E,CACF,EAAG,CAAC7B,EAAMU,CAAgB,CAAC,EAE3BrB,GAAaiD,GAAa,CAExB,GAAIA,EAAI,OAAS,SAAU,CACrBtC,IAAS,eAAiBA,IAAS,oBACrCC,EAAQ,OAAO,EACf4B,EAAc,EAAE,GACP7B,IAAS,UAClBC,EAAQ,OAAO,EACfkB,EAAS,EAAE,GACFnB,IAAS,QAClBC,EAAQS,IAAqB,YAAc,cAAgB,UAAU,EAC5DV,IAAS,cAClBC,EAAQ,UAAU,EAElBJ,EAAM,QAAQ,EAEhB,MACF,CAGA,GAAIG,IAAS,WAAY,CACvB,GAAIsC,EAAI,OAAS,MAAQA,EAAI,OAAS,IACpCnC,EAAqBoC,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,UACpCD,EAAI,OAAS,QAAUA,EAAI,OAAS,IAC7CnC,EAAqBoC,GAAM,KAAK,IAAIP,GAAU,OAAS,EAAGO,EAAI,CAAC,CAAC,UACvDD,EAAI,OAAS,SAAU,CAChC,IAAME,EAAIR,GAAU9B,CAAgB,EACpCS,EAAoB6B,EAAE,EAAE,EACxBjC,EAAiB,CAAC,EACdiC,EAAE,KAAO,aACXnC,EAAgB,CAAC,EACjBJ,EAAQ,aAAa,IAErBQ,EAAc,QAAQ,EACtBR,EAAQ,OAAO,EAEnB,CACA,MACF,CAGA,GAAID,IAAS,cAAe,CAC1B,GAAIsC,EAAI,OAAS,MAAQA,EAAI,OAAS,IACpCjC,EAAiBkC,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,UAChCD,EAAI,OAAS,QAAUA,EAAI,OAAS,IAC7CjC,EAAiBkC,GAAM,KAAK,IAAIE,GAAa,OAAS,EAAGF,EAAI,CAAC,CAAC,UACtDD,EAAI,OAAS,SAAU,CAChC,IAAMI,EAAOD,GAAarC,CAAY,EAAE,GACxCK,EAAciC,CAAI,EAClBnC,EAAiB,CAAC,EAClBN,EAAQ,OAAO,CACjB,CACA,MACF,CAGA,GAAID,IAAS,QAAS,CACpB,GAAIsC,EAAI,OAAS,MAAQA,EAAI,OAAS,IACpC/B,EAAkBgC,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,UACjCD,EAAI,OAAS,QAAUA,EAAI,OAAS,IAC7C/B,EAAkBgC,GAAM,KAAK,IAAIN,EAAO,OAAS,EAAGM,EAAI,CAAC,CAAC,UACjDD,EAAI,OAAS,SAAU,CAChC,IAAMK,EAAIV,EAAO3B,CAAa,EAC9BO,EAAiB8B,EAAE,EAAE,EACjBjC,IAAqB,SACvBkC,GAAgBlC,EAAkBiC,EAAE,GAAI,MAAS,EACxCnC,IAAe,SACxBsB,EAAc,QAAU,GACxB7B,EAAQ,aAAa,IAErBA,EAAQ,QAAQ,EAChBc,EAAe,EAAE,EACjBI,EAAS,EAAE,EAEf,CACA,MACF,CAGA,GAAInB,IAAS,SAAU,CACrB,GAAIsC,EAAI,OAAS,SAAU,CACzB,GAAI,CAACxB,EAAY,KAAK,EAAG,CACvBK,EAAS,yBAAyB,EAClC,MACF,CACAyB,GAAgBlC,EAAkBE,EAAeE,EAAY,KAAK,CAAC,CACrE,MAAWwB,EAAI,MAAQA,EAAI,OAAS,IAClCrB,EAAYsB,GAAM,CAACA,CAAC,EACXD,EAAI,OAAS,aACtBvB,EAAgBwB,GAAMA,EAAE,MAAM,EAAG,EAAE,CAAC,EACpCpB,EAAS,EAAE,GACFmB,EAAI,MAAQA,EAAI,OAAS,KAClCvB,EAAe,EAAE,EACjBI,EAAS,EAAE,GACFmB,EAAI,UAAYA,EAAI,SAAS,SAAW,GAAK,CAACA,EAAI,MAAQ,CAACA,EAAI,OACxEvB,EAAgBwB,GAAMA,EAAID,EAAI,QAAQ,EACtCnB,EAAS,EAAE,GAEb,MACF,CAGA,GAAInB,IAAS,cAAe,CAC1B,GAAIsC,EAAI,OAAS,SAAU,CACzB,IAAMO,EAAOrB,GAAe,KAAK,EACjC,GAAI,CAACqB,GAAQf,EAAc,QAAS,OACpCA,EAAc,QAAU,GACxB7B,EAAQ,kBAAkB,EAC1B,GAAI,CACF,GAAM,CAAE,kBAAA6C,CAAkB,EAAI,GAAQ,cAAc,EACpDA,EAAkBD,EAAMvB,EAAeZ,CAAgB,EACpD,KAAMqC,GAAgB,CACrBH,GAAgBlC,EAAkBE,EAAe,MAAS,EAC1Df,EAAM,WAAW,CACf,SAAUa,EACV,MAAOE,EACP,WAAYmC,EAAO,YACrB,CAAC,CACH,CAAC,EACA,MAAOC,GAAe,CACrBlB,EAAc,QAAU,GACxBD,EAAcmB,EAAI,OAAO,EACzB/C,EAAQ,aAAa,CACvB,CAAC,CACL,MAAQ,CACN6B,EAAc,QAAU,GACxBD,EAAc,uBAAuB,EACrC5B,EAAQ,aAAa,CACvB,CACA,MACF,CACIqC,EAAI,MAAQA,EAAI,OAAS,IAC3BX,GAAaY,GAAM,CAACA,CAAC,EACZD,EAAI,OAAS,aACtBb,GAAmBc,GAAMA,EAAE,MAAM,EAAG,EAAE,CAAC,EACvCV,EAAc,EAAE,GACPS,EAAI,MAAQA,EAAI,OAAS,KAClCb,GAAkB,EAAE,EACpBI,EAAc,EAAE,GACPS,EAAI,UAAYA,EAAI,SAAS,SAAW,GAAK,CAACA,EAAI,MAAQ,CAACA,EAAI,OACxEb,GAAmBc,GAAMA,EAAID,EAAI,QAAQ,EACzCT,EAAc,EAAE,GAElB,MACF,CACF,CAAC,EAED,IAAMe,GAAkB,CAACK,EAAcC,EAAeC,IAAoB,CACxE,IAAMC,EAAiB,QAAQ,WAAQ,EAAG,SAAS,EAC7CC,EAAkB,QAAKD,EAAW,aAAa,EAEjDE,EAA8B,CAAC,EACnC,GAAI,CACK,cAAWD,CAAU,IAC1BC,EAAS,KAAK,MAAS,gBAAaD,EAAY,OAAO,CAAC,EAE5D,MAAQ,CAAC,CAETC,EAAO,SAAWL,EAClBK,EAAO,MAAQJ,EACXC,IACGG,EAAO,UAASA,EAAO,QAAU,CAAC,GACvCA,EAAO,QAAQL,CAAI,EAAIE,GAGjB,cAAWC,CAAS,GAAM,aAAUA,EAAW,CAAE,UAAW,EAAK,CAAC,EACvE,iBAAcC,EAAY,KAAK,UAAUC,EAAQ,KAAM,CAAC,EAAG,OAAO,EAErEzD,EAAM,WAAW,CAAE,SAAUoD,EAAM,MAAAC,EAAO,OAAAC,CAAO,CAAC,CACpD,EAGMI,GAAc7C,IAAqB,YACnC8C,EAAQD,GAAc,EAAI7C,IAAqB,SAAW,EAAI,EAC9D+C,EAAalB,GAAoB,CACrC,OAAQA,EAAG,CACT,IAAK,WAAY,MAAO,KAAKiB,CAAK,GAClC,IAAK,cAAe,MAAO,MAC3B,IAAK,QAAS,OAAOD,GAAc,MAAQ7C,IAAqB,SAAW,MAAQ,MACnF,IAAK,SAAU,OAAO6C,GAAc,MAAQ,MAC5C,IAAK,cAAe,MAAO,MAC3B,IAAK,mBAAoB,MAAO,MAChC,QAAS,MAAO,EAClB,CACF,EAEA,OACE/D,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAU,EAEV,UAAAD,EAAC,QAAK,GAAI,EAAE,QAAS,WAAYN,GAAe,KAC7C,wBACH,EACAM,EAAC,QAAM,YAAG,EAGTS,IAAS,YACRR,GAAC,OAAI,cAAc,SACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,KAAM,WAAYN,GAAe,KAC1C,iBAAQwE,EAAU,UAAU,CAAC,oBAChC,EACAlE,EAAC,QAAM,YAAG,EACTyC,GAAU,IAAI,CAACQ,EAAGkB,IACjBnE,EAAC,QAEC,GAAIW,IAAqBwD,EAAI,EAAE,QAAU,EAAE,UAC3C,WAAYxD,IAAqBwD,EAAIzE,GAAe,KAAO,OAE1D,cAAKiB,IAAqBwD,EAAI,IAAM,GAAG,IAAIlB,EAAE,IAAI,KAAKtC,IAAqBwD,EAAIlB,EAAE,KAAO,EAAE,IAJtFA,EAAE,EAKT,CACD,EACDjD,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,UAAY,wDAA+C,GACzE,EAIDS,IAAS,eACRR,GAAC,OAAI,cAAc,SACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,KAAM,WAAYN,GAAe,KAC1C,iBAAQwE,EAAU,aAAa,CAAC,qCACnC,EACAlE,EAAC,QAAM,YAAG,EACTkD,GAAa,IAAI,CAACkB,EAAGD,IACpBnE,EAAC,QAEC,GAAIa,IAAiBsD,EAAI,EAAE,QAAU,EAAE,UACvC,WAAYtD,IAAiBsD,EAAIzE,GAAe,KAAO,OAEtD,cAAKmB,IAAiBsD,EAAI,IAAM,GAAG,IAAIC,EAAE,IAAI,KAAKvD,IAAiBsD,EAAIC,EAAE,KAAO,EAAE,IAJ9EA,EAAE,EAKT,CACD,EACDpE,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,UAAY,sDAA6C,GACvE,EAIDS,IAAS,SACRR,GAAC,OAAI,cAAc,SACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,KAAM,WAAYN,GAAe,KAC1C,SAAAuB,IAAe,QACZ,QAAQiD,EAAU,OAAO,CAAC,6CAC1B,QAAQA,EAAU,OAAO,CAAC,mBAAmB1B,EAAS,IAAI,IAChE,EACAxC,EAAC,QAAM,YAAG,EACT0C,EAAO,IAAI,CAACU,EAAGe,IACdnE,EAAC,QAEC,GAAIe,IAAkBoD,EAAI,EAAE,QAAU,EAAE,UACxC,WAAYpD,IAAkBoD,EAAIzE,GAAe,KAAO,OAEvD,cAAKqB,IAAkBoD,EAAI,IAAM,GAAG,IAAIf,EAAE,IAAI,GAAGA,EAAE,KAAO,KAAKA,EAAE,IAAI,GAAK,EAAE,IAJxEA,EAAE,EAKT,CACD,EACDpD,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,UAAY,sDAA6C,GACvE,EAIDS,IAAS,UACRR,GAAC,OAAI,cAAc,SACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,KAAM,WAAYN,GAAe,KAC1C,iBAAQwE,EAAU,QAAQ,CAAC,kBAC9B,EACAlE,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,QACT,wBAAemB,CAAgB,aAAaE,CAAa,GAC5D,EACCgD,GAASlD,CAAgB,GACxBnB,EAAC,QAAK,GAAI,EAAE,QACT,yBAAgBqE,GAASlD,CAAgB,CAAC,GAC7C,EAEFnB,EAAC,QAAK,GAAI,EAAE,QACT,oCAA2BsE,GAASnD,CAAgB,GAAK,KAAK,GACjE,EACAnB,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,KACT,gBAAOyB,EAAUF,EAAcA,EAAY,QAAQ,KAAM,GAAG,CAAC,IAChE,EACCI,GACC3B,EAAC,QAAK,GAAI,EAAE,MAAQ;AAAA,IAAO2B,CAAK,GAAG,EAErC3B,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,UAAY,0EAAiE,GAC3F,EAIDS,IAAS,eACRR,GAAC,OAAI,cAAc,SACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,KAAM,WAAYN,GAAe,KAC1C,iBAAQwE,EAAU,aAAa,CAAC,gBACnC,EACAlE,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,KAAO,mDAA0C,EAC5D6B,EACC7B,EAAC,QAAK,GAAI,EAAE,QAAU,oCAA2B6B,EAAS,UAAU,EAAG,EAAE,CAAC,MAAM,EAC9E,KACJ7B,EAAC,QAAK,GAAI,EAAE,KAAO,wEAA+D,EAClFA,EAAC,QAAK,GAAI,EAAE,KAAO,kEAAyD,EAC3EqC,GACCpC,GAAAF,GAAA,CACE,UAAAC,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,MAAQ,qBAAYqC,EAAU,GAAG,GAC/C,EACE,KACJrC,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,KACT,oBAAWmC,GAAWF,GAAiBA,GAAe,QAAQ,KAAM,GAAG,CAAC,IAC3E,EACAjC,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,UAAY,sEAA6D,GACvF,EAIDS,IAAS,oBACRR,GAAC,OAAI,cAAc,SACjB,UAAAD,EAAC,QAAK,GAAI,EAAE,KAAM,WAAYN,GAAe,KAC1C,iBAAQwE,EAAU,kBAAkB,CAAC,gBACxC,EACAlE,EAAC,QAAM,YAAG,EACVA,EAAC,QAAK,GAAI,EAAE,QAAU,2CAAkC,GAC1D,GAEJ,CAEJ,CA9cA,IAwBMyC,GAOAS,GAKAN,GAsBAD,GAIA2B,GAMAD,GApENE,GAAAC,EAAA,kBAiBAC,IAOMhC,GAAY,CAChB,CAAE,GAAI,YAAa,KAAM,qBAAsB,KAAM,4BAA6B,EAClF,CAAE,GAAI,SAAU,KAAM,SAAU,KAAM,YAAa,EACnD,CAAE,GAAI,SAAU,KAAM,YAAa,KAAM,2BAA4B,EACrE,CAAE,GAAI,SAAU,KAAM,iBAAkB,KAAM,mBAAoB,CACpE,EAEMS,GAAe,CACnB,CAAE,GAAI,SAAU,KAAM,UAAW,KAAM,8CAA+C,EACtF,CAAE,GAAI,QAAS,KAAM,QAAS,KAAM,gCAAiC,CACvE,EAEMN,GAAwE,CAC5E,UAAW,CACT,CAAE,GAAI,oBAAqB,KAAM,oBAAqB,KAAM,4BAA6B,EACzF,CAAE,GAAI,kBAAmB,KAAM,kBAAmB,KAAM,cAAe,EACvE,CAAE,GAAI,4BAA6B,KAAM,mBAAoB,KAAM,SAAU,CAC/E,EACA,OAAQ,CACN,CAAE,GAAI,SAAU,KAAM,SAAU,KAAM,aAAc,EACpD,CAAE,GAAI,cAAe,KAAM,cAAe,KAAM,SAAU,EAC1D,CAAE,GAAI,KAAM,KAAM,KAAM,KAAM,WAAY,CAC5C,EACA,OAAQ,CACN,CAAE,GAAI,mBAAoB,KAAM,mBAAoB,KAAM,aAAc,EACxE,CAAE,GAAI,iBAAkB,KAAM,iBAAkB,KAAM,cAAe,CACvE,EACA,OAAQ,CACN,CAAE,GAAI,WAAY,KAAM,YAAa,KAAM,iBAAkB,EAC7D,CAAE,GAAI,YAAa,KAAM,aAAc,KAAM,cAAe,EAC5D,CAAE,GAAI,UAAW,KAAM,UAAW,KAAM,gBAAiB,CAC3D,CACF,EAEMD,GAAe,CACnB,CAAE,GAAI,mBAAoB,KAAM,mBAAoB,KAAM,iCAAkC,CAC9F,EAEM2B,GAAmC,CACvC,UAAW,oBACX,OAAQ,iBACR,OAAQ,gBACV,EAEMD,GAAmC,CACvC,UAAW,8CACX,OAAQ,uCACR,OAAQ,oCACV,ICnEA,OAAS,kBAAAK,OAAsB,gBAC/B,OAAS,YAAAC,OAAgB,QACzB,OAAS,eAAAC,GAAa,yBAAAC,OAA6B,iBAoF7C,cAAAC,GAkBI,QAAAC,OAlBJ,6BAhFC,SAASC,GAAaC,EAAgC,CAC3D,GAAM,CAAE,MAAAC,CAAM,EAAIC,EAAS,EACrB,EAAID,EACJE,EAAMC,GAAO,EACbC,EAAOT,GAAsB,EAC7B,CAACU,EAAcC,CAAe,EAAIb,GAAS,CAAC,EAG5Cc,EAAWL,EAAI,SAAS,OAASA,EAAI,SAAS,OAAO,EAAI,CAAC,EAC1DM,EAAY,MAAM,QAAQD,CAAQ,EACpCA,EAAS,IAAKE,GACZA,EAAK,YAAY,MAAQA,EAAK,MAAQ,SACxC,EACA,CAAC,EAECC,EAAoE,CACxE,CACE,MAAO,WACP,KAAM,CACJ,CAAC,WAAYR,EAAI,QAAQ,EACzB,CAAC,QAASA,EAAI,KAAK,EACnB,CAAC,YAAaA,EAAI,UAAU,CAC9B,CACF,EACA,CACE,MAAO,SACP,KAAM,CACJ,CAAC,OAAQ,QAAQ,OAAO,EACxB,CAAC,WAAY,GAAG,QAAQ,QAAQ,IAAI,QAAQ,IAAI,EAAE,EAClD,CACE,WACA,QAAQ,IAAI,cAAgB,QAAQ,IAAI,MAAQ,SAClD,EACA,CAAC,QAAS,QAAQ,IAAI,OAAS,SAAS,CAC1C,CACF,EACA,CACE,MAAO,UAAUM,EAAU,MAAM,IACjC,KAAMA,EAAU,MAAM,EAAG,EAAE,EAAE,IAAKG,GAAiB,CAAC,SAAUA,CAAI,CAAC,CACrE,CACF,EAGMC,EAID,CAAC,EACN,QAAWC,KAAWH,EAAU,CAC9BE,EAAM,KAAK,CAAE,KAAM,SAAU,KAAMC,EAAQ,KAAM,CAAC,EAClD,OAAW,CAACC,EAAOC,CAAK,IAAKF,EAAQ,KACnCD,EAAM,KAAK,CAAE,KAAM,MAAO,KAAME,EAAO,MAAAC,CAAM,CAAC,EAEhDH,EAAM,KAAK,CAAE,KAAM,MAAO,KAAM,GAAI,MAAO,EAAG,CAAC,CACjD,CAEA,IAAMI,EAAa,KAAK,IAAI,GAAIZ,EAAK,QAAU,IAAM,EAAE,EAEvDV,GAAauB,GAAa,EACpBA,EAAI,OAAS,UAAYA,EAAI,OAAS,MAAKlB,EAAM,QAAQ,GACzDkB,EAAI,OAAS,MAAQA,EAAI,OAAS,MACpCX,EAAiBY,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,GACvCD,EAAI,OAAS,QAAUA,EAAI,OAAS,MACtCX,EAAiBY,GAAM,KAAK,IAAIN,EAAM,OAASI,EAAYE,EAAI,CAAC,CAAC,CACrE,CAAC,EAED,IAAMC,EAAUP,EAAM,MAAMP,EAAcA,EAAeW,CAAU,EAEnE,OACEnB,GAAC,OACC,YAAY,SACZ,YAAa,EAAE,QACf,SAAU,EACV,SAAU,EACV,cAAc,SACd,SAAS,WACT,IAAI,MACJ,KAAK,MACL,MAAM,MAEN,UAAAD,GAAC,QAAK,GAAI,EAAE,QAAS,WAAYJ,GAAe,KAC7C,2BACH,EACAI,GAAC,QAAM,YAAG,EACTuB,EAAQ,IAAI,CAACC,EAAMC,IACdD,EAAK,OAAS,SAEdxB,GAAC,QAEC,GAAI,EAAE,UACN,WAAYJ,GAAe,KAE1B,cAAK4B,EAAK,IAAI,IAJV,KAAKC,CAAC,EAKb,EAGA,CAACD,EAAK,MAAQ,CAACA,EAAK,MAAcxB,GAAC,QAAqB,aAAX,KAAKyB,CAAC,EAAQ,EAE7DxB,GAAC,OAAmB,cAAc,MAChC,UAAAD,GAAC,QAAK,GAAI,EAAE,UAAY,gBAAOwB,EAAK,IAAI,GAAG,EAC1CA,EAAK,OAASxB,GAAC,QAAK,GAAI,EAAE,KAAO,aAAIwB,EAAK,KAAK,GAAG,IAF3C,KAAKC,CAAC,EAGhB,CAEH,EACDzB,GAAC,QAAM,YAAG,EACVA,GAAC,QAAK,GAAI,EAAE,QACT,4CACH,GACF,CAEJ,CAzHA,IAAA0B,GAAAC,EAAA,kBAQAC,IACAC,OCTA,IAAAC,GAAA,GAAAC,GAAAD,GAAA,cAAAE,KAeA,UAAYC,OAAQ,KACpB,UAAYC,OAAU,OACtB,UAAYC,OAAQ,KACpB,OAAS,cAAAC,GAAY,eAAAC,GAAa,yBAAAC,OAA6B,iBAC/D,OAAS,qBAAAC,GAAmB,kBAAAC,OAAsB,gBAClD,OAAS,YAAAC,GAAU,UAAAC,GAAQ,eAAAC,OAAmB,QAC9C,OACE,gBAAAC,GACA,qBAAAC,GACA,kBAAAC,GACA,oBAAAC,OACK,eACP,OAAS,eAAAC,GAAa,mBAAAC,GAAiB,mBAAAC,OAAuB,aA+LxD,OACE,OAAAC,EADF,QAAAC,OAAA,6BArJN,SAASC,GAASC,EAKf,CACD,IAAMC,EAAOjB,GAAsB,EAC7B,CAAE,MAAAkB,EAAO,QAAAC,EAAS,QAAAC,EAAS,WAAAC,CAAW,EAAIC,EAAS,EACnDC,EAAIL,EAEJ,CAACM,EAAOC,CAAQ,EAAItB,GAAgBa,EAAM,QAAQ,OAAS,UAAY,MAAM,EAC7E,CAACU,EAAQC,CAAS,EAAIxB,GAAiB,MAAM,EAC7C,CAACyB,EAAQC,CAAS,EAAI1B,GAAS,OAAO,EACtC,CAAC2B,EAAUC,CAAW,EAAI5B,GAASa,EAAM,QAAQ,QAAQ,EACzD,CAACgB,EAAOC,CAAQ,EAAI9B,GAASa,EAAM,QAAQ,OAASL,GAAgBK,EAAM,QAAQ,QAAQ,GAAK,SAAS,EACxG,CAACkB,EAAYC,CAAa,EAAIhC,GAASa,EAAM,QAAQ,UAAU,EAC/D,CAACoB,EAAQC,CAAS,EAAIlC,GAAwD,EAC9E,CAACmC,EAAgBC,CAAiB,EAAIpC,GAAS,CAAC,EAChD,CAACqC,EAAYC,CAAa,EAAItC,GAA6B,EAC3D,CAACuC,EAAaC,EAAc,EAAIxC,GAAS,EAAI,EAG7CyC,GAAWxC,GAAOY,EAAM,KAAK,EAC7B6B,GAAczC,GAAOY,EAAM,QAAQ,EACnC8B,GAAQ1C,GAAOY,EAAM,iBAAiB,EAGtC+B,GAAoB3C,GAAiF,IAAI,EAIzG4C,GAAuB5C,GAAiE,IAAI,EAC5F,CAAC6C,EAAmBC,CAAoB,EAAI/C,GAGxC,IAAI,EAGRgD,EAAoB9C,GAAY,CAAC+C,EAAkBC,IAChD,IAAI,QAASC,GAAY,CAC9BN,GAAqB,QAAUM,EAC/BJ,EAAqB,CAAE,SAAAE,EAAU,QAAAC,CAAQ,CAAC,CAC5C,CAAC,EACA,CAAC,CAAC,EAGLP,GAAM,QAAQ,YAAY,MAAOM,EAAkBC,IAAoB,CACrE,IAAME,EAAW,MAAMJ,EAAkBC,EAAUC,CAAO,EAC1D,OAAOE,IAAa,SAAW,QAAUA,CAC3C,CAAC,EAGD,IAAMC,EAAenD,GAAY,CAACoD,EAAqBC,EAAkBC,IAAoB,CAG3F,IAAIC,EAAcD,EAClB,GAAIA,IAAW,OAAW,CACxB,IAAME,EAASjD,GAAgB6C,CAAW,EAC1C,GAAI,QAAQ,IAAII,CAAM,EACpBD,EAAc,QAAQ,IAAIC,CAAM,MAEhC,IAAI,CACF,IAAMC,EAAkB,QAAQ,WAAQ,EAAG,UAAW,aAAa,EAC5D,cAAWA,CAAU,IAE1BF,EADe,KAAK,MAAS,gBAAaE,EAAY,OAAO,CAAC,EACzC,UAAUL,CAAW,EAE9C,MAAQ,CAAC,CAEb,CAEA,IAAMM,EAAoC,CACxC,SAAUN,EACV,MAAOC,EACP,OAAQE,GAAe,OACvB,QAAS5C,EAAM,QAAQ,SAAW,OAClC,YAAa,EACb,UAAW,IACb,EAEMgD,EAAW,IAAItD,GAAYqD,EAAalB,GAAY,QAASC,GAAM,OAAO,EAChFF,GAAS,QAAUoB,EACnBjC,EAAY0B,CAAW,EACvBxB,EAASyB,CAAQ,CACnB,EAAG,CAAC1C,EAAM,QAAQ,OAAO,CAAC,EAGpBiD,GAAsB5D,GAAa6D,GAAgB,CACvD/B,EAAc+B,CAAG,CACnB,EAAG,CAAC,CAAC,EAILnE,GAAaoE,GAAa,CAExB,GAAI,EAAAzC,IAAW,QAAUyC,EAAI,OAAS,UAGtC,IAAIA,EAAI,MAAQA,EAAI,OAAS,IAAK,CAChC,IAAMC,EAAW,WAAmB,gBAChCA,EAASA,EAAQ,EAChB,QAAQ,KAAK,CAAC,CACrB,CAEID,EAAI,MAAQA,EAAI,OAAS,MAC3B1C,EAAS,SAAS,EAClBI,EAAU,OAAO,GAGfsC,EAAI,MAAQA,EAAI,OAAS,KAC3BxC,EAAW0C,GAAOA,IAAM,QAAU,OAAS,OAAQ,EAGjDF,EAAI,MAAQA,EAAI,OAAS,KAC3BxC,EAAW0C,GAAOA,IAAM,WAAa,OAAS,UAAW,EAGvDF,EAAI,MAAQA,EAAI,OAAS,KAC3BxB,GAAgB2B,GAAM,CAACA,CAAC,EAGtBH,EAAI,MAAQA,EAAI,OAAS,KAC3BxC,EAAW0C,GAAOA,IAAM,QAAU,OAAS,OAAQ,EAGjDF,EAAI,MAAQA,EAAI,OAAS,KAC3BxC,EAAW0C,GAAOA,IAAM,UAAY,OAAS,SAAU,EAGrDF,EAAI,OAAS,MACfxC,EAAW0C,GAAOA,IAAM,OAAS,OAAS,MAAO,EAG/CF,EAAI,OAAS,UACfxC,EAAU,MAAM,EAEpB,EAAG,CAAC,CAAC,EAGL,IAAM4C,GAAsBlE,GAAamE,GAAwB,CAE/D/C,EAAS,SAAS,EAClBE,EAAU,MAAM,EAChBE,EAAU,OAAO,CACnB,EAAG,CAAC,CAAC,EAEL,OACEf,GAAC,OAAI,MAAOG,EAAK,MAAO,OAAQA,EAAK,OAAQ,cAAc,SAEzD,UAAAH,GAAC,OAAI,OAAQ,EAAG,cAAc,MAAM,SAAU,EAAG,WAAY,EAC3D,UAAAD,EAAC,QAAK,GAAIU,EAAE,QAAS,WAAYrB,GAAe,KAAO,kBAAS,EAChEW,EAAC,QAAK,GAAIU,EAAE,OAAS,oBAAM,EAC3BV,EAAC,QAAK,GAAIU,EAAE,UAAY,SAAAS,EAAM,EAC9BnB,EAAC,QAAK,GAAIU,EAAE,OAAS,oBAAM,EAC3BV,EAAC,QAAK,GAAIe,IAAW,QAAUL,EAAE,MAAQK,IAAW,gBAAkBL,EAAE,QAAUA,EAAE,QACjF,SAAAK,EACH,GACF,EAGCJ,IAAU,WACTX,EAAC4D,GAAA,CACC,MAAM,UACN,SAAU3C,EACV,MAAOE,EACP,OAAQI,EACR,eAAgBE,EAChB,OAAQV,EACV,EAIFf,EAAC,OAAI,OAAQ,EAAG,WAAY,EAC1B,SAAAA,EAAC,QAAK,GAAIU,EAAE,OAAS,kBAAI,OAAO,KAAK,IAAIN,EAAK,MAAO,EAAE,CAAC,EAAE,EAC5D,EAGAH,GAAC,OAAI,cAAc,MAAM,SAAU,EACjC,UAAAD,EAAC6D,GAAA,CACC,MAAO,CACL,MAAO9B,GAAS,QAChB,SAAUC,GAAY,QACtB,kBAAmBC,GAAM,QACzB,WAAAZ,EACA,SAAAJ,EACA,MAAAE,EACA,kBAAAmB,EACA,aAAAK,EACA,cAAeS,EACjB,EAEA,SAAApD,EAAC,OAAI,SAAU,EAAG,cAAc,SAC7B,SAAAa,IAAW,WACVb,EAAC8D,GAAA,CACC,SAAUJ,GACV,QAAS,IAAM5C,EAAU,MAAM,EACjC,EACED,IAAW,QACbb,EAAC+D,GAAA,CACC,WAAaC,GAAW,CACtBrB,EAAaqB,EAAO,SAAUA,EAAO,MAAOA,EAAO,MAAM,EACzDlD,EAAU,MAAM,CAClB,EACA,QAAS,IAAMA,EAAU,MAAM,EACjC,EACEH,IAAU,OACZX,EAACiE,GAAA,CACC,SAAUhD,EACV,MAAOE,EACP,WAAYE,EACZ,QAASf,EACT,SAAU,CAAC4D,EAAMC,IAAW,CAC1BjC,GAAkB,QAAU,CAAE,KAAAgC,EAAM,OAAAC,CAAO,EAC3CvD,EAAS,SAAS,CACpB,EACF,EAEAZ,EAACoE,GAAA,CACC,SAAUpD,EACV,SAAU,CAACqD,EAAGC,IAAM9C,EAAU,CAAE,MAAO6C,EAAG,OAAQC,CAAE,CAAC,EACrD,aAAc1C,EACd,iBAAkBF,EAClB,aAAe8B,GAAM1C,EAAU0C,CAAW,EAC1C,eAAgBtB,GAAkB,QACpC,EAEJ,EACF,EAGCL,GACC7B,EAACuE,GAAA,CACC,SAAUtD,EACV,MAAOE,EACP,WAAYE,EACZ,OAAQE,EACR,eAAgBE,EAChB,WAAYE,EACZ,OAAQZ,EACR,QAAST,EACX,GAEJ,EAGAN,EAAC,OAAI,OAAQ,EAAG,WAAY,EAC1B,SAAAA,EAAC,QAAK,GAAIU,EAAE,OAAS,kBAAI,OAAO,KAAK,IAAIN,EAAK,MAAO,EAAE,CAAC,EAAE,EAC5D,EAGCO,IAAU,UACTX,EAACwE,GAAA,CACC,WAAYnD,EACZ,aAAcN,IAAW,gBAC3B,EAEAf,EAACyE,GAAA,CACC,SAAUxD,EACV,MAAOE,EACP,KAAMhB,EAAM,QAAQ,KACpB,WAAYkB,EACZ,OAAQE,EACR,eAAgBE,EAChB,WAAYE,EACZ,aAAcZ,IAAW,gBAC3B,EAIDF,IAAW,SACVb,EAAC0E,GAAA,CACC,SAAUzD,EACV,aAAcE,EACd,SAAWwD,GAAM,CACfhC,EAAa1B,EAAU0D,CAAC,EACxB7D,EAAU,MAAM,CAClB,EACA,QAAS,IAAMA,EAAU,MAAM,EACjC,EAIDD,IAAW,WACVb,EAAC4E,GAAA,CACC,SAAWC,GAAc,CAEvB,OADA/D,EAAU,MAAM,EACR+D,EAAW,CAEjB,IAAK,cACHjE,EAAS,SAAS,EAClBI,EAAU,OAAO,EACjB,MACF,IAAK,iBACHF,EAAU,UAAU,EACpB,MACF,IAAK,gBACHF,EAAS,SAAS,EAClBI,EAAU,OAAO,EACjB,MAEF,IAAK,eACHF,EAAU,OAAO,EACjB,MAEF,IAAK,aACHP,EAAQ,MAAM,EACd,MACF,IAAK,cACHA,EAAQ,OAAO,EACf,MACF,IAAK,eACHO,EAAU,OAAO,EACjB,MAEF,IAAK,kBACHgB,GAAgB2B,GAAM,CAACA,CAAC,EACxB,MACF,IAAK,qBACL,IAAK,mBAEH,MAEF,IAAK,gBACH3C,EAAU,QAAQ,EAClB,MACF,IAAK,cACHA,EAAU,MAAM,EAChB,MACF,IAAK,gBACHE,EAAU,QAAQ,EAClB,MACF,IAAK,eACHF,EAAU,OAAO,EACjB,MACF,IAAK,cAAe,CAClB,IAAMgE,EAAQ,WAAmB,gBAC7BA,EAAMA,EAAK,EACV,QAAQ,KAAK,CAAC,EACnB,KACF,CACF,CACF,EACA,QAAS,IAAMhE,EAAU,MAAM,EACjC,EAIDD,IAAW,QACVb,EAAC+E,GAAA,CACC,QAAS,IAAMjE,EAAU,MAAM,EACjC,EAIDD,IAAW,SACVb,EAACgF,GAAA,CACC,QAAS,IAAMlE,EAAU,MAAM,EACjC,EAIDD,IAAW,UACVb,EAACiF,GAAA,CAAa,QAAS,IAAMnE,EAAU,MAAM,EAAG,GAEpD,CAEJ,CAIA,eAAsBjC,GAASqG,EAAoC,CAEjE,IAAMC,EAAW,IAAI1F,GACf2F,EAAWF,EAAQ,OAAS,OAASvF,GAAe,OACtDuF,EAAQ,OAAS,YAAcvF,GAAe,aAC9CA,GAAe,QACb0F,EAAK,IAAI3F,GAAkB0F,EAAUF,EAAQ,UAAU,EAI7DG,EAAG,YAAY,MAAOC,EAAWC,IACxB,OACR,EAED,MAAM3F,GAAiBuF,EAAU,CAC/B,WAAYD,EAAQ,WACpB,kBAAmBG,CACrB,CAAC,EAGD,IAAIG,EAAiBN,EAAQ,OACzBO,EAAmBP,EAAQ,SAC3BQ,EAAgBR,EAAQ,MACxBS,EAAkBT,EAAQ,QAE9B,GAAI,CAACM,EAAgB,CAEnB,IAAMvC,EAAkB,QAAQ,WAAQ,EAAG,UAAW,aAAa,EAC/D2C,EAAoC,CAAC,EACzC,GAAI,CACK,cAAW3C,CAAU,IAC1B2C,EAAe,KAAK,MAAS,gBAAa3C,EAAY,OAAO,CAAC,EAElE,MAAQ,CAAC,CAGLwC,IAAqB,aAAeG,EAAa,WACnDH,EAAmBG,EAAa,UAE9B,CAACF,GAAiBE,EAAa,QACjCF,EAAgBE,EAAa,OAE3B,CAACD,GAAmBC,EAAa,UACnCD,EAAkBC,EAAa,SAIjC,IAAM5C,EAASjD,GAAgB0F,CAAgB,EAC3C,QAAQ,IAAIzC,CAAM,EACpBwC,EAAiB,QAAQ,IAAIxC,CAAM,EAG5B4C,EAAa,UAAUH,CAAgB,IAC9CD,EAAiBI,EAAa,QAAQH,CAAgB,EAE1D,CAGA,IAAMvC,EAAoC,CACxC,SAAUuC,EACV,MAAOC,GAAiB,OACxB,OAAQF,GAAkB,OAC1B,QAASG,GAAmB,OAC5B,YAAa,EACb,UAAW,IACb,EAGME,EAAQ,IAAIhG,GAAYqD,EAAaiC,EAAUE,CAAE,EAGnDS,EACAZ,EAAQ,QAAU,SACpBY,EAAe,MAAMC,GAAoB,GAI3C,IAAMC,EAAiCd,EAAQ,QAAU,QAAU,QAC/DA,EAAQ,QAAU,QAAUY,GAAgB,OAE1CG,EAAgBC,GAAe,UAAWF,CAAY,EAC5DG,GAAsBF,EAAc,EAAE,EAEtC,QAAQ,MAAM,EAGdG,GAAiB,QAAQ,EAEzB,IAAMC,EAAW,MAAMjH,GAAkB,CACvC,SAAU,GACV,YAAa,EACf,CAAC,EACKkH,EAAOrH,GAAWoH,CAAQ,EAChCC,EAAK,OACHtG,EAACuG,GAAA,CAAc,KAAMrB,EAAQ,MAAO,aAAcY,EAAc,eAAc,GAC5E,SAAA9F,EAACwG,GAAA,CACC,SAAAxG,EAACE,GAAA,CACC,QAAS,CAAE,GAAGgF,EAAS,SAAUO,EAAkB,MAAOC,GAAiB,MAAU,EACrF,MAAOG,EACP,SAAUV,EACV,kBAAmBE,EACrB,EACF,EACF,CACF,EAGA,IAAIoB,EAAe,GACblD,EAAU,IAAM,CACpB,GAAI,CAAAkD,EACJ,CAAAA,EAAe,GACf,GAAI,CAAEH,EAAK,QAAQ,CAAG,MAAQ,CAAC,CAC/B,GAAI,CAAED,EAAS,QAAQ,CAAG,MAAQ,CAAC,CACnCK,GAAmB,EACnBC,GAA0B,EAC1B,QAAQ,KAAK,CAAC,EAChB,EAEA,QAAQ,GAAG,SAAUpD,CAAO,EAC5B,QAAQ,GAAG,UAAWA,CAAO,EAG5B,WAAmB,gBAAkBA,EAGtC,MAAM,IAAI,QAAQ,IAAM,CAAC,CAAC,CAC5B,CArjBA,IAAAqD,GAAAC,EAAA,kBA8BAC,IACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,OChCA,OAAS,WAAAC,OAAe,YACxB,OAAS,mBAAAC,OAA+C,aAExD,IAAMC,GAAU,IAAIF,GAEpBE,GACG,KAAK,YAAY,EACjB,YAAY,mDAAmD,EAC/D,QAAQ,OAAO,EACf,OAAO,sBAAuB,YAAY,EAC1C,OAAO,4BAA6B,cAAe,WAAW,EAC9D,OAAO,kBAAmB,SAAS,EACnC,OAAO,mBAAoB,+BAA+B,EAC1D,OAAO,wBAAyB,oBAAqB,QAAQ,IAAI,CAAC,EAClE,OAAO,gBAAiB,wCAAyC,KAAK,EACtE,OAAO,oBAAqB,2BAA2B,EACvD,OAAO,iBAAkB,mCAAmC,EAC5D,OAAO,kBAAmB,2BAA4B,MAAM,EAC5D,SAAS,WAAY,gBAAgB,EACrC,OAAO,MAAOC,EAAQC,IAAS,CAC9B,GAAM,CAAE,SAAAC,CAAS,EAAI,KAAM,uCAC3B,MAAMA,EAAS,CACb,OAAAF,EACA,SAAUC,EAAK,SACf,MAAOA,EAAK,OAASH,GAAgBG,EAAK,QAAQ,EAClD,OAAQA,EAAK,OACb,QAASA,EAAK,QACd,WAAYA,EAAK,IACjB,KAAMA,EAAK,KACX,OAAQA,EAAK,OACb,SAAUA,EAAK,SACf,MAAOA,EAAK,KACd,CAAC,CACH,CAAC,EAEHF,GAAQ,MAAM",
6
+ "names": ["RGBA", "rgbToHex", "SyntaxStyle", "createContext", "useContext", "useState", "useEffect", "useRef", "useMemo", "jsx", "t", "hex", "buildTheme", "p", "getThemeIds", "THEMES", "a", "b", "getThemeColors", "themeId", "mode", "def", "luminance", "r", "g", "rs", "gs", "bs", "c", "s", "queryTerminalBackground", "resolve", "timeout", "cleanup", "buf", "onData", "data", "match", "parse", "wasRaw", "detectThemeFromEnv", "bg", "parts", "detectTerminalTheme", "_detectedMode", "rgb", "setTerminalBackground", "color", "restoreTerminalBackground", "generateSyntaxStyle", "theme", "ThemeProvider", "props", "initialMode", "initialThemeId", "setThemeIdState", "currentMode", "setCurrentMode", "setTheme", "syncBg", "setSyncBg", "customBg", "setCustomBgState", "syncBgRef", "customBgRef", "modeRef", "themeIdRef", "applyTerminalBg", "colors", "setThemeId", "id", "setMode", "m", "setCustomBg", "setSyncTerminalBg", "sync", "syntaxStyle", "ThemeContext", "useTheme", "ctx", "init_theme", "__esmMin", "createContext", "useContext", "jsx", "SDKProvider", "props", "SDKContext", "useSDK", "ctx", "init_sdk", "__esmMin", "createContext", "useContext", "useState", "useEffect", "useCallback", "useRef", "jsx", "jsxs", "getToastColor", "type", "theme", "ToastProvider", "props", "useTheme", "toasts", "setToasts", "idRef", "timersRef", "removeToast", "id", "prev", "t", "timer", "toast", "message", "duration", "dur", "DEFAULT_DURATION", "item", "next", "MAX_VISIBLE", "removed", "r", "ToastContext", "color", "icon", "TOAST_ICONS", "useToast", "ctx", "init_toast", "__esmMin", "init_theme", "fs", "path", "getCompletions", "input", "workingDir", "SLASH_COMMANDS", "c", "atIdx", "query", "results", "p", "MENTION_PROVIDERS", "fileQuery", "files", "getProjectFiles", "f", "parts", "tool", "subcommands", "TOOL_SUBCOMMANDS", "sub", "s", "pathResults", "getPathCompletions", "prefix", "getGhostText", "match", "pathCommands", "cmd", "partial", "readPathEntries", "dir", "entries", "base", "e", "a", "b", "lower", "skipDirs", "walk", "rel", "depth", "init_autocomplete", "__esmMin", "TextAttributes", "useState", "useRef", "useMemo", "useKeyboard", "execSync", "Fragment", "jsx", "jsxs", "readClipboard", "readClipboardImage", "base64", "InputArea", "props", "theme", "useTheme", "value", "setValue", "pendingImages", "setPendingImages", "selectedIdx", "setSelectedIdx", "dropdownOpen", "setDropdownOpen", "valueRef", "imageCountRef", "suggestions", "completions", "getCompletions", "ghost", "getGhostText", "showDropdown", "key", "i", "s", "text", "v", "img", "prev", "clip", "firstLine", "next", "isSlashCommand", "windowStart", "MAX_VISIBLE", "visibleSuggestions", "hasAbove", "hasBelow", "isSelected", "color", "init_input_area", "__esmMin", "init_theme", "init_autocomplete", "TextAttributes", "useTerminalDimensions", "jsx", "jsxs", "Home", "props", "theme", "useTheme", "dims", "w", "h", "shortDir", "home", "d", "subtitle", "version", "isSmall", "isMedium", "logo", "LOGO_COMPACT", "LOGO_FULL", "infoLines", "maxKeyLen", "k", "actions", "maxActionKey", "a", "line", "i", "key", "val", "action", "InputArea", "init_home", "__esmMin", "init_theme", "init_input_area", "TextAttributes", "Fragment", "jsx", "jsxs", "stripInlineMarkdown", "text", "RenderMarkdown", "props", "t", "syntaxStyle", "useTheme", "lines", "rendered", "i", "line", "codeLines", "codeBlock", "bulletMatch", "indent", "content", "numMatch", "formatTimestamp", "ts", "d", "h", "m", "ampm", "MessageList", "theme", "msg", "ToolCallRow", "icon", "TOOL_ICONS", "statusIcon", "statusColor", "shortName", "trimText", "s", "max", "first", "init_message_list", "__esmMin", "init_theme", "TextAttributes", "useState", "useKeyboard", "jsx", "jsxs", "PermissionPrompt", "props", "theme", "useTheme", "selected", "setSelected", "key", "s", "OPTIONS", "opt", "init_permission_prompt", "__esmMin", "init_theme", "useState", "useEffect", "jsx", "jsxs", "LoadingSpinner", "props", "theme", "useTheme", "frame", "setFrame", "interval", "f", "FRAMES", "init_loading_spinner", "__esmMin", "init_theme", "setTerminalTitle", "title", "resetTerminalTitle", "init_terminal_title", "__esmMin", "fs", "path", "os", "ensureDir", "CONV_DIR", "generateId", "now", "rand", "deriveTitle", "message", "clean", "createConversation", "provider", "model", "addMessage", "conv", "role", "content", "toolName", "saveConversation", "filePath", "loadConversation", "id", "match", "f", "listConversations", "files", "convs", "file", "data", "a", "b", "deleteConversation", "forkConversation", "idOrConv", "original", "forked", "m", "formatRelativeDate", "timestamp", "diff", "seconds", "minutes", "hours", "days", "init_history", "__esmMin", "ContextProviderRegistry", "TerminalContextProvider", "UrlContextProvider", "TreeContextProvider", "CodebaseContextProvider", "ClipboardContextProvider", "FileIncludeContextProvider", "getRegistry", "registry", "terminalProvider", "pushTerminalOutput", "output", "resolveContextProviders", "message", "workingDir", "reg", "expandedMessage", "appendSections", "trigger", "TRIGGERS", "idx", "afterTrigger", "endIdx", "arg", "fullTrigger", "providerName", "provider", "result", "hasContextMentions", "t", "init_context_providers", "__esmMin", "useState", "useRef", "useEffect", "TextAttributes", "useKeyboard", "fs", "path", "os", "execSync", "jsx", "jsxs", "detectShellCommand", "input", "trimmed", "firstWord", "SHELL_COMMANDS", "InterruptPrompt", "props", "theme", "useTheme", "selected", "setSelected", "options", "key", "s", "preview", "opt", "i", "SessionView", "sdk", "useSDK", "setMode", "toast", "useToast", "setTerminalTitle", "messages", "setMessages", "streamingText", "setStreamingText", "streamingTextRef", "isStreaming", "setIsStreaming", "activeTool", "setActiveTool", "pendingPermission", "setPendingPermission", "pendingInterrupt", "setPendingInterrupt", "queuedMessagesRef", "totalInputRef", "totalOutputRef", "msgIdCounterRef", "conversationRef", "backgroundJobsRef", "bgIdCounterRef", "createConversation", "addMessage", "role", "content", "extra", "msg", "prev", "updateMessage", "id", "updates", "m", "loadStoredConfig", "configPath", "saveConfigKey", "value", "configDir", "config", "loadProjectSettings", "settingsPath", "claudePath", "runBackgroundJob", "prompt", "job", "bgResult", "bgCallbacks", "token", "error", "err", "handleSlashCommand", "cmd", "command", "args", "arg", "getDefaultModel", "defaultModel", "currentMode", "resolved", "setParts", "valParts", "lines", "k", "v", "levels", "settings", "allow", "deny", "hooksPath", "hooks", "keys", "rulesDir", "files", "f", "convs", "listConversations", "c", "date", "formatRelativeDate", "msgCount", "conv", "loadConversation", "viewMsgs", "prefix", "sourceConv", "forked", "forkConversation", "deleteConversation", "jobs", "j", "elapsed", "result", "btwMsg", "btwResult", "btwCallbacks", "fullLogout", "prov", "masked", "envVars", "hasEnvKey", "name", "checks", "envKey", "hasCdoing", "hasClaude", "runningJobs", "cdoingDir", "runShellCommand", "shellCmd", "output", "errorMsg", "pushTerminalOutput", "handleInterrupt", "text", "images", "partialResponse", "doSendMessage", "handleQueue", "processQueue", "next", "sendMessage", "shellParts", "target", "initialMessageSentRef", "expandedText", "hasContextMentions", "resolveContextProviders", "currentToolId", "turnInput", "callbacks", "current", "description", "_name", "isError", "summary", "usage", "pct", "MessageList", "PermissionPrompt", "decision", "LoadingSpinner", "InputArea", "init_session", "__esmMin", "init_message_list", "init_input_area", "init_permission_prompt", "init_loading_spinner", "init_sdk", "init_theme", "init_toast", "init_terminal_title", "init_history", "init_context_providers", "TextAttributes", "Fragment", "jsx", "jsxs", "StatusBar", "props", "theme", "useTheme", "home", "shortDir", "tokenInfo", "pct", "contextBar", "init_status_bar", "__esmMin", "init_theme", "TextAttributes", "jsx", "jsxs", "SessionHeader", "props", "theme", "useTheme", "inTok", "outTok", "pct", "pctColor", "statusColor", "left", "init_session_header", "__esmMin", "init_theme", "jsx", "jsxs", "SessionFooter", "props", "theme", "useTheme", "home", "shortDir", "init_session_footer", "__esmMin", "init_theme", "TextAttributes", "jsx", "jsxs", "trunc", "str", "max", "bar", "pct", "len", "filled", "Sidebar", "props", "theme", "useTheme", "home", "dir", "pctColor", "inTok", "outTok", "statusColor", "lines", "sep", "header", "title", "row", "label", "value", "fg", "padded", "W", "shortcut", "key", "f", "name", "diff", "line", "i", "init_sidebar", "__esmMin", "init_theme", "TextAttributes", "useState", "useKeyboard", "jsx", "jsxs", "DialogModel", "props", "theme", "useTheme", "models", "MODELS", "selected", "setSelected", "m", "key", "s", "model", "i", "init_dialog_model", "__esmMin", "init_theme", "TextAttributes", "useState", "useMemo", "useKeyboard", "jsx", "jsxs", "fuzzyMatch", "query", "text", "lower", "q", "qi", "i", "DialogCommand", "props", "theme", "useTheme", "setQuery", "selected", "setSelected", "filtered", "COMMANDS", "cmd", "groups", "map", "list", "flatList", "clampedSelected", "key", "s", "flatIndex", "rows", "category", "cmds", "isSel", "shortcutText", "init_dialog_command", "__esmMin", "init_theme", "TextAttributes", "useState", "useKeyboard", "jsx", "jsxs", "buildLines", "lines", "entry", "KEYBOARD_SHORTCUTS", "SLASH_COMMANDS", "AT_MENTIONS", "DialogHelp", "props", "theme", "useTheme", "scrollOffset", "setScrollOffset", "maxOffset", "ALL_LINES", "PAGE_SIZE", "key", "s", "visibleLines", "keyColWidth", "line", "i", "paddedKey", "init_dialog_help", "__esmMin", "init_theme", "TextAttributes", "useState", "useMemo", "useKeyboard", "useTerminalDimensions", "Fragment", "jsx", "jsxs", "DialogTheme", "props", "theme", "themeId", "mode", "customBg", "setThemeId", "setMode", "setCustomBg", "useTheme", "t", "dims", "initialThemeId", "initialMode", "initialCustomBg", "themeIds", "getThemeIds", "section", "setSection", "modeSelected", "setModeSelected", "bgInput", "setBgInput", "query", "setQuery", "selected", "setSelected", "filtered", "q", "id", "def", "THEMES", "clampedSelected", "maxVisible", "scrollOffset", "visibleItems", "modeOptions", "nextSection", "s", "idx", "SECTIONS", "isValidHex", "key", "next", "newQ", "q2", "first", "opt", "i", "isSel", "isActive", "isCurrent", "init_dialog_theme", "__esmMin", "init_theme", "TextAttributes", "useState", "useMemo", "useKeyboard", "useTerminalDimensions", "jsx", "jsxs", "SessionBrowser", "props", "theme", "useTheme", "dims", "conversations", "setConversations", "listConversations", "selected", "setSelected", "confirmDelete", "setConfirmDelete", "viewMode", "setViewMode", "viewScroll", "setViewScroll", "maxVisible", "scrollOffset", "visibleConvs", "key", "s", "conv", "msgs", "m", "deleteConversation", "updated", "forkConversation", "visibleMsgs", "total", "i", "prefix", "color", "content", "isSelected", "date", "formatRelativeDate", "msgCount", "title", "init_session_browser", "__esmMin", "init_theme", "init_history", "fs", "path", "os", "execSync", "TextAttributes", "useState", "useRef", "useEffect", "useKeyboard", "Fragment", "jsx", "jsxs", "openBrowser", "url", "cmd", "SetupWizard", "props", "theme", "useTheme", "step", "setStep", "selectedProvider", "setSelectedProvider", "selectedAuth", "setSelectedAuth", "selectedModel", "setSelectedModel", "authMethod", "setAuthMethod", "chosenProviderId", "setChosenProviderId", "chosenModelId", "setChosenModelId", "apiKeyInput", "setApiKeyInput", "showKey", "setShowKey", "error", "setError", "oauthUrl", "setOauthUrl", "oauthVerifier", "setOauthVerifier", "oauthCodeInput", "setOauthCodeInput", "showCode", "setShowCode", "oauthError", "setOauthError", "exchangingRef", "provider", "PROVIDERS", "models", "OAUTH_MODELS", "MODELS", "generateOAuthUrl", "codeVerifier", "key", "s", "p", "AUTH_METHODS", "auth", "m", "saveAndComplete", "code", "exchangeOAuthCode", "tokens", "err", "prov", "model", "apiKey", "configDir", "configPath", "config", "isAnthropic", "total", "stepLabel", "i", "a", "KEY_URLS", "ENV_VARS", "init_setup_wizard", "__esmMin", "init_theme", "TextAttributes", "useState", "useKeyboard", "useTerminalDimensions", "jsx", "jsxs", "DialogStatus", "props", "theme", "useTheme", "sdk", "useSDK", "dims", "scrollOffset", "setScrollOffset", "allTools", "toolNames", "tool", "sections", "name", "lines", "section", "label", "value", "maxVisible", "key", "s", "visible", "line", "i", "init_dialog_status", "__esmMin", "init_theme", "init_sdk", "app_exports", "__export", "startTUI", "fs", "path", "os", "createRoot", "useKeyboard", "useTerminalDimensions", "createCliRenderer", "TextAttributes", "useState", "useRef", "useCallback", "ToolRegistry", "PermissionManager", "PermissionMode", "registerAllTools", "AgentRunner", "getDefaultModel", "getApiKeyEnvVar", "jsx", "jsxs", "AppShell", "props", "dims", "theme", "themeId", "setMode", "setThemeId", "useTheme", "t", "route", "setRoute", "dialog", "setDialog", "status", "setStatus", "provider", "setProvider", "model", "setModel", "workingDir", "setWorkingDir", "tokens", "setTokens", "contextPercent", "setContextPercent", "activeTool", "setActiveTool", "showSidebar", "setShowSidebar", "agentRef", "registryRef", "pmRef", "initialMessageRef", "permissionResolveRef", "pendingPermission", "setPendingPermission", "requestPermission", "toolName", "message", "resolve", "decision", "rebuildAgent", "newProvider", "newModel", "apiKey", "resolvedKey", "envVar", "configPath", "modelConfig", "newAgent", "handleSetWorkingDir", "dir", "key", "cleanup", "d", "s", "handleResumeSession", "_conv", "SessionHeader", "SDKProvider", "SessionBrowser", "SetupWizard", "config", "Home", "text", "images", "SessionView", "i", "o", "Sidebar", "SessionFooter", "StatusBar", "DialogModel", "m", "DialogCommand", "commandId", "exit", "DialogHelp", "DialogTheme", "DialogStatus", "options", "registry", "permMode", "pm", "_toolName", "_message", "resolvedApiKey", "resolvedProvider", "resolvedModel", "resolvedBaseUrl", "storedConfig", "agent", "detectedMode", "detectTerminalTheme", "resolvedMode", "initialColors", "getThemeColors", "setTerminalBackground", "setTerminalTitle", "renderer", "root", "ThemeProvider", "ToastProvider", "isCleaningUp", "resetTerminalTitle", "restoreTerminalBackground", "init_app", "__esmMin", "init_theme", "init_sdk", "init_toast", "init_home", "init_session", "init_status_bar", "init_session_header", "init_session_footer", "init_sidebar", "init_dialog_model", "init_dialog_command", "init_dialog_help", "init_dialog_theme", "init_session_browser", "init_setup_wizard", "init_dialog_status", "init_terminal_title", "Command", "getDefaultModel", "program", "prompt", "opts", "startTUI"]
7
+ }