openmagic 0.34.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +126 -2
- package/dist/cli.js.map +1 -1
- package/dist/toolbar/index.global.js +38 -38
- package/dist/toolbar/index.global.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/proxy.ts","../src/security.ts","../src/server.ts","../src/config.ts","../src/filesystem.ts","../src/llm/registry.ts","../src/llm/prompts.ts","../src/llm/openai.ts","../src/llm/anthropic.ts","../src/llm/google.ts","../src/llm/proxy.ts","../src/detect.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { resolve, join } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\n\n// Suppress http-proxy deprecation warning noise\nconst origEmitWarning = process.emitWarning;\nprocess.emitWarning = function (warning: any, ...args: any[]) {\n if (typeof warning === \"string\" && warning.includes(\"util._extend\")) return;\n return origEmitWarning.call(process, warning, ...args);\n} as typeof process.emitWarning;\n\n// Global error handlers — prevent silent crashes\nprocess.on(\"unhandledRejection\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Unhandled error:\"), (err as Error)?.message || err);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Fatal error:\"), err.message);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n process.exit(1);\n});\n\n// Track child processes for cleanup\nconst childProcesses: ChildProcess[] = [];\nlet lastDetectedPort: number | null = null; // Port detected from dev server output\nimport { createProxyServer } from \"./proxy.js\";\nimport { generateSessionToken } from \"./security.js\";\nimport {\n detectDevServer,\n findAvailablePort,\n isPortOpen,\n detectDevScripts,\n getProjectName,\n checkDependenciesInstalled,\n verifyPortOwnership,\n} from \"./detect.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { cleanupBackups } from \"./filesystem.js\";\n\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\n\nfunction ask(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nfunction waitForPort(\n port: number,\n timeoutMs: number = 60000,\n shouldAbort?: () => boolean\n): Promise<boolean> {\n const start = Date.now();\n return new Promise((resolve) => {\n const check = async () => {\n if (shouldAbort?.()) {\n resolve(false);\n return;\n }\n if (await isPortOpen(port)) {\n resolve(true);\n return;\n }\n const elapsed = Date.now() - start;\n if (elapsed > timeoutMs) {\n resolve(false);\n return;\n }\n // Aggressive early polling, then back off\n const interval = elapsed < 10000 ? 300 : 1000;\n setTimeout(check, interval);\n };\n check();\n });\n}\n\nfunction runCommand(cmd: string, args: string[], cwd: string = process.cwd()): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: true,\n });\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.on(\"error\", () => resolve(false));\n child.on(\"close\", (code) => resolve(code === 0));\n } catch {\n resolve(false);\n }\n });\n}\n\nasync function healthCheck(proxyPort: number, _targetPort: number): Promise<void> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n\n // Check OpenMagic's own health endpoint (not the app — app may require auth)\n const res = await fetch(`http://127.0.0.1:${proxyPort}/__openmagic__/health`, {\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n if (res.ok) {\n console.log(chalk.green(\" ✓ Toolbar ready.\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Proxy started but toolbar health check failed.\"));\n }\n } catch {\n console.log(\n chalk.yellow(\" ⚠ Could not verify proxy. The dev server may still be starting.\")\n );\n console.log(\n chalk.dim(\" Try refreshing the page in a few seconds.\")\n );\n }\n console.log(\"\");\n}\n\n// Detect common dev server errors and show hints\nfunction formatDevServerLine(line: string): string {\n const trimmed = line.trim();\n if (!trimmed) return \"\";\n\n // Detect error patterns and add context\n if (trimmed.startsWith(\"Error:\") || trimmed.includes(\"ModuleNotFoundError\") || trimmed.includes(\"Can't resolve\")) {\n return chalk.red(` │ ${trimmed}`);\n }\n if (trimmed.includes(\"EADDRINUSE\") || trimmed.includes(\"address already in use\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Port is already in use. Stop the other process or use --port <different-port>\");\n }\n if (trimmed.includes(\"EACCES\") || trimmed.includes(\"permission denied\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Permission denied. Try a different port or check file permissions.\");\n }\n if (trimmed.includes(\"Cannot find module\") || trimmed.includes(\"MODULE_NOT_FOUND\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Missing dependency. Try running npm install.\");\n }\n\n return chalk.dim(` │ ${trimmed}`);\n}\n\nconst program = new Command();\n\nprogram\n .name(\"openmagic\")\n .description(\"AI-powered coding toolbar for any web application\")\n .version(VERSION)\n .option(\"-p, --port <port>\", \"Dev server port to proxy\", \"\")\n .option(\n \"-l, --listen <port>\",\n \"Port for the OpenMagic proxy\",\n \"4567\"\n )\n .option(\n \"-r, --root <paths...>\",\n \"Project root directories (defaults to cwd)\"\n )\n .option(\"--no-open\", \"Don't auto-open browser\")\n .option(\"--host <host>\", \"Dev server host\", \"localhost\")\n .action(async (opts) => {\n console.log(\"\");\n console.log(\n \" 🪄 \" + chalk.bold.hex(\"#6c5ce7\")(\"OpenMagic\") + chalk.dim(` v${VERSION}`) + \" ✨\"\n );\n console.log(chalk.dim(\" AI coding toolbar for any web app\"));\n console.log(\"\");\n\n let targetPort: number;\n let targetHost = opts.host;\n\n if (opts.port) {\n // User specified a port\n targetPort = parseInt(opts.port, 10);\n const isRunning = await isPortOpen(targetPort);\n if (!isRunning) {\n // Port specified but not running — offer to start it\n const started = await offerToStartDevServer(targetPort);\n if (!started) {\n process.exit(1);\n }\n // Use port detected from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\n const recheck = await detectDevServer();\n if (recheck) { targetPort = recheck.port; targetHost = recheck.host; }\n }\n }\n } else {\n // Auto-detect running dev server\n console.log(chalk.dim(\" Scanning for dev server...\"));\n const detected = await detectDevServer();\n\n if (detected && detected.fromScripts) {\n // Trusted detection via package.json scripts\n targetPort = detected.port;\n targetHost = detected.host;\n } else if (detected && !detected.fromScripts) {\n // Found a port via generic scan — confirm with user\n const answer = await ask(\n chalk.yellow(` Found a server on port ${detected.port}. Is this your project's dev server? `) +\n chalk.dim(\"(y/n) \")\n );\n if (answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\" || answer === \"\") {\n targetPort = detected.port;\n targetHost = detected.host;\n } else {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n process.exit(0);\n }\n } else {\n // No server running — try to detect and start from package.json\n const started = await offerToStartDevServer();\n if (!started) {\n process.exit(1);\n }\n // Use port from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\n const redetected = await detectDevServer();\n if (!redetected) {\n console.log(chalk.red(\" ✗ Could not detect the dev server after starting.\"));\n console.log(chalk.dim(\" Try specifying the port: npx openmagic --port 3000\"));\n console.log(\"\");\n process.exit(1);\n }\n targetPort = redetected.port;\n targetHost = redetected.host;\n }\n }\n }\n\n console.log(\n chalk.green(` ✓ Dev server running at ${targetHost}:${targetPort}`)\n );\n\n // Set up roots\n const roots = (opts.root || [process.cwd()]).map((r: string) =>\n resolve(r)\n );\n\n // Save roots to config\n const config = loadConfig();\n saveConfig({ ...config, roots, targetPort });\n\n // Generate session token\n generateSessionToken();\n\n // Find available port (single port — proxy + toolbar + WS all on same origin)\n let proxyPort = parseInt(opts.listen, 10);\n while (await isPortOpen(proxyPort)) {\n proxyPort++;\n if (proxyPort > parseInt(opts.listen, 10) + 100) {\n console.log(chalk.red(\" Could not find an available port.\"));\n process.exit(1);\n }\n }\n\n // Single server: proxy + toolbar + WebSocket all on one port\n const proxyServer = createProxyServer(targetHost, targetPort!, roots);\n\n proxyServer.listen(proxyPort, \"localhost\", async () => {\n const proxyUrl = `http://localhost:${proxyPort}`;\n console.log(\"\");\n console.log(chalk.bold.green(\" Ready!\"));\n console.log(\"\");\n console.log(\n chalk.bold(\" → \") + chalk.bold.underline.cyan(proxyUrl)\n );\n console.log(\"\");\n\n await healthCheck(proxyPort, targetPort!);\n\n console.log(chalk.dim(\" Press Ctrl+C to stop.\"));\n console.log(\n chalk.dim(\" Errors below are from your dev server, not OpenMagic.\")\n );\n console.log(\"\");\n\n if (opts.open !== false) {\n open(`http://localhost:${proxyPort}`).catch(() => {});\n }\n });\n\n // Graceful shutdown\n const shutdown = () => {\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n cleanupBackups();\n proxyServer.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n });\n\n// --- Smart Dev Server Start ---\n\nasync function offerToStartDevServer(expectedPort?: number): Promise<boolean> {\n const projectName = getProjectName();\n const scripts = detectDevScripts();\n\n if (scripts.length === 0) {\n // Check for plain HTML project (index.html without package.json scripts)\n const htmlPath = join(process.cwd(), \"index.html\");\n if (existsSync(htmlPath)) {\n console.log(\n chalk.dim(\" No dev scripts found, but index.html detected.\")\n );\n console.log(\"\");\n const answer = await ask(\n chalk.white(\" Serve this directory as a static site? \") + chalk.dim(\"(Y/n) \")\n );\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n return false;\n }\n\n // Start a built-in static file server using Node's http module\n const staticPort = expectedPort || 8080;\n console.log(chalk.dim(` Starting static server on port ${staticPort}...`));\n\n const staticChild = spawn(\"node\", [\"-e\", `\n const http = require(\"http\");\n const fs = require(\"fs\");\n const path = require(\"path\");\n const mimes = {\".html\":\"text/html\",\".css\":\"text/css\",\".js\":\"application/javascript\",\".json\":\"application/json\",\".png\":\"image/png\",\".jpg\":\"image/jpeg\",\".svg\":\"image/svg+xml\",\".ico\":\"image/x-icon\",\".gif\":\"image/gif\",\".woff2\":\"font/woff2\",\".woff\":\"font/woff\"};\n http.createServer((req, res) => {\n let p = path.join(${JSON.stringify(process.cwd())}, req.url === \"/\" ? \"/index.html\" : req.url);\n try { p = decodeURIComponent(p); } catch {}\n fs.readFile(p, (err, data) => {\n if (err) { res.writeHead(404); res.end(\"Not found\"); return; }\n const ext = path.extname(p).toLowerCase();\n res.writeHead(200, {\"Content-Type\": mimes[ext] || \"application/octet-stream\"});\n res.end(data);\n });\n }).listen(${staticPort}, \"localhost\", () => console.log(\"Static server ready on port ${staticPort}\"));\n `], {\n cwd: process.cwd(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: false,\n });\n\n childProcesses.push(staticChild);\n staticChild.stdout?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().trim().split(\"\\n\")) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n // Wait for it to start\n const up = await waitForPort(staticPort, 5000);\n if (up) {\n lastDetectedPort = staticPort;\n console.log(chalk.green(` ✓ Static server running on port ${staticPort}`));\n return true;\n }\n console.log(chalk.red(\" ✗ Failed to start static server.\"));\n return false;\n }\n\n console.log(\n chalk.yellow(\" ⚠ No dev server detected and no dev scripts found.\")\n );\n console.log(\"\");\n console.log(chalk.white(\" Start your dev server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // Check if dependencies are installed\n const deps = checkDependenciesInstalled();\n if (!deps.installed) {\n console.log(\n chalk.yellow(\" ⚠ node_modules/ not found. Dependencies need to be installed.\")\n );\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Run `) +\n chalk.cyan(deps.installCommand) +\n chalk.white(\"? \") +\n chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(` Run ${deps.installCommand} manually, then try again.`));\n console.log(\"\");\n return false;\n }\n\n console.log(\"\");\n console.log(chalk.dim(` Installing dependencies with ${deps.packageManager}...`));\n\n const [installCmd, ...installArgs] = deps.installCommand.split(\" \");\n const installed = await runCommand(installCmd, installArgs);\n\n if (!installed) {\n console.log(chalk.red(\" ✗ Dependency installation failed.\"));\n console.log(chalk.dim(` Try running ${deps.installCommand} manually.`));\n console.log(\"\");\n return false;\n }\n\n console.log(chalk.green(\" ✓ Dependencies installed.\"));\n console.log(\"\");\n }\n\n // Pick the best script\n let chosen = scripts[0];\n if (scripts.length === 1) {\n // Only one option\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n chalk.white(` in ${projectName}`) +\n chalk.dim(` (${chosen.framework})`)\n );\n console.log(chalk.dim(` → ${chosen.command}`));\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Start it now? `) + chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n } else {\n // Multiple scripts — let user pick\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found ${scripts.length} dev scripts in ${projectName}:`)\n );\n console.log(\"\");\n\n scripts.forEach((s, i) => {\n console.log(\n chalk.cyan(` ${i + 1}) `) +\n chalk.white(`npm run ${s.name}`) +\n chalk.dim(` — ${s.framework} (port ${s.defaultPort})`)\n );\n console.log(chalk.dim(` ${s.command}`));\n });\n\n console.log(\"\");\n const answer = await ask(\n chalk.white(` Which one to start? `) +\n chalk.dim(`(1-${scripts.length}, or n to cancel) `)\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\" || answer === \"\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n\n const idx = parseInt(answer, 10) - 1;\n if (idx < 0 || idx >= scripts.length || isNaN(idx)) {\n // Default to first\n chosen = scripts[0];\n } else {\n chosen = scripts[idx];\n }\n }\n\n // Start the dev server\n let port = expectedPort || chosen.defaultPort;\n\n // Check if the expected port is already occupied by another process\n let portChanged = false;\n if (await isPortOpen(port)) {\n const owned = verifyPortOwnership(port, process.cwd());\n if (owned === true) {\n // Port is occupied by this project — already running\n console.log(chalk.green(` ✓ Dev server already running on port ${port}`));\n lastDetectedPort = port;\n return true;\n }\n // Port is taken by something else — find a free one\n const altPort = await findAvailablePort(port + 1);\n console.log(\"\");\n console.log(\n chalk.yellow(` ⚠ Port ${port} is already in use by another process.`)\n );\n console.log(\n chalk.dim(` Starting on port ${altPort} instead.`)\n );\n port = altPort;\n portChanged = true;\n }\n\n console.log(\"\");\n console.log(\n chalk.dim(` Starting `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n (portChanged ? chalk.dim(` (port ${port})`) : \"\") +\n chalk.dim(\"...\")\n );\n\n // Use the correct package manager run command\n const depsInfo = checkDependenciesInstalled();\n const runCmd = depsInfo.packageManager === \"yarn\" ? \"yarn\" :\n depsInfo.packageManager === \"pnpm\" ? \"pnpm\" :\n depsInfo.packageManager === \"bun\" ? \"bun\" : \"npm\";\n const runArgs = runCmd === \"npm\" ? [\"run\", chosen.name] : [chosen.name];\n\n // If port was changed due to conflict, pass --port to frameworks that accept it\n const PORT_FLAG_FRAMEWORKS = new Set([\"Next.js\", \"Vite\", \"Angular\", \"Vue CLI\", \"Astro\", \"Remix\", \"SvelteKit\", \"Nuxt\", \"Create React App\", \"Gatsby\", \"Parcel\", \"Webpack\"]);\n if (portChanged && PORT_FLAG_FRAMEWORKS.has(chosen.framework)) {\n if (runCmd === \"npm\") {\n runArgs.push(\"--\", \"--port\", String(port));\n } else {\n runArgs.push(\"--port\", String(port));\n }\n }\n\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(runCmd, runArgs, {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: {\n ...process.env,\n PORT: String(port),\n BROWSER: \"none\",\n BROWSER_NONE: \"true\",\n },\n });\n } catch (e: unknown) {\n console.log(chalk.red(` ✗ Failed to start: ${(e as Error).message}`));\n return false;\n }\n\n childProcesses.push(child);\n let childExited = false;\n\n child.on(\"error\", (err) => {\n childExited = true;\n console.log(chalk.red(`\\n ✗ Failed to start: ${err.message}`));\n });\n\n child.on(\"exit\", (code) => {\n childExited = true;\n if (code !== null && code !== 0) {\n console.log(chalk.red(`\\n ✗ Dev server exited with code ${code}`));\n }\n });\n\n // Clean up all child processes on exit\n const cleanup = () => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGTERM\"); } catch {}\n }\n setTimeout(() => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGKILL\"); } catch {}\n }\n }, 3000);\n };\n process.once(\"exit\", cleanup);\n process.once(\"SIGINT\", cleanup);\n process.once(\"SIGTERM\", cleanup);\n\n // Wait for the port to open via TCP polling\n console.log(\n chalk.dim(` Waiting for dev server on port ${port}...`)\n );\n\n const isUp = await waitForPort(port, 60000, () => childExited);\n\n if (isUp) {\n lastDetectedPort = port;\n console.log(\"\");\n return true;\n }\n\n // Port didn't open but process is still running — scan nearby ports\n if (!childExited) {\n const scanPorts = [port, 3000, 3001, 3002, 5173, 5174, 4200, 8080, 8000, 4000, 1234, 4321, 3333, 8081]\n .filter((p, i, a) => a.indexOf(p) === i); // dedupe\n for (const scanPort of scanPorts) {\n if (await isPortOpen(scanPort)) {\n const owned = verifyPortOwnership(scanPort, process.cwd());\n if (owned === false) continue;\n console.log(\n chalk.green(`\\n ✓ Dev server found on port ${scanPort}.`)\n );\n lastDetectedPort = scanPort;\n return true;\n }\n }\n }\n\n if (childExited) {\n console.log(\n chalk.red(` ✗ Dev server failed to start.`)\n );\n console.log(\"\");\n\n // Check for Node.js version mismatch\n try {\n const pkgPath = join(process.cwd(), \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n if (pkg.engines?.node) {\n console.log(chalk.yellow(` This project requires Node.js ${pkg.engines.node}`));\n console.log(chalk.dim(` You are running Node.js ${process.version}`));\n console.log(\"\");\n }\n }\n } catch {}\n\n console.log(chalk.white(\" Options:\"));\n console.log(chalk.dim(\" 1. Fix the error above and try again\"));\n console.log(chalk.dim(\" 2. Start the server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // All detection methods exhausted\n console.log(\n chalk.yellow(`\\n ⚠ Could not find the dev server after 60s.`)\n );\n console.log(chalk.dim(` Check the output above for errors.`));\n console.log(chalk.dim(` Or start the server manually, then run:`));\n console.log(chalk.cyan(` npx openmagic --port <your-port>`));\n console.log(\"\");\n return false;\n}\n\nprogram.parse();\n","import http from \"node:http\";\nimport httpProxy from \"http-proxy\";\nimport { getSessionToken } from \"./security.js\";\nimport { attachOpenMagic } from \"./server.js\";\n\n/**\n * Create a single-port proxy server that:\n * 1. Serves /__openmagic__/* (toolbar bundle, health, WebSocket)\n * 2. Proxies everything else to the dev server\n * 3. Injects the toolbar script into HTML responses\n */\nexport function createProxyServer(\n targetHost: string,\n targetPort: number,\n roots: string[]\n): http.Server {\n const proxy = httpProxy.createProxyServer({\n target: `http://${targetHost}:${targetPort}`,\n selfHandleResponse: true,\n // ws: false — we handle WebSocket upgrades manually in server.on(\"upgrade\")\n });\n\n const token = getSessionToken();\n\n // Strip Accept-Encoding on HTML requests so upstream sends uncompressed (enables streaming injection)\n // Only apply to regular HTTP requests, not WebSocket upgrades\n proxy.on(\"proxyReq\", (proxyReq, req) => {\n const accept = req.headers.accept || \"\";\n // Only strip for requests that might return HTML (not for API calls, assets, WS upgrades)\n if (accept.includes(\"text/html\") || accept.includes(\"*/*\") || !accept) {\n proxyReq.removeHeader(\"Accept-Encoding\");\n }\n });\n\n proxy.on(\"proxyRes\", (proxyRes, req, res) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isHtml = contentType.includes(\"text/html\");\n const status = proxyRes.statusCode || 200;\n\n if (!isHtml && status < 400) {\n // Non-HTML success: pass through unchanged\n res.writeHead(status, proxyRes.headers);\n proxyRes.on(\"error\", () => { try { res.end(); } catch {} });\n proxyRes.pipe(res);\n return;\n }\n\n if (isHtml) {\n // HTML response: stream through and append toolbar script\n const headers = { ...proxyRes.headers };\n delete headers[\"content-length\"];\n delete headers[\"content-encoding\"];\n delete headers[\"transfer-encoding\"];\n delete headers[\"content-security-policy\"];\n delete headers[\"content-security-policy-report-only\"];\n delete headers[\"x-content-security-policy\"];\n delete headers[\"etag\"];\n delete headers[\"last-modified\"];\n headers[\"cache-control\"] = \"no-store\";\n\n res.writeHead(status, headers);\n proxyRes.on(\"error\", () => { try { res.end(buildInjectionScript(token)); } catch {} });\n proxyRes.pipe(res, { end: false });\n proxyRes.on(\"end\", () => {\n res.end(buildInjectionScript(token));\n });\n return;\n }\n\n // Non-HTML error (4xx/5xx) — wrap in HTML with toolbar so user can still interact\n const chunks: Buffer[] = [];\n let totalSize = 0;\n proxyRes.on(\"data\", (c: Buffer) => { if (totalSize < 16384) { chunks.push(c); totalSize += c.length; } });\n proxyRes.on(\"error\", () => { try { res.end(); } catch {} });\n proxyRes.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString(\"utf-8\").slice(0, 2000);\n const toolbarScript = buildInjectionScript(token);\n res.writeHead(status, { \"Content-Type\": \"text/html\", \"Cache-Control\": \"no-store\" });\n res.end(`<html><head><meta charset=\"utf-8\"><title>Error ${status}</title></head>\n<body style=\"font-family:system-ui;padding:40px;background:#0f0f1e;color:#e0e0e0;\">\n<h2 style=\"color:#e94560;\">Error ${status}</h2>\n<pre style=\"color:#888;white-space:pre-wrap;max-width:800px;overflow:auto;font-size:13px;\">${body.replace(/</g,\"<\")}</pre>\n<p style=\"color:#555;font-size:13px;\">This error is from your dev server, not OpenMagic. The toolbar is available below.</p>\n${toolbarScript}\n</body></html>`);\n });\n });\n\n proxy.on(\"error\", (err, _req, res) => {\n if (res instanceof http.ServerResponse && !res.headersSent) {\n const toolbarScript = buildInjectionScript(token);\n res.writeHead(502, { \"Content-Type\": \"text/html\" });\n res.end(\n `<html><body style=\"font-family:system-ui;padding:40px;background:#1a1a2e;color:#e0e0e0;\">\n <h2 style=\"color:#e94560;\">OpenMagic — Cannot connect to dev server</h2>\n <p>Could not reach <code>${targetHost}:${targetPort}</code></p>\n <p style=\"color:#888;\">Make sure your dev server is running, then refresh this page.</p>\n <p style=\"color:#666;font-size:13px;\">${err.message}</p>\n ${toolbarScript}\n </body></html>`\n );\n } else if (res && typeof (res as any).destroy === \"function\") {\n // WebSocket socket error — destroy cleanly\n try { (res as any).destroy(); } catch {}\n }\n });\n\n // Shared references — set after server creation\n let omHandle: ((req: http.IncomingMessage, res: http.ServerResponse) => boolean) | null = null;\n let omUpgrade: ((req: http.IncomingMessage, socket: any, head: Buffer) => boolean) | null = null;\n\n const server = http.createServer((req, res) => {\n if (omHandle && omHandle(req, res)) return;\n proxy.web(req, res);\n });\n\n // Attach OpenMagic endpoints to THIS server (same port, noServer WSS)\n const om = attachOpenMagic(server, roots);\n omHandle = om.handleRequest;\n omUpgrade = om.handleUpgrade;\n\n // Single upgrade handler — OpenMagic WS first, everything else to dev server\n server.on(\"upgrade\", (req, socket, head) => {\n // Try OpenMagic WebSocket first\n if (omUpgrade && omUpgrade(req, socket, head)) return;\n // Everything else (HMR, hot reload, etc.) forwarded to dev server\n proxy.ws(req, socket, head);\n });\n\n return server;\n}\n\n// Same-origin injection — toolbar.js and WS served from THIS server\nfunction buildInjectionScript(token: string): string {\n return `<script src=\"/__openmagic__/toolbar.js?v=${Date.now()}\" data-openmagic=\"true\" data-openmagic-token=\"${token}\" defer></script>`;\n}\n","import { randomBytes } from \"node:crypto\";\n\nlet sessionToken: string | null = null;\n\nexport function generateSessionToken(): string {\n sessionToken = randomBytes(32).toString(\"hex\");\n return sessionToken;\n}\n\nexport function getSessionToken(): string {\n if (!sessionToken) {\n return generateSessionToken();\n }\n return sessionToken;\n}\n\nexport function validateToken(token: string): boolean {\n return token === sessionToken;\n}\n","import http from \"node:http\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { WebSocketServer, WebSocket } from \"ws\";\nimport { validateToken } from \"./security.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { readFileSafe, writeFileSafe, listFiles, getProjectTree, grepFiles, getBackupForFile, cleanupBackups } from \"./filesystem.js\";\nimport type {\n WsMessage,\n HandshakePayload,\n FsReadPayload,\n FsWritePayload,\n FsListPayload,\n LlmChatPayload,\n ConfigSetPayload,\n OpenMagicConfig,\n} from \"./shared-types.js\";\nimport { handleLlmChat } from \"./llm/proxy.js\";\nimport { MODEL_REGISTRY } from \"./llm/registry.js\";\n\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ── Server-side log buffer ──\nconst MAX_SERVER_LOGS = 200;\nconst serverLogs: { level: string; msg: string; ts: number }[] = [];\n\nfunction captureServerLog(level: string, ...args: any[]) {\n const msg = args.map(a => {\n try { return typeof a === \"object\" ? JSON.stringify(a).slice(0, 500) : String(a); }\n catch { return String(a); }\n }).join(\" \");\n serverLogs.push({ level, msg, ts: Date.now() });\n if (serverLogs.length > MAX_SERVER_LOGS) serverLogs.shift();\n}\n\n// Intercept console to buffer server logs\nconst _origLog = console.log, _origWarn = console.warn, _origErr = console.error, _origInfo = console.info;\nconsole.log = (...a: any[]) => { captureServerLog(\"log\", ...a); _origLog(...a); };\nconsole.warn = (...a: any[]) => { captureServerLog(\"warn\", ...a); _origWarn(...a); };\nconsole.error = (...a: any[]) => { captureServerLog(\"error\", ...a); _origErr(...a); };\nconsole.info = (...a: any[]) => { captureServerLog(\"info\", ...a); _origInfo(...a); };\n\ninterface ClientState {\n authenticated: boolean;\n}\n\n/**\n * Attach OpenMagic endpoints to an existing HTTP server.\n * Handles: toolbar bundle serving, health check, WebSocket.\n * Returns a request handler and the WSS instance.\n */\nexport function attachOpenMagic(\n httpServer: http.Server,\n roots: string[]\n): {\n wss: WebSocketServer;\n handleRequest: (req: http.IncomingMessage, res: http.ServerResponse) => boolean;\n handleUpgrade: (req: http.IncomingMessage, socket: any, head: Buffer) => boolean;\n} {\n\n // Request handler for /__openmagic__/ paths — returns true if handled\n function handleRequest(req: http.IncomingMessage, res: http.ServerResponse): boolean {\n if (!req.url?.startsWith(\"/__openmagic__/\")) return false;\n\n // Strip query string for path matching (e.g., toolbar.js?v=123)\n const urlPath = req.url.split(\"?\")[0];\n\n if (urlPath === \"/__openmagic__/toolbar.js\") {\n serveToolbarBundle(res);\n return true;\n }\n\n if (urlPath === \"/__openmagic__/health\") {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(JSON.stringify({ status: \"ok\", version: VERSION }));\n return true;\n }\n\n return false;\n }\n\n // WebSocket server — noServer mode so it doesn't intercept non-OpenMagic upgrades\n const wss = new WebSocketServer({ noServer: true });\n\n const clientStates = new WeakMap<WebSocket, ClientState>();\n\n wss.on(\"connection\", (ws, req) => {\n const origin = req.headers.origin || \"\";\n if (origin && !origin.startsWith(\"http://localhost\") && !origin.startsWith(\"http://127.0.0.1\")) {\n ws.close(4003, \"Forbidden origin\");\n return;\n }\n clientStates.set(ws, { authenticated: false });\n\n ws.on(\"message\", async (data) => {\n let msg: WsMessage;\n try {\n msg = JSON.parse(data.toString());\n } catch {\n sendError(ws, \"parse_error\", \"Invalid JSON\");\n return;\n }\n\n const state = clientStates.get(ws)!;\n\n if (!state.authenticated && msg.type !== \"handshake\") {\n sendError(ws, \"auth_required\", \"Handshake required\");\n return;\n }\n\n try {\n await handleMessage(ws, msg, state, roots);\n } catch (e: unknown) {\n sendError(ws, \"internal_error\", (e as Error).message, msg.id);\n }\n });\n\n ws.on(\"close\", () => {\n clientStates.delete(ws);\n });\n });\n\n // Handle WebSocket upgrades for OpenMagic path only\n function handleUpgrade(req: http.IncomingMessage, socket: any, head: Buffer): boolean {\n const urlPath = (req.url || \"\").split(\"?\")[0];\n if (urlPath === \"/__openmagic__/ws\") {\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit(\"connection\", ws, req);\n });\n return true;\n }\n return false;\n }\n\n return { wss, handleRequest, handleUpgrade };\n}\n\nasync function handleMessage(\n ws: WebSocket,\n msg: WsMessage,\n state: ClientState,\n roots: string[]\n): Promise<void> {\n switch (msg.type) {\n case \"handshake\": {\n const payload = msg.payload as HandshakePayload;\n if (!payload?.token) {\n sendError(ws, \"invalid_payload\", \"Missing token in handshake\", msg.id);\n ws.close();\n return;\n }\n if (!validateToken(payload.token)) {\n sendError(ws, \"auth_failed\", \"Invalid token\", msg.id);\n ws.close();\n return;\n }\n state.authenticated = true;\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"handshake.ok\",\n payload: {\n version: VERSION,\n roots,\n config: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n apiKeys: Object.fromEntries(Object.entries(config.apiKeys || {}).map(([k]) => [k, true])),\n },\n },\n });\n break;\n }\n\n case \"fs.read\": {\n const payload = msg.payload as FsReadPayload;\n if (!payload?.path) {\n sendError(ws, \"invalid_payload\", \"Missing path\", msg.id);\n break;\n }\n const result = readFileSafe(payload.path, roots);\n if (\"error\" in result) {\n sendError(ws, \"fs_error\", result.error, msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.content\",\n payload: { path: payload.path, content: result.content },\n });\n }\n break;\n }\n\n case \"fs.write\": {\n const payload = msg.payload as FsWritePayload;\n if (!payload?.path || payload.content === undefined) {\n sendError(ws, \"invalid_payload\", \"Missing path or content\", msg.id);\n break;\n }\n const writeResult = writeFileSafe(payload.path, payload.content, roots);\n if (!writeResult.ok) {\n sendError(ws, \"fs_error\", writeResult.error || \"Write failed\", msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.written\",\n payload: { path: payload.path, ok: true },\n });\n }\n break;\n }\n\n case \"fs.undo\": {\n const payload = msg.payload as { path: string };\n if (!payload?.path) { sendError(ws, \"invalid_payload\", \"Missing path\", msg.id); break; }\n const backupPath = getBackupForFile(payload.path);\n if (!backupPath) { sendError(ws, \"fs_error\", \"No backup found\", msg.id); break; }\n try {\n const backupContent = readFileSync(backupPath, \"utf-8\");\n const writeResult = writeFileSafe(payload.path, backupContent, roots);\n if (!writeResult.ok) { sendError(ws, \"fs_error\", writeResult.error || \"Undo failed\", msg.id); break; }\n send(ws, { id: msg.id, type: \"fs.undone\", payload: { path: payload.path, ok: true } });\n } catch (e: unknown) {\n sendError(ws, \"fs_error\", `Backup read failed: ${(e as Error).message}`, msg.id);\n }\n break;\n }\n\n case \"fs.list\": {\n const payload = msg.payload as FsListPayload | undefined;\n const root = payload?.root || roots[0];\n const files = listFiles(root, roots);\n send(ws, {\n id: msg.id,\n type: \"fs.tree\",\n payload: { files, projectTree: getProjectTree(roots) },\n });\n break;\n }\n\n case \"llm.chat\": {\n const payload = msg.payload as LlmChatPayload;\n const config = loadConfig();\n\n // Resolve API key: per-provider keys first, then global fallback\n const provider = payload.provider || config.provider || \"openai\";\n const apiKey = config.apiKeys?.[provider] || config.apiKey || \"\";\n const providerMeta = MODEL_REGISTRY?.[provider];\n\n if (!apiKey && !providerMeta?.local) {\n sendError(ws, \"config_error\", \"API key not configured\", msg.id);\n return;\n }\n\n await handleLlmChat(\n {\n provider,\n model: payload.model || config.model || MODEL_REGISTRY[provider]?.models[0]?.id || \"gpt-4o\",\n apiKey,\n messages: payload.messages,\n context: payload.context,\n },\n (chunk) => {\n send(ws, { id: msg.id, type: \"llm.chunk\", payload: { delta: chunk } });\n },\n (result) => {\n send(ws, { id: msg.id, type: \"llm.done\", payload: result });\n },\n (error) => {\n send(ws, { id: msg.id, type: \"llm.error\", payload: { message: error } });\n }\n );\n break;\n }\n\n case \"config.get\": {\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"config.value\",\n payload: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!(config.apiKeys?.[config.provider || \"\"] || config.apiKey),\n roots: config.roots || roots,\n apiKeys: Object.fromEntries(\n Object.entries(config.apiKeys || {}).map(([k]) => [k, true])\n ),\n },\n });\n break;\n }\n\n case \"config.set\": {\n const payload = msg.payload as ConfigSetPayload;\n const updates: Partial<OpenMagicConfig> = {};\n if (payload.provider !== undefined) updates.provider = payload.provider;\n if (payload.model !== undefined) updates.model = payload.model;\n // Per-provider key storage\n if (payload.apiKey !== undefined && payload.provider) {\n const existing = loadConfig();\n const apiKeys = { ...(existing.apiKeys || {}) };\n apiKeys[payload.provider] = payload.apiKey;\n updates.apiKeys = apiKeys;\n updates.apiKey = payload.apiKey; // backward compat\n } else if (payload.apiKey !== undefined) {\n updates.apiKey = payload.apiKey;\n }\n const result = saveConfig(updates);\n if (!result.ok) {\n sendError(ws, \"config_error\", result.error || \"Failed to save\", msg.id);\n } else {\n send(ws, { id: msg.id, type: \"config.saved\", payload: { ok: true } });\n }\n break;\n }\n\n case \"fs.grep\": {\n const payload = msg.payload as { pattern: string; path?: string };\n if (!payload?.pattern) {\n sendError(ws, \"invalid_payload\", \"Missing pattern\", msg.id);\n break;\n }\n const searchRoot = payload.path ? join(roots[0] || process.cwd(), payload.path) : (roots[0] || process.cwd());\n const results = grepFiles(payload.pattern, searchRoot, roots);\n send(ws, { id: msg.id, type: \"fs.grep.result\", payload: { results } });\n break;\n }\n\n case \"debug.logs\": {\n send(ws, {\n id: msg.id,\n type: \"debug.logs\",\n payload: {\n logs: serverLogs.slice(-100),\n nodeVersion: process.version,\n platform: process.platform,\n arch: process.arch,\n uptime: Math.round(process.uptime()),\n memoryMB: Math.round(process.memoryUsage().rss / 1024 / 1024),\n pid: process.pid,\n cwd: process.cwd(),\n },\n });\n break;\n }\n\n default:\n sendError(ws, \"unknown_type\", `Unknown message type: ${msg.type}`, msg.id);\n }\n}\n\nfunction send(ws: WebSocket, msg: WsMessage): void {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nfunction sendError(ws: WebSocket, code: string, message: string, id?: string): void {\n send(ws, { id: id || \"error\", type: \"error\", payload: { code, message } });\n}\n\nfunction serveToolbarBundle(res: http.ServerResponse): void {\n const bundlePaths = [\n join(__dirname, \"toolbar\", \"index.global.js\"),\n join(__dirname, \"..\", \"dist\", \"toolbar\", \"index.global.js\"),\n ];\n\n for (const bundlePath of bundlePaths) {\n try {\n if (existsSync(bundlePath)) {\n const content = readFileSync(bundlePath, \"utf-8\");\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n \"Cache-Control\": \"no-cache\",\n });\n res.end(content);\n return;\n }\n } catch {\n continue;\n }\n }\n\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(`(function(){var d=document.createElement(\"div\");d.style.cssText=\"position:fixed;bottom:20px;right:20px;background:#1a1a2e;color:#e94560;padding:16px 24px;border-radius:12px;font-family:system-ui;font-size:14px;z-index:2147483647;box-shadow:0 4px 24px rgba(0,0,0,0.3);\";d.textContent=\"OpenMagic: Toolbar bundle not found.\";document.body.appendChild(d);})();`);\n}\n","import { readFileSync, writeFileSync, renameSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { OpenMagicConfig } from \"./shared-types.js\";\n\nconst CONFIG_DIR = join(homedir(), \".openmagic\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function loadConfig(): Partial<OpenMagicConfig> {\n ensureConfigDir();\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n try {\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(updates: Partial<OpenMagicConfig>): { ok: boolean; error?: string } {\n try {\n ensureConfigDir();\n const existing = loadConfig();\n const merged = { ...existing, ...updates };\n const tmpFile = CONFIG_FILE + \".tmp\";\n writeFileSync(tmpFile, JSON.stringify(merged, null, 2), { encoding: \"utf-8\", mode: 0o600 });\n renameSync(tmpFile, CONFIG_FILE);\n return { ok: true };\n } catch (e: unknown) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","import {\n readFileSync,\n writeFileSync,\n existsSync,\n statSync,\n lstatSync,\n readdirSync,\n copyFileSync,\n mkdirSync,\n realpathSync,\n unlinkSync,\n rmSync,\n} from \"node:fs\";\nimport { join, resolve, relative, dirname, extname } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { createHash } from \"node:crypto\";\nimport type { FileEntry } from \"./shared-types.js\";\n\nconst IGNORED_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \".nuxt\",\n \".svelte-kit\",\n \"dist\",\n \"build\",\n \".cache\",\n \".turbo\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \".DS_Store\",\n]);\n\nconst IGNORED_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".ico\",\n \".webp\",\n \".mp4\",\n \".mp3\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".lock\",\n]);\n\nexport function isPathSafe(filePath: string, roots: string[]): boolean {\n const resolved = resolve(filePath);\n\n // Also check realpath to prevent symlink escape\n let real: string;\n try {\n real = realpathSync(resolved);\n } catch {\n // File doesn't exist yet (for writes) — use resolved path\n real = resolved;\n }\n\n return roots.some((root) => {\n const resolvedRoot = resolve(root);\n const rel = relative(resolvedRoot, resolved);\n const realRel = relative(resolvedRoot, real);\n return (\n (!rel.startsWith(\"..\") && !rel.startsWith(\"/\") && !rel.startsWith(\"\\\\\")) &&\n (!realRel.startsWith(\"..\") && !realRel.startsWith(\"/\") && !realRel.startsWith(\"\\\\\"))\n );\n });\n}\n\nexport function readFileSafe(\n filePath: string,\n roots: string[]\n): { content: string } | { error: string } {\n if (!isPathSafe(filePath, roots)) {\n return { error: \"Path is outside allowed roots\" };\n }\n if (!existsSync(filePath)) {\n return { error: \"File not found\" };\n }\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return { content };\n } catch (e: unknown) {\n return { error: `Failed to read file: ${(e as Error).message}` };\n }\n}\n\n// ── Backup Management (temp directory) ──\nconst BACKUP_DIR = join(tmpdir(), \"openmagic-backups\");\nconst backupMap = new Map<string, string>(); // originalPath -> backupTempPath\n\nfunction getBackupPath(filePath: string): string {\n const hash = createHash(\"md5\").update(resolve(filePath)).digest(\"hex\").slice(0, 12);\n const name = filePath.split(/[/\\\\]/).pop() || \"file\";\n return join(BACKUP_DIR, `${hash}_${name}`);\n}\n\nexport function getBackupForFile(filePath: string): string | undefined {\n return backupMap.get(resolve(filePath));\n}\n\nexport function cleanupBackups(): void {\n try {\n if (existsSync(BACKUP_DIR)) {\n rmSync(BACKUP_DIR, { recursive: true, force: true });\n }\n } catch {}\n backupMap.clear();\n}\n\nexport function writeFileSafe(\n filePath: string,\n content: string,\n roots: string[]\n): { ok: boolean; error?: string; backupPath?: string } {\n if (!isPathSafe(filePath, roots)) {\n return { ok: false, error: \"Path is outside allowed roots\" };\n }\n\n try {\n // Create backup in temp directory\n let backupPath: string | undefined;\n if (existsSync(filePath)) {\n if (!existsSync(BACKUP_DIR)) mkdirSync(BACKUP_DIR, { recursive: true });\n backupPath = getBackupPath(filePath);\n copyFileSync(filePath, backupPath);\n backupMap.set(resolve(filePath), backupPath);\n }\n\n // Ensure directory exists\n const dir = dirname(filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(filePath, content, \"utf-8\");\n return { ok: true, backupPath };\n } catch (e: unknown) {\n return { ok: false, error: `Failed to write file: ${(e as Error).message}` };\n }\n}\n\nconst MAX_LIST_ENTRIES = 2000;\n\nexport function listFiles(\n rootPath: string,\n roots: string[],\n maxDepth: number = 4\n): FileEntry[] {\n if (!isPathSafe(rootPath, roots)) {\n return [];\n }\n\n const entries: FileEntry[] = [];\n\n function walk(dir: string, depth: number): void {\n if (depth > maxDepth || entries.length >= MAX_LIST_ENTRIES) return;\n\n let items: string[];\n try {\n items = readdirSync(dir);\n } catch {\n return;\n }\n\n for (const item of items) {\n if (entries.length >= MAX_LIST_ENTRIES) return;\n if (IGNORED_DIRS.has(item)) continue;\n if (item.startsWith(\".\") && item !== \".env.example\") continue;\n\n const fullPath = join(dir, item);\n let stat;\n try {\n stat = lstatSync(fullPath);\n } catch {\n continue;\n }\n if (stat.isSymbolicLink()) continue;\n\n const relPath = relative(rootPath, fullPath);\n\n if (stat.isDirectory()) {\n entries.push({ path: relPath, type: \"dir\", name: item });\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!IGNORED_EXTENSIONS.has(ext)) {\n entries.push({ path: relPath, type: \"file\", name: item });\n }\n }\n }\n }\n\n walk(rootPath, 0);\n return entries;\n}\n\nconst GREP_EXTENSIONS = new Set([\n \".js\", \".jsx\", \".ts\", \".tsx\", \".mjs\", \".cjs\",\n \".vue\", \".svelte\", \".astro\",\n \".html\", \".htm\", \".css\", \".scss\", \".less\",\n \".json\", \".md\", \".yaml\", \".yml\",\n \".php\", \".py\", \".rb\",\n]);\n\nconst MAX_GREP_FILE_SIZE = 256 * 1024; // 256KB — skip large generated/bundled files\nconst MAX_GREP_FILES_SCANNED = 500; // stop walking after scanning this many files\n\nexport function grepFiles(\n pattern: string,\n searchRoot: string,\n roots: string[],\n maxResults: number = 30\n): { file: string; lineNum: number; line: string }[] {\n if (!isPathSafe(searchRoot, roots)) return [];\n\n const results: { file: string; lineNum: number; line: string }[] = [];\n const lowerPattern = pattern.toLowerCase();\n let filesScanned = 0;\n\n function walk(dir: string, depth: number): void {\n if (depth > 6 || results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n let items: string[];\n try { items = readdirSync(dir); } catch { return; }\n\n for (const item of items) {\n if (results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n if (IGNORED_DIRS.has(item) || (item.startsWith(\".\") && item !== \".env.example\")) continue;\n\n const fullPath = join(dir, item);\n let stat;\n try { stat = lstatSync(fullPath); } catch { continue; }\n if (stat.isSymbolicLink()) continue;\n\n if (stat.isDirectory()) {\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!GREP_EXTENSIONS.has(ext)) continue;\n if (stat.size > MAX_GREP_FILE_SIZE) continue; // skip large files\n filesScanned++;\n\n try {\n const content = readFileSync(fullPath, \"utf-8\");\n const lines = content.split(\"\\n\");\n let fileMatches = 0;\n for (let i = 0; i < lines.length && fileMatches < 5; i++) {\n if (lines[i].toLowerCase().includes(lowerPattern)) {\n results.push({\n file: relative(searchRoot, fullPath),\n lineNum: i + 1,\n line: lines[i].trim().slice(0, 200),\n });\n fileMatches++;\n }\n }\n } catch {}\n }\n }\n }\n\n walk(searchRoot, 0);\n return results;\n}\n\nexport function getProjectTree(roots: string[]): string {\n const lines: string[] = [];\n for (const root of roots) {\n lines.push(`[${root}]`);\n const files = listFiles(root, roots, 3);\n for (const f of files) {\n const indent = f.path.split(\"/\").length - 1;\n const prefix = \" \".repeat(indent);\n const icon = f.type === \"dir\" ? \"/\" : \"\";\n lines.push(`${prefix}${f.name}${icon}`);\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n}\n","import type { ProviderRegistry } from \"../shared-types.js\";\n\nexport const MODEL_REGISTRY: ProviderRegistry = {\n // ─── OpenAI ───────────────────────────────────────────────────\n openai: {\n name: \"OpenAI\",\n models: [\n // GPT-5.4 family (March 2026 — latest flagship)\n {\n id: \"gpt-5.4\",\n name: \"GPT-5.4\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-pro\",\n name: \"GPT-5.4 Pro\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.4-mini\",\n name: \"GPT-5.4 Mini\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-nano\",\n name: \"GPT-5.4 Nano\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n // GPT-5.2 family (reasoning-focused)\n {\n id: \"gpt-5.2\",\n name: \"GPT-5.2 Thinking\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.2-pro\",\n name: \"GPT-5.2 Pro\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n // o-series reasoning models\n {\n id: \"o3\",\n name: \"o3 (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"o4-mini\",\n name: \"o4-mini (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // GPT-4.1 family\n {\n id: \"gpt-4.1\",\n name: \"GPT-4.1\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-mini\",\n name: \"GPT-4.1 Mini\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-nano\",\n name: \"GPT-4.1 Nano\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n // Codex\n {\n id: \"codex-mini-latest\",\n name: \"Codex Mini\",\n vision: false,\n context: 192000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.openai.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Anthropic ────────────────────────────────────────────────\n anthropic: {\n name: \"Anthropic\",\n models: [\n // Claude 4.6 (latest — Feb 2026)\n {\n id: \"claude-opus-4-6\",\n name: \"Claude Opus 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 128000,\n },\n },\n {\n id: \"claude-sonnet-4-6\",\n name: \"Claude Sonnet 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n // Claude 4.5\n {\n id: \"claude-haiku-4-5-20251001\",\n name: \"Claude Haiku 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 5000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Sonnet 4.5\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-5-20251101\",\n name: \"Claude Opus 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 64000,\n },\n },\n // Claude 4.0\n {\n id: \"claude-sonnet-4-20250514\",\n name: \"Claude Sonnet 4\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-20250514\",\n name: \"Claude Opus 4\",\n vision: true,\n context: 200000,\n maxOutput: 32000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 32000,\n },\n },\n ],\n apiBase: \"https://api.anthropic.com/v1\",\n keyPrefix: \"sk-ant-\",\n keyPlaceholder: \"sk-ant-...\",\n },\n\n // ─── Google Gemini ────────────────────────────────────────────\n google: {\n name: \"Google Gemini\",\n models: [\n // Gemini 3.1 (latest — Feb-Mar 2026)\n {\n id: \"gemini-3.1-pro-preview\",\n name: \"Gemini 3.1 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // Gemini 3.0\n {\n id: \"gemini-3-flash-preview\",\n name: \"Gemini 3 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-3.1-flash-lite-preview\",\n name: \"Gemini 3.1 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n // Gemini 2.5\n {\n id: \"gemini-2.5-pro\",\n name: \"Gemini 2.5 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gemini-2.5-flash\",\n name: \"Gemini 2.5 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-2.5-flash-lite\",\n name: \"Gemini 2.5 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n ],\n apiBase: \"https://generativelanguage.googleapis.com/v1beta\",\n keyPrefix: \"AI\",\n keyPlaceholder: \"AIza...\",\n },\n\n // ─── xAI (Grok) ──────────────────────────────────────────────\n xai: {\n name: \"xAI (Grok)\",\n models: [\n {\n id: \"grok-4.20-0309-reasoning\",\n name: \"Grok 4.20 Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"grok-4.20-0309-non-reasoning\",\n name: \"Grok 4.20\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n {\n id: \"grok-4-1-fast-reasoning\",\n name: \"Grok 4.1 Fast Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"grok-4-1-fast-non-reasoning\",\n name: \"Grok 4.1 Fast\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n ],\n apiBase: \"https://api.x.ai/v1\",\n keyPrefix: \"xai-\",\n keyPlaceholder: \"xai-...\",\n },\n\n // ─── DeepSeek ─────────────────────────────────────────────────\n deepseek: {\n name: \"DeepSeek\",\n models: [\n {\n id: \"deepseek-chat\",\n name: \"DeepSeek V3.2\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n },\n {\n id: \"deepseek-reasoner\",\n name: \"DeepSeek R1\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.deepseek.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Mistral ──────────────────────────────────────────────────\n mistral: {\n name: \"Mistral\",\n models: [\n {\n id: \"mistral-large-3-25-12\",\n name: \"Mistral Large 3\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-4-0-26-03\",\n name: \"Mistral Small 4\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-3-2-25-06\",\n name: \"Mistral Small 3.2\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"codestral-2508\",\n name: \"Codestral\",\n vision: false,\n context: 262144,\n maxOutput: 32768,\n },\n {\n id: \"devstral-2-25-12\",\n name: \"Devstral 2\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"magistral-medium-1-2-25-09\",\n name: \"Magistral Medium (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"magistral-small-1-2-25-09\",\n name: \"Magistral Small (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.mistral.ai/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter API key...\",\n },\n\n // ─── Groq ─────────────────────────────────────────────────────\n groq: {\n name: \"Groq\",\n models: [\n {\n id: \"meta-llama/llama-4-scout-17b-16e-instruct\",\n name: \"Llama 4 Scout 17B\",\n vision: true,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"llama-3.3-70b-versatile\",\n name: \"Llama 3.3 70B\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"llama-3.1-8b-instant\",\n name: \"Llama 3.1 8B Instant\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"qwen/qwen3-32b\",\n name: \"Qwen 3 32B\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n ],\n apiBase: \"https://api.groq.com/openai/v1\",\n keyPrefix: \"gsk_\",\n keyPlaceholder: \"gsk_...\",\n },\n\n // ─── MiniMax ───────────────────────────────────────────────────\n minimax: {\n name: \"MiniMax\",\n models: [\n { id: \"MiniMax-M2.7\", name: \"MiniMax M2.7\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.7-highspeed\", name: \"MiniMax M2.7 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5\", name: \"MiniMax M2.5\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5-highspeed\", name: \"MiniMax M2.5 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n ],\n apiBase: \"https://api.minimax.chat/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter MiniMax API key...\",\n },\n\n // ─── Moonshot / Kimi ──────────────────────────────────────────\n moonshot: {\n name: \"Kimi (Moonshot)\",\n models: [\n {\n id: \"kimi-k2.5\",\n name: \"Kimi K2.5\",\n vision: true,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"kimi-k2-thinking\",\n name: \"Kimi K2 Thinking\",\n vision: false,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.moonshot.cn/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Moonshot API key...\",\n },\n\n // ─── Alibaba Qwen (DashScope) ────────────────────────────────\n qwen: {\n name: \"Qwen (Alibaba)\",\n models: [\n { id: \"qwen3.5-plus\", name: \"Qwen 3.5 Plus\", vision: true, context: 1010000, maxOutput: 16384 },\n { id: \"qwen-plus\", name: \"Qwen Plus\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-max\", name: \"Qwen Max\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-turbo\", name: \"Qwen Turbo\", vision: false, context: 131072, maxOutput: 8192 },\n ],\n apiBase: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter DashScope API key...\",\n },\n\n // ─── Zhipu AI (GLM) ──────────────────────────────────────────\n zhipu: {\n name: \"Zhipu AI (GLM)\",\n models: [\n { id: \"glm-5\", name: \"GLM-5\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.7\", name: \"GLM-4.7\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.6\", name: \"GLM-4.6\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.5\", name: \"GLM-4.5\", vision: true, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://open.bigmodel.cn/api/paas/v4\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Zhipu API key...\",\n },\n\n // ─── ByteDance Doubao ─────────────────────────────────────────\n doubao: {\n name: \"Doubao (ByteDance)\",\n models: [\n { id: \"doubao-seed-2-0-pro\", name: \"Doubao Seed 2.0 Pro\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"doubao-seed-2-0-lite\", name: \"Doubao Seed 2.0 Lite\", vision: false, context: 131072, maxOutput: 8192 },\n { id: \"doubao-seed-2-0-code\", name: \"Doubao Seed 2.0 Code\", vision: false, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://ark.cn-beijing.volces.com/api/v3\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Volcano Engine API key...\",\n },\n\n // ─── Ollama (Local) ───────────────────────────────────────────\n ollama: {\n name: \"Ollama (Local)\",\n models: [],\n apiBase: \"http://localhost:11434/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── OpenRouter (200+ models) ─────────────────────────────────\n openrouter: {\n name: \"OpenRouter\",\n models: [],\n apiBase: \"https://openrouter.ai/api/v1\",\n keyPrefix: \"sk-or-\",\n keyPlaceholder: \"sk-or-...\",\n },\n};\n","import type { LlmContext } from \"../shared-types.js\";\n\nexport const SYSTEM_PROMPT = `You are OpenMagic, an AI coding assistant embedded in a developer's web application. You help modify the codebase based on visual context from the running app.\n\n## Your Role\n- You can see the developer's running web application (DOM elements, screenshots, styles)\n- You propose code modifications to their source files\n- Your changes are applied directly to their codebase and reflected via hot reload\n\n## Response Format\nYou MUST respond with valid JSON in this exact format:\n\n\\`\\`\\`json\n{\n \"modifications\": [\n {\n \"file\": \"relative/path/to/file.tsx\",\n \"type\": \"edit\",\n \"search\": \"exact code to find (multi-line ok)\",\n \"replace\": \"replacement code\"\n }\n ],\n \"explanation\": \"Brief description of what was changed and why\"\n}\n\\`\\`\\`\n\n## Modification Types\n- \\`edit\\`: Replace existing code. \\`search\\` must match exactly in the file. \\`replace\\` is the new code.\n- \\`create\\`: Create a new file. Use \\`content\\` instead of search/replace.\n- \\`delete\\`: Delete a file. No search/replace/content needed.\n\n## Rules\n1. If the user is asking a QUESTION (not requesting a change), respond with {\"modifications\":[],\"explanation\":\"your answer here\"}. Only propose modifications when the user explicitly wants something changed.\n2. NEVER use delete+create to modify an existing file. Always use edit with search/replace. Only use create for genuinely new files that don't exist yet.\n3. Copy the search string EXACTLY from the grounded source files — do not retype, reformat, or change whitespace/indentation\n4. Include 3-5 lines of surrounding context in the search field to ensure uniqueness\n5. Keep modifications minimal — change only what's needed. Do NOT rewrite entire files.\n6. If the grounded files don't contain the code you need to modify, return: {\"modifications\":[],\"explanation\":\"NEED_FILE: exact/relative/path/to/file.ext\"}\n7. To search for a pattern across the codebase, return: {\"modifications\":[],\"explanation\":\"SEARCH_FILES: \\\\\"pattern\\\\\" in optional/path/\"}\n7. For style changes: check the dependencies (package.json) to know if the project uses Tailwind, MUI, etc. Use the project's styling approach, not raw CSS\n8. Use the selected element's cssSelector, className, parentContainerStyles, and siblings to understand the full layout context\n9. Use the page URL route and componentHint to identify the correct source file to modify\n10. Always preserve existing code style, conventions, and indentation\n11. ALWAYS respond with valid JSON only — no text before or after the JSON object`;\n\nexport function buildContextParts(context: LlmContext): Parameters<typeof buildUserMessage>[1] {\n const parts: Parameters<typeof buildUserMessage>[1] = {};\n\n // Send FULL element context with all available signals\n if (context.selectedElement) {\n const el = context.selectedElement as any;\n const elementData: Record<string, unknown> = {\n cssSelector: el.cssSelector,\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n outerHTML: el.outerHTML,\n computedStyles: el.computedStyles,\n ancestry: el.ancestry,\n componentHint: el.componentHint,\n };\n // Parent container styles (layout context)\n if (el.parentStyles && Object.keys(el.parentStyles).length) {\n elementData.parentContainerStyles = el.parentStyles;\n }\n // Sibling elements (what else is in the same container)\n if (el.siblings?.length) {\n elementData.siblings = el.siblings;\n }\n // Matched CSS rules from stylesheets\n if (el.matchedCssRules?.length) {\n elementData.matchedCssRules = el.matchedCssRules;\n }\n // Viewport dimensions\n if (el.viewport) {\n elementData.viewport = el.viewport;\n }\n // Accessibility attributes\n if (el.ariaAttributes && Object.keys(el.ariaAttributes).length) {\n elementData.ariaAttributes = el.ariaAttributes;\n }\n // Event handlers\n if (el.eventHandlers?.length) {\n elementData.eventHandlers = el.eventHandlers;\n }\n // React props\n if (el.reactProps) {\n elementData.reactProps = el.reactProps;\n }\n // Children layout measurements (pixel-level spacing between children)\n if (el.childrenLayout?.length) {\n elementData.childrenLayout = el.childrenLayout;\n }\n // Resolved Tailwind/utility classes to actual CSS values\n if (el.resolvedClasses?.length) {\n elementData.resolvedClasses = el.resolvedClasses;\n }\n parts.selectedElement = JSON.stringify(elementData, null, 2);\n }\n\n if (context.files?.length) {\n parts.files = context.files;\n }\n if (context.projectTree) parts.projectTree = context.projectTree;\n if ((context as any).pageUrl) parts.pageUrl = (context as any).pageUrl;\n if ((context as any).pageTitle) parts.pageTitle = (context as any).pageTitle;\n if (context.networkLogs) parts.networkLogs = context.networkLogs.map(l => `${l.method} ${l.url} → ${l.status || \"pending\"}`).join(\"\\n\");\n if (context.consoleLogs) parts.consoleLogs = context.consoleLogs.map(l => `[${l.level}] ${l.args.join(\" \")}`).join(\"\\n\");\n if ((context as any).searchResults?.length) {\n parts.searchResults = (context as any).searchResults.map(\n (s: any) => `Search: \"${s.query}\"\\n${s.matches.map((m: any) => ` ${m.file}:${m.lineNum}: ${m.line}`).join(\"\\n\")}`\n ).join(\"\\n\\n\");\n }\n return parts;\n}\n\nexport function buildUserMessage(\n userPrompt: string,\n context: {\n selectedElement?: string;\n screenshot?: string;\n files?: Array<{ path: string; content: string }>;\n fileContent?: string;\n filePath?: string;\n networkLogs?: string;\n consoleLogs?: string;\n projectTree?: string;\n pageUrl?: string;\n pageTitle?: string;\n searchResults?: string;\n }\n): string {\n const parts: string[] = [];\n\n // Page context — helps LLM find the right route/page component\n if (context.pageUrl || context.pageTitle) {\n parts.push(`## Page Context\\nURL: ${context.pageUrl || \"unknown\"}\\nTitle: ${context.pageTitle || \"unknown\"}`);\n }\n\n if (context.projectTree) {\n parts.push(`## Project Structure\\n\\`\\`\\`\\n${context.projectTree}\\n\\`\\`\\``);\n }\n\n // Grounded source files\n if (context.files?.length) {\n parts.push(`## Grounded Source Files\\n${context.files.map(f => `### ${f.path}\\n\\`\\`\\`\\n${f.content}\\n\\`\\`\\``).join(\"\\n\\n\")}`);\n } else if (context.filePath && context.fileContent) {\n parts.push(`## Source File: ${context.filePath}\\n\\`\\`\\`\\n${context.fileContent}\\n\\`\\`\\``);\n }\n\n // Selected element — full context including selector, styles, ancestry\n if (context.selectedElement) {\n parts.push(`## Selected Element\\n\\`\\`\\`json\\n${context.selectedElement}\\n\\`\\`\\``);\n }\n\n if (context.networkLogs) {\n parts.push(`## Recent Network Requests\\n\\`\\`\\`\\n${context.networkLogs}\\n\\`\\`\\``);\n }\n\n if (context.consoleLogs) {\n parts.push(`## Console Output\\n\\`\\`\\`\\n${context.consoleLogs}\\n\\`\\`\\``);\n }\n\n if (context.searchResults) {\n parts.push(`## Search Results\\n\\`\\`\\`\\n${context.searchResults}\\n\\`\\`\\``);\n }\n\n parts.push(`## User Request\\n${userPrompt}`);\n\n return parts.join(\"\\n\\n\");\n}\n","import type { ChatMessage, ContentPart, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\ninterface OpenAICompatibleRequest {\n model: string;\n messages: Array<{\n role: string;\n content: string | Array<{ type: string; text?: string; image_url?: { url: string } }>;\n }>;\n stream: boolean;\n max_tokens?: number;\n max_completion_tokens?: number;\n reasoning_effort?: string;\n}\n\nexport async function chatOpenAICompatible(\n provider: string,\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const providerConfig = MODEL_REGISTRY[provider];\n if (!providerConfig) {\n onError(`Unknown provider: ${provider}`);\n return;\n }\n\n const apiBase = providerConfig.apiBase;\n const url = `${apiBase}/chat/completions`;\n\n // Build messages with context\n const apiMessages: OpenAICompatibleRequest[\"messages\"] = [\n { role: \"system\", content: SYSTEM_PROMPT },\n ];\n\n // Only enrich the LAST user message with context (not all historical ones)\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\n\n // If we have a screenshot and the model supports vision, add it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (context.screenshot && modelInfo?.vision) {\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image_url\",\n image_url: { url: context.screenshot },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else if (msg.role === \"system\") {\n continue; // System prompt already added\n } else {\n apiMessages.push({\n role: msg.role,\n content: msg.content as string,\n });\n }\n }\n\n // GPT-5.x, o3, o4 models require max_completion_tokens instead of max_tokens\n const usesCompletionTokens = provider === \"openai\" && (\n model.startsWith(\"gpt-5\") || model.startsWith(\"o3\") || model.startsWith(\"o4\") || model.startsWith(\"codex\")\n );\n\n const body: OpenAICompatibleRequest = {\n model,\n messages: apiMessages,\n stream: true,\n };\n\n if (usesCompletionTokens) {\n body.max_completion_tokens = 4096;\n } else {\n body.max_tokens = 4096;\n }\n\n // Add thinking/reasoning config if the model supports it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (modelInfo?.thinking?.supported && modelInfo.thinking.paramType === \"level\") {\n body.reasoning_effort = modelInfo.thinking.defaultLevel || \"medium\";\n const limit = Math.min(modelInfo.maxOutput, 16384);\n if (usesCompletionTokens) {\n body.max_completion_tokens = limit;\n } else {\n body.max_tokens = limit;\n }\n }\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (provider === \"ollama\") {\n // Ollama doesn't need auth\n } else {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(`Invalid API key for ${providerConfig.name}. Check your key in Settings.`);\n } else if (response.status === 429) {\n onError(`Rate limit exceeded for ${providerConfig.name}. Wait a moment and try again.`);\n } else {\n onError(`${providerConfig.name} API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n // Stream SSE response\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n if (data === \"[DONE]\") continue;\n\n try {\n const parsed = JSON.parse(data);\n const delta = parsed.choices?.[0]?.delta?.content;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\ninterface AnthropicMessage {\n role: \"user\" | \"assistant\";\n content: string | Array<{ type: string; text?: string; source?: { type: string; media_type: string; data: string } }>;\n}\n\nexport async function chatAnthropic(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = \"https://api.anthropic.com/v1/messages\";\n\n const apiMessages: AnthropicMessage[] = [];\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\n\n // If screenshot available, use vision\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: \"image/png\",\n data: base64Data,\n },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else {\n apiMessages.push({\n role: msg.role as \"user\" | \"assistant\",\n content: msg.content as string,\n });\n }\n }\n\n // Build body with optional extended thinking\n const providerConfig = MODEL_REGISTRY.anthropic;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingBudget = modelInfo?.thinking?.defaultBudget || 0;\n\n const body: Record<string, unknown> = {\n model,\n max_tokens: thinkingBudget > 0 ? Math.max(thinkingBudget + 4096, 16384) : 4096,\n system: SYSTEM_PROMPT,\n messages: apiMessages,\n stream: true,\n };\n\n // Add extended thinking if supported\n if (thinkingBudget > 0) {\n body.thinking = {\n type: \"enabled\",\n budget_tokens: thinkingBudget,\n };\n }\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Anthropic API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Anthropic rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Anthropic API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n if (parsed.type === \"content_block_delta\") {\n const delta = parsed.delta?.text;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\nexport async function chatGoogle(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?key=${apiKey}&alt=sse`;\n\n const contents: Array<{\n role: string;\n parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }>;\n }> = [];\n\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"system\") continue;\n\n const role = msg.role === \"assistant\" ? \"model\" : \"user\";\n\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\n\n const parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }> = [\n { text: enrichedContent },\n ];\n\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n parts.push({\n inline_data: {\n mime_type: \"image/png\",\n data: base64Data,\n },\n });\n }\n\n contents.push({ role, parts });\n } else {\n contents.push({\n role,\n parts: [{ text: msg.content as string }],\n });\n }\n }\n\n // Check for thinking support\n const providerConfig = MODEL_REGISTRY.google;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingLevel = modelInfo?.thinking?.defaultLevel;\n\n const generationConfig: Record<string, unknown> = {\n maxOutputTokens: 8192,\n };\n\n const thinkingConfig = (thinkingLevel && thinkingLevel !== \"none\")\n ? { thinkingLevel: thinkingLevel.toUpperCase() }\n : undefined;\n\n const body: Record<string, unknown> = {\n system_instruction: {\n parts: [{ text: SYSTEM_PROMPT }],\n },\n contents,\n generationConfig,\n };\n if (thinkingConfig) {\n body.thinkingConfig = thinkingConfig;\n }\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Google API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Google API rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Google API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext, LlmResponse } from \"../shared-types.js\";\nimport { chatOpenAICompatible } from \"./openai.js\";\nimport { chatAnthropic } from \"./anthropic.js\";\nimport { chatGoogle } from \"./google.js\";\n\n// Providers that use OpenAI-compatible API format\nconst OPENAI_COMPATIBLE_PROVIDERS = new Set([\n \"openai\",\n \"deepseek\",\n \"groq\",\n \"mistral\",\n \"xai\",\n \"ollama\",\n \"openrouter\",\n \"minimax\",\n \"moonshot\",\n \"qwen\",\n \"zhipu\",\n \"doubao\",\n]);\n\ninterface LlmChatParams {\n provider: string;\n model: string;\n apiKey: string;\n messages: ChatMessage[];\n context: LlmContext;\n}\n\nfunction extractJsonFromResponse(content: string): string | null {\n // Try markdown-wrapped JSON first (most common)\n const mdMatch = content.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n if (mdMatch?.[1]) {\n const candidate = mdMatch[1].trim();\n try { JSON.parse(candidate); return candidate; } catch {}\n }\n\n // Brace-counting extraction (handles raw JSON in response)\n const start = content.indexOf('{');\n if (start === -1) return null;\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (let i = start; i < content.length; i++) {\n const ch = content[i];\n if (escape) { escape = false; continue; }\n if (ch === '\\\\' && inString) { escape = true; continue; }\n if (ch === '\"') { inString = !inString; continue; }\n if (inString) continue;\n if (ch === '{') depth++;\n if (ch === '}') {\n depth--;\n if (depth === 0) {\n const candidate = content.substring(start, i + 1);\n try { JSON.parse(candidate); return candidate; } catch { return null; }\n }\n }\n }\n return null;\n}\n\nexport async function handleLlmChat(\n params: LlmChatParams,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string; modifications?: LlmResponse[\"modifications\"] }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const { provider, model, apiKey, messages, context } = params;\n\n const wrappedOnDone = (result: { content: string }) => {\n let modifications: LlmResponse[\"modifications\"] | undefined;\n try {\n const json = extractJsonFromResponse(result.content);\n if (json) {\n const parsed = JSON.parse(json) as LlmResponse;\n modifications = parsed.modifications;\n }\n } catch {\n // JSON parse failed — return raw content\n }\n onDone({ content: result.content, modifications });\n };\n\n try {\n if (provider === \"anthropic\") {\n await chatAnthropic(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (provider === \"google\") {\n await chatGoogle(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (OPENAI_COMPATIBLE_PROVIDERS.has(provider)) {\n await chatOpenAICompatible(\n provider,\n model,\n apiKey,\n messages,\n context,\n onChunk,\n wrappedOnDone,\n onError\n );\n } else {\n onError(`Unsupported provider: ${provider}. Check your Settings.`);\n }\n } catch (e: unknown) {\n const msg = (e as Error).message || \"Unknown error\";\n if (msg.includes(\"fetch\") || msg.includes(\"ECONNREFUSED\") || msg.includes(\"network\")) {\n onError(`Network error: Could not reach the ${provider} API. Check your internet connection.`);\n } else {\n onError(`Unexpected error with ${provider}: ${msg}`);\n }\n }\n}\n","import { createConnection } from \"node:net\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\nconst COMMON_DEV_PORTS = [\n 3000, // React (CRA), Next.js, Express\n 5173, // Vite\n 5174, // Vite (alternate)\n 4200, // Angular\n 8080, // Vue CLI, generic\n 8000, // Django, Python\n 3001, // Common alternate\n 4000, // Phoenix, generic\n 1234, // Parcel\n 4321, // Astro\n 3333, // Remix\n 8081, // Metro (React Native)\n 9000, // generic\n 8888, // Jupyter, generic\n 5000, // Flask (last — macOS AirPlay also uses 5000)\n];\n\nfunction checkPortSingle(port: number, host: string): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host, timeout: 1000 });\n socket.unref();\n socket.on(\"connect\", () => { socket.destroy(); resolve(true); });\n socket.on(\"error\", () => { socket.destroy(); resolve(false); });\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n}\n\n// Check both IPv4 and IPv6 — many dev servers (Vite, Node) listen on ::1 only\nasync function checkPort(port: number, host: string = \"127.0.0.1\"): Promise<boolean> {\n const results = await Promise.all([\n checkPortSingle(port, host),\n checkPortSingle(port, \"::1\"),\n checkPortSingle(port, \"localhost\"),\n ]);\n return results.some(Boolean);\n}\n\nexport interface DetectedServer {\n port: number;\n host: string;\n fromScripts?: boolean; // true if detected via package.json scripts\n}\n\n/**\n * Check if the process listening on a port is running from (or near) the expected directory.\n * Uses lsof on macOS/Linux to get the PID, then checks its working directory.\n * Returns true if verified, false if wrong project, null if can't determine.\n */\nexport function verifyPortOwnership(port: number, expectedDir: string): boolean | null {\n try {\n // Get PIDs listening on this port\n const pidOutput = execSync(`lsof -i :${port} -sTCP:LISTEN -t 2>/dev/null`, {\n encoding: \"utf-8\",\n timeout: 3000,\n }).trim();\n\n if (!pidOutput) return null;\n\n const pids = pidOutput.split(\"\\n\").map((p) => p.trim()).filter(Boolean);\n const expected = resolve(expectedDir);\n\n for (const pid of pids) {\n try {\n // Get working directory of this process\n const cwdOutput = execSync(\n `lsof -a -p ${pid} -d cwd -Fn 2>/dev/null | grep ^n | head -1`,\n { encoding: \"utf-8\", timeout: 3000 }\n ).trim();\n\n if (!cwdOutput) continue;\n const processCwd = resolve(cwdOutput.slice(1)); // strip leading 'n'\n\n // Match if the process cwd is the project dir, a parent, or a child\n if (processCwd === expected || expected.startsWith(processCwd) || processCwd.startsWith(expected)) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n // We got PIDs but none matched the project directory\n return false;\n } catch {\n // lsof not available or failed — can't verify\n return null;\n }\n}\n\nexport async function detectDevServer(cwd: string = process.cwd()): Promise<DetectedServer | null> {\n // First: check ports hinted by the project's dev scripts (most reliable)\n const scripts = detectDevScripts(cwd);\n const scriptPorts = scripts.map((s) => s.defaultPort).filter((p, i, a) => a.indexOf(p) === i);\n\n if (scriptPorts.length > 0) {\n for (const port of scriptPorts) {\n if (await checkPort(port)) {\n // Verify this port actually belongs to this project\n const owned = verifyPortOwnership(port, cwd);\n if (owned === false) {\n // Wrong project on this port — skip it\n continue;\n }\n return { port, host: \"localhost\", fromScripts: true };\n }\n }\n // Scripts exist but none running (or all belong to other projects)\n return null;\n }\n\n // No recognized scripts — scan common ports (but flag as unverified)\n const checks = COMMON_DEV_PORTS.map(async (port) => {\n const isOpen = await checkPort(port);\n return isOpen ? port : null;\n });\n\n const results = await Promise.all(checks);\n\n for (const foundPort of results) {\n if (foundPort === null) continue;\n // For generic scan, also check ownership\n const owned = verifyPortOwnership(foundPort, cwd);\n if (owned === false) continue; // skip — belongs to another project\n return { port: foundPort, host: \"localhost\", fromScripts: false };\n }\n\n return null;\n}\n\nexport async function isPortOpen(port: number): Promise<boolean> {\n return checkPort(port);\n}\n\nexport async function findAvailablePort(startPort: number): Promise<number> {\n let port = startPort;\n while (await isPortOpen(port)) {\n port++;\n if (port > startPort + 100) {\n throw new Error(`Could not find an available port near ${startPort}`);\n }\n }\n return port;\n}\n\n// --- Package.json Dev Script Detection ---\n\nexport interface DevScript {\n name: string; // e.g. \"dev\", \"start\", \"serve\"\n command: string; // e.g. \"next dev\", \"vite\", \"ng serve\"\n framework: string; // e.g. \"Next.js\", \"Vite\", \"Angular\"\n defaultPort: number;\n}\n\nconst FRAMEWORK_PATTERNS: Array<{\n match: RegExp;\n framework: string;\n defaultPort: number;\n}> = [\n { match: /\\bnext\\b/, framework: \"Next.js\", defaultPort: 3000 },\n { match: /\\bvite\\b/, framework: \"Vite\", defaultPort: 5173 },\n { match: /\\bnuxt\\b/, framework: \"Nuxt\", defaultPort: 3000 },\n { match: /\\bng\\s+serve\\b/, framework: \"Angular\", defaultPort: 4200 },\n { match: /\\bvue-cli-service\\s+serve\\b/, framework: \"Vue CLI\", defaultPort: 8080 },\n { match: /\\bsvelte-kit\\b/, framework: \"SvelteKit\", defaultPort: 5173 },\n { match: /\\bastro\\b/, framework: \"Astro\", defaultPort: 4321 },\n { match: /\\bremix\\b/, framework: \"Remix\", defaultPort: 3000 },\n { match: /\\breact-scripts\\s+start\\b/, framework: \"Create React App\", defaultPort: 3000 },\n { match: /\\bparcel\\b/, framework: \"Parcel\", defaultPort: 1234 },\n { match: /\\bwebpack\\s+serve\\b|webpack-dev-server/, framework: \"Webpack\", defaultPort: 8080 },\n { match: /\\bgatsby\\b/, framework: \"Gatsby\", defaultPort: 8000 },\n { match: /\\bturborepo\\b|\\bturbo\\b.*dev/, framework: \"Turborepo\", defaultPort: 3000 },\n { match: /\\bexpo\\b/, framework: \"Expo\", defaultPort: 8081 },\n { match: /\\bnodemon\\b|\\bts-node\\b|\\bnode\\b/, framework: \"Node.js\", defaultPort: 3000 },\n { match: /\\bflask\\b/, framework: \"Flask\", defaultPort: 5000 },\n { match: /\\bdjango\\b|manage\\.py\\s+runserver/, framework: \"Django\", defaultPort: 8000 },\n { match: /\\brails\\b/, framework: \"Rails\", defaultPort: 3000 },\n { match: /\\bphp\\s+.*serve\\b|artisan\\s+serve/, framework: \"PHP/Laravel\", defaultPort: 8000 },\n];\n\nconst DEV_SCRIPT_NAMES = [\"dev\", \"start\", \"serve\", \"develop\", \"dev:start\", \"start:dev\", \"server\", \"dev:server\", \"web\", \"frontend\"];\n\nexport function detectDevScripts(cwd: string = process.cwd()): DevScript[] {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return [];\n\n let pkg: any;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n } catch {\n return [];\n }\n\n if (!pkg.scripts) return [];\n\n const scripts: DevScript[] = [];\n\n for (const name of DEV_SCRIPT_NAMES) {\n const command = pkg.scripts[name];\n if (!command) continue;\n\n // Detect framework from command\n let framework = \"Unknown\";\n let defaultPort = 3000;\n\n for (const pattern of FRAMEWORK_PATTERNS) {\n if (pattern.match.test(command)) {\n framework = pattern.framework;\n defaultPort = pattern.defaultPort;\n break;\n }\n }\n\n // Try to extract port from command (e.g., --port 4000, -p 8080)\n const portMatch = command.match(/(?:--port|-p)\\s+(\\d+)/);\n if (portMatch) {\n defaultPort = parseInt(portMatch[1], 10);\n }\n\n scripts.push({ name, command, framework, defaultPort });\n }\n\n return scripts;\n}\n\nexport function getProjectName(cwd: string = process.cwd()): string {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return \"this project\";\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n return pkg.name || \"this project\";\n } catch {\n return \"this project\";\n }\n}\n\n// --- Dependency Installation Check ---\n\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\n\nexport interface DependencyStatus {\n installed: boolean;\n packageManager: PackageManager;\n installCommand: string;\n}\n\nconst LOCK_FILES: Array<{ file: string; pm: PackageManager }> = [\n { file: \"pnpm-lock.yaml\", pm: \"pnpm\" },\n { file: \"yarn.lock\", pm: \"yarn\" },\n { file: \"bun.lockb\", pm: \"bun\" },\n { file: \"bun.lock\", pm: \"bun\" },\n { file: \"package-lock.json\", pm: \"npm\" },\n];\n\nconst INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: \"npm install\",\n yarn: \"yarn install\",\n pnpm: \"pnpm install\",\n bun: \"bun install\",\n};\n\nexport function checkDependenciesInstalled(cwd: string = process.cwd()): DependencyStatus {\n const hasNodeModules = existsSync(join(cwd, \"node_modules\"));\n\n // Detect package manager from lock file\n let pm: PackageManager = \"npm\";\n for (const { file, pm: detectedPm } of LOCK_FILES) {\n if (existsSync(join(cwd, file))) {\n pm = detectedPm;\n break;\n }\n }\n\n return {\n installed: hasNodeModules,\n packageManager: pm,\n installCommand: INSTALL_COMMANDS[pm],\n };\n}\n"],"mappings":"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","names":["resolve","join","existsSync","readFileSync","readFileSync","existsSync","join","dirname","readFileSync","writeFileSync","existsSync","mkdirSync","join","modelInfo","dirname","readFileSync","join","existsSync","readFileSync","existsSync","join","resolve","createRequire","_require","VERSION","resolve","VERSION","resolve","join","existsSync","readFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/proxy.ts","../src/security.ts","../src/server.ts","../src/config.ts","../src/filesystem.ts","../src/llm/registry.ts","../src/llm/prompts.ts","../src/llm/openai.ts","../src/llm/anthropic.ts","../src/llm/google.ts","../src/llm/proxy.ts","../src/detect.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { resolve, join } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\n\n// Suppress http-proxy deprecation warning noise\nconst origEmitWarning = process.emitWarning;\nprocess.emitWarning = function (warning: any, ...args: any[]) {\n if (typeof warning === \"string\" && warning.includes(\"util._extend\")) return;\n return origEmitWarning.call(process, warning, ...args);\n} as typeof process.emitWarning;\n\n// Global error handlers — prevent silent crashes\nprocess.on(\"unhandledRejection\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Unhandled error:\"), (err as Error)?.message || err);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Fatal error:\"), err.message);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n process.exit(1);\n});\n\n// Track child processes for cleanup\nconst childProcesses: ChildProcess[] = [];\nlet lastDetectedPort: number | null = null; // Port detected from dev server output\nimport { createProxyServer } from \"./proxy.js\";\nimport { generateSessionToken } from \"./security.js\";\nimport {\n detectDevServer,\n findAvailablePort,\n isPortOpen,\n detectDevScripts,\n getProjectName,\n checkDependenciesInstalled,\n verifyPortOwnership,\n checkNodeCompatibility,\n} from \"./detect.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { cleanupBackups } from \"./filesystem.js\";\n\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\n\nfunction ask(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nfunction waitForPort(\n port: number,\n timeoutMs: number = 60000,\n shouldAbort?: () => boolean\n): Promise<boolean> {\n const start = Date.now();\n return new Promise((resolve) => {\n const check = async () => {\n if (shouldAbort?.()) {\n resolve(false);\n return;\n }\n if (await isPortOpen(port)) {\n resolve(true);\n return;\n }\n const elapsed = Date.now() - start;\n if (elapsed > timeoutMs) {\n resolve(false);\n return;\n }\n // Aggressive early polling, then back off\n const interval = elapsed < 10000 ? 300 : 1000;\n setTimeout(check, interval);\n };\n check();\n });\n}\n\nfunction runCommand(cmd: string, args: string[], cwd: string = process.cwd()): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: true,\n });\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.on(\"error\", () => resolve(false));\n child.on(\"close\", (code) => resolve(code === 0));\n } catch {\n resolve(false);\n }\n });\n}\n\nasync function healthCheck(proxyPort: number, _targetPort: number): Promise<void> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n\n // Check OpenMagic's own health endpoint (not the app — app may require auth)\n const res = await fetch(`http://127.0.0.1:${proxyPort}/__openmagic__/health`, {\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n if (res.ok) {\n console.log(chalk.green(\" ✓ Toolbar ready.\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Proxy started but toolbar health check failed.\"));\n }\n } catch {\n console.log(\n chalk.yellow(\" ⚠ Could not verify proxy. The dev server may still be starting.\")\n );\n console.log(\n chalk.dim(\" Try refreshing the page in a few seconds.\")\n );\n }\n console.log(\"\");\n}\n\n// Detect common dev server errors and show hints\nfunction formatDevServerLine(line: string): string {\n const trimmed = line.trim();\n if (!trimmed) return \"\";\n\n // Detect error patterns and add context\n if (trimmed.startsWith(\"Error:\") || trimmed.includes(\"ModuleNotFoundError\") || trimmed.includes(\"Can't resolve\")) {\n return chalk.red(` │ ${trimmed}`);\n }\n if (trimmed.includes(\"EADDRINUSE\") || trimmed.includes(\"address already in use\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Port is already in use. Stop the other process or use --port <different-port>\");\n }\n if (trimmed.includes(\"EACCES\") || trimmed.includes(\"permission denied\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Permission denied. Try a different port or check file permissions.\");\n }\n if (trimmed.includes(\"Cannot find module\") || trimmed.includes(\"MODULE_NOT_FOUND\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Missing dependency. Try running npm install.\");\n }\n\n return chalk.dim(` │ ${trimmed}`);\n}\n\n// Track which framework was detected (for diagnostic hints)\nlet detectedFramework: string | null = null;\n\n/**\n * After the proxy starts, check if the upstream app actually serves content.\n * If it returns 404, warn with framework-specific troubleshooting hints.\n */\nasync function validateAppHealth(targetHost: string, targetPort: number): Promise<void> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n const res = await fetch(`http://${targetHost}:${targetPort}/`, {\n signal: controller.signal,\n redirect: \"manual\",\n headers: { Accept: \"text/html\" },\n });\n clearTimeout(timeout);\n\n const status = res.status;\n\n // 2xx or redirect → app is healthy\n if (status >= 200 && status < 400) return;\n\n if (status === 404) {\n console.log(chalk.yellow(\" ⚠ Your app returned 404 for the root path (\\\"/\\\").\"));\n console.log(chalk.dim(\" The dev server is running, but no page matched.\"));\n console.log(\"\");\n\n if (detectedFramework === \"Next.js\") {\n console.log(chalk.dim(\" Common Next.js causes:\"));\n console.log(chalk.dim(\" • A stray package-lock.json in a parent directory confuses\"));\n console.log(chalk.dim(\" Turbopack's workspace root detection.\"));\n console.log(chalk.dim(\" → Check for ~/package-lock.json and remove if unneeded\"));\n console.log(chalk.dim(\" → Or set turbopack.root in next.config (Next.js 15+)\"));\n console.log(chalk.dim(\" • Missing src/app/page.tsx (App Router) or pages/index.tsx\"));\n console.log(chalk.dim(\" • Middleware redirecting all routes to an auth provider\"));\n } else if (detectedFramework === \"Angular\") {\n console.log(chalk.dim(\" Angular hint: ensure the base href matches the proxy path.\"));\n } else if (detectedFramework === \"Vite\") {\n console.log(chalk.dim(\" Vite hint: check that index.html exists in the project root.\"));\n } else {\n console.log(chalk.dim(\" Check your framework's routing configuration.\"));\n }\n\n console.log(\"\");\n console.log(chalk.dim(\" The toolbar is still available — navigate to a working route.\"));\n console.log(\"\");\n } else if (status >= 500) {\n console.log(chalk.yellow(` ⚠ Your app returned HTTP ${status} on the root path.`));\n console.log(chalk.dim(\" There may be a server-side error. Check your dev server output.\"));\n console.log(\"\");\n }\n } catch {\n // Connection failed or timeout — don't warn here, proxy error page handles it\n }\n}\n\nconst program = new Command();\n\nprogram\n .name(\"openmagic\")\n .description(\"AI-powered coding toolbar for any web application\")\n .version(VERSION)\n .option(\"-p, --port <port>\", \"Dev server port to proxy\", \"\")\n .option(\n \"-l, --listen <port>\",\n \"Port for the OpenMagic proxy\",\n \"4567\"\n )\n .option(\n \"-r, --root <paths...>\",\n \"Project root directories (defaults to cwd)\"\n )\n .option(\"--no-open\", \"Don't auto-open browser\")\n .option(\"--host <host>\", \"Dev server host\", \"localhost\")\n .action(async (opts) => {\n console.log(\"\");\n console.log(\n \" 🪄 \" + chalk.bold.hex(\"#6c5ce7\")(\"OpenMagic\") + chalk.dim(` v${VERSION}`) + \" ✨\"\n );\n console.log(chalk.dim(\" AI coding toolbar for any web app\"));\n console.log(\"\");\n\n let targetPort: number;\n let targetHost = opts.host;\n\n if (opts.port) {\n // User specified a port\n targetPort = parseInt(opts.port, 10);\n const isRunning = await isPortOpen(targetPort);\n if (!isRunning) {\n // Port specified but not running — offer to start it\n const started = await offerToStartDevServer(targetPort);\n if (!started) {\n process.exit(1);\n }\n // Use port detected from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\n const recheck = await detectDevServer();\n if (recheck) { targetPort = recheck.port; targetHost = recheck.host; }\n }\n }\n } else {\n // Auto-detect running dev server\n console.log(chalk.dim(\" Scanning for dev server...\"));\n const detected = await detectDevServer();\n\n if (detected && detected.fromScripts) {\n // Trusted detection via package.json scripts\n targetPort = detected.port;\n targetHost = detected.host;\n } else if (detected && !detected.fromScripts) {\n // Found a port via generic scan — confirm with user\n const answer = await ask(\n chalk.yellow(` Found a server on port ${detected.port}. Is this your project's dev server? `) +\n chalk.dim(\"(y/n) \")\n );\n if (answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\" || answer === \"\") {\n targetPort = detected.port;\n targetHost = detected.host;\n } else {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n process.exit(0);\n }\n } else {\n // No server running — try to detect and start from package.json\n const started = await offerToStartDevServer();\n if (!started) {\n process.exit(1);\n }\n // Use port from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\n const redetected = await detectDevServer();\n if (!redetected) {\n console.log(chalk.red(\" ✗ Could not detect the dev server after starting.\"));\n console.log(chalk.dim(\" Try specifying the port: npx openmagic --port 3000\"));\n console.log(\"\");\n process.exit(1);\n }\n targetPort = redetected.port;\n targetHost = redetected.host;\n }\n }\n }\n\n // Detect framework for diagnostic hints (even if server was already running)\n if (!detectedFramework) {\n const scripts = detectDevScripts();\n if (scripts.length > 0) detectedFramework = scripts[0].framework;\n }\n\n console.log(\n chalk.green(` ✓ Dev server running at ${targetHost}:${targetPort}`)\n );\n\n // Set up roots\n const roots = (opts.root || [process.cwd()]).map((r: string) =>\n resolve(r)\n );\n\n // Save roots to config\n const config = loadConfig();\n saveConfig({ ...config, roots, targetPort });\n\n // Generate session token\n generateSessionToken();\n\n // Find available port (single port — proxy + toolbar + WS all on same origin)\n let proxyPort = parseInt(opts.listen, 10);\n while (await isPortOpen(proxyPort)) {\n proxyPort++;\n if (proxyPort > parseInt(opts.listen, 10) + 100) {\n console.log(chalk.red(\" Could not find an available port.\"));\n process.exit(1);\n }\n }\n\n // Single server: proxy + toolbar + WebSocket all on one port\n const proxyServer = createProxyServer(targetHost, targetPort!, roots);\n\n proxyServer.listen(proxyPort, \"localhost\", async () => {\n const proxyUrl = `http://localhost:${proxyPort}`;\n console.log(\"\");\n console.log(chalk.bold.green(\" Ready!\"));\n console.log(\"\");\n console.log(\n chalk.bold(\" → \") + chalk.bold.underline.cyan(proxyUrl)\n );\n console.log(\"\");\n\n await healthCheck(proxyPort, targetPort!);\n\n // Validate the upstream app actually serves content\n await validateAppHealth(targetHost, targetPort!);\n\n console.log(chalk.dim(\" Press Ctrl+C to stop.\"));\n console.log(\n chalk.dim(\" Errors below are from your dev server, not OpenMagic.\")\n );\n console.log(\"\");\n\n if (opts.open !== false) {\n open(`http://localhost:${proxyPort}`).catch(() => {});\n }\n });\n\n // Graceful shutdown\n const shutdown = () => {\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n cleanupBackups();\n proxyServer.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n });\n\n// --- Smart Dev Server Start ---\n\nasync function offerToStartDevServer(expectedPort?: number): Promise<boolean> {\n const projectName = getProjectName();\n const scripts = detectDevScripts();\n\n if (scripts.length === 0) {\n // Check for plain HTML project (index.html without package.json scripts)\n const htmlPath = join(process.cwd(), \"index.html\");\n if (existsSync(htmlPath)) {\n console.log(\n chalk.dim(\" No dev scripts found, but index.html detected.\")\n );\n console.log(\"\");\n const answer = await ask(\n chalk.white(\" Serve this directory as a static site? \") + chalk.dim(\"(Y/n) \")\n );\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n return false;\n }\n\n // Start a built-in static file server using Node's http module\n const staticPort = expectedPort || 8080;\n console.log(chalk.dim(` Starting static server on port ${staticPort}...`));\n\n const staticChild = spawn(\"node\", [\"-e\", `\n const http = require(\"http\");\n const fs = require(\"fs\");\n const path = require(\"path\");\n const mimes = {\".html\":\"text/html\",\".css\":\"text/css\",\".js\":\"application/javascript\",\".json\":\"application/json\",\".png\":\"image/png\",\".jpg\":\"image/jpeg\",\".svg\":\"image/svg+xml\",\".ico\":\"image/x-icon\",\".gif\":\"image/gif\",\".woff2\":\"font/woff2\",\".woff\":\"font/woff\"};\n http.createServer((req, res) => {\n let p = path.join(${JSON.stringify(process.cwd())}, req.url === \"/\" ? \"/index.html\" : req.url);\n try { p = decodeURIComponent(p); } catch {}\n fs.readFile(p, (err, data) => {\n if (err) { res.writeHead(404); res.end(\"Not found\"); return; }\n const ext = path.extname(p).toLowerCase();\n res.writeHead(200, {\"Content-Type\": mimes[ext] || \"application/octet-stream\"});\n res.end(data);\n });\n }).listen(${staticPort}, \"localhost\", () => console.log(\"Static server ready on port ${staticPort}\"));\n `], {\n cwd: process.cwd(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: false,\n });\n\n childProcesses.push(staticChild);\n staticChild.stdout?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().trim().split(\"\\n\")) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n // Wait for it to start\n const up = await waitForPort(staticPort, 5000);\n if (up) {\n lastDetectedPort = staticPort;\n console.log(chalk.green(` ✓ Static server running on port ${staticPort}`));\n return true;\n }\n console.log(chalk.red(\" ✗ Failed to start static server.\"));\n return false;\n }\n\n console.log(\n chalk.yellow(\" ⚠ No dev server detected and no dev scripts found.\")\n );\n console.log(\"\");\n console.log(chalk.white(\" Start your dev server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // Check if dependencies are installed\n const deps = checkDependenciesInstalled();\n if (!deps.installed) {\n console.log(\n chalk.yellow(\" ⚠ node_modules/ not found. Dependencies need to be installed.\")\n );\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Run `) +\n chalk.cyan(deps.installCommand) +\n chalk.white(\"? \") +\n chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(` Run ${deps.installCommand} manually, then try again.`));\n console.log(\"\");\n return false;\n }\n\n console.log(\"\");\n console.log(chalk.dim(` Installing dependencies with ${deps.packageManager}...`));\n\n const [installCmd, ...installArgs] = deps.installCommand.split(\" \");\n const installed = await runCommand(installCmd, installArgs);\n\n if (!installed) {\n console.log(chalk.red(\" ✗ Dependency installation failed.\"));\n console.log(chalk.dim(` Try running ${deps.installCommand} manually.`));\n console.log(\"\");\n return false;\n }\n\n console.log(chalk.green(\" ✓ Dependencies installed.\"));\n console.log(\"\");\n }\n\n // Pick the best script\n let chosen = scripts[0];\n if (scripts.length === 1) {\n // Only one option\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n chalk.white(` in ${projectName}`) +\n chalk.dim(` (${chosen.framework})`)\n );\n console.log(chalk.dim(` → ${chosen.command}`));\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Start it now? `) + chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n } else {\n // Multiple scripts — let user pick\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found ${scripts.length} dev scripts in ${projectName}:`)\n );\n console.log(\"\");\n\n scripts.forEach((s, i) => {\n console.log(\n chalk.cyan(` ${i + 1}) `) +\n chalk.white(`npm run ${s.name}`) +\n chalk.dim(` — ${s.framework} (port ${s.defaultPort})`)\n );\n console.log(chalk.dim(` ${s.command}`));\n });\n\n console.log(\"\");\n const answer = await ask(\n chalk.white(` Which one to start? `) +\n chalk.dim(`(1-${scripts.length}, or n to cancel) `)\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\" || answer === \"\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n\n const idx = parseInt(answer, 10) - 1;\n if (idx < 0 || idx >= scripts.length || isNaN(idx)) {\n // Default to first\n chosen = scripts[0];\n } else {\n chosen = scripts[idx];\n }\n }\n\n // Track framework for diagnostic hints later\n detectedFramework = chosen.framework;\n\n // Pre-flight: check Node.js version compatibility\n const compat = checkNodeCompatibility(chosen.framework);\n if (!compat.ok) {\n console.log(chalk.red(`\\n ✗ ${compat.message}`));\n console.log(\"\");\n console.log(chalk.white(\" Switch Node.js version before running:\"));\n console.log(chalk.cyan(\" nvm use 20\"));\n console.log(chalk.dim(\" # then re-run: npx openmagic\"));\n console.log(\"\");\n return false;\n }\n\n // Start the dev server\n let port = expectedPort || chosen.defaultPort;\n\n // Check if the expected port is already occupied by another process\n let portChanged = false;\n if (await isPortOpen(port)) {\n const owned = verifyPortOwnership(port, process.cwd());\n if (owned === true) {\n // Port is occupied by this project — already running\n console.log(chalk.green(` ✓ Dev server already running on port ${port}`));\n lastDetectedPort = port;\n return true;\n }\n // Port is taken by something else — find a free one\n const altPort = await findAvailablePort(port + 1);\n console.log(\"\");\n console.log(\n chalk.yellow(` ⚠ Port ${port} is already in use by another process.`)\n );\n console.log(\n chalk.dim(` Starting on port ${altPort} instead.`)\n );\n port = altPort;\n portChanged = true;\n }\n\n console.log(\"\");\n console.log(\n chalk.dim(` Starting `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n (portChanged ? chalk.dim(` (port ${port})`) : \"\") +\n chalk.dim(\"...\")\n );\n\n // Use the correct package manager run command\n const depsInfo = checkDependenciesInstalled();\n const runCmd = depsInfo.packageManager === \"yarn\" ? \"yarn\" :\n depsInfo.packageManager === \"pnpm\" ? \"pnpm\" :\n depsInfo.packageManager === \"bun\" ? \"bun\" : \"npm\";\n const runArgs = runCmd === \"npm\" ? [\"run\", chosen.name] : [chosen.name];\n\n // If port was changed due to conflict, pass --port to frameworks that accept it\n const PORT_FLAG_FRAMEWORKS = new Set([\"Next.js\", \"Vite\", \"Angular\", \"Vue CLI\", \"Astro\", \"Remix\", \"SvelteKit\", \"Nuxt\", \"Create React App\", \"Gatsby\", \"Parcel\", \"Webpack\"]);\n if (portChanged && PORT_FLAG_FRAMEWORKS.has(chosen.framework)) {\n if (runCmd === \"npm\") {\n runArgs.push(\"--\", \"--port\", String(port));\n } else {\n runArgs.push(\"--port\", String(port));\n }\n }\n\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(runCmd, runArgs, {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: {\n ...process.env,\n PORT: String(port),\n BROWSER: \"none\",\n BROWSER_NONE: \"true\",\n },\n });\n } catch (e: unknown) {\n console.log(chalk.red(` ✗ Failed to start: ${(e as Error).message}`));\n return false;\n }\n\n childProcesses.push(child);\n let childExited = false;\n\n child.on(\"error\", (err) => {\n childExited = true;\n console.log(chalk.red(`\\n ✗ Failed to start: ${err.message}`));\n });\n\n child.on(\"exit\", (code) => {\n childExited = true;\n if (code !== null && code !== 0) {\n console.log(chalk.red(`\\n ✗ Dev server exited with code ${code}`));\n }\n });\n\n // Clean up all child processes on exit\n const cleanup = () => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGTERM\"); } catch {}\n }\n setTimeout(() => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGKILL\"); } catch {}\n }\n }, 3000);\n };\n process.once(\"exit\", cleanup);\n process.once(\"SIGINT\", cleanup);\n process.once(\"SIGTERM\", cleanup);\n\n // Wait for the port to open via TCP polling\n console.log(\n chalk.dim(` Waiting for dev server on port ${port}...`)\n );\n\n const isUp = await waitForPort(port, 60000, () => childExited);\n\n if (isUp) {\n lastDetectedPort = port;\n console.log(\"\");\n return true;\n }\n\n // Port didn't open but process is still running — scan nearby ports\n if (!childExited) {\n const scanPorts = [port, 3000, 3001, 3002, 5173, 5174, 4200, 8080, 8000, 4000, 1234, 4321, 3333, 8081]\n .filter((p, i, a) => a.indexOf(p) === i); // dedupe\n for (const scanPort of scanPorts) {\n if (await isPortOpen(scanPort)) {\n const owned = verifyPortOwnership(scanPort, process.cwd());\n if (owned === false) continue;\n console.log(\n chalk.green(`\\n ✓ Dev server found on port ${scanPort}.`)\n );\n lastDetectedPort = scanPort;\n return true;\n }\n }\n }\n\n if (childExited) {\n console.log(\n chalk.red(` ✗ Dev server failed to start.`)\n );\n console.log(\"\");\n\n // Check for Node.js version mismatch\n try {\n const pkgPath = join(process.cwd(), \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n if (pkg.engines?.node) {\n console.log(chalk.yellow(` This project requires Node.js ${pkg.engines.node}`));\n console.log(chalk.dim(` You are running Node.js ${process.version}`));\n console.log(\"\");\n }\n }\n } catch {}\n\n // Also check framework-specific requirements\n if (chosen?.framework) {\n const compat = checkNodeCompatibility(chosen.framework);\n if (!compat.ok) {\n console.log(chalk.yellow(` ${compat.message}`));\n console.log(chalk.dim(\" Switch with: nvm use 20\"));\n console.log(\"\");\n }\n }\n\n console.log(chalk.white(\" Options:\"));\n console.log(chalk.dim(\" 1. Fix the error above and try again\"));\n console.log(chalk.dim(\" 2. Start the server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // All detection methods exhausted\n console.log(\n chalk.yellow(`\\n ⚠ Could not find the dev server after 60s.`)\n );\n console.log(chalk.dim(` Check the output above for errors.`));\n console.log(chalk.dim(` Or start the server manually, then run:`));\n console.log(chalk.cyan(` npx openmagic --port <your-port>`));\n console.log(\"\");\n return false;\n}\n\nprogram.parse();\n","import http from \"node:http\";\nimport httpProxy from \"http-proxy\";\nimport { getSessionToken } from \"./security.js\";\nimport { attachOpenMagic } from \"./server.js\";\n\n/**\n * Create a single-port proxy server that:\n * 1. Serves /__openmagic__/* (toolbar bundle, health, WebSocket)\n * 2. Proxies everything else to the dev server\n * 3. Injects the toolbar script into HTML responses\n */\nexport function createProxyServer(\n targetHost: string,\n targetPort: number,\n roots: string[]\n): http.Server {\n const proxy = httpProxy.createProxyServer({\n target: `http://${targetHost}:${targetPort}`,\n selfHandleResponse: true,\n changeOrigin: true, // Rewrite Host header to match upstream — required by Vite 5.4+ and some Next.js setups\n // ws: false — we handle WebSocket upgrades manually in server.on(\"upgrade\")\n });\n\n const token = getSessionToken();\n\n // Strip Accept-Encoding on HTML requests so upstream sends uncompressed (enables streaming injection)\n // Only apply to regular HTTP requests, not WebSocket upgrades\n proxy.on(\"proxyReq\", (proxyReq, req) => {\n const accept = req.headers.accept || \"\";\n // Only strip for requests that might return HTML (not for API calls, assets, WS upgrades)\n if (accept.includes(\"text/html\") || accept.includes(\"*/*\") || !accept) {\n proxyReq.removeHeader(\"Accept-Encoding\");\n }\n });\n\n proxy.on(\"proxyRes\", (proxyRes, req, res) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isHtml = contentType.includes(\"text/html\");\n const status = proxyRes.statusCode || 200;\n\n if (!isHtml && status < 400) {\n // Non-HTML success: pass through unchanged\n res.writeHead(status, proxyRes.headers);\n proxyRes.on(\"error\", () => { try { res.end(); } catch {} });\n proxyRes.pipe(res);\n return;\n }\n\n if (isHtml) {\n // HTML response: stream through and append toolbar script\n const headers = { ...proxyRes.headers };\n delete headers[\"content-length\"];\n delete headers[\"content-encoding\"];\n delete headers[\"transfer-encoding\"];\n delete headers[\"content-security-policy\"];\n delete headers[\"content-security-policy-report-only\"];\n delete headers[\"x-content-security-policy\"];\n delete headers[\"etag\"];\n delete headers[\"last-modified\"];\n headers[\"cache-control\"] = \"no-store\";\n\n res.writeHead(status, headers);\n proxyRes.on(\"error\", () => { try { res.end(buildInjectionScript(token)); } catch {} });\n proxyRes.pipe(res, { end: false });\n proxyRes.on(\"end\", () => {\n res.end(buildInjectionScript(token));\n });\n return;\n }\n\n // Non-HTML error (4xx/5xx) — wrap in HTML with toolbar so user can still interact\n const chunks: Buffer[] = [];\n let totalSize = 0;\n proxyRes.on(\"data\", (c: Buffer) => { if (totalSize < 16384) { chunks.push(c); totalSize += c.length; } });\n proxyRes.on(\"error\", () => { try { res.end(); } catch {} });\n proxyRes.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString(\"utf-8\").slice(0, 2000);\n const toolbarScript = buildInjectionScript(token);\n res.writeHead(status, { \"Content-Type\": \"text/html\", \"Cache-Control\": \"no-store\" });\n res.end(`<html><head><meta charset=\"utf-8\"><title>Error ${status}</title></head>\n<body style=\"font-family:system-ui;padding:40px;background:#0f0f1e;color:#e0e0e0;\">\n<h2 style=\"color:#e94560;\">Error ${status}</h2>\n<pre style=\"color:#888;white-space:pre-wrap;max-width:800px;overflow:auto;font-size:13px;\">${body.replace(/</g,\"<\")}</pre>\n<p style=\"color:#555;font-size:13px;\">This error is from your dev server, not OpenMagic. The toolbar is available below.</p>\n${toolbarScript}\n</body></html>`);\n });\n });\n\n proxy.on(\"error\", (err, _req, res) => {\n if (res instanceof http.ServerResponse && !res.headersSent) {\n const toolbarScript = buildInjectionScript(token);\n res.writeHead(502, { \"Content-Type\": \"text/html\" });\n res.end(\n `<html><body style=\"font-family:system-ui;padding:40px;background:#1a1a2e;color:#e0e0e0;\">\n <h2 style=\"color:#e94560;\">OpenMagic — Cannot connect to dev server</h2>\n <p>Could not reach <code>${targetHost}:${targetPort}</code></p>\n <p style=\"color:#888;\">Make sure your dev server is running, then refresh this page.</p>\n <p style=\"color:#666;font-size:13px;\">${err.message}</p>\n ${toolbarScript}\n </body></html>`\n );\n } else if (res && typeof (res as any).destroy === \"function\") {\n // WebSocket socket error — destroy cleanly\n try { (res as any).destroy(); } catch {}\n }\n });\n\n // Shared references — set after server creation\n let omHandle: ((req: http.IncomingMessage, res: http.ServerResponse) => boolean) | null = null;\n let omUpgrade: ((req: http.IncomingMessage, socket: any, head: Buffer) => boolean) | null = null;\n\n const server = http.createServer((req, res) => {\n if (omHandle && omHandle(req, res)) return;\n proxy.web(req, res);\n });\n\n // Attach OpenMagic endpoints to THIS server (same port, noServer WSS)\n const om = attachOpenMagic(server, roots);\n omHandle = om.handleRequest;\n omUpgrade = om.handleUpgrade;\n\n // Single upgrade handler — OpenMagic WS first, everything else to dev server\n server.on(\"upgrade\", (req, socket, head) => {\n // Try OpenMagic WebSocket first\n if (omUpgrade && omUpgrade(req, socket, head)) return;\n // Everything else (HMR, hot reload, etc.) forwarded to dev server\n proxy.ws(req, socket, head);\n });\n\n return server;\n}\n\n// Same-origin injection — toolbar.js and WS served from THIS server\nfunction buildInjectionScript(token: string): string {\n return `<script src=\"/__openmagic__/toolbar.js?v=${Date.now()}\" data-openmagic=\"true\" data-openmagic-token=\"${token}\" defer></script>`;\n}\n","import { randomBytes } from \"node:crypto\";\n\nlet sessionToken: string | null = null;\n\nexport function generateSessionToken(): string {\n sessionToken = randomBytes(32).toString(\"hex\");\n return sessionToken;\n}\n\nexport function getSessionToken(): string {\n if (!sessionToken) {\n return generateSessionToken();\n }\n return sessionToken;\n}\n\nexport function validateToken(token: string): boolean {\n return token === sessionToken;\n}\n","import http from \"node:http\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { WebSocketServer, WebSocket } from \"ws\";\nimport { validateToken } from \"./security.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { readFileSafe, writeFileSafe, listFiles, getProjectTree, grepFiles, getBackupForFile, cleanupBackups } from \"./filesystem.js\";\nimport type {\n WsMessage,\n HandshakePayload,\n FsReadPayload,\n FsWritePayload,\n FsListPayload,\n LlmChatPayload,\n ConfigSetPayload,\n OpenMagicConfig,\n} from \"./shared-types.js\";\nimport { handleLlmChat } from \"./llm/proxy.js\";\nimport { MODEL_REGISTRY } from \"./llm/registry.js\";\n\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ── Server-side log buffer ──\nconst MAX_SERVER_LOGS = 200;\nconst serverLogs: { level: string; msg: string; ts: number }[] = [];\n\nfunction captureServerLog(level: string, ...args: any[]) {\n const msg = args.map(a => {\n try { return typeof a === \"object\" ? JSON.stringify(a).slice(0, 500) : String(a); }\n catch { return String(a); }\n }).join(\" \");\n serverLogs.push({ level, msg, ts: Date.now() });\n if (serverLogs.length > MAX_SERVER_LOGS) serverLogs.shift();\n}\n\n// Intercept console to buffer server logs\nconst _origLog = console.log, _origWarn = console.warn, _origErr = console.error, _origInfo = console.info;\nconsole.log = (...a: any[]) => { captureServerLog(\"log\", ...a); _origLog(...a); };\nconsole.warn = (...a: any[]) => { captureServerLog(\"warn\", ...a); _origWarn(...a); };\nconsole.error = (...a: any[]) => { captureServerLog(\"error\", ...a); _origErr(...a); };\nconsole.info = (...a: any[]) => { captureServerLog(\"info\", ...a); _origInfo(...a); };\n\ninterface ClientState {\n authenticated: boolean;\n}\n\n/**\n * Attach OpenMagic endpoints to an existing HTTP server.\n * Handles: toolbar bundle serving, health check, WebSocket.\n * Returns a request handler and the WSS instance.\n */\nexport function attachOpenMagic(\n httpServer: http.Server,\n roots: string[]\n): {\n wss: WebSocketServer;\n handleRequest: (req: http.IncomingMessage, res: http.ServerResponse) => boolean;\n handleUpgrade: (req: http.IncomingMessage, socket: any, head: Buffer) => boolean;\n} {\n\n // Request handler for /__openmagic__/ paths — returns true if handled\n function handleRequest(req: http.IncomingMessage, res: http.ServerResponse): boolean {\n if (!req.url?.startsWith(\"/__openmagic__/\")) return false;\n\n // Strip query string for path matching (e.g., toolbar.js?v=123)\n const urlPath = req.url.split(\"?\")[0];\n\n if (urlPath === \"/__openmagic__/toolbar.js\") {\n serveToolbarBundle(res);\n return true;\n }\n\n if (urlPath === \"/__openmagic__/health\") {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(JSON.stringify({ status: \"ok\", version: VERSION }));\n return true;\n }\n\n return false;\n }\n\n // WebSocket server — noServer mode so it doesn't intercept non-OpenMagic upgrades\n const wss = new WebSocketServer({ noServer: true });\n\n const clientStates = new WeakMap<WebSocket, ClientState>();\n\n wss.on(\"connection\", (ws, req) => {\n const origin = req.headers.origin || \"\";\n if (origin && !origin.startsWith(\"http://localhost\") && !origin.startsWith(\"http://127.0.0.1\")) {\n ws.close(4003, \"Forbidden origin\");\n return;\n }\n clientStates.set(ws, { authenticated: false });\n\n ws.on(\"message\", async (data) => {\n let msg: WsMessage;\n try {\n msg = JSON.parse(data.toString());\n } catch {\n sendError(ws, \"parse_error\", \"Invalid JSON\");\n return;\n }\n\n const state = clientStates.get(ws)!;\n\n if (!state.authenticated && msg.type !== \"handshake\") {\n sendError(ws, \"auth_required\", \"Handshake required\");\n return;\n }\n\n try {\n await handleMessage(ws, msg, state, roots);\n } catch (e: unknown) {\n sendError(ws, \"internal_error\", (e as Error).message, msg.id);\n }\n });\n\n ws.on(\"close\", () => {\n clientStates.delete(ws);\n });\n });\n\n // Handle WebSocket upgrades for OpenMagic path only\n function handleUpgrade(req: http.IncomingMessage, socket: any, head: Buffer): boolean {\n const urlPath = (req.url || \"\").split(\"?\")[0];\n if (urlPath === \"/__openmagic__/ws\") {\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit(\"connection\", ws, req);\n });\n return true;\n }\n return false;\n }\n\n return { wss, handleRequest, handleUpgrade };\n}\n\nasync function handleMessage(\n ws: WebSocket,\n msg: WsMessage,\n state: ClientState,\n roots: string[]\n): Promise<void> {\n switch (msg.type) {\n case \"handshake\": {\n const payload = msg.payload as HandshakePayload;\n if (!payload?.token) {\n sendError(ws, \"invalid_payload\", \"Missing token in handshake\", msg.id);\n ws.close();\n return;\n }\n if (!validateToken(payload.token)) {\n sendError(ws, \"auth_failed\", \"Invalid token\", msg.id);\n ws.close();\n return;\n }\n state.authenticated = true;\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"handshake.ok\",\n payload: {\n version: VERSION,\n roots,\n config: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n apiKeys: Object.fromEntries(Object.entries(config.apiKeys || {}).map(([k]) => [k, true])),\n },\n },\n });\n break;\n }\n\n case \"fs.read\": {\n const payload = msg.payload as FsReadPayload;\n if (!payload?.path) {\n sendError(ws, \"invalid_payload\", \"Missing path\", msg.id);\n break;\n }\n const result = readFileSafe(payload.path, roots);\n if (\"error\" in result) {\n sendError(ws, \"fs_error\", result.error, msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.content\",\n payload: { path: payload.path, content: result.content },\n });\n }\n break;\n }\n\n case \"fs.write\": {\n const payload = msg.payload as FsWritePayload;\n if (!payload?.path || payload.content === undefined) {\n sendError(ws, \"invalid_payload\", \"Missing path or content\", msg.id);\n break;\n }\n const writeResult = writeFileSafe(payload.path, payload.content, roots);\n if (!writeResult.ok) {\n sendError(ws, \"fs_error\", writeResult.error || \"Write failed\", msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.written\",\n payload: { path: payload.path, ok: true },\n });\n }\n break;\n }\n\n case \"fs.undo\": {\n const payload = msg.payload as { path: string };\n if (!payload?.path) { sendError(ws, \"invalid_payload\", \"Missing path\", msg.id); break; }\n const backupPath = getBackupForFile(payload.path);\n if (!backupPath) { sendError(ws, \"fs_error\", \"No backup found\", msg.id); break; }\n try {\n const backupContent = readFileSync(backupPath, \"utf-8\");\n const writeResult = writeFileSafe(payload.path, backupContent, roots);\n if (!writeResult.ok) { sendError(ws, \"fs_error\", writeResult.error || \"Undo failed\", msg.id); break; }\n send(ws, { id: msg.id, type: \"fs.undone\", payload: { path: payload.path, ok: true } });\n } catch (e: unknown) {\n sendError(ws, \"fs_error\", `Backup read failed: ${(e as Error).message}`, msg.id);\n }\n break;\n }\n\n case \"fs.list\": {\n const payload = msg.payload as FsListPayload | undefined;\n const root = payload?.root || roots[0];\n const files = listFiles(root, roots);\n send(ws, {\n id: msg.id,\n type: \"fs.tree\",\n payload: { files, projectTree: getProjectTree(roots) },\n });\n break;\n }\n\n case \"llm.chat\": {\n const payload = msg.payload as LlmChatPayload;\n const config = loadConfig();\n\n // Resolve API key: per-provider keys first, then global fallback\n const provider = payload.provider || config.provider || \"openai\";\n const apiKey = config.apiKeys?.[provider] || config.apiKey || \"\";\n const providerMeta = MODEL_REGISTRY?.[provider];\n\n if (!apiKey && !providerMeta?.local) {\n sendError(ws, \"config_error\", \"API key not configured\", msg.id);\n return;\n }\n\n await handleLlmChat(\n {\n provider,\n model: payload.model || config.model || MODEL_REGISTRY[provider]?.models[0]?.id || \"gpt-4o\",\n apiKey,\n messages: payload.messages,\n context: payload.context,\n },\n (chunk) => {\n send(ws, { id: msg.id, type: \"llm.chunk\", payload: { delta: chunk } });\n },\n (result) => {\n send(ws, { id: msg.id, type: \"llm.done\", payload: result });\n },\n (error) => {\n send(ws, { id: msg.id, type: \"llm.error\", payload: { message: error } });\n }\n );\n break;\n }\n\n case \"config.get\": {\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"config.value\",\n payload: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!(config.apiKeys?.[config.provider || \"\"] || config.apiKey),\n roots: config.roots || roots,\n apiKeys: Object.fromEntries(\n Object.entries(config.apiKeys || {}).map(([k]) => [k, true])\n ),\n },\n });\n break;\n }\n\n case \"config.set\": {\n const payload = msg.payload as ConfigSetPayload;\n const updates: Partial<OpenMagicConfig> = {};\n if (payload.provider !== undefined) updates.provider = payload.provider;\n if (payload.model !== undefined) updates.model = payload.model;\n // Per-provider key storage\n if (payload.apiKey !== undefined && payload.provider) {\n const existing = loadConfig();\n const apiKeys = { ...(existing.apiKeys || {}) };\n apiKeys[payload.provider] = payload.apiKey;\n updates.apiKeys = apiKeys;\n updates.apiKey = payload.apiKey; // backward compat\n } else if (payload.apiKey !== undefined) {\n updates.apiKey = payload.apiKey;\n }\n const result = saveConfig(updates);\n if (!result.ok) {\n sendError(ws, \"config_error\", result.error || \"Failed to save\", msg.id);\n } else {\n send(ws, { id: msg.id, type: \"config.saved\", payload: { ok: true } });\n }\n break;\n }\n\n case \"fs.grep\": {\n const payload = msg.payload as { pattern: string; path?: string };\n if (!payload?.pattern) {\n sendError(ws, \"invalid_payload\", \"Missing pattern\", msg.id);\n break;\n }\n const searchRoot = payload.path ? join(roots[0] || process.cwd(), payload.path) : (roots[0] || process.cwd());\n const results = grepFiles(payload.pattern, searchRoot, roots);\n send(ws, { id: msg.id, type: \"fs.grep.result\", payload: { results } });\n break;\n }\n\n case \"debug.logs\": {\n send(ws, {\n id: msg.id,\n type: \"debug.logs\",\n payload: {\n logs: serverLogs.slice(-100),\n nodeVersion: process.version,\n platform: process.platform,\n arch: process.arch,\n uptime: Math.round(process.uptime()),\n memoryMB: Math.round(process.memoryUsage().rss / 1024 / 1024),\n pid: process.pid,\n cwd: process.cwd(),\n },\n });\n break;\n }\n\n default:\n sendError(ws, \"unknown_type\", `Unknown message type: ${msg.type}`, msg.id);\n }\n}\n\nfunction send(ws: WebSocket, msg: WsMessage): void {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nfunction sendError(ws: WebSocket, code: string, message: string, id?: string): void {\n send(ws, { id: id || \"error\", type: \"error\", payload: { code, message } });\n}\n\nfunction serveToolbarBundle(res: http.ServerResponse): void {\n const bundlePaths = [\n join(__dirname, \"toolbar\", \"index.global.js\"),\n join(__dirname, \"..\", \"dist\", \"toolbar\", \"index.global.js\"),\n ];\n\n for (const bundlePath of bundlePaths) {\n try {\n if (existsSync(bundlePath)) {\n const content = readFileSync(bundlePath, \"utf-8\");\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n \"Cache-Control\": \"no-cache\",\n });\n res.end(content);\n return;\n }\n } catch {\n continue;\n }\n }\n\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(`(function(){var d=document.createElement(\"div\");d.style.cssText=\"position:fixed;bottom:20px;right:20px;background:#1a1a2e;color:#e94560;padding:16px 24px;border-radius:12px;font-family:system-ui;font-size:14px;z-index:2147483647;box-shadow:0 4px 24px rgba(0,0,0,0.3);\";d.textContent=\"OpenMagic: Toolbar bundle not found.\";document.body.appendChild(d);})();`);\n}\n","import { readFileSync, writeFileSync, renameSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { OpenMagicConfig } from \"./shared-types.js\";\n\nconst CONFIG_DIR = join(homedir(), \".openmagic\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function loadConfig(): Partial<OpenMagicConfig> {\n ensureConfigDir();\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n try {\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(updates: Partial<OpenMagicConfig>): { ok: boolean; error?: string } {\n try {\n ensureConfigDir();\n const existing = loadConfig();\n const merged = { ...existing, ...updates };\n const tmpFile = CONFIG_FILE + \".tmp\";\n writeFileSync(tmpFile, JSON.stringify(merged, null, 2), { encoding: \"utf-8\", mode: 0o600 });\n renameSync(tmpFile, CONFIG_FILE);\n return { ok: true };\n } catch (e: unknown) {\n return { ok: false, error: (e as Error).message };\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","import {\n readFileSync,\n writeFileSync,\n existsSync,\n statSync,\n lstatSync,\n readdirSync,\n copyFileSync,\n mkdirSync,\n realpathSync,\n unlinkSync,\n rmSync,\n} from \"node:fs\";\nimport { join, resolve, relative, dirname, extname } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { createHash } from \"node:crypto\";\nimport type { FileEntry } from \"./shared-types.js\";\n\nconst IGNORED_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \".nuxt\",\n \".svelte-kit\",\n \"dist\",\n \"build\",\n \".cache\",\n \".turbo\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \".DS_Store\",\n]);\n\nconst IGNORED_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".ico\",\n \".webp\",\n \".mp4\",\n \".mp3\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".lock\",\n]);\n\nexport function isPathSafe(filePath: string, roots: string[]): boolean {\n const resolved = resolve(filePath);\n\n // Also check realpath to prevent symlink escape\n let real: string;\n try {\n real = realpathSync(resolved);\n } catch {\n // File doesn't exist yet (for writes) — use resolved path\n real = resolved;\n }\n\n return roots.some((root) => {\n const resolvedRoot = resolve(root);\n const rel = relative(resolvedRoot, resolved);\n const realRel = relative(resolvedRoot, real);\n return (\n (!rel.startsWith(\"..\") && !rel.startsWith(\"/\") && !rel.startsWith(\"\\\\\")) &&\n (!realRel.startsWith(\"..\") && !realRel.startsWith(\"/\") && !realRel.startsWith(\"\\\\\"))\n );\n });\n}\n\nexport function readFileSafe(\n filePath: string,\n roots: string[]\n): { content: string } | { error: string } {\n if (!isPathSafe(filePath, roots)) {\n return { error: \"Path is outside allowed roots\" };\n }\n if (!existsSync(filePath)) {\n return { error: \"File not found\" };\n }\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return { content };\n } catch (e: unknown) {\n return { error: `Failed to read file: ${(e as Error).message}` };\n }\n}\n\n// ── Backup Management (temp directory) ──\nconst BACKUP_DIR = join(tmpdir(), \"openmagic-backups\");\nconst backupMap = new Map<string, string>(); // originalPath -> backupTempPath\n\nfunction getBackupPath(filePath: string): string {\n const hash = createHash(\"md5\").update(resolve(filePath)).digest(\"hex\").slice(0, 12);\n const name = filePath.split(/[/\\\\]/).pop() || \"file\";\n return join(BACKUP_DIR, `${hash}_${name}`);\n}\n\nexport function getBackupForFile(filePath: string): string | undefined {\n return backupMap.get(resolve(filePath));\n}\n\nexport function cleanupBackups(): void {\n try {\n if (existsSync(BACKUP_DIR)) {\n rmSync(BACKUP_DIR, { recursive: true, force: true });\n }\n } catch {}\n backupMap.clear();\n}\n\nexport function writeFileSafe(\n filePath: string,\n content: string,\n roots: string[]\n): { ok: boolean; error?: string; backupPath?: string } {\n if (!isPathSafe(filePath, roots)) {\n return { ok: false, error: \"Path is outside allowed roots\" };\n }\n\n try {\n // Create backup in temp directory\n let backupPath: string | undefined;\n if (existsSync(filePath)) {\n if (!existsSync(BACKUP_DIR)) mkdirSync(BACKUP_DIR, { recursive: true });\n backupPath = getBackupPath(filePath);\n copyFileSync(filePath, backupPath);\n backupMap.set(resolve(filePath), backupPath);\n }\n\n // Ensure directory exists\n const dir = dirname(filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(filePath, content, \"utf-8\");\n return { ok: true, backupPath };\n } catch (e: unknown) {\n return { ok: false, error: `Failed to write file: ${(e as Error).message}` };\n }\n}\n\nconst MAX_LIST_ENTRIES = 2000;\n\nexport function listFiles(\n rootPath: string,\n roots: string[],\n maxDepth: number = 4\n): FileEntry[] {\n if (!isPathSafe(rootPath, roots)) {\n return [];\n }\n\n const entries: FileEntry[] = [];\n\n function walk(dir: string, depth: number): void {\n if (depth > maxDepth || entries.length >= MAX_LIST_ENTRIES) return;\n\n let items: string[];\n try {\n items = readdirSync(dir);\n } catch {\n return;\n }\n\n for (const item of items) {\n if (entries.length >= MAX_LIST_ENTRIES) return;\n if (IGNORED_DIRS.has(item)) continue;\n if (item.startsWith(\".\") && item !== \".env.example\") continue;\n\n const fullPath = join(dir, item);\n let stat;\n try {\n stat = lstatSync(fullPath);\n } catch {\n continue;\n }\n if (stat.isSymbolicLink()) continue;\n\n const relPath = relative(rootPath, fullPath);\n\n if (stat.isDirectory()) {\n entries.push({ path: relPath, type: \"dir\", name: item });\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!IGNORED_EXTENSIONS.has(ext)) {\n entries.push({ path: relPath, type: \"file\", name: item });\n }\n }\n }\n }\n\n walk(rootPath, 0);\n return entries;\n}\n\nconst GREP_EXTENSIONS = new Set([\n \".js\", \".jsx\", \".ts\", \".tsx\", \".mjs\", \".cjs\",\n \".vue\", \".svelte\", \".astro\",\n \".html\", \".htm\", \".css\", \".scss\", \".less\",\n \".json\", \".md\", \".yaml\", \".yml\",\n \".php\", \".py\", \".rb\",\n]);\n\nconst MAX_GREP_FILE_SIZE = 256 * 1024; // 256KB — skip large generated/bundled files\nconst MAX_GREP_FILES_SCANNED = 500; // stop walking after scanning this many files\n\nexport function grepFiles(\n pattern: string,\n searchRoot: string,\n roots: string[],\n maxResults: number = 30\n): { file: string; lineNum: number; line: string }[] {\n if (!isPathSafe(searchRoot, roots)) return [];\n\n const results: { file: string; lineNum: number; line: string }[] = [];\n const lowerPattern = pattern.toLowerCase();\n let filesScanned = 0;\n\n function walk(dir: string, depth: number): void {\n if (depth > 6 || results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n let items: string[];\n try { items = readdirSync(dir); } catch { return; }\n\n for (const item of items) {\n if (results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n if (IGNORED_DIRS.has(item) || (item.startsWith(\".\") && item !== \".env.example\")) continue;\n\n const fullPath = join(dir, item);\n let stat;\n try { stat = lstatSync(fullPath); } catch { continue; }\n if (stat.isSymbolicLink()) continue;\n\n if (stat.isDirectory()) {\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!GREP_EXTENSIONS.has(ext)) continue;\n if (stat.size > MAX_GREP_FILE_SIZE) continue; // skip large files\n filesScanned++;\n\n try {\n const content = readFileSync(fullPath, \"utf-8\");\n const lines = content.split(\"\\n\");\n let fileMatches = 0;\n for (let i = 0; i < lines.length && fileMatches < 5; i++) {\n if (lines[i].toLowerCase().includes(lowerPattern)) {\n results.push({\n file: relative(searchRoot, fullPath),\n lineNum: i + 1,\n line: lines[i].trim().slice(0, 200),\n });\n fileMatches++;\n }\n }\n } catch {}\n }\n }\n }\n\n walk(searchRoot, 0);\n return results;\n}\n\nexport function getProjectTree(roots: string[]): string {\n const lines: string[] = [];\n for (const root of roots) {\n lines.push(`[${root}]`);\n const files = listFiles(root, roots, 3);\n for (const f of files) {\n const indent = f.path.split(\"/\").length - 1;\n const prefix = \" \".repeat(indent);\n const icon = f.type === \"dir\" ? \"/\" : \"\";\n lines.push(`${prefix}${f.name}${icon}`);\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n}\n","import type { ProviderRegistry } from \"../shared-types.js\";\n\nexport const MODEL_REGISTRY: ProviderRegistry = {\n // ─── OpenAI ───────────────────────────────────────────────────\n openai: {\n name: \"OpenAI\",\n models: [\n // GPT-5.4 family (March 2026 — latest flagship)\n {\n id: \"gpt-5.4\",\n name: \"GPT-5.4\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-pro\",\n name: \"GPT-5.4 Pro\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.4-mini\",\n name: \"GPT-5.4 Mini\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-nano\",\n name: \"GPT-5.4 Nano\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n // GPT-5.2 family (reasoning-focused)\n {\n id: \"gpt-5.2\",\n name: \"GPT-5.2 Thinking\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.2-pro\",\n name: \"GPT-5.2 Pro\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n // o-series reasoning models\n {\n id: \"o3\",\n name: \"o3 (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"o4-mini\",\n name: \"o4-mini (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // GPT-4.1 family\n {\n id: \"gpt-4.1\",\n name: \"GPT-4.1\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-mini\",\n name: \"GPT-4.1 Mini\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-nano\",\n name: \"GPT-4.1 Nano\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n // Codex\n {\n id: \"codex-mini-latest\",\n name: \"Codex Mini\",\n vision: false,\n context: 192000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.openai.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Anthropic ────────────────────────────────────────────────\n anthropic: {\n name: \"Anthropic\",\n models: [\n // Claude 4.6 (latest — Feb 2026)\n {\n id: \"claude-opus-4-6\",\n name: \"Claude Opus 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 128000,\n },\n },\n {\n id: \"claude-sonnet-4-6\",\n name: \"Claude Sonnet 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n // Claude 4.5\n {\n id: \"claude-haiku-4-5-20251001\",\n name: \"Claude Haiku 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 5000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Sonnet 4.5\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-5-20251101\",\n name: \"Claude Opus 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 64000,\n },\n },\n // Claude 4.0\n {\n id: \"claude-sonnet-4-20250514\",\n name: \"Claude Sonnet 4\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-20250514\",\n name: \"Claude Opus 4\",\n vision: true,\n context: 200000,\n maxOutput: 32000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 32000,\n },\n },\n ],\n apiBase: \"https://api.anthropic.com/v1\",\n keyPrefix: \"sk-ant-\",\n keyPlaceholder: \"sk-ant-...\",\n },\n\n // ─── Google Gemini ────────────────────────────────────────────\n google: {\n name: \"Google Gemini\",\n models: [\n // Gemini 3.1 (latest — Feb-Mar 2026)\n {\n id: \"gemini-3.1-pro-preview\",\n name: \"Gemini 3.1 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // Gemini 3.0\n {\n id: \"gemini-3-flash-preview\",\n name: \"Gemini 3 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-3.1-flash-lite-preview\",\n name: \"Gemini 3.1 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n // Gemini 2.5\n {\n id: \"gemini-2.5-pro\",\n name: \"Gemini 2.5 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gemini-2.5-flash\",\n name: \"Gemini 2.5 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-2.5-flash-lite\",\n name: \"Gemini 2.5 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n ],\n apiBase: \"https://generativelanguage.googleapis.com/v1beta\",\n keyPrefix: \"AI\",\n keyPlaceholder: \"AIza...\",\n },\n\n // ─── xAI (Grok) ──────────────────────────────────────────────\n xai: {\n name: \"xAI (Grok)\",\n models: [\n {\n id: \"grok-4.20-0309-reasoning\",\n name: \"Grok 4.20 Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"grok-4.20-0309-non-reasoning\",\n name: \"Grok 4.20\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n {\n id: \"grok-4-1-fast-reasoning\",\n name: \"Grok 4.1 Fast Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"grok-4-1-fast-non-reasoning\",\n name: \"Grok 4.1 Fast\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n ],\n apiBase: \"https://api.x.ai/v1\",\n keyPrefix: \"xai-\",\n keyPlaceholder: \"xai-...\",\n },\n\n // ─── DeepSeek ─────────────────────────────────────────────────\n deepseek: {\n name: \"DeepSeek\",\n models: [\n {\n id: \"deepseek-chat\",\n name: \"DeepSeek V3.2\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n },\n {\n id: \"deepseek-reasoner\",\n name: \"DeepSeek R1\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.deepseek.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Mistral ──────────────────────────────────────────────────\n mistral: {\n name: \"Mistral\",\n models: [\n {\n id: \"mistral-large-3-25-12\",\n name: \"Mistral Large 3\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-4-0-26-03\",\n name: \"Mistral Small 4\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-3-2-25-06\",\n name: \"Mistral Small 3.2\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"codestral-2508\",\n name: \"Codestral\",\n vision: false,\n context: 262144,\n maxOutput: 32768,\n },\n {\n id: \"devstral-2-25-12\",\n name: \"Devstral 2\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"magistral-medium-1-2-25-09\",\n name: \"Magistral Medium (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"magistral-small-1-2-25-09\",\n name: \"Magistral Small (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.mistral.ai/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter API key...\",\n },\n\n // ─── Groq ─────────────────────────────────────────────────────\n groq: {\n name: \"Groq\",\n models: [\n {\n id: \"meta-llama/llama-4-scout-17b-16e-instruct\",\n name: \"Llama 4 Scout 17B\",\n vision: true,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"llama-3.3-70b-versatile\",\n name: \"Llama 3.3 70B\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"llama-3.1-8b-instant\",\n name: \"Llama 3.1 8B Instant\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"qwen/qwen3-32b\",\n name: \"Qwen 3 32B\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n ],\n apiBase: \"https://api.groq.com/openai/v1\",\n keyPrefix: \"gsk_\",\n keyPlaceholder: \"gsk_...\",\n },\n\n // ─── MiniMax ───────────────────────────────────────────────────\n minimax: {\n name: \"MiniMax\",\n models: [\n { id: \"MiniMax-M2.7\", name: \"MiniMax M2.7\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.7-highspeed\", name: \"MiniMax M2.7 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5\", name: \"MiniMax M2.5\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5-highspeed\", name: \"MiniMax M2.5 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n ],\n apiBase: \"https://api.minimax.chat/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter MiniMax API key...\",\n },\n\n // ─── Moonshot / Kimi ──────────────────────────────────────────\n moonshot: {\n name: \"Kimi (Moonshot)\",\n models: [\n {\n id: \"kimi-k2.5\",\n name: \"Kimi K2.5\",\n vision: true,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"kimi-k2-thinking\",\n name: \"Kimi K2 Thinking\",\n vision: false,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.moonshot.cn/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Moonshot API key...\",\n },\n\n // ─── Alibaba Qwen (DashScope) ────────────────────────────────\n qwen: {\n name: \"Qwen (Alibaba)\",\n models: [\n { id: \"qwen3.5-plus\", name: \"Qwen 3.5 Plus\", vision: true, context: 1010000, maxOutput: 16384 },\n { id: \"qwen-plus\", name: \"Qwen Plus\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-max\", name: \"Qwen Max\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-turbo\", name: \"Qwen Turbo\", vision: false, context: 131072, maxOutput: 8192 },\n ],\n apiBase: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter DashScope API key...\",\n },\n\n // ─── Zhipu AI (GLM) ──────────────────────────────────────────\n zhipu: {\n name: \"Zhipu AI (GLM)\",\n models: [\n { id: \"glm-5\", name: \"GLM-5\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.7\", name: \"GLM-4.7\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.6\", name: \"GLM-4.6\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.5\", name: \"GLM-4.5\", vision: true, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://open.bigmodel.cn/api/paas/v4\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Zhipu API key...\",\n },\n\n // ─── ByteDance Doubao ─────────────────────────────────────────\n doubao: {\n name: \"Doubao (ByteDance)\",\n models: [\n { id: \"doubao-seed-2-0-pro\", name: \"Doubao Seed 2.0 Pro\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"doubao-seed-2-0-lite\", name: \"Doubao Seed 2.0 Lite\", vision: false, context: 131072, maxOutput: 8192 },\n { id: \"doubao-seed-2-0-code\", name: \"Doubao Seed 2.0 Code\", vision: false, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://ark.cn-beijing.volces.com/api/v3\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Volcano Engine API key...\",\n },\n\n // ─── Ollama (Local) ───────────────────────────────────────────\n ollama: {\n name: \"Ollama (Local)\",\n models: [],\n apiBase: \"http://localhost:11434/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── OpenRouter (200+ models) ─────────────────────────────────\n openrouter: {\n name: \"OpenRouter\",\n models: [],\n apiBase: \"https://openrouter.ai/api/v1\",\n keyPrefix: \"sk-or-\",\n keyPlaceholder: \"sk-or-...\",\n },\n};\n","import type { LlmContext } from \"../shared-types.js\";\n\nexport const SYSTEM_PROMPT = `You are OpenMagic, an AI coding assistant embedded in a developer's web application. You help modify the codebase based on visual context from the running app.\n\n## Your Role\n- You can see the developer's running web application (DOM elements, screenshots, styles)\n- You propose code modifications to their source files\n- Your changes are applied directly to their codebase and reflected via hot reload\n\n## Response Format\nYou MUST respond with valid JSON in this exact format:\n\n\\`\\`\\`json\n{\n \"modifications\": [\n {\n \"file\": \"relative/path/to/file.tsx\",\n \"type\": \"edit\",\n \"search\": \"exact code to find (multi-line ok)\",\n \"replace\": \"replacement code\"\n }\n ],\n \"explanation\": \"Brief description of what was changed and why\"\n}\n\\`\\`\\`\n\n## Modification Types\n- \\`edit\\`: Replace existing code. \\`search\\` must match exactly in the file. \\`replace\\` is the new code.\n- \\`create\\`: Create a new file. Use \\`content\\` instead of search/replace.\n- \\`delete\\`: Delete a file. No search/replace/content needed.\n\n## Rules\n1. If the user is asking a QUESTION (not requesting a change), respond with {\"modifications\":[],\"explanation\":\"your answer here\"}. Only propose modifications when the user explicitly wants something changed.\n2. NEVER use delete+create to modify an existing file. Always use edit with search/replace. Only use create for genuinely new files that don't exist yet.\n3. Copy the search string EXACTLY from the grounded source files — do not retype, reformat, or change whitespace/indentation\n4. Include 3-5 lines of surrounding context in the search field to ensure uniqueness\n5. Keep modifications minimal — change only what's needed. Do NOT rewrite entire files.\n6. If the grounded files don't contain the code you need to modify, return: {\"modifications\":[],\"explanation\":\"NEED_FILE: exact/relative/path/to/file.ext\"}\n7. To search for a pattern across the codebase, return: {\"modifications\":[],\"explanation\":\"SEARCH_FILES: \\\\\"pattern\\\\\" in optional/path/\"}\n7. For style changes: check the dependencies (package.json) to know if the project uses Tailwind, MUI, etc. Use the project's styling approach, not raw CSS\n8. Use the selected element's cssSelector, className, parentContainerStyles, and siblings to understand the full layout context\n9. Use the page URL route and componentHint to identify the correct source file to modify\n10. Always preserve existing code style, conventions, and indentation\n11. ALWAYS respond with valid JSON only — no text before or after the JSON object`;\n\nexport function buildContextParts(context: LlmContext): Parameters<typeof buildUserMessage>[1] {\n const parts: Parameters<typeof buildUserMessage>[1] = {};\n\n // Send FULL element context with all available signals\n if (context.selectedElement) {\n const el = context.selectedElement as any;\n const elementData: Record<string, unknown> = {\n cssSelector: el.cssSelector,\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n outerHTML: el.outerHTML,\n computedStyles: el.computedStyles,\n ancestry: el.ancestry,\n componentHint: el.componentHint,\n };\n // Parent container styles (layout context)\n if (el.parentStyles && Object.keys(el.parentStyles).length) {\n elementData.parentContainerStyles = el.parentStyles;\n }\n // Sibling elements (what else is in the same container)\n if (el.siblings?.length) {\n elementData.siblings = el.siblings;\n }\n // Matched CSS rules from stylesheets\n if (el.matchedCssRules?.length) {\n elementData.matchedCssRules = el.matchedCssRules;\n }\n // Viewport dimensions\n if (el.viewport) {\n elementData.viewport = el.viewport;\n }\n // Accessibility attributes\n if (el.ariaAttributes && Object.keys(el.ariaAttributes).length) {\n elementData.ariaAttributes = el.ariaAttributes;\n }\n // Event handlers\n if (el.eventHandlers?.length) {\n elementData.eventHandlers = el.eventHandlers;\n }\n // React props\n if (el.reactProps) {\n elementData.reactProps = el.reactProps;\n }\n // Children layout measurements (pixel-level spacing between children)\n if (el.childrenLayout?.length) {\n elementData.childrenLayout = el.childrenLayout;\n }\n // Resolved Tailwind/utility classes to actual CSS values\n if (el.resolvedClasses?.length) {\n elementData.resolvedClasses = el.resolvedClasses;\n }\n parts.selectedElement = JSON.stringify(elementData, null, 2);\n }\n\n if (context.files?.length) {\n parts.files = context.files;\n }\n if (context.projectTree) parts.projectTree = context.projectTree;\n if ((context as any).pageUrl) parts.pageUrl = (context as any).pageUrl;\n if ((context as any).pageTitle) parts.pageTitle = (context as any).pageTitle;\n if (context.networkLogs) parts.networkLogs = context.networkLogs.map(l => `${l.method} ${l.url} → ${l.status || \"pending\"}`).join(\"\\n\");\n if (context.consoleLogs) parts.consoleLogs = context.consoleLogs.map(l => `[${l.level}] ${l.args.join(\" \")}`).join(\"\\n\");\n if ((context as any).searchResults?.length) {\n parts.searchResults = (context as any).searchResults.map(\n (s: any) => `Search: \"${s.query}\"\\n${s.matches.map((m: any) => ` ${m.file}:${m.lineNum}: ${m.line}`).join(\"\\n\")}`\n ).join(\"\\n\\n\");\n }\n return parts;\n}\n\nexport function buildUserMessage(\n userPrompt: string,\n context: {\n selectedElement?: string;\n screenshot?: string;\n files?: Array<{ path: string; content: string }>;\n fileContent?: string;\n filePath?: string;\n networkLogs?: string;\n consoleLogs?: string;\n projectTree?: string;\n pageUrl?: string;\n pageTitle?: string;\n searchResults?: string;\n }\n): string {\n const parts: string[] = [];\n\n // Page context — helps LLM find the right route/page component\n if (context.pageUrl || context.pageTitle) {\n parts.push(`## Page Context\\nURL: ${context.pageUrl || \"unknown\"}\\nTitle: ${context.pageTitle || \"unknown\"}`);\n }\n\n if (context.projectTree) {\n parts.push(`## Project Structure\\n\\`\\`\\`\\n${context.projectTree}\\n\\`\\`\\``);\n }\n\n // Grounded source files\n if (context.files?.length) {\n parts.push(`## Grounded Source Files\\n${context.files.map(f => `### ${f.path}\\n\\`\\`\\`\\n${f.content}\\n\\`\\`\\``).join(\"\\n\\n\")}`);\n } else if (context.filePath && context.fileContent) {\n parts.push(`## Source File: ${context.filePath}\\n\\`\\`\\`\\n${context.fileContent}\\n\\`\\`\\``);\n }\n\n // Selected element — full context including selector, styles, ancestry\n if (context.selectedElement) {\n parts.push(`## Selected Element\\n\\`\\`\\`json\\n${context.selectedElement}\\n\\`\\`\\``);\n }\n\n if (context.networkLogs) {\n parts.push(`## Recent Network Requests\\n\\`\\`\\`\\n${context.networkLogs}\\n\\`\\`\\``);\n }\n\n if (context.consoleLogs) {\n parts.push(`## Console Output\\n\\`\\`\\`\\n${context.consoleLogs}\\n\\`\\`\\``);\n }\n\n if (context.searchResults) {\n parts.push(`## Search Results\\n\\`\\`\\`\\n${context.searchResults}\\n\\`\\`\\``);\n }\n\n parts.push(`## User Request\\n${userPrompt}`);\n\n return parts.join(\"\\n\\n\");\n}\n","import type { ChatMessage, ContentPart, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\ninterface OpenAICompatibleRequest {\n model: string;\n messages: Array<{\n role: string;\n content: string | Array<{ type: string; text?: string; image_url?: { url: string } }>;\n }>;\n stream: boolean;\n max_tokens?: number;\n max_completion_tokens?: number;\n reasoning_effort?: string;\n}\n\nexport async function chatOpenAICompatible(\n provider: string,\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const providerConfig = MODEL_REGISTRY[provider];\n if (!providerConfig) {\n onError(`Unknown provider: ${provider}`);\n return;\n }\n\n const apiBase = providerConfig.apiBase;\n const url = `${apiBase}/chat/completions`;\n\n // Build messages with context\n const apiMessages: OpenAICompatibleRequest[\"messages\"] = [\n { role: \"system\", content: SYSTEM_PROMPT },\n ];\n\n // Only enrich the LAST user message with context (not all historical ones)\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\n\n // If we have a screenshot and the model supports vision, add it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (context.screenshot && modelInfo?.vision) {\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image_url\",\n image_url: { url: context.screenshot },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else if (msg.role === \"system\") {\n continue; // System prompt already added\n } else {\n apiMessages.push({\n role: msg.role,\n content: msg.content as string,\n });\n }\n }\n\n // GPT-5.x, o3, o4 models require max_completion_tokens instead of max_tokens\n const usesCompletionTokens = provider === \"openai\" && (\n model.startsWith(\"gpt-5\") || model.startsWith(\"o3\") || model.startsWith(\"o4\") || model.startsWith(\"codex\")\n );\n\n const body: OpenAICompatibleRequest = {\n model,\n messages: apiMessages,\n stream: true,\n };\n\n if (usesCompletionTokens) {\n body.max_completion_tokens = 4096;\n } else {\n body.max_tokens = 4096;\n }\n\n // Add thinking/reasoning config if the model supports it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (modelInfo?.thinking?.supported && modelInfo.thinking.paramType === \"level\") {\n body.reasoning_effort = modelInfo.thinking.defaultLevel || \"medium\";\n const limit = Math.min(modelInfo.maxOutput, 16384);\n if (usesCompletionTokens) {\n body.max_completion_tokens = limit;\n } else {\n body.max_tokens = limit;\n }\n }\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (provider === \"ollama\") {\n // Ollama doesn't need auth\n } else {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(`Invalid API key for ${providerConfig.name}. Check your key in Settings.`);\n } else if (response.status === 429) {\n onError(`Rate limit exceeded for ${providerConfig.name}. Wait a moment and try again.`);\n } else {\n onError(`${providerConfig.name} API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n // Stream SSE response\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n if (data === \"[DONE]\") continue;\n\n try {\n const parsed = JSON.parse(data);\n const delta = parsed.choices?.[0]?.delta?.content;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\ninterface AnthropicMessage {\n role: \"user\" | \"assistant\";\n content: string | Array<{ type: string; text?: string; source?: { type: string; media_type: string; data: string } }>;\n}\n\nexport async function chatAnthropic(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = \"https://api.anthropic.com/v1/messages\";\n\n const apiMessages: AnthropicMessage[] = [];\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\n\n // If screenshot available, use vision\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: \"image/png\",\n data: base64Data,\n },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else {\n apiMessages.push({\n role: msg.role as \"user\" | \"assistant\",\n content: msg.content as string,\n });\n }\n }\n\n // Build body with optional extended thinking\n const providerConfig = MODEL_REGISTRY.anthropic;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingBudget = modelInfo?.thinking?.defaultBudget || 0;\n\n const body: Record<string, unknown> = {\n model,\n max_tokens: thinkingBudget > 0 ? Math.max(thinkingBudget + 4096, 16384) : 4096,\n system: SYSTEM_PROMPT,\n messages: apiMessages,\n stream: true,\n };\n\n // Add extended thinking if supported\n if (thinkingBudget > 0) {\n body.thinking = {\n type: \"enabled\",\n budget_tokens: thinkingBudget,\n };\n }\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Anthropic API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Anthropic rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Anthropic API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n if (parsed.type === \"content_block_delta\") {\n const delta = parsed.delta?.text;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\nexport async function chatGoogle(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?key=${apiKey}&alt=sse`;\n\n const contents: Array<{\n role: string;\n parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }>;\n }> = [];\n\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"system\") continue;\n\n const role = msg.role === \"assistant\" ? \"model\" : \"user\";\n\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\n\n const parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }> = [\n { text: enrichedContent },\n ];\n\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n parts.push({\n inline_data: {\n mime_type: \"image/png\",\n data: base64Data,\n },\n });\n }\n\n contents.push({ role, parts });\n } else {\n contents.push({\n role,\n parts: [{ text: msg.content as string }],\n });\n }\n }\n\n // Check for thinking support\n const providerConfig = MODEL_REGISTRY.google;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingLevel = modelInfo?.thinking?.defaultLevel;\n\n const generationConfig: Record<string, unknown> = {\n maxOutputTokens: 8192,\n };\n\n const thinkingConfig = (thinkingLevel && thinkingLevel !== \"none\")\n ? { thinkingLevel: thinkingLevel.toUpperCase() }\n : undefined;\n\n const body: Record<string, unknown> = {\n system_instruction: {\n parts: [{ text: SYSTEM_PROMPT }],\n },\n contents,\n generationConfig,\n };\n if (thinkingConfig) {\n body.thinkingConfig = thinkingConfig;\n }\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Google API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Google API rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Google API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext, LlmResponse } from \"../shared-types.js\";\nimport { chatOpenAICompatible } from \"./openai.js\";\nimport { chatAnthropic } from \"./anthropic.js\";\nimport { chatGoogle } from \"./google.js\";\n\n// Providers that use OpenAI-compatible API format\nconst OPENAI_COMPATIBLE_PROVIDERS = new Set([\n \"openai\",\n \"deepseek\",\n \"groq\",\n \"mistral\",\n \"xai\",\n \"ollama\",\n \"openrouter\",\n \"minimax\",\n \"moonshot\",\n \"qwen\",\n \"zhipu\",\n \"doubao\",\n]);\n\ninterface LlmChatParams {\n provider: string;\n model: string;\n apiKey: string;\n messages: ChatMessage[];\n context: LlmContext;\n}\n\nfunction extractJsonFromResponse(content: string): string | null {\n // Try markdown-wrapped JSON first (most common)\n const mdMatch = content.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n if (mdMatch?.[1]) {\n const candidate = mdMatch[1].trim();\n try { JSON.parse(candidate); return candidate; } catch {}\n }\n\n // Brace-counting extraction (handles raw JSON in response)\n const start = content.indexOf('{');\n if (start === -1) return null;\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (let i = start; i < content.length; i++) {\n const ch = content[i];\n if (escape) { escape = false; continue; }\n if (ch === '\\\\' && inString) { escape = true; continue; }\n if (ch === '\"') { inString = !inString; continue; }\n if (inString) continue;\n if (ch === '{') depth++;\n if (ch === '}') {\n depth--;\n if (depth === 0) {\n const candidate = content.substring(start, i + 1);\n try { JSON.parse(candidate); return candidate; } catch { return null; }\n }\n }\n }\n return null;\n}\n\nexport async function handleLlmChat(\n params: LlmChatParams,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string; modifications?: LlmResponse[\"modifications\"] }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const { provider, model, apiKey, messages, context } = params;\n\n const wrappedOnDone = (result: { content: string }) => {\n let modifications: LlmResponse[\"modifications\"] | undefined;\n try {\n const json = extractJsonFromResponse(result.content);\n if (json) {\n const parsed = JSON.parse(json) as LlmResponse;\n modifications = parsed.modifications;\n }\n } catch {\n // JSON parse failed — return raw content\n }\n onDone({ content: result.content, modifications });\n };\n\n try {\n if (provider === \"anthropic\") {\n await chatAnthropic(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (provider === \"google\") {\n await chatGoogle(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (OPENAI_COMPATIBLE_PROVIDERS.has(provider)) {\n await chatOpenAICompatible(\n provider,\n model,\n apiKey,\n messages,\n context,\n onChunk,\n wrappedOnDone,\n onError\n );\n } else {\n onError(`Unsupported provider: ${provider}. Check your Settings.`);\n }\n } catch (e: unknown) {\n const msg = (e as Error).message || \"Unknown error\";\n if (msg.includes(\"fetch\") || msg.includes(\"ECONNREFUSED\") || msg.includes(\"network\")) {\n onError(`Network error: Could not reach the ${provider} API. Check your internet connection.`);\n } else {\n onError(`Unexpected error with ${provider}: ${msg}`);\n }\n }\n}\n","import { createConnection } from \"node:net\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\nconst COMMON_DEV_PORTS = [\n 3000, // React (CRA), Next.js, Express\n 5173, // Vite\n 5174, // Vite (alternate)\n 4200, // Angular\n 8080, // Vue CLI, generic\n 8000, // Django, Python\n 3001, // Common alternate\n 4000, // Phoenix, generic\n 1234, // Parcel\n 4321, // Astro\n 3333, // Remix\n 8081, // Metro (React Native)\n 9000, // generic\n 8888, // Jupyter, generic\n 5000, // Flask (last — macOS AirPlay also uses 5000)\n];\n\nfunction checkPortSingle(port: number, host: string): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host, timeout: 1000 });\n socket.unref();\n socket.on(\"connect\", () => { socket.destroy(); resolve(true); });\n socket.on(\"error\", () => { socket.destroy(); resolve(false); });\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n}\n\n// Check both IPv4 and IPv6 — many dev servers (Vite, Node) listen on ::1 only\nasync function checkPort(port: number, host: string = \"127.0.0.1\"): Promise<boolean> {\n const results = await Promise.all([\n checkPortSingle(port, host),\n checkPortSingle(port, \"::1\"),\n checkPortSingle(port, \"localhost\"),\n ]);\n return results.some(Boolean);\n}\n\nexport interface DetectedServer {\n port: number;\n host: string;\n fromScripts?: boolean; // true if detected via package.json scripts\n}\n\n/**\n * Check if the process listening on a port is running from (or near) the expected directory.\n * Uses lsof on macOS/Linux to get the PID, then checks its working directory.\n * Returns true if verified, false if wrong project, null if can't determine.\n */\nexport function verifyPortOwnership(port: number, expectedDir: string): boolean | null {\n try {\n // Get PIDs listening on this port\n const pidOutput = execSync(`lsof -i :${port} -sTCP:LISTEN -t 2>/dev/null`, {\n encoding: \"utf-8\",\n timeout: 3000,\n }).trim();\n\n if (!pidOutput) return null;\n\n const pids = pidOutput.split(\"\\n\").map((p) => p.trim()).filter(Boolean);\n const expected = resolve(expectedDir);\n\n for (const pid of pids) {\n try {\n // Get working directory of this process\n const cwdOutput = execSync(\n `lsof -a -p ${pid} -d cwd -Fn 2>/dev/null | grep ^n | head -1`,\n { encoding: \"utf-8\", timeout: 3000 }\n ).trim();\n\n if (!cwdOutput) continue;\n const processCwd = resolve(cwdOutput.slice(1)); // strip leading 'n'\n\n // Match if the process cwd is the project dir, a parent, or a child\n if (processCwd === expected || expected.startsWith(processCwd) || processCwd.startsWith(expected)) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n // We got PIDs but none matched the project directory\n return false;\n } catch {\n // lsof not available or failed — can't verify\n return null;\n }\n}\n\nexport async function detectDevServer(cwd: string = process.cwd()): Promise<DetectedServer | null> {\n // First: check ports hinted by the project's dev scripts + .env (most reliable)\n const scripts = detectDevScripts(cwd);\n const envPort = checkEnvPort(cwd);\n const scriptPorts = [\n ...(envPort ? [envPort] : []),\n ...scripts.map((s) => s.defaultPort),\n ].filter((p, i, a) => a.indexOf(p) === i);\n\n if (scriptPorts.length > 0) {\n for (const port of scriptPorts) {\n if (await checkPort(port)) {\n // Verify this port actually belongs to this project\n const owned = verifyPortOwnership(port, cwd);\n if (owned === false) {\n // Wrong project on this port — skip it\n continue;\n }\n return { port, host: \"localhost\", fromScripts: true };\n }\n }\n // Scripts exist but none running (or all belong to other projects)\n return null;\n }\n\n // No recognized scripts — scan common ports (but flag as unverified)\n const checks = COMMON_DEV_PORTS.map(async (port) => {\n const isOpen = await checkPort(port);\n return isOpen ? port : null;\n });\n\n const results = await Promise.all(checks);\n\n for (const foundPort of results) {\n if (foundPort === null) continue;\n // For generic scan, also check ownership\n const owned = verifyPortOwnership(foundPort, cwd);\n if (owned === false) continue; // skip — belongs to another project\n return { port: foundPort, host: \"localhost\", fromScripts: false };\n }\n\n return null;\n}\n\nexport async function isPortOpen(port: number): Promise<boolean> {\n return checkPort(port);\n}\n\nexport async function findAvailablePort(startPort: number): Promise<number> {\n let port = startPort;\n while (await isPortOpen(port)) {\n port++;\n if (port > startPort + 100) {\n throw new Error(`Could not find an available port near ${startPort}`);\n }\n }\n return port;\n}\n\n// --- Package.json Dev Script Detection ---\n\nexport interface DevScript {\n name: string; // e.g. \"dev\", \"start\", \"serve\"\n command: string; // e.g. \"next dev\", \"vite\", \"ng serve\"\n framework: string; // e.g. \"Next.js\", \"Vite\", \"Angular\"\n defaultPort: number;\n}\n\nconst FRAMEWORK_PATTERNS: Array<{\n match: RegExp;\n framework: string;\n defaultPort: number;\n}> = [\n { match: /\\bnext\\b/, framework: \"Next.js\", defaultPort: 3000 },\n { match: /\\bvite\\b/, framework: \"Vite\", defaultPort: 5173 },\n { match: /\\bnuxt\\b/, framework: \"Nuxt\", defaultPort: 3000 },\n { match: /\\bng\\s+serve\\b/, framework: \"Angular\", defaultPort: 4200 },\n { match: /\\bvue-cli-service\\s+serve\\b/, framework: \"Vue CLI\", defaultPort: 8080 },\n { match: /\\bsvelte-kit\\b/, framework: \"SvelteKit\", defaultPort: 5173 },\n { match: /\\bastro\\b/, framework: \"Astro\", defaultPort: 4321 },\n { match: /\\bremix\\b/, framework: \"Remix\", defaultPort: 3000 },\n { match: /\\breact-scripts\\s+start\\b/, framework: \"Create React App\", defaultPort: 3000 },\n { match: /\\bparcel\\b/, framework: \"Parcel\", defaultPort: 1234 },\n { match: /\\bwebpack\\s+serve\\b|webpack-dev-server/, framework: \"Webpack\", defaultPort: 8080 },\n { match: /\\bgatsby\\b/, framework: \"Gatsby\", defaultPort: 8000 },\n { match: /\\bturborepo\\b|\\bturbo\\b.*dev/, framework: \"Turborepo\", defaultPort: 3000 },\n { match: /\\bexpo\\b/, framework: \"Expo\", defaultPort: 8081 },\n { match: /\\bnodemon\\b|\\bts-node\\b|\\bnode\\b/, framework: \"Node.js\", defaultPort: 3000 },\n { match: /\\bflask\\b/, framework: \"Flask\", defaultPort: 5000 },\n { match: /\\bdjango\\b|manage\\.py\\s+runserver/, framework: \"Django\", defaultPort: 8000 },\n { match: /\\brails\\b/, framework: \"Rails\", defaultPort: 3000 },\n { match: /\\bphp\\s+.*serve\\b|artisan\\s+serve/, framework: \"PHP/Laravel\", defaultPort: 8000 },\n];\n\nconst DEV_SCRIPT_NAMES = [\"dev\", \"start\", \"serve\", \"develop\", \"dev:start\", \"start:dev\", \"server\", \"dev:server\", \"web\", \"frontend\"];\n\nexport function detectDevScripts(cwd: string = process.cwd()): DevScript[] {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return [];\n\n let pkg: any;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n } catch {\n return [];\n }\n\n if (!pkg.scripts) return [];\n\n const scripts: DevScript[] = [];\n\n for (const name of DEV_SCRIPT_NAMES) {\n const command = pkg.scripts[name];\n if (!command) continue;\n\n // Detect framework from command\n let framework = \"Unknown\";\n let defaultPort = 3000;\n\n for (const pattern of FRAMEWORK_PATTERNS) {\n if (pattern.match.test(command)) {\n framework = pattern.framework;\n defaultPort = pattern.defaultPort;\n break;\n }\n }\n\n // Try to extract port from command (e.g., --port 4000, -p 8080)\n const portMatch = command.match(/(?:--port|-p)\\s+(\\d+)/);\n if (portMatch) {\n defaultPort = parseInt(portMatch[1], 10);\n }\n\n scripts.push({ name, command, framework, defaultPort });\n }\n\n return scripts;\n}\n\n// --- Node.js Version Compatibility ---\n\n// Minimum Node.js versions for modern frameworks (conservative — covers latest majors)\nconst FRAMEWORK_NODE_REQUIREMENTS: Record<string, { minNode: string; label: string }> = {\n \"Next.js\": { minNode: \"18.17.0\", label: \"Next.js 14+\" },\n \"Vite\": { minNode: \"18.0.0\", label: \"Vite 5+\" },\n \"Angular\": { minNode: \"18.13.0\", label: \"Angular 17+\" },\n \"SvelteKit\": { minNode: \"18.13.0\", label: \"SvelteKit 2+\" },\n \"Nuxt\": { minNode: \"18.0.0\", label: \"Nuxt 3+\" },\n \"Astro\": { minNode: \"18.14.1\", label: \"Astro 4+\" },\n \"Remix\": { minNode: \"18.0.0\", label: \"Remix 2+\" },\n \"Create React App\": { minNode: \"14.0.0\", label: \"Create React App\" },\n \"Gatsby\": { minNode: \"18.0.0\", label: \"Gatsby 5+\" },\n \"Vue CLI\": { minNode: \"14.0.0\", label: \"Vue CLI\" },\n \"Webpack\": { minNode: \"14.0.0\", label: \"Webpack 5+\" },\n \"Parcel\": { minNode: \"16.0.0\", label: \"Parcel 2+\" },\n};\n\nfunction semverGte(a: string, b: string): boolean {\n const pa = a.split(\".\").map(Number);\n const pb = b.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((pa[i] || 0) > (pb[i] || 0)) return true;\n if ((pa[i] || 0) < (pb[i] || 0)) return false;\n }\n return true; // equal\n}\n\nexport function checkNodeCompatibility(framework: string): { ok: boolean; message?: string } {\n const req = FRAMEWORK_NODE_REQUIREMENTS[framework];\n if (!req) return { ok: true };\n\n const current = process.versions.node;\n if (!semverGte(current, req.minNode)) {\n return {\n ok: false,\n message: `${req.label} requires Node.js >= ${req.minNode}, but you are running v${current}`,\n };\n }\n return { ok: true };\n}\n\n// --- .env PORT detection ---\n\n/**\n * Check .env files for a PORT variable. Helps detect when the dev server\n * is configured to run on a non-default port via environment.\n */\nexport function checkEnvPort(cwd: string = process.cwd()): number | null {\n const envFiles = [\".env.local\", \".env.development.local\", \".env.development\", \".env\"];\n for (const envFile of envFiles) {\n const envPath = join(cwd, envFile);\n if (!existsSync(envPath)) continue;\n try {\n const content = readFileSync(envPath, \"utf-8\");\n const match = content.match(/^PORT\\s*=\\s*(\\d+)/m);\n if (match) return parseInt(match[1], 10);\n } catch {\n continue;\n }\n }\n return null;\n}\n\n// --- Project name ---\n\nexport function getProjectName(cwd: string = process.cwd()): string {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return \"this project\";\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n return pkg.name || \"this project\";\n } catch {\n return \"this project\";\n }\n}\n\n// --- Dependency Installation Check ---\n\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\n\nexport interface DependencyStatus {\n installed: boolean;\n packageManager: PackageManager;\n installCommand: string;\n}\n\nconst LOCK_FILES: Array<{ file: string; pm: PackageManager }> = [\n { file: \"pnpm-lock.yaml\", pm: \"pnpm\" },\n { file: \"yarn.lock\", pm: \"yarn\" },\n { file: \"bun.lockb\", pm: \"bun\" },\n { file: \"bun.lock\", pm: \"bun\" },\n { file: \"package-lock.json\", pm: \"npm\" },\n];\n\nconst INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: \"npm install\",\n yarn: \"yarn install\",\n pnpm: \"pnpm install\",\n bun: \"bun install\",\n};\n\nexport function checkDependenciesInstalled(cwd: string = process.cwd()): DependencyStatus {\n const hasNodeModules = existsSync(join(cwd, \"node_modules\"));\n\n // Detect package manager from lock file\n let pm: PackageManager = \"npm\";\n for (const { file, pm: detectedPm } of LOCK_FILES) {\n if (existsSync(join(cwd, file))) {\n pm = detectedPm;\n break;\n }\n }\n\n return {\n installed: hasNodeModules,\n packageManager: pm,\n installCommand: INSTALL_COMMANDS[pm],\n };\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAS,WAAAA,UAAS,QAAAC,aAAY;AAC9B,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,aAAgC;AACzC,SAAS,uBAAuB;;;ACNhC,OAAO,UAAU;AACjB,OAAO,eAAe;;;ACDtB,SAAS,mBAAmB;AAE5B,IAAI,eAA8B;AAE3B,SAAS,uBAA+B;AAC7C,iBAAe,YAAY,EAAE,EAAE,SAAS,KAAK;AAC7C,SAAO;AACT;AAEO,SAAS,kBAA0B;AACxC,MAAI,CAAC,cAAc;AACjB,WAAO,qBAAqB;AAAA,EAC9B;AACA,SAAO;AACT;AAEO,SAAS,cAAc,OAAwB;AACpD,SAAO,UAAU;AACnB;;;ACjBA,SAAS,gBAAAC,eAAc,cAAAC,mBAAkB;AACzC,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB,iBAAiB;;;ACJ3C,SAAS,cAAc,eAAe,YAAY,WAAW,kBAAkB;AAC/E,SAAS,YAAY;AACrB,SAAS,eAAe;AAGxB,IAAM,aAAa,KAAK,QAAQ,GAAG,YAAY;AAC/C,IAAM,cAAc,KAAK,YAAY,aAAa;AAElD,SAAS,kBAAwB;AAC/B,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,cAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AACF;AAEO,SAAS,aAAuC;AACrD,kBAAgB;AAChB,MAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,UAAM,MAAM,aAAa,aAAa,OAAO;AAC7C,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,WAAW,SAAoE;AAC7F,MAAI;AACF,oBAAgB;AAChB,UAAM,WAAW,WAAW;AAC5B,UAAM,SAAS,EAAE,GAAG,UAAU,GAAG,QAAQ;AACzC,UAAM,UAAU,cAAc;AAC9B,kBAAc,SAAS,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,EAAE,UAAU,SAAS,MAAM,IAAM,CAAC;AAC1F,eAAW,SAAS,WAAW;AAC/B,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,SAAS,GAAY;AACnB,WAAO,EAAE,IAAI,OAAO,OAAQ,EAAY,QAAQ;AAAA,EAClD;AACF;;;ACvCA;AAAA,EACE,gBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,cAAAC;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAAC;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AACP,SAAS,QAAAC,OAAM,SAAS,UAAU,SAAS,eAAe;AAC1D,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAG3B,IAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,WAAW,UAAkB,OAA0B;AACrE,QAAM,WAAW,QAAQ,QAAQ;AAGjC,MAAI;AACJ,MAAI;AACF,WAAO,aAAa,QAAQ;AAAA,EAC9B,QAAQ;AAEN,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,KAAK,CAAC,SAAS;AAC1B,UAAM,eAAe,QAAQ,IAAI;AACjC,UAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,UAAM,UAAU,SAAS,cAAc,IAAI;AAC3C,WACG,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,IAAI,WAAW,GAAG,KAAK,CAAC,IAAI,WAAW,IAAI,MACrE,CAAC,QAAQ,WAAW,IAAI,KAAK,CAAC,QAAQ,WAAW,GAAG,KAAK,CAAC,QAAQ,WAAW,IAAI;AAAA,EAEtF,CAAC;AACH;AAEO,SAAS,aACd,UACA,OACyC;AACzC,MAAI,CAAC,WAAW,UAAU,KAAK,GAAG;AAChC,WAAO,EAAE,OAAO,gCAAgC;AAAA,EAClD;AACA,MAAI,CAACF,YAAW,QAAQ,GAAG;AACzB,WAAO,EAAE,OAAO,iBAAiB;AAAA,EACnC;AACA,MAAI;AACF,UAAM,UAAUF,cAAa,UAAU,OAAO;AAC9C,WAAO,EAAE,QAAQ;AAAA,EACnB,SAAS,GAAY;AACnB,WAAO,EAAE,OAAO,wBAAyB,EAAY,OAAO,GAAG;AAAA,EACjE;AACF;AAGA,IAAM,aAAaI,MAAK,OAAO,GAAG,mBAAmB;AACrD,IAAM,YAAY,oBAAI,IAAoB;AAE1C,SAAS,cAAc,UAA0B;AAC/C,QAAM,OAAO,WAAW,KAAK,EAAE,OAAO,QAAQ,QAAQ,CAAC,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAClF,QAAM,OAAO,SAAS,MAAM,OAAO,EAAE,IAAI,KAAK;AAC9C,SAAOA,MAAK,YAAY,GAAG,IAAI,IAAI,IAAI,EAAE;AAC3C;AAEO,SAAS,iBAAiB,UAAsC;AACrE,SAAO,UAAU,IAAI,QAAQ,QAAQ,CAAC;AACxC;AAEO,SAAS,iBAAuB;AACrC,MAAI;AACF,QAAIF,YAAW,UAAU,GAAG;AAC1B,aAAO,YAAY,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACrD;AAAA,EACF,QAAQ;AAAA,EAAC;AACT,YAAU,MAAM;AAClB;AAEO,SAAS,cACd,UACA,SACA,OACsD;AACtD,MAAI,CAAC,WAAW,UAAU,KAAK,GAAG;AAChC,WAAO,EAAE,IAAI,OAAO,OAAO,gCAAgC;AAAA,EAC7D;AAEA,MAAI;AAEF,QAAI;AACJ,QAAIA,YAAW,QAAQ,GAAG;AACxB,UAAI,CAACA,YAAW,UAAU,EAAG,CAAAC,WAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AACtE,mBAAa,cAAc,QAAQ;AACnC,mBAAa,UAAU,UAAU;AACjC,gBAAU,IAAI,QAAQ,QAAQ,GAAG,UAAU;AAAA,IAC7C;AAGA,UAAM,MAAM,QAAQ,QAAQ;AAC5B,QAAI,CAACD,YAAW,GAAG,GAAG;AACpB,MAAAC,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACpC;AAEA,IAAAF,eAAc,UAAU,SAAS,OAAO;AACxC,WAAO,EAAE,IAAI,MAAM,WAAW;AAAA,EAChC,SAAS,GAAY;AACnB,WAAO,EAAE,IAAI,OAAO,OAAO,yBAA0B,EAAY,OAAO,GAAG;AAAA,EAC7E;AACF;AAEA,IAAM,mBAAmB;AAElB,SAAS,UACd,UACA,OACA,WAAmB,GACN;AACb,MAAI,CAAC,WAAW,UAAU,KAAK,GAAG;AAChC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAuB,CAAC;AAE9B,WAAS,KAAK,KAAa,OAAqB;AAC9C,QAAI,QAAQ,YAAY,QAAQ,UAAU,iBAAkB;AAE5D,QAAI;AACJ,QAAI;AACF,cAAQ,YAAY,GAAG;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AAEA,eAAW,QAAQ,OAAO;AACxB,UAAI,QAAQ,UAAU,iBAAkB;AACxC,UAAI,aAAa,IAAI,IAAI,EAAG;AAC5B,UAAI,KAAK,WAAW,GAAG,KAAK,SAAS,eAAgB;AAErD,YAAM,WAAWG,MAAK,KAAK,IAAI;AAC/B,UAAI;AACJ,UAAI;AACF,eAAO,UAAU,QAAQ;AAAA,MAC3B,QAAQ;AACN;AAAA,MACF;AACA,UAAI,KAAK,eAAe,EAAG;AAE3B,YAAM,UAAU,SAAS,UAAU,QAAQ;AAE3C,UAAI,KAAK,YAAY,GAAG;AACtB,gBAAQ,KAAK,EAAE,MAAM,SAAS,MAAM,OAAO,MAAM,KAAK,CAAC;AACvD,aAAK,UAAU,QAAQ,CAAC;AAAA,MAC1B,WAAW,KAAK,OAAO,GAAG;AACxB,cAAM,MAAM,QAAQ,IAAI,EAAE,YAAY;AACtC,YAAI,CAAC,mBAAmB,IAAI,GAAG,GAAG;AAChC,kBAAQ,KAAK,EAAE,MAAM,SAAS,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,OAAK,UAAU,CAAC;AAChB,SAAO;AACT;AAEA,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EACtC;AAAA,EAAQ;AAAA,EAAW;AAAA,EACnB;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAClC;AAAA,EAAS;AAAA,EAAO;AAAA,EAAS;AAAA,EACzB;AAAA,EAAQ;AAAA,EAAO;AACjB,CAAC;AAED,IAAM,qBAAqB,MAAM;AACjC,IAAM,yBAAyB;AAExB,SAAS,UACd,SACA,YACA,OACA,aAAqB,IAC8B;AACnD,MAAI,CAAC,WAAW,YAAY,KAAK,EAAG,QAAO,CAAC;AAE5C,QAAM,UAA6D,CAAC;AACpE,QAAM,eAAe,QAAQ,YAAY;AACzC,MAAI,eAAe;AAEnB,WAAS,KAAK,KAAa,OAAqB;AAC9C,QAAI,QAAQ,KAAK,QAAQ,UAAU,cAAc,gBAAgB,uBAAwB;AACzF,QAAI;AACJ,QAAI;AAAE,cAAQ,YAAY,GAAG;AAAA,IAAG,QAAQ;AAAE;AAAA,IAAQ;AAElD,eAAW,QAAQ,OAAO;AACxB,UAAI,QAAQ,UAAU,cAAc,gBAAgB,uBAAwB;AAC5E,UAAI,aAAa,IAAI,IAAI,KAAM,KAAK,WAAW,GAAG,KAAK,SAAS,eAAiB;AAEjF,YAAM,WAAWA,MAAK,KAAK,IAAI;AAC/B,UAAI;AACJ,UAAI;AAAE,eAAO,UAAU,QAAQ;AAAA,MAAG,QAAQ;AAAE;AAAA,MAAU;AACtD,UAAI,KAAK,eAAe,EAAG;AAE3B,UAAI,KAAK,YAAY,GAAG;AACtB,aAAK,UAAU,QAAQ,CAAC;AAAA,MAC1B,WAAW,KAAK,OAAO,GAAG;AACxB,cAAM,MAAM,QAAQ,IAAI,EAAE,YAAY;AACtC,YAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG;AAC/B,YAAI,KAAK,OAAO,mBAAoB;AACpC;AAEA,YAAI;AACF,gBAAM,UAAUJ,cAAa,UAAU,OAAO;AAC9C,gBAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,cAAI,cAAc;AAClB,mBAAS,IAAI,GAAG,IAAI,MAAM,UAAU,cAAc,GAAG,KAAK;AACxD,gBAAI,MAAM,CAAC,EAAE,YAAY,EAAE,SAAS,YAAY,GAAG;AACjD,sBAAQ,KAAK;AAAA,gBACX,MAAM,SAAS,YAAY,QAAQ;AAAA,gBACnC,SAAS,IAAI;AAAA,gBACb,MAAM,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG;AAAA,cACpC,CAAC;AACD;AAAA,YACF;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAAC;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,OAAK,YAAY,CAAC;AAClB,SAAO;AACT;AAEO,SAAS,eAAe,OAAyB;AACtD,QAAM,QAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,KAAK,IAAI,IAAI,GAAG;AACtB,UAAM,QAAQ,UAAU,MAAM,OAAO,CAAC;AACtC,eAAW,KAAK,OAAO;AACrB,YAAM,SAAS,EAAE,KAAK,MAAM,GAAG,EAAE,SAAS;AAC1C,YAAM,SAAS,KAAK,OAAO,MAAM;AACjC,YAAM,OAAO,EAAE,SAAS,QAAQ,MAAM;AACtC,YAAM,KAAK,GAAG,MAAM,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA,IACxC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AC1RO,IAAM,iBAAmC;AAAA;AAAA,EAE9C,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA,MAEN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO;AAAA,UACjD,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO;AAAA,UACjD,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,MAAM;AAAA,UACxC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,MAAM;AAAA,UACxC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO;AAAA,UACjD,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO;AAAA,UACjD,cAAc;AAAA,QAChB;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA,MAEN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA,MAEN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,MAAM;AAAA,UACxC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,MAAM;AAAA,UACxC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA;AAAA,MAEA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,MAAM;AAAA,UACxC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,QAAQ,OAAO,UAAU,MAAM;AAAA,UACxC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,IAAI,gBAAgB,MAAM,gBAAgB,QAAQ,MAAM,SAAS,SAAS,WAAW,MAAM;AAAA,MAC7F,EAAE,IAAI,0BAA0B,MAAM,0BAA0B,QAAQ,MAAM,SAAS,SAAS,WAAW,MAAM;AAAA,MACjH,EAAE,IAAI,gBAAgB,MAAM,gBAAgB,QAAQ,MAAM,SAAS,SAAS,WAAW,MAAM;AAAA,MAC7F,EAAE,IAAI,0BAA0B,MAAM,0BAA0B,QAAQ,MAAM,SAAS,SAAS,WAAW,MAAM;AAAA,IACnH;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,QAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,IAAI,gBAAgB,MAAM,iBAAiB,QAAQ,MAAM,SAAS,OAAS,WAAW,MAAM;AAAA,MAC9F,EAAE,IAAI,aAAa,MAAM,aAAa,QAAQ,OAAO,SAAS,QAAQ,WAAW,MAAM;AAAA,MACvF,EAAE,IAAI,YAAY,MAAM,YAAY,QAAQ,OAAO,SAAS,QAAQ,WAAW,MAAM;AAAA,MACrF,EAAE,IAAI,cAAc,MAAM,cAAc,QAAQ,OAAO,SAAS,QAAQ,WAAW,KAAK;AAAA,IAC1F;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,IAAI,SAAS,MAAM,SAAS,QAAQ,MAAM,SAAS,QAAQ,WAAW,MAAM;AAAA,MAC9E,EAAE,IAAI,WAAW,MAAM,WAAW,QAAQ,MAAM,SAAS,QAAQ,WAAW,MAAM;AAAA,MAClF,EAAE,IAAI,WAAW,MAAM,WAAW,QAAQ,MAAM,SAAS,QAAQ,WAAW,MAAM;AAAA,MAClF,EAAE,IAAI,WAAW,MAAM,WAAW,QAAQ,MAAM,SAAS,QAAQ,WAAW,MAAM;AAAA,IACpF;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,IAAI,uBAAuB,MAAM,uBAAuB,QAAQ,OAAO,SAAS,QAAQ,WAAW,MAAM;AAAA,MAC3G,EAAE,IAAI,wBAAwB,MAAM,wBAAwB,QAAQ,OAAO,SAAS,QAAQ,WAAW,KAAK;AAAA,MAC5G,EAAE,IAAI,wBAAwB,MAAM,wBAAwB,QAAQ,OAAO,SAAS,QAAQ,WAAW,MAAM;AAAA,IAC/G;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,OAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY;AAAA,IACV,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AACF;;;ACtpBO,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2CtB,SAAS,kBAAkB,SAA6D;AAC7F,QAAM,QAAgD,CAAC;AAGvD,MAAI,QAAQ,iBAAiB;AAC3B,UAAM,KAAK,QAAQ;AACnB,UAAM,cAAuC;AAAA,MAC3C,aAAa,GAAG;AAAA,MAChB,SAAS,GAAG;AAAA,MACZ,IAAI,GAAG;AAAA,MACP,WAAW,GAAG;AAAA,MACd,WAAW,GAAG;AAAA,MACd,gBAAgB,GAAG;AAAA,MACnB,UAAU,GAAG;AAAA,MACb,eAAe,GAAG;AAAA,IACpB;AAEA,QAAI,GAAG,gBAAgB,OAAO,KAAK,GAAG,YAAY,EAAE,QAAQ;AAC1D,kBAAY,wBAAwB,GAAG;AAAA,IACzC;AAEA,QAAI,GAAG,UAAU,QAAQ;AACvB,kBAAY,WAAW,GAAG;AAAA,IAC5B;AAEA,QAAI,GAAG,iBAAiB,QAAQ;AAC9B,kBAAY,kBAAkB,GAAG;AAAA,IACnC;AAEA,QAAI,GAAG,UAAU;AACf,kBAAY,WAAW,GAAG;AAAA,IAC5B;AAEA,QAAI,GAAG,kBAAkB,OAAO,KAAK,GAAG,cAAc,EAAE,QAAQ;AAC9D,kBAAY,iBAAiB,GAAG;AAAA,IAClC;AAEA,QAAI,GAAG,eAAe,QAAQ;AAC5B,kBAAY,gBAAgB,GAAG;AAAA,IACjC;AAEA,QAAI,GAAG,YAAY;AACjB,kBAAY,aAAa,GAAG;AAAA,IAC9B;AAEA,QAAI,GAAG,gBAAgB,QAAQ;AAC7B,kBAAY,iBAAiB,GAAG;AAAA,IAClC;AAEA,QAAI,GAAG,iBAAiB,QAAQ;AAC9B,kBAAY,kBAAkB,GAAG;AAAA,IACnC;AACA,UAAM,kBAAkB,KAAK,UAAU,aAAa,MAAM,CAAC;AAAA,EAC7D;AAEA,MAAI,QAAQ,OAAO,QAAQ;AACzB,UAAM,QAAQ,QAAQ;AAAA,EACxB;AACA,MAAI,QAAQ,YAAa,OAAM,cAAc,QAAQ;AACrD,MAAK,QAAgB,QAAS,OAAM,UAAW,QAAgB;AAC/D,MAAK,QAAgB,UAAW,OAAM,YAAa,QAAgB;AACnE,MAAI,QAAQ,YAAa,OAAM,cAAc,QAAQ,YAAY,IAAI,OAAK,GAAG,EAAE,MAAM,IAAI,EAAE,GAAG,WAAM,EAAE,UAAU,SAAS,EAAE,EAAE,KAAK,IAAI;AACtI,MAAI,QAAQ,YAAa,OAAM,cAAc,QAAQ,YAAY,IAAI,OAAK,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,GAAG,CAAC,EAAE,EAAE,KAAK,IAAI;AACvH,MAAK,QAAgB,eAAe,QAAQ;AAC1C,UAAM,gBAAiB,QAAgB,cAAc;AAAA,MACnD,CAAC,MAAW,YAAY,EAAE,KAAK;AAAA,EAAM,EAAE,QAAQ,IAAI,CAAC,MAAW,KAAK,EAAE,IAAI,IAAI,EAAE,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IAClH,EAAE,KAAK,MAAM;AAAA,EACf;AACA,SAAO;AACT;AAEO,SAAS,iBACd,YACA,SAaQ;AACR,QAAM,QAAkB,CAAC;AAGzB,MAAI,QAAQ,WAAW,QAAQ,WAAW;AACxC,UAAM,KAAK;AAAA,OAAyB,QAAQ,WAAW,SAAS;AAAA,SAAY,QAAQ,aAAa,SAAS,EAAE;AAAA,EAC9G;AAEA,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK;AAAA;AAAA,EAAiC,QAAQ,WAAW;AAAA,OAAU;AAAA,EAC3E;AAGA,MAAI,QAAQ,OAAO,QAAQ;AACzB,UAAM,KAAK;AAAA,EAA6B,QAAQ,MAAM,IAAI,OAAK,OAAO,EAAE,IAAI;AAAA;AAAA,EAAa,EAAE,OAAO;AAAA,OAAU,EAAE,KAAK,MAAM,CAAC,EAAE;AAAA,EAC9H,WAAW,QAAQ,YAAY,QAAQ,aAAa;AAClD,UAAM,KAAK,mBAAmB,QAAQ,QAAQ;AAAA;AAAA,EAAa,QAAQ,WAAW;AAAA,OAAU;AAAA,EAC1F;AAGA,MAAI,QAAQ,iBAAiB;AAC3B,UAAM,KAAK;AAAA;AAAA,EAAoC,QAAQ,eAAe;AAAA,OAAU;AAAA,EAClF;AAEA,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK;AAAA;AAAA,EAAuC,QAAQ,WAAW;AAAA,OAAU;AAAA,EACjF;AAEA,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK;AAAA;AAAA,EAA8B,QAAQ,WAAW;AAAA,OAAU;AAAA,EACxE;AAEA,MAAI,QAAQ,eAAe;AACzB,UAAM,KAAK;AAAA;AAAA,EAA8B,QAAQ,aAAa;AAAA,OAAU;AAAA,EAC1E;AAEA,QAAM,KAAK;AAAA,EAAoB,UAAU,EAAE;AAE3C,SAAO,MAAM,KAAK,MAAM;AAC1B;;;AC1JA,eAAsB,qBACpB,UACA,OACA,QACA,UACA,SACA,SACA,QACA,SACe;AACf,QAAM,iBAAiB,eAAe,QAAQ;AAC9C,MAAI,CAAC,gBAAgB;AACnB,YAAQ,qBAAqB,QAAQ,EAAE;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,eAAe;AAC/B,QAAM,MAAM,GAAG,OAAO;AAGtB,QAAM,cAAmD;AAAA,IACvD,EAAE,MAAM,UAAU,SAAS,cAAc;AAAA,EAC3C;AAGA,QAAM,cAAc,SAAS,OAAO,CAAC,KAAK,GAAG,MAAM,EAAE,SAAS,SAAS,IAAI,KAAK,EAAE;AAElF,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,MAAM,SAAS,CAAC;AACtB,QAAI,IAAI,SAAS,UAAU,OAAO,IAAI,YAAY,YAAY,MAAM,aAAa;AAC/E,YAAM,kBAAkB,iBAAiB,IAAI,SAAS,kBAAkB,OAAO,CAAC;AAGhF,YAAMK,aAAY,eAAe,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK;AAClE,UAAI,QAAQ,cAAcA,YAAW,QAAQ;AAC3C,oBAAY,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,YACP,EAAE,MAAM,QAAQ,MAAM,gBAAgB;AAAA,YACtC;AAAA,cACE,MAAM;AAAA,cACN,WAAW,EAAE,KAAK,QAAQ,WAAW;AAAA,YACvC;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AACL,oBAAY,KAAK,EAAE,MAAM,QAAQ,SAAS,gBAAgB,CAAC;AAAA,MAC7D;AAAA,IACF,WAAW,IAAI,SAAS,UAAU;AAChC;AAAA,IACF,OAAO;AACL,kBAAY,KAAK;AAAA,QACf,MAAM,IAAI;AAAA,QACV,SAAS,IAAI;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,uBAAuB,aAAa,aACxC,MAAM,WAAW,OAAO,KAAK,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW,OAAO;AAG3G,QAAM,OAAgC;AAAA,IACpC;AAAA,IACA,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAEA,MAAI,sBAAsB;AACxB,SAAK,wBAAwB;AAAA,EAC/B,OAAO;AACL,SAAK,aAAa;AAAA,EACpB;AAGA,QAAM,YAAY,eAAe,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK;AAClE,MAAI,WAAW,UAAU,aAAa,UAAU,SAAS,cAAc,SAAS;AAC9E,SAAK,mBAAmB,UAAU,SAAS,gBAAgB;AAC3D,UAAM,QAAQ,KAAK,IAAI,UAAU,WAAW,KAAK;AACjD,QAAI,sBAAsB;AACxB,WAAK,wBAAwB;AAAA,IAC/B,OAAO;AACL,WAAK,aAAa;AAAA,IACpB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,IAClB;AAEA,QAAI,aAAa,UAAU;AAAA,IAE3B,OAAO;AACL,cAAQ,eAAe,IAAI,UAAU,MAAM;AAAA,IAC7C;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,eAAe;AACnE,UAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;AACtD,gBAAQ,uBAAuB,eAAe,IAAI,+BAA+B;AAAA,MACnF,WAAW,SAAS,WAAW,KAAK;AAClC,gBAAQ,2BAA2B,eAAe,IAAI,gCAAgC;AAAA,MACxF,OAAO;AACL,gBAAQ,GAAG,eAAe,IAAI,cAAc,SAAS,MAAM,KAAK,UAAU,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,MAC3F;AACA;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,MAAM;AAClB,cAAQ,kBAAkB;AAC1B;AAAA,IACF;AAGA,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,cAAc;AAClB,QAAI,SAAS;AAEb,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,WAAW,QAAQ,EAAG;AAChC,cAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAChC,YAAI,SAAS,SAAU;AAEvB,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,gBAAM,QAAQ,OAAO,UAAU,CAAC,GAAG,OAAO;AAC1C,cAAI,OAAO;AACT,2BAAe;AACf,oBAAQ,KAAK;AAAA,UACf;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,YAAY,CAAC;AAAA,EACjC,SAAS,GAAY;AACnB,YAAQ,mBAAoB,EAAY,OAAO,EAAE;AAAA,EACnD;AACF;;;ACpKA,eAAsB,cACpB,OACA,QACA,UACA,SACA,SACA,QACA,SACe;AACf,QAAM,MAAM;AAEZ,QAAM,cAAkC,CAAC;AACzC,QAAM,cAAc,SAAS,OAAO,CAAC,KAAK,GAAG,MAAM,EAAE,SAAS,SAAS,IAAI,KAAK,EAAE;AAElF,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,MAAM,SAAS,CAAC;AACtB,QAAI,IAAI,SAAS,SAAU;AAE3B,QAAI,IAAI,SAAS,UAAU,OAAO,IAAI,YAAY,YAAY,MAAM,aAAa;AAC/E,YAAM,kBAAkB,iBAAiB,IAAI,SAAS,kBAAkB,OAAO,CAAC;AAGhF,UAAI,QAAQ,YAAY;AACtB,cAAM,aAAa,QAAQ,WAAW;AAAA,UACpC;AAAA,UACA;AAAA,QACF;AACA,oBAAY,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,YACP,EAAE,MAAM,QAAQ,MAAM,gBAAgB;AAAA,YACtC;AAAA,cACE,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,MAAM;AAAA,cACR;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AACL,oBAAY,KAAK,EAAE,MAAM,QAAQ,SAAS,gBAAgB,CAAC;AAAA,MAC7D;AAAA,IACF,OAAO;AACL,kBAAY,KAAK;AAAA,QACf,MAAM,IAAI;AAAA,QACV,SAAS,IAAI;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,iBAAiB,eAAe;AACtC,QAAM,YAAY,gBAAgB,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK;AACnE,QAAM,iBAAiB,WAAW,UAAU,iBAAiB;AAE7D,QAAM,OAAgC;AAAA,IACpC;AAAA,IACA,YAAY,iBAAiB,IAAI,KAAK,IAAI,iBAAiB,MAAM,KAAK,IAAI;AAAA,IAC1E,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAGA,MAAI,iBAAiB,GAAG;AACtB,SAAK,WAAW;AAAA,MACd,MAAM;AAAA,MACN,eAAe;AAAA,IACjB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,aAAa;AAAA,QACb,qBAAqB;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,eAAe;AACnE,UAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;AACtD,gBAAQ,wDAAwD;AAAA,MAClE,WAAW,SAAS,WAAW,KAAK;AAClC,gBAAQ,6DAA6D;AAAA,MACvE,OAAO;AACL,gBAAQ,uBAAuB,SAAS,MAAM,KAAK,UAAU,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,MAC9E;AACA;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,MAAM;AAClB,cAAQ,kBAAkB;AAC1B;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,cAAc;AAClB,QAAI,SAAS;AAEb,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,WAAW,QAAQ,EAAG;AAChC,cAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAEhC,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cAAI,OAAO,SAAS,uBAAuB;AACzC,kBAAM,QAAQ,OAAO,OAAO;AAC5B,gBAAI,OAAO;AACT,6BAAe;AACf,sBAAQ,KAAK;AAAA,YACf;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,YAAY,CAAC;AAAA,EACjC,SAAS,GAAY;AACnB,YAAQ,mBAAoB,EAAY,OAAO,EAAE;AAAA,EACnD;AACF;;;AC9IA,eAAsB,WACpB,OACA,QACA,UACA,SACA,SACA,QACA,SACe;AACf,QAAM,MAAM,2DAA2D,KAAK,8BAA8B,MAAM;AAEhH,QAAM,WAGD,CAAC;AAEN,QAAM,cAAc,SAAS,OAAO,CAAC,KAAK,GAAG,MAAM,EAAE,SAAS,SAAS,IAAI,KAAK,EAAE;AAElF,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,MAAM,SAAS,CAAC;AACtB,QAAI,IAAI,SAAS,SAAU;AAE3B,UAAM,OAAO,IAAI,SAAS,cAAc,UAAU;AAElD,QAAI,IAAI,SAAS,UAAU,OAAO,IAAI,YAAY,YAAY,MAAM,aAAa;AAC/E,YAAM,kBAAkB,iBAAiB,IAAI,SAAS,kBAAkB,OAAO,CAAC;AAEhF,YAAM,QAAqF;AAAA,QACzF,EAAE,MAAM,gBAAgB;AAAA,MAC1B;AAEA,UAAI,QAAQ,YAAY;AACtB,cAAM,aAAa,QAAQ,WAAW;AAAA,UACpC;AAAA,UACA;AAAA,QACF;AACA,cAAM,KAAK;AAAA,UACT,aAAa;AAAA,YACX,WAAW;AAAA,YACX,MAAM;AAAA,UACR;AAAA,QACF,CAAC;AAAA,MACH;AAEA,eAAS,KAAK,EAAE,MAAM,MAAM,CAAC;AAAA,IAC/B,OAAO;AACL,eAAS,KAAK;AAAA,QACZ;AAAA,QACA,OAAO,CAAC,EAAE,MAAM,IAAI,QAAkB,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,iBAAiB,eAAe;AACtC,QAAM,YAAY,gBAAgB,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK;AACnE,QAAM,gBAAgB,WAAW,UAAU;AAE3C,QAAM,mBAA4C;AAAA,IAChD,iBAAiB;AAAA,EACnB;AAEA,QAAM,iBAAkB,iBAAiB,kBAAkB,SACvD,EAAE,eAAe,cAAc,YAAY,EAAE,IAC7C;AAEJ,QAAM,OAAgC;AAAA,IACpC,oBAAoB;AAAA,MAClB,OAAO,CAAC,EAAE,MAAM,cAAc,CAAC;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,gBAAgB;AAClB,SAAK,iBAAiB;AAAA,EACxB;AAEA,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,eAAe;AACnE,UAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;AACtD,gBAAQ,qDAAqD;AAAA,MAC/D,WAAW,SAAS,WAAW,KAAK;AAClC,gBAAQ,8DAA8D;AAAA,MACxE,OAAO;AACL,gBAAQ,oBAAoB,SAAS,MAAM,KAAK,UAAU,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,MAC3E;AACA;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,MAAM;AAClB,cAAQ,kBAAkB;AAC1B;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,cAAc;AAClB,QAAI,SAAS;AAEb,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,WAAW,QAAQ,EAAG;AAChC,cAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAEhC,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,gBAAM,OAAO,OAAO,aAAa,CAAC,GAAG,SAAS,QAAQ,CAAC,GAAG;AAC1D,cAAI,MAAM;AACR,2BAAe;AACf,oBAAQ,IAAI;AAAA,UACd;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,YAAY,CAAC;AAAA,EACjC,SAAS,GAAY;AACnB,YAAQ,mBAAoB,EAAY,OAAO,EAAE;AAAA,EACnD;AACF;;;ACrIA,IAAM,8BAA8B,oBAAI,IAAI;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAUD,SAAS,wBAAwB,SAAgC;AAE/D,QAAM,UAAU,QAAQ,MAAM,8BAA8B;AAC5D,MAAI,UAAU,CAAC,GAAG;AAChB,UAAM,YAAY,QAAQ,CAAC,EAAE,KAAK;AAClC,QAAI;AAAE,WAAK,MAAM,SAAS;AAAG,aAAO;AAAA,IAAW,QAAQ;AAAA,IAAC;AAAA,EAC1D;AAGA,QAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,MAAI,UAAU,GAAI,QAAO;AAEzB,MAAI,QAAQ;AACZ,MAAI,WAAW;AACf,MAAI,SAAS;AAEb,WAAS,IAAI,OAAO,IAAI,QAAQ,QAAQ,KAAK;AAC3C,UAAM,KAAK,QAAQ,CAAC;AACpB,QAAI,QAAQ;AAAE,eAAS;AAAO;AAAA,IAAU;AACxC,QAAI,OAAO,QAAQ,UAAU;AAAE,eAAS;AAAM;AAAA,IAAU;AACxD,QAAI,OAAO,KAAK;AAAE,iBAAW,CAAC;AAAU;AAAA,IAAU;AAClD,QAAI,SAAU;AACd,QAAI,OAAO,IAAK;AAChB,QAAI,OAAO,KAAK;AACd;AACA,UAAI,UAAU,GAAG;AACf,cAAM,YAAY,QAAQ,UAAU,OAAO,IAAI,CAAC;AAChD,YAAI;AAAE,eAAK,MAAM,SAAS;AAAG,iBAAO;AAAA,QAAW,QAAQ;AAAE,iBAAO;AAAA,QAAM;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,cACpB,QACA,SACA,QACA,SACe;AACf,QAAM,EAAE,UAAU,OAAO,QAAQ,UAAU,QAAQ,IAAI;AAEvD,QAAM,gBAAgB,CAAC,WAAgC;AACrD,QAAI;AACJ,QAAI;AACF,YAAM,OAAO,wBAAwB,OAAO,OAAO;AACnD,UAAI,MAAM;AACR,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,wBAAgB,OAAO;AAAA,MACzB;AAAA,IACF,QAAQ;AAAA,IAER;AACA,WAAO,EAAE,SAAS,OAAO,SAAS,cAAc,CAAC;AAAA,EACnD;AAEA,MAAI;AACF,QAAI,aAAa,aAAa;AAC5B,YAAM,cAAc,OAAO,QAAQ,UAAU,SAAS,SAAS,eAAe,OAAO;AAAA,IACvF,WAAW,aAAa,UAAU;AAChC,YAAM,WAAW,OAAO,QAAQ,UAAU,SAAS,SAAS,eAAe,OAAO;AAAA,IACpF,WAAW,4BAA4B,IAAI,QAAQ,GAAG;AACpD,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ,yBAAyB,QAAQ,wBAAwB;AAAA,IACnE;AAAA,EACF,SAAS,GAAY;AACnB,UAAM,MAAO,EAAY,WAAW;AACpC,QAAI,IAAI,SAAS,OAAO,KAAK,IAAI,SAAS,cAAc,KAAK,IAAI,SAAS,SAAS,GAAG;AACpF,cAAQ,sCAAsC,QAAQ,uCAAuC;AAAA,IAC/F,OAAO;AACL,cAAQ,yBAAyB,QAAQ,KAAK,GAAG,EAAE;AAAA,IACrD;AAAA,EACF;AACF;;;AR3FA,SAAS,qBAAqB;AAC9B,IAAM,WAAW,cAAc,YAAY,GAAG;AAC9C,IAAM,UAAkB,SAAS,iBAAiB,EAAE;AACpD,IAAM,YAAYC,SAAQ,cAAc,YAAY,GAAG,CAAC;AAGxD,IAAM,kBAAkB;AACxB,IAAM,aAA2D,CAAC;AAElE,SAAS,iBAAiB,UAAkB,MAAa;AACvD,QAAM,MAAM,KAAK,IAAI,OAAK;AACxB,QAAI;AAAE,aAAO,OAAO,MAAM,WAAW,KAAK,UAAU,CAAC,EAAE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC;AAAA,IAAG,QAC5E;AAAE,aAAO,OAAO,CAAC;AAAA,IAAG;AAAA,EAC5B,CAAC,EAAE,KAAK,GAAG;AACX,aAAW,KAAK,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,EAAE,CAAC;AAC9C,MAAI,WAAW,SAAS,gBAAiB,YAAW,MAAM;AAC5D;AAGA,IAAM,WAAW,QAAQ;AAAzB,IAA8B,YAAY,QAAQ;AAAlD,IAAwD,WAAW,QAAQ;AAA3E,IAAkF,YAAY,QAAQ;AACtG,QAAQ,MAAM,IAAI,MAAa;AAAE,mBAAiB,OAAO,GAAG,CAAC;AAAG,WAAS,GAAG,CAAC;AAAG;AAChF,QAAQ,OAAO,IAAI,MAAa;AAAE,mBAAiB,QAAQ,GAAG,CAAC;AAAG,YAAU,GAAG,CAAC;AAAG;AACnF,QAAQ,QAAQ,IAAI,MAAa;AAAE,mBAAiB,SAAS,GAAG,CAAC;AAAG,WAAS,GAAG,CAAC;AAAG;AACpF,QAAQ,OAAO,IAAI,MAAa;AAAE,mBAAiB,QAAQ,GAAG,CAAC;AAAG,YAAU,GAAG,CAAC;AAAG;AAW5E,SAAS,gBACd,YACA,OAKA;AAGA,WAAS,cAAc,KAA2B,KAAmC;AACnF,QAAI,CAAC,IAAI,KAAK,WAAW,iBAAiB,EAAG,QAAO;AAGpD,UAAM,UAAU,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC;AAEpC,QAAI,YAAY,6BAA6B;AAC3C,yBAAmB,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,QAAI,YAAY,yBAAyB;AACvC,UAAI,UAAU,KAAK;AAAA,QACjB,gBAAgB;AAAA,QAChB,+BAA+B;AAAA,MACjC,CAAC;AACD,UAAI,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,SAAS,QAAQ,CAAC,CAAC;AAC1D,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,MAAM,IAAI,gBAAgB,EAAE,UAAU,KAAK,CAAC;AAElD,QAAM,eAAe,oBAAI,QAAgC;AAEzD,MAAI,GAAG,cAAc,CAAC,IAAI,QAAQ;AAChC,UAAM,SAAS,IAAI,QAAQ,UAAU;AACrC,QAAI,UAAU,CAAC,OAAO,WAAW,kBAAkB,KAAK,CAAC,OAAO,WAAW,kBAAkB,GAAG;AAC9F,SAAG,MAAM,MAAM,kBAAkB;AACjC;AAAA,IACF;AACA,iBAAa,IAAI,IAAI,EAAE,eAAe,MAAM,CAAC;AAE7C,OAAG,GAAG,WAAW,OAAO,SAAS;AAC/B,UAAI;AACJ,UAAI;AACF,cAAM,KAAK,MAAM,KAAK,SAAS,CAAC;AAAA,MAClC,QAAQ;AACN,kBAAU,IAAI,eAAe,cAAc;AAC3C;AAAA,MACF;AAEA,YAAM,QAAQ,aAAa,IAAI,EAAE;AAEjC,UAAI,CAAC,MAAM,iBAAiB,IAAI,SAAS,aAAa;AACpD,kBAAU,IAAI,iBAAiB,oBAAoB;AACnD;AAAA,MACF;AAEA,UAAI;AACF,cAAM,cAAc,IAAI,KAAK,OAAO,KAAK;AAAA,MAC3C,SAAS,GAAY;AACnB,kBAAU,IAAI,kBAAmB,EAAY,SAAS,IAAI,EAAE;AAAA,MAC9D;AAAA,IACF,CAAC;AAED,OAAG,GAAG,SAAS,MAAM;AACnB,mBAAa,OAAO,EAAE;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAGD,WAAS,cAAc,KAA2B,QAAa,MAAuB;AACpF,UAAM,WAAW,IAAI,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC;AAC5C,QAAI,YAAY,qBAAqB;AACnC,UAAI,cAAc,KAAK,QAAQ,MAAM,CAAC,OAAO;AAC3C,YAAI,KAAK,cAAc,IAAI,GAAG;AAAA,MAChC,CAAC;AACD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,KAAK,eAAe,cAAc;AAC7C;AAEA,eAAe,cACb,IACA,KACA,OACA,OACe;AACf,UAAQ,IAAI,MAAM;AAAA,IAChB,KAAK,aAAa;AAChB,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,SAAS,OAAO;AACnB,kBAAU,IAAI,mBAAmB,8BAA8B,IAAI,EAAE;AACrE,WAAG,MAAM;AACT;AAAA,MACF;AACA,UAAI,CAAC,cAAc,QAAQ,KAAK,GAAG;AACjC,kBAAU,IAAI,eAAe,iBAAiB,IAAI,EAAE;AACpD,WAAG,MAAM;AACT;AAAA,MACF;AACA,YAAM,gBAAgB;AACtB,YAAM,SAAS,WAAW;AAC1B,WAAK,IAAI;AAAA,QACP,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,UACP,SAAS;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,YACN,UAAU,OAAO;AAAA,YACjB,OAAO,OAAO;AAAA,YACd,WAAW,CAAC,CAAC,OAAO;AAAA,YACpB,SAAS,OAAO,YAAY,OAAO,QAAQ,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,UAC1F;AAAA,QACF;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,SAAS,MAAM;AAClB,kBAAU,IAAI,mBAAmB,gBAAgB,IAAI,EAAE;AACvD;AAAA,MACF;AACA,YAAM,SAAS,aAAa,QAAQ,MAAM,KAAK;AAC/C,UAAI,WAAW,QAAQ;AACrB,kBAAU,IAAI,YAAY,OAAO,OAAO,IAAI,EAAE;AAAA,MAChD,OAAO;AACL,aAAK,IAAI;AAAA,UACP,IAAI,IAAI;AAAA,UACR,MAAM;AAAA,UACN,SAAS,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,QAAQ;AAAA,QACzD,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAAA,IAEA,KAAK,YAAY;AACf,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,SAAS,QAAQ,QAAQ,YAAY,QAAW;AACnD,kBAAU,IAAI,mBAAmB,2BAA2B,IAAI,EAAE;AAClE;AAAA,MACF;AACA,YAAM,cAAc,cAAc,QAAQ,MAAM,QAAQ,SAAS,KAAK;AACtE,UAAI,CAAC,YAAY,IAAI;AACnB,kBAAU,IAAI,YAAY,YAAY,SAAS,gBAAgB,IAAI,EAAE;AAAA,MACvE,OAAO;AACL,aAAK,IAAI;AAAA,UACP,IAAI,IAAI;AAAA,UACR,MAAM;AAAA,UACN,SAAS,EAAE,MAAM,QAAQ,MAAM,IAAI,KAAK;AAAA,QAC1C,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,SAAS,MAAM;AAAE,kBAAU,IAAI,mBAAmB,gBAAgB,IAAI,EAAE;AAAG;AAAA,MAAO;AACvF,YAAM,aAAa,iBAAiB,QAAQ,IAAI;AAChD,UAAI,CAAC,YAAY;AAAE,kBAAU,IAAI,YAAY,mBAAmB,IAAI,EAAE;AAAG;AAAA,MAAO;AAChF,UAAI;AACF,cAAM,gBAAgBC,cAAa,YAAY,OAAO;AACtD,cAAM,cAAc,cAAc,QAAQ,MAAM,eAAe,KAAK;AACpE,YAAI,CAAC,YAAY,IAAI;AAAE,oBAAU,IAAI,YAAY,YAAY,SAAS,eAAe,IAAI,EAAE;AAAG;AAAA,QAAO;AACrG,aAAK,IAAI,EAAE,IAAI,IAAI,IAAI,MAAM,aAAa,SAAS,EAAE,MAAM,QAAQ,MAAM,IAAI,KAAK,EAAE,CAAC;AAAA,MACvF,SAAS,GAAY;AACnB,kBAAU,IAAI,YAAY,uBAAwB,EAAY,OAAO,IAAI,IAAI,EAAE;AAAA,MACjF;AACA;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,YAAM,UAAU,IAAI;AACpB,YAAM,OAAO,SAAS,QAAQ,MAAM,CAAC;AACrC,YAAM,QAAQ,UAAU,MAAM,KAAK;AACnC,WAAK,IAAI;AAAA,QACP,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,SAAS,EAAE,OAAO,aAAa,eAAe,KAAK,EAAE;AAAA,MACvD,CAAC;AACD;AAAA,IACF;AAAA,IAEA,KAAK,YAAY;AACf,YAAM,UAAU,IAAI;AACpB,YAAM,SAAS,WAAW;AAG1B,YAAM,WAAW,QAAQ,YAAY,OAAO,YAAY;AACxD,YAAM,SAAS,OAAO,UAAU,QAAQ,KAAK,OAAO,UAAU;AAC9D,YAAM,eAAe,iBAAiB,QAAQ;AAE9C,UAAI,CAAC,UAAU,CAAC,cAAc,OAAO;AACnC,kBAAU,IAAI,gBAAgB,0BAA0B,IAAI,EAAE;AAC9D;AAAA,MACF;AAEA,YAAM;AAAA,QACJ;AAAA,UACE;AAAA,UACA,OAAO,QAAQ,SAAS,OAAO,SAAS,eAAe,QAAQ,GAAG,OAAO,CAAC,GAAG,MAAM;AAAA,UACnF;AAAA,UACA,UAAU,QAAQ;AAAA,UAClB,SAAS,QAAQ;AAAA,QACnB;AAAA,QACA,CAAC,UAAU;AACT,eAAK,IAAI,EAAE,IAAI,IAAI,IAAI,MAAM,aAAa,SAAS,EAAE,OAAO,MAAM,EAAE,CAAC;AAAA,QACvE;AAAA,QACA,CAAC,WAAW;AACV,eAAK,IAAI,EAAE,IAAI,IAAI,IAAI,MAAM,YAAY,SAAS,OAAO,CAAC;AAAA,QAC5D;AAAA,QACA,CAAC,UAAU;AACT,eAAK,IAAI,EAAE,IAAI,IAAI,IAAI,MAAM,aAAa,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;AAAA,QACzE;AAAA,MACF;AACA;AAAA,IACF;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,SAAS,WAAW;AAC1B,WAAK,IAAI;AAAA,QACP,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,UACP,UAAU,OAAO;AAAA,UACjB,OAAO,OAAO;AAAA,UACd,WAAW,CAAC,EAAE,OAAO,UAAU,OAAO,YAAY,EAAE,KAAK,OAAO;AAAA,UAChE,OAAO,OAAO,SAAS;AAAA,UACvB,SAAS,OAAO;AAAA,YACd,OAAO,QAAQ,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;AAAA,UAC7D;AAAA,QACF;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,UAAU,IAAI;AACpB,YAAM,UAAoC,CAAC;AAC3C,UAAI,QAAQ,aAAa,OAAW,SAAQ,WAAW,QAAQ;AAC/D,UAAI,QAAQ,UAAU,OAAW,SAAQ,QAAQ,QAAQ;AAEzD,UAAI,QAAQ,WAAW,UAAa,QAAQ,UAAU;AACpD,cAAM,WAAW,WAAW;AAC5B,cAAM,UAAU,EAAE,GAAI,SAAS,WAAW,CAAC,EAAG;AAC9C,gBAAQ,QAAQ,QAAQ,IAAI,QAAQ;AACpC,gBAAQ,UAAU;AAClB,gBAAQ,SAAS,QAAQ;AAAA,MAC3B,WAAW,QAAQ,WAAW,QAAW;AACvC,gBAAQ,SAAS,QAAQ;AAAA,MAC3B;AACA,YAAM,SAAS,WAAW,OAAO;AACjC,UAAI,CAAC,OAAO,IAAI;AACd,kBAAU,IAAI,gBAAgB,OAAO,SAAS,kBAAkB,IAAI,EAAE;AAAA,MACxE,OAAO;AACL,aAAK,IAAI,EAAE,IAAI,IAAI,IAAI,MAAM,gBAAgB,SAAS,EAAE,IAAI,KAAK,EAAE,CAAC;AAAA,MACtE;AACA;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,SAAS,SAAS;AACrB,kBAAU,IAAI,mBAAmB,mBAAmB,IAAI,EAAE;AAC1D;AAAA,MACF;AACA,YAAM,aAAa,QAAQ,OAAOC,MAAK,MAAM,CAAC,KAAK,QAAQ,IAAI,GAAG,QAAQ,IAAI,IAAK,MAAM,CAAC,KAAK,QAAQ,IAAI;AAC3G,YAAM,UAAU,UAAU,QAAQ,SAAS,YAAY,KAAK;AAC5D,WAAK,IAAI,EAAE,IAAI,IAAI,IAAI,MAAM,kBAAkB,SAAS,EAAE,QAAQ,EAAE,CAAC;AACrE;AAAA,IACF;AAAA,IAEA,KAAK,cAAc;AACjB,WAAK,IAAI;AAAA,QACP,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM,WAAW,MAAM,IAAI;AAAA,UAC3B,aAAa,QAAQ;AAAA,UACrB,UAAU,QAAQ;AAAA,UAClB,MAAM,QAAQ;AAAA,UACd,QAAQ,KAAK,MAAM,QAAQ,OAAO,CAAC;AAAA,UACnC,UAAU,KAAK,MAAM,QAAQ,YAAY,EAAE,MAAM,OAAO,IAAI;AAAA,UAC5D,KAAK,QAAQ;AAAA,UACb,KAAK,QAAQ,IAAI;AAAA,QACnB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,IAEA;AACE,gBAAU,IAAI,gBAAgB,yBAAyB,IAAI,IAAI,IAAI,IAAI,EAAE;AAAA,EAC7E;AACF;AAEA,SAAS,KAAK,IAAe,KAAsB;AACjD,MAAI,GAAG,eAAe,UAAU,MAAM;AACpC,OAAG,KAAK,KAAK,UAAU,GAAG,CAAC;AAAA,EAC7B;AACF;AAEA,SAAS,UAAU,IAAe,MAAc,SAAiB,IAAmB;AAClF,OAAK,IAAI,EAAE,IAAI,MAAM,SAAS,MAAM,SAAS,SAAS,EAAE,MAAM,QAAQ,EAAE,CAAC;AAC3E;AAEA,SAAS,mBAAmB,KAAgC;AAC1D,QAAM,cAAc;AAAA,IAClBA,MAAK,WAAW,WAAW,iBAAiB;AAAA,IAC5CA,MAAK,WAAW,MAAM,QAAQ,WAAW,iBAAiB;AAAA,EAC5D;AAEA,aAAW,cAAc,aAAa;AACpC,QAAI;AACF,UAAIC,YAAW,UAAU,GAAG;AAC1B,cAAM,UAAUF,cAAa,YAAY,OAAO;AAChD,YAAI,UAAU,KAAK;AAAA,UACjB,gBAAgB;AAAA,UAChB,+BAA+B;AAAA,UAC/B,iBAAiB;AAAA,QACnB,CAAC;AACD,YAAI,IAAI,OAAO;AACf;AAAA,MACF;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU,KAAK;AAAA,IACjB,gBAAgB;AAAA,IAChB,+BAA+B;AAAA,EACjC,CAAC;AACD,MAAI,IAAI,sWAAsW;AAChX;;;AFnYO,SAAS,kBACd,YACA,YACA,OACa;AACb,QAAM,QAAQ,UAAU,kBAAkB;AAAA,IACxC,QAAQ,UAAU,UAAU,IAAI,UAAU;AAAA,IAC1C,oBAAoB;AAAA,IACpB,cAAc;AAAA;AAAA;AAAA,EAEhB,CAAC;AAED,QAAM,QAAQ,gBAAgB;AAI9B,QAAM,GAAG,YAAY,CAAC,UAAU,QAAQ;AACtC,UAAM,SAAS,IAAI,QAAQ,UAAU;AAErC,QAAI,OAAO,SAAS,WAAW,KAAK,OAAO,SAAS,KAAK,KAAK,CAAC,QAAQ;AACrE,eAAS,aAAa,iBAAiB;AAAA,IACzC;AAAA,EACF,CAAC;AAED,QAAM,GAAG,YAAY,CAAC,UAAU,KAAK,QAAQ;AAC3C,UAAM,cAAc,SAAS,QAAQ,cAAc,KAAK;AACxD,UAAM,SAAS,YAAY,SAAS,WAAW;AAC/C,UAAM,SAAS,SAAS,cAAc;AAEtC,QAAI,CAAC,UAAU,SAAS,KAAK;AAE3B,UAAI,UAAU,QAAQ,SAAS,OAAO;AACtC,eAAS,GAAG,SAAS,MAAM;AAAE,YAAI;AAAE,cAAI,IAAI;AAAA,QAAG,QAAQ;AAAA,QAAC;AAAA,MAAE,CAAC;AAC1D,eAAS,KAAK,GAAG;AACjB;AAAA,IACF;AAEA,QAAI,QAAQ;AAEV,YAAM,UAAU,EAAE,GAAG,SAAS,QAAQ;AACtC,aAAO,QAAQ,gBAAgB;AAC/B,aAAO,QAAQ,kBAAkB;AACjC,aAAO,QAAQ,mBAAmB;AAClC,aAAO,QAAQ,yBAAyB;AACxC,aAAO,QAAQ,qCAAqC;AACpD,aAAO,QAAQ,2BAA2B;AAC1C,aAAO,QAAQ,MAAM;AACrB,aAAO,QAAQ,eAAe;AAC9B,cAAQ,eAAe,IAAI;AAE3B,UAAI,UAAU,QAAQ,OAAO;AAC7B,eAAS,GAAG,SAAS,MAAM;AAAE,YAAI;AAAE,cAAI,IAAI,qBAAqB,KAAK,CAAC;AAAA,QAAG,QAAQ;AAAA,QAAC;AAAA,MAAE,CAAC;AACrF,eAAS,KAAK,KAAK,EAAE,KAAK,MAAM,CAAC;AACjC,eAAS,GAAG,OAAO,MAAM;AACvB,YAAI,IAAI,qBAAqB,KAAK,CAAC;AAAA,MACrC,CAAC;AACD;AAAA,IACF;AAGA,UAAM,SAAmB,CAAC;AAC1B,QAAI,YAAY;AAChB,aAAS,GAAG,QAAQ,CAAC,MAAc;AAAE,UAAI,YAAY,OAAO;AAAE,eAAO,KAAK,CAAC;AAAG,qBAAa,EAAE;AAAA,MAAQ;AAAA,IAAE,CAAC;AACxG,aAAS,GAAG,SAAS,MAAM;AAAE,UAAI;AAAE,YAAI,IAAI;AAAA,MAAG,QAAQ;AAAA,MAAC;AAAA,IAAE,CAAC;AAC1D,aAAS,GAAG,OAAO,MAAM;AACvB,YAAM,OAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO,EAAE,MAAM,GAAG,GAAI;AAClE,YAAM,gBAAgB,qBAAqB,KAAK;AAChD,UAAI,UAAU,QAAQ,EAAE,gBAAgB,aAAa,iBAAiB,WAAW,CAAC;AAClF,UAAI,IAAI,kDAAkD,MAAM;AAAA;AAAA,mCAEnC,MAAM;AAAA,6FACoD,KAAK,QAAQ,MAAK,MAAM,CAAC;AAAA;AAAA,EAEpH,aAAa;AAAA,eACA;AAAA,IACX,CAAC;AAAA,EACH,CAAC;AAED,QAAM,GAAG,SAAS,CAAC,KAAK,MAAM,QAAQ;AACpC,QAAI,eAAe,KAAK,kBAAkB,CAAC,IAAI,aAAa;AAC1D,YAAM,gBAAgB,qBAAqB,KAAK;AAChD,UAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,UAAI;AAAA,QACF;AAAA;AAAA,qCAE6B,UAAU,IAAI,UAAU;AAAA;AAAA,kDAEX,IAAI,OAAO;AAAA,YACjD,aAAa;AAAA;AAAA,MAEnB;AAAA,IACF,WAAW,OAAO,OAAQ,IAAY,YAAY,YAAY;AAE5D,UAAI;AAAE,QAAC,IAAY,QAAQ;AAAA,MAAG,QAAQ;AAAA,MAAC;AAAA,IACzC;AAAA,EACF,CAAC;AAGD,MAAI,WAAsF;AAC1F,MAAI,YAAwF;AAE5F,QAAM,SAAS,KAAK,aAAa,CAAC,KAAK,QAAQ;AAC7C,QAAI,YAAY,SAAS,KAAK,GAAG,EAAG;AACpC,UAAM,IAAI,KAAK,GAAG;AAAA,EACpB,CAAC;AAGD,QAAM,KAAK,gBAAgB,QAAQ,KAAK;AACxC,aAAW,GAAG;AACd,cAAY,GAAG;AAGf,SAAO,GAAG,WAAW,CAAC,KAAK,QAAQ,SAAS;AAE1C,QAAI,aAAa,UAAU,KAAK,QAAQ,IAAI,EAAG;AAE/C,UAAM,GAAG,KAAK,QAAQ,IAAI;AAAA,EAC5B,CAAC;AAED,SAAO;AACT;AAGA,SAAS,qBAAqB,OAAuB;AACnD,SAAO,4CAA4C,KAAK,IAAI,CAAC,iDAAiD,KAAK;AACrH;;;AWxIA,SAAS,wBAAwB;AACjC,SAAS,gBAAAG,eAAc,cAAAC,mBAAkB;AACzC,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AAC9B,SAAS,gBAAgB;AAEzB,IAAM,mBAAmB;AAAA,EACvB;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAEA,SAAS,gBAAgB,MAAc,MAAgC;AACrE,SAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,UAAM,SAAS,iBAAiB,EAAE,MAAM,MAAM,SAAS,IAAK,CAAC;AAC7D,WAAO,MAAM;AACb,WAAO,GAAG,WAAW,MAAM;AAAE,aAAO,QAAQ;AAAG,MAAAA,SAAQ,IAAI;AAAA,IAAG,CAAC;AAC/D,WAAO,GAAG,SAAS,MAAM;AAAE,aAAO,QAAQ;AAAG,MAAAA,SAAQ,KAAK;AAAA,IAAG,CAAC;AAC9D,WAAO,GAAG,WAAW,MAAM;AAAE,aAAO,QAAQ;AAAG,MAAAA,SAAQ,KAAK;AAAA,IAAG,CAAC;AAAA,EAClE,CAAC;AACH;AAGA,eAAe,UAAU,MAAc,OAAe,aAA+B;AACnF,QAAM,UAAU,MAAM,QAAQ,IAAI;AAAA,IAChC,gBAAgB,MAAM,IAAI;AAAA,IAC1B,gBAAgB,MAAM,KAAK;AAAA,IAC3B,gBAAgB,MAAM,WAAW;AAAA,EACnC,CAAC;AACD,SAAO,QAAQ,KAAK,OAAO;AAC7B;AAaO,SAAS,oBAAoB,MAAc,aAAqC;AACrF,MAAI;AAEF,UAAM,YAAY,SAAS,YAAY,IAAI,gCAAgC;AAAA,MACzE,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC,EAAE,KAAK;AAER,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,OAAO,UAAU,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AACtE,UAAM,WAAWA,SAAQ,WAAW;AAEpC,eAAW,OAAO,MAAM;AACtB,UAAI;AAEF,cAAM,YAAY;AAAA,UAChB,cAAc,GAAG;AAAA,UACjB,EAAE,UAAU,SAAS,SAAS,IAAK;AAAA,QACrC,EAAE,KAAK;AAEP,YAAI,CAAC,UAAW;AAChB,cAAM,aAAaA,SAAQ,UAAU,MAAM,CAAC,CAAC;AAG7C,YAAI,eAAe,YAAY,SAAS,WAAW,UAAU,KAAK,WAAW,WAAW,QAAQ,GAAG;AACjG,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AACN;AAAA,MACF;AAAA,IACF;AAGA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBAAgB,MAAc,QAAQ,IAAI,GAAmC;AAEjG,QAAM,UAAU,iBAAiB,GAAG;AACpC,QAAM,UAAU,aAAa,GAAG;AAChC,QAAM,cAAc;AAAA,IAClB,GAAI,UAAU,CAAC,OAAO,IAAI,CAAC;AAAA,IAC3B,GAAG,QAAQ,IAAI,CAAC,MAAM,EAAE,WAAW;AAAA,EACrC,EAAE,OAAO,CAAC,GAAG,GAAG,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;AAExC,MAAI,YAAY,SAAS,GAAG;AAC1B,eAAW,QAAQ,aAAa;AAC9B,UAAI,MAAM,UAAU,IAAI,GAAG;AAEzB,cAAM,QAAQ,oBAAoB,MAAM,GAAG;AAC3C,YAAI,UAAU,OAAO;AAEnB;AAAA,QACF;AACA,eAAO,EAAE,MAAM,MAAM,aAAa,aAAa,KAAK;AAAA,MACtD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,iBAAiB,IAAI,OAAO,SAAS;AAClD,UAAM,SAAS,MAAM,UAAU,IAAI;AACnC,WAAO,SAAS,OAAO;AAAA,EACzB,CAAC;AAED,QAAM,UAAU,MAAM,QAAQ,IAAI,MAAM;AAExC,aAAW,aAAa,SAAS;AAC/B,QAAI,cAAc,KAAM;AAExB,UAAM,QAAQ,oBAAoB,WAAW,GAAG;AAChD,QAAI,UAAU,MAAO;AACrB,WAAO,EAAE,MAAM,WAAW,MAAM,aAAa,aAAa,MAAM;AAAA,EAClE;AAEA,SAAO;AACT;AAEA,eAAsB,WAAW,MAAgC;AAC/D,SAAO,UAAU,IAAI;AACvB;AAEA,eAAsB,kBAAkB,WAAoC;AAC1E,MAAI,OAAO;AACX,SAAO,MAAM,WAAW,IAAI,GAAG;AAC7B;AACA,QAAI,OAAO,YAAY,KAAK;AAC1B,YAAM,IAAI,MAAM,yCAAyC,SAAS,EAAE;AAAA,IACtE;AAAA,EACF;AACA,SAAO;AACT;AAWA,IAAM,qBAID;AAAA,EACH,EAAE,OAAO,YAAY,WAAW,WAAW,aAAa,IAAK;AAAA,EAC7D,EAAE,OAAO,YAAY,WAAW,QAAQ,aAAa,KAAK;AAAA,EAC1D,EAAE,OAAO,YAAY,WAAW,QAAQ,aAAa,IAAK;AAAA,EAC1D,EAAE,OAAO,kBAAkB,WAAW,WAAW,aAAa,KAAK;AAAA,EACnE,EAAE,OAAO,+BAA+B,WAAW,WAAW,aAAa,KAAK;AAAA,EAChF,EAAE,OAAO,kBAAkB,WAAW,aAAa,aAAa,KAAK;AAAA,EACrE,EAAE,OAAO,aAAa,WAAW,SAAS,aAAa,KAAK;AAAA,EAC5D,EAAE,OAAO,aAAa,WAAW,SAAS,aAAa,IAAK;AAAA,EAC5D,EAAE,OAAO,6BAA6B,WAAW,oBAAoB,aAAa,IAAK;AAAA,EACvF,EAAE,OAAO,cAAc,WAAW,UAAU,aAAa,KAAK;AAAA,EAC9D,EAAE,OAAO,0CAA0C,WAAW,WAAW,aAAa,KAAK;AAAA,EAC3F,EAAE,OAAO,cAAc,WAAW,UAAU,aAAa,IAAK;AAAA,EAC9D,EAAE,OAAO,gCAAgC,WAAW,aAAa,aAAa,IAAK;AAAA,EACnF,EAAE,OAAO,YAAY,WAAW,QAAQ,aAAa,KAAK;AAAA,EAC1D,EAAE,OAAO,oCAAoC,WAAW,WAAW,aAAa,IAAK;AAAA,EACrF,EAAE,OAAO,aAAa,WAAW,SAAS,aAAa,IAAK;AAAA,EAC5D,EAAE,OAAO,qCAAqC,WAAW,UAAU,aAAa,IAAK;AAAA,EACrF,EAAE,OAAO,aAAa,WAAW,SAAS,aAAa,IAAK;AAAA,EAC5D,EAAE,OAAO,qCAAqC,WAAW,eAAe,aAAa,IAAK;AAC5F;AAEA,IAAM,mBAAmB,CAAC,OAAO,SAAS,SAAS,WAAW,aAAa,aAAa,UAAU,cAAc,OAAO,UAAU;AAE1H,SAAS,iBAAiB,MAAc,QAAQ,IAAI,GAAgB;AACzE,QAAM,UAAUD,MAAK,KAAK,cAAc;AACxC,MAAI,CAACD,YAAW,OAAO,EAAG,QAAO,CAAC;AAElC,MAAI;AACJ,MAAI;AACF,UAAM,KAAK,MAAMD,cAAa,SAAS,OAAO,CAAC;AAAA,EACjD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,CAAC,IAAI,QAAS,QAAO,CAAC;AAE1B,QAAM,UAAuB,CAAC;AAE9B,aAAW,QAAQ,kBAAkB;AACnC,UAAM,UAAU,IAAI,QAAQ,IAAI;AAChC,QAAI,CAAC,QAAS;AAGd,QAAI,YAAY;AAChB,QAAI,cAAc;AAElB,eAAW,WAAW,oBAAoB;AACxC,UAAI,QAAQ,MAAM,KAAK,OAAO,GAAG;AAC/B,oBAAY,QAAQ;AACpB,sBAAc,QAAQ;AACtB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,QAAQ,MAAM,uBAAuB;AACvD,QAAI,WAAW;AACb,oBAAc,SAAS,UAAU,CAAC,GAAG,EAAE;AAAA,IACzC;AAEA,YAAQ,KAAK,EAAE,MAAM,SAAS,WAAW,YAAY,CAAC;AAAA,EACxD;AAEA,SAAO;AACT;AAKA,IAAM,8BAAkF;AAAA,EACtF,WAAoB,EAAE,SAAS,WAAW,OAAO,cAAc;AAAA,EAC/D,QAAoB,EAAE,SAAS,UAAW,OAAO,UAAU;AAAA,EAC3D,WAAoB,EAAE,SAAS,WAAW,OAAO,cAAc;AAAA,EAC/D,aAAoB,EAAE,SAAS,WAAW,OAAO,eAAe;AAAA,EAChE,QAAoB,EAAE,SAAS,UAAW,OAAO,UAAU;AAAA,EAC3D,SAAoB,EAAE,SAAS,WAAW,OAAO,WAAW;AAAA,EAC5D,SAAoB,EAAE,SAAS,UAAW,OAAO,WAAW;AAAA,EAC5D,oBAAoB,EAAE,SAAS,UAAW,OAAO,mBAAmB;AAAA,EACpE,UAAoB,EAAE,SAAS,UAAW,OAAO,YAAY;AAAA,EAC7D,WAAoB,EAAE,SAAS,UAAW,OAAO,UAAU;AAAA,EAC3D,WAAoB,EAAE,SAAS,UAAW,OAAO,aAAa;AAAA,EAC9D,UAAoB,EAAE,SAAS,UAAW,OAAO,YAAY;AAC/D;AAEA,SAAS,UAAU,GAAW,GAAoB;AAChD,QAAM,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAClC,QAAM,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAClC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,SAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AACxC,SAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AAAA,EAC1C;AACA,SAAO;AACT;AAEO,SAAS,uBAAuB,WAAsD;AAC3F,QAAM,MAAM,4BAA4B,SAAS;AACjD,MAAI,CAAC,IAAK,QAAO,EAAE,IAAI,KAAK;AAE5B,QAAM,UAAU,QAAQ,SAAS;AACjC,MAAI,CAAC,UAAU,SAAS,IAAI,OAAO,GAAG;AACpC,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS,GAAG,IAAI,KAAK,wBAAwB,IAAI,OAAO,0BAA0B,OAAO;AAAA,IAC3F;AAAA,EACF;AACA,SAAO,EAAE,IAAI,KAAK;AACpB;AAQO,SAAS,aAAa,MAAc,QAAQ,IAAI,GAAkB;AACvE,QAAM,WAAW,CAAC,cAAc,0BAA0B,oBAAoB,MAAM;AACpF,aAAW,WAAW,UAAU;AAC9B,UAAM,UAAUE,MAAK,KAAK,OAAO;AACjC,QAAI,CAACD,YAAW,OAAO,EAAG;AAC1B,QAAI;AACF,YAAM,UAAUD,cAAa,SAAS,OAAO;AAC7C,YAAM,QAAQ,QAAQ,MAAM,oBAAoB;AAChD,UAAI,MAAO,QAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAAA,IACzC,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAIO,SAAS,eAAe,MAAc,QAAQ,IAAI,GAAW;AAClE,QAAM,UAAUE,MAAK,KAAK,cAAc;AACxC,MAAI,CAACD,YAAW,OAAO,EAAG,QAAO;AACjC,MAAI;AACF,UAAM,MAAM,KAAK,MAAMD,cAAa,SAAS,OAAO,CAAC;AACrD,WAAO,IAAI,QAAQ;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAYA,IAAM,aAA0D;AAAA,EAC9D,EAAE,MAAM,kBAAkB,IAAI,OAAO;AAAA,EACrC,EAAE,MAAM,aAAa,IAAI,OAAO;AAAA,EAChC,EAAE,MAAM,aAAa,IAAI,MAAM;AAAA,EAC/B,EAAE,MAAM,YAAY,IAAI,MAAM;AAAA,EAC9B,EAAE,MAAM,qBAAqB,IAAI,MAAM;AACzC;AAEA,IAAM,mBAAmD;AAAA,EACvD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AACP;AAEO,SAAS,2BAA2B,MAAc,QAAQ,IAAI,GAAqB;AACxF,QAAM,iBAAiBC,YAAWC,MAAK,KAAK,cAAc,CAAC;AAG3D,MAAI,KAAqB;AACzB,aAAW,EAAE,MAAM,IAAI,WAAW,KAAK,YAAY;AACjD,QAAID,YAAWC,MAAK,KAAK,IAAI,CAAC,GAAG;AAC/B,WAAK;AACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,gBAAgB,iBAAiB,EAAE;AAAA,EACrC;AACF;;;AZpTA,SAAS,iBAAAE,sBAAqB;AApC9B,IAAM,kBAAkB,QAAQ;AAChC,QAAQ,cAAc,SAAU,YAAiB,MAAa;AAC5D,MAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,cAAc,EAAG;AACrE,SAAO,gBAAgB,KAAK,SAAS,SAAS,GAAG,IAAI;AACvD;AAGA,QAAQ,GAAG,sBAAsB,CAAC,QAAQ;AACxC,UAAQ,MAAM,MAAM,IAAI,kCAAkC,GAAI,KAAe,WAAW,GAAG;AAC3F,UAAQ,MAAM,MAAM,IAAI,uEAAuE,CAAC;AAClG,CAAC;AAED,QAAQ,GAAG,qBAAqB,CAAC,QAAQ;AACvC,UAAQ,MAAM,MAAM,IAAI,8BAA8B,GAAG,IAAI,OAAO;AACpE,UAAQ,MAAM,MAAM,IAAI,uEAAuE,CAAC;AAChG,UAAQ,KAAK,CAAC;AAChB,CAAC;AAGD,IAAM,iBAAiC,CAAC;AACxC,IAAI,mBAAkC;AAiBtC,IAAMC,YAAWD,eAAc,YAAY,GAAG;AAC9C,IAAME,WAAkBD,UAAS,iBAAiB,EAAE;AAEpD,SAAS,IAAI,UAAmC;AAC9C,QAAM,KAAK,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAC3E,SAAO,IAAI,QAAQ,CAACE,aAAY;AAC9B,OAAG,SAAS,UAAU,CAAC,WAAW;AAChC,SAAG,MAAM;AACT,MAAAA,SAAQ,OAAO,KAAK,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,YACP,MACA,YAAoB,KACpB,aACkB;AAClB,QAAM,QAAQ,KAAK,IAAI;AACvB,SAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,UAAM,QAAQ,YAAY;AACxB,UAAI,cAAc,GAAG;AACnB,QAAAA,SAAQ,KAAK;AACb;AAAA,MACF;AACA,UAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,QAAAA,SAAQ,IAAI;AACZ;AAAA,MACF;AACA,YAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,UAAI,UAAU,WAAW;AACvB,QAAAA,SAAQ,KAAK;AACb;AAAA,MACF;AAEA,YAAM,WAAW,UAAU,MAAQ,MAAM;AACzC,iBAAW,OAAO,QAAQ;AAAA,IAC5B;AACA,UAAM;AAAA,EACR,CAAC;AACH;AAEA,SAAS,WAAW,KAAa,MAAgB,MAAc,QAAQ,IAAI,GAAqB;AAC9F,SAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,MAAM;AAAA,QAC7B;AAAA,QACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,QAChC,OAAO;AAAA,MACT,CAAC;AAED,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,cAAM,QAAQ,KAAK,SAAS,EAAE,KAAK,EAAE,MAAM,IAAI;AAC/C,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,KAAK,EAAG,SAAQ,OAAO,MAAM,MAAM,IAAI,YAAO,IAAI;AAAA,CAAI,CAAC;AAAA,QAClE;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,cAAM,QAAQ,KAAK,SAAS,EAAE,KAAK,EAAE,MAAM,IAAI;AAC/C,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,KAAK,EAAG,SAAQ,OAAO,MAAM,MAAM,IAAI,YAAO,IAAI;AAAA,CAAI,CAAC;AAAA,QAClE;AAAA,MACF,CAAC;AAED,YAAM,GAAG,SAAS,MAAMA,SAAQ,KAAK,CAAC;AACtC,YAAM,GAAG,SAAS,CAAC,SAASA,SAAQ,SAAS,CAAC,CAAC;AAAA,IACjD,QAAQ;AACN,MAAAA,SAAQ,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAEA,eAAe,YAAY,WAAmB,aAAoC;AAChF,MAAI;AACF,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,GAAI;AAGzD,UAAM,MAAM,MAAM,MAAM,oBAAoB,SAAS,yBAAyB;AAAA,MAC5E,QAAQ,WAAW;AAAA,IACrB,CAAC;AACD,iBAAa,OAAO;AAEpB,QAAI,IAAI,IAAI;AACV,cAAQ,IAAI,MAAM,MAAM,0BAAqB,CAAC;AAAA,IAChD,OAAO;AACL,cAAQ,IAAI,MAAM,OAAO,0DAAqD,CAAC;AAAA,IACjF;AAAA,EACF,QAAQ;AACN,YAAQ;AAAA,MACN,MAAM,OAAO,yEAAoE;AAAA,IACnF;AACA,YAAQ;AAAA,MACN,MAAM,IAAI,gDAAgD;AAAA,IAC5D;AAAA,EACF;AACA,UAAQ,IAAI,EAAE;AAChB;AA4BA,IAAI,oBAAmC;AAMvC,eAAe,kBAAkB,YAAoB,YAAmC;AACtF,MAAI;AACF,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,GAAI;AAEzD,UAAM,MAAM,MAAM,MAAM,UAAU,UAAU,IAAI,UAAU,KAAK;AAAA,MAC7D,QAAQ,WAAW;AAAA,MACnB,UAAU;AAAA,MACV,SAAS,EAAE,QAAQ,YAAY;AAAA,IACjC,CAAC;AACD,iBAAa,OAAO;AAEpB,UAAM,SAAS,IAAI;AAGnB,QAAI,UAAU,OAAO,SAAS,IAAK;AAEnC,QAAI,WAAW,KAAK;AAClB,cAAQ,IAAI,MAAM,OAAO,0DAAuD,CAAC;AACjF,cAAQ,IAAI,MAAM,IAAI,sDAAsD,CAAC;AAC7E,cAAQ,IAAI,EAAE;AAEd,UAAI,sBAAsB,WAAW;AACnC,gBAAQ,IAAI,MAAM,IAAI,6BAA6B,CAAC;AACpD,gBAAQ,IAAI,MAAM,IAAI,sEAAiE,CAAC;AACxF,gBAAQ,IAAI,MAAM,IAAI,8CAA8C,CAAC;AACrE,gBAAQ,IAAI,MAAM,IAAI,oEAA+D,CAAC;AACtF,gBAAQ,IAAI,MAAM,IAAI,kEAA6D,CAAC;AACpF,gBAAQ,IAAI,MAAM,IAAI,sEAAiE,CAAC;AACxF,gBAAQ,IAAI,MAAM,IAAI,mEAA8D,CAAC;AAAA,MACvF,WAAW,sBAAsB,WAAW;AAC1C,gBAAQ,IAAI,MAAM,IAAI,iEAAiE,CAAC;AAAA,MAC1F,WAAW,sBAAsB,QAAQ;AACvC,gBAAQ,IAAI,MAAM,IAAI,mEAAmE,CAAC;AAAA,MAC5F,OAAO;AACL,gBAAQ,IAAI,MAAM,IAAI,oDAAoD,CAAC;AAAA,MAC7E;AAEA,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,MAAM,IAAI,yEAAoE,CAAC;AAC3F,cAAQ,IAAI,EAAE;AAAA,IAChB,WAAW,UAAU,KAAK;AACxB,cAAQ,IAAI,MAAM,OAAO,oCAA+B,MAAM,oBAAoB,CAAC;AACnF,cAAQ,IAAI,MAAM,IAAI,sEAAsE,CAAC;AAC7F,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,WAAW,EAChB,YAAY,mDAAmD,EAC/D,QAAQC,QAAO,EACf,OAAO,qBAAqB,4BAA4B,EAAE,EAC1D;AAAA,EACC;AAAA,EACA;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,aAAa,yBAAyB,EAC7C,OAAO,iBAAiB,mBAAmB,WAAW,EACtD,OAAO,OAAO,SAAS;AACtB,UAAQ,IAAI,EAAE;AACd,UAAQ;AAAA,IACN,iBAAU,MAAM,KAAK,IAAI,SAAS,EAAE,WAAW,IAAI,MAAM,IAAI,KAAKA,QAAO,EAAE,IAAI;AAAA,EACjF;AACA,UAAQ,IAAI,MAAM,IAAI,qCAAqC,CAAC;AAC5D,UAAQ,IAAI,EAAE;AAEd,MAAI;AACJ,MAAI,aAAa,KAAK;AAEtB,MAAI,KAAK,MAAM;AAEb,iBAAa,SAAS,KAAK,MAAM,EAAE;AACnC,UAAM,YAAY,MAAM,WAAW,UAAU;AAC7C,QAAI,CAAC,WAAW;AAEd,YAAM,UAAU,MAAM,sBAAsB,UAAU;AACtD,UAAI,CAAC,SAAS;AACZ,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,kBAAkB;AACpB,qBAAa;AAAA,MACf,OAAO;AACL,cAAM,UAAU,MAAM,gBAAgB;AACtC,YAAI,SAAS;AAAE,uBAAa,QAAQ;AAAM,uBAAa,QAAQ;AAAA,QAAM;AAAA,MACvE;AAAA,IACF;AAAA,EACF,OAAO;AAEL,YAAQ,IAAI,MAAM,IAAI,8BAA8B,CAAC;AACrD,UAAM,WAAW,MAAM,gBAAgB;AAEvC,QAAI,YAAY,SAAS,aAAa;AAEpC,mBAAa,SAAS;AACtB,mBAAa,SAAS;AAAA,IACxB,WAAW,YAAY,CAAC,SAAS,aAAa;AAE5C,YAAM,SAAS,MAAM;AAAA,QACnB,MAAM,OAAO,4BAA4B,SAAS,IAAI,uCAAuC,IAC7F,MAAM,IAAI,QAAQ;AAAA,MACpB;AACA,UAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,SAAS,WAAW,IAAI;AACnF,qBAAa,SAAS;AACtB,qBAAa,SAAS;AAAA,MACxB,OAAO;AACL,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,MAAM,IAAI,oCAAoC,CAAC;AAC3D,gBAAQ,IAAI,MAAM,KAAK,sCAAsC,CAAC;AAC9D,gBAAQ,IAAI,EAAE;AACd,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,OAAO;AAEL,YAAM,UAAU,MAAM,sBAAsB;AAC5C,UAAI,CAAC,SAAS;AACZ,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,kBAAkB;AACpB,qBAAa;AAAA,MACf,OAAO;AACL,cAAM,aAAa,MAAM,gBAAgB;AACzC,YAAI,CAAC,YAAY;AACf,kBAAQ,IAAI,MAAM,IAAI,2DAAsD,CAAC;AAC7E,kBAAQ,IAAI,MAAM,IAAI,yDAAyD,CAAC;AAChF,kBAAQ,IAAI,EAAE;AACd,kBAAQ,KAAK,CAAC;AAAA,QAChB;AACA,qBAAa,WAAW;AACxB,qBAAa,WAAW;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,mBAAmB;AACtB,UAAM,UAAU,iBAAiB;AACjC,QAAI,QAAQ,SAAS,EAAG,qBAAoB,QAAQ,CAAC,EAAE;AAAA,EACzD;AAEA,UAAQ;AAAA,IACN,MAAM,MAAM,mCAA8B,UAAU,IAAI,UAAU,EAAE;AAAA,EACtE;AAGA,QAAM,SAAS,KAAK,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG;AAAA,IAAI,CAAC,MAChDC,SAAQ,CAAC;AAAA,EACX;AAGA,QAAM,SAAS,WAAW;AAC1B,aAAW,EAAE,GAAG,QAAQ,OAAO,WAAW,CAAC;AAG3C,uBAAqB;AAGrB,MAAI,YAAY,SAAS,KAAK,QAAQ,EAAE;AACxC,SAAO,MAAM,WAAW,SAAS,GAAG;AAClC;AACA,QAAI,YAAY,SAAS,KAAK,QAAQ,EAAE,IAAI,KAAK;AAC/C,cAAQ,IAAI,MAAM,IAAI,qCAAqC,CAAC;AAC5D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,cAAc,kBAAkB,YAAY,YAAa,KAAK;AAEpE,cAAY,OAAO,WAAW,aAAa,YAAY;AACrD,UAAM,WAAW,oBAAoB,SAAS;AAC9C,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,KAAK,MAAM,UAAU,CAAC;AACxC,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,MAAM,KAAK,WAAM,IAAI,MAAM,KAAK,UAAU,KAAK,QAAQ;AAAA,IACzD;AACA,YAAQ,IAAI,EAAE;AAEd,UAAM,YAAY,WAAW,UAAW;AAGxC,UAAM,kBAAkB,YAAY,UAAW;AAE/C,YAAQ,IAAI,MAAM,IAAI,yBAAyB,CAAC;AAChD,YAAQ;AAAA,MACN,MAAM,IAAI,yDAAyD;AAAA,IACrE;AACA,YAAQ,IAAI,EAAE;AAEd,QAAI,KAAK,SAAS,OAAO;AACvB,WAAK,oBAAoB,SAAS,EAAE,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACtD;AAAA,EACF,CAAC;AAGD,QAAM,WAAW,MAAM;AACrB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,IAAI,8BAA8B,CAAC;AACrD,mBAAe;AACf,gBAAY,MAAM;AAClB,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,QAAQ;AAChC,CAAC;AAIH,eAAe,sBAAsB,cAAyC;AAC5E,QAAM,cAAc,eAAe;AACnC,QAAM,UAAU,iBAAiB;AAEjC,MAAI,QAAQ,WAAW,GAAG;AAExB,UAAM,WAAWC,MAAK,QAAQ,IAAI,GAAG,YAAY;AACjD,QAAIC,YAAW,QAAQ,GAAG;AACxB,cAAQ;AAAA,QACN,MAAM,IAAI,kDAAkD;AAAA,MAC9D;AACA,cAAQ,IAAI,EAAE;AACd,YAAM,SAAS,MAAM;AAAA,QACnB,MAAM,MAAM,2CAA2C,IAAI,MAAM,IAAI,QAAQ;AAAA,MAC/E;AACA,UAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,MAAM;AACjE,eAAO;AAAA,MACT;AAGA,YAAM,aAAa,gBAAgB;AACnC,cAAQ,IAAI,MAAM,IAAI,oCAAoC,UAAU,KAAK,CAAC;AAE1E,YAAM,cAAc,MAAM,QAAQ,CAAC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAMjB,KAAK,UAAU,QAAQ,IAAI,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAQvC,UAAU,iEAAiE,UAAU;AAAA,OAClG,GAAG;AAAA,QACF,KAAK,QAAQ,IAAI;AAAA,QACjB,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,QAChC,UAAU;AAAA,MACZ,CAAC;AAED,qBAAe,KAAK,WAAW;AAC/B,kBAAY,QAAQ,GAAG,QAAQ,CAAC,MAAc;AAC5C,mBAAW,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG;AAClD,cAAI,KAAK,KAAK,EAAG,SAAQ,OAAO,MAAM,MAAM,IAAI,YAAO,IAAI;AAAA,CAAI,CAAC;AAAA,QAClE;AAAA,MACF,CAAC;AAGD,YAAM,KAAK,MAAM,YAAY,YAAY,GAAI;AAC7C,UAAI,IAAI;AACN,2BAAmB;AACnB,gBAAQ,IAAI,MAAM,MAAM,2CAAsC,UAAU,EAAE,CAAC;AAC3E,eAAO;AAAA,MACT;AACA,cAAQ,IAAI,MAAM,IAAI,0CAAqC,CAAC;AAC5D,aAAO;AAAA,IACT;AAEA,YAAQ;AAAA,MACN,MAAM,OAAO,4DAAuD;AAAA,IACtE;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,MAAM,6CAA6C,CAAC;AACtE,YAAQ,IAAI,MAAM,KAAK,sCAAsC,CAAC;AAC9D,YAAQ,IAAI,EAAE;AACd,WAAO;AAAA,EACT;AAGA,QAAM,OAAO,2BAA2B;AACxC,MAAI,CAAC,KAAK,WAAW;AACnB,YAAQ;AAAA,MACN,MAAM,OAAO,uEAAkE;AAAA,IACjF;AACA,YAAQ,IAAI,EAAE;AAEd,UAAM,SAAS,MAAM;AAAA,MACnB,MAAM,MAAM,QAAQ,IACpB,MAAM,KAAK,KAAK,cAAc,IAC9B,MAAM,MAAM,IAAI,IAChB,MAAM,IAAI,QAAQ;AAAA,IACpB;AAEA,QAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,MAAM;AACjE,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,MAAM,IAAI,SAAS,KAAK,cAAc,4BAA4B,CAAC;AAC/E,cAAQ,IAAI,EAAE;AACd,aAAO;AAAA,IACT;AAEA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,IAAI,kCAAkC,KAAK,cAAc,KAAK,CAAC;AAEjF,UAAM,CAAC,YAAY,GAAG,WAAW,IAAI,KAAK,eAAe,MAAM,GAAG;AAClE,UAAM,YAAY,MAAM,WAAW,YAAY,WAAW;AAE1D,QAAI,CAAC,WAAW;AACd,cAAQ,IAAI,MAAM,IAAI,2CAAsC,CAAC;AAC7D,cAAQ,IAAI,MAAM,IAAI,oBAAoB,KAAK,cAAc,YAAY,CAAC;AAC1E,cAAQ,IAAI,EAAE;AACd,aAAO;AAAA,IACT;AAEA,YAAQ,IAAI,MAAM,MAAM,mCAA8B,CAAC;AACvD,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,MAAI,SAAS,QAAQ,CAAC;AACtB,MAAI,QAAQ,WAAW,GAAG;AAExB,YAAQ;AAAA,MACN,MAAM,OAAO,mCAA8B;AAAA,IAC7C;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,MAAM,MAAM,UAAU,IACtB,MAAM,KAAK,WAAW,OAAO,IAAI,EAAE,IACnC,MAAM,MAAM,OAAO,WAAW,EAAE,IAChC,MAAM,IAAI,KAAK,OAAO,SAAS,GAAG;AAAA,IACpC;AACA,YAAQ,IAAI,MAAM,IAAI,eAAU,OAAO,OAAO,EAAE,CAAC;AACjD,YAAQ,IAAI,EAAE;AAEd,UAAM,SAAS,MAAM;AAAA,MACnB,MAAM,MAAM,kBAAkB,IAAI,MAAM,IAAI,QAAQ;AAAA,IACtD;AAEA,QAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,MAAM;AACjE,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,MAAM,IAAI,0DAA0D,CAAC;AACjF,cAAQ,IAAI,EAAE;AACd,aAAO;AAAA,IACT;AAAA,EACF,OAAO;AAEL,YAAQ;AAAA,MACN,MAAM,OAAO,mCAA8B;AAAA,IAC7C;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,MAAM,MAAM,WAAW,QAAQ,MAAM,mBAAmB,WAAW,GAAG;AAAA,IACxE;AACA,YAAQ,IAAI,EAAE;AAEd,YAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,cAAQ;AAAA,QACN,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAC3B,MAAM,MAAM,WAAW,EAAE,IAAI,EAAE,IAC/B,MAAM,IAAI,WAAM,EAAE,SAAS,UAAU,EAAE,WAAW,GAAG;AAAA,MACvD;AACA,cAAQ,IAAI,MAAM,IAAI,UAAU,EAAE,OAAO,EAAE,CAAC;AAAA,IAC9C,CAAC;AAED,YAAQ,IAAI,EAAE;AACd,UAAM,SAAS,MAAM;AAAA,MACnB,MAAM,MAAM,wBAAwB,IACpC,MAAM,IAAI,MAAM,QAAQ,MAAM,oBAAoB;AAAA,IACpD;AAEA,QAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,QAAQ,WAAW,IAAI;AAClF,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,MAAM,IAAI,0DAA0D,CAAC;AACjF,cAAQ,IAAI,EAAE;AACd,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,SAAS,QAAQ,EAAE,IAAI;AACnC,QAAI,MAAM,KAAK,OAAO,QAAQ,UAAU,MAAM,GAAG,GAAG;AAElD,eAAS,QAAQ,CAAC;AAAA,IACpB,OAAO;AACL,eAAS,QAAQ,GAAG;AAAA,IACtB;AAAA,EACF;AAGA,sBAAoB,OAAO;AAG3B,QAAM,SAAS,uBAAuB,OAAO,SAAS;AACtD,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,IAAI,MAAM,IAAI;AAAA,YAAU,OAAO,OAAO,EAAE,CAAC;AACjD,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,MAAM,0CAA0C,CAAC;AACnE,YAAQ,IAAI,MAAM,KAAK,gBAAgB,CAAC;AACxC,YAAQ,IAAI,MAAM,IAAI,kCAAkC,CAAC;AACzD,YAAQ,IAAI,EAAE;AACd,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,gBAAgB,OAAO;AAGlC,MAAI,cAAc;AAClB,MAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,UAAM,QAAQ,oBAAoB,MAAM,QAAQ,IAAI,CAAC;AACrD,QAAI,UAAU,MAAM;AAElB,cAAQ,IAAI,MAAM,MAAM,gDAA2C,IAAI,EAAE,CAAC;AAC1E,yBAAmB;AACnB,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,MAAM,kBAAkB,OAAO,CAAC;AAChD,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,MAAM,OAAO,kBAAa,IAAI,wCAAwC;AAAA,IACxE;AACA,YAAQ;AAAA,MACN,MAAM,IAAI,yBAAyB,OAAO,WAAW;AAAA,IACvD;AACA,WAAO;AACP,kBAAc;AAAA,EAChB;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ;AAAA,IACN,MAAM,IAAI,aAAa,IACvB,MAAM,KAAK,WAAW,OAAO,IAAI,EAAE,KAClC,cAAc,MAAM,IAAI,UAAU,IAAI,GAAG,IAAI,MAC9C,MAAM,IAAI,KAAK;AAAA,EACjB;AAGA,QAAM,WAAW,2BAA2B;AAC5C,QAAM,SAAS,SAAS,mBAAmB,SAAS,SAClD,SAAS,mBAAmB,SAAS,SACrC,SAAS,mBAAmB,QAAQ,QAAQ;AAC9C,QAAM,UAAU,WAAW,QAAQ,CAAC,OAAO,OAAO,IAAI,IAAI,CAAC,OAAO,IAAI;AAGtE,QAAM,uBAAuB,oBAAI,IAAI,CAAC,WAAW,QAAQ,WAAW,WAAW,SAAS,SAAS,aAAa,QAAQ,oBAAoB,UAAU,UAAU,SAAS,CAAC;AACxK,MAAI,eAAe,qBAAqB,IAAI,OAAO,SAAS,GAAG;AAC7D,QAAI,WAAW,OAAO;AACpB,cAAQ,KAAK,MAAM,UAAU,OAAO,IAAI,CAAC;AAAA,IAC3C,OAAO;AACL,cAAQ,KAAK,UAAU,OAAO,IAAI,CAAC;AAAA,IACrC;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,QAAQ,SAAS;AAAA,MAC7B,KAAK,QAAQ,IAAI;AAAA,MACjB,OAAO;AAAA,MACP,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,MAAM,OAAO,IAAI;AAAA,QACjB,SAAS;AAAA,QACT,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH,SAAS,GAAY;AACnB,YAAQ,IAAI,MAAM,IAAI,8BAA0B,EAAY,OAAO,EAAE,CAAC;AACtE,WAAO;AAAA,EACT;AAEA,iBAAe,KAAK,KAAK;AACzB,MAAI,cAAc;AAElB,QAAM,GAAG,SAAS,CAAC,QAAQ;AACzB,kBAAc;AACd,YAAQ,IAAI,MAAM,IAAI;AAAA,6BAA2B,IAAI,OAAO,EAAE,CAAC;AAAA,EACjE,CAAC;AAED,QAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,kBAAc;AACd,QAAI,SAAS,QAAQ,SAAS,GAAG;AAC/B,cAAQ,IAAI,MAAM,IAAI;AAAA,wCAAsC,IAAI,EAAE,CAAC;AAAA,IACrE;AAAA,EACF,CAAC;AAGD,QAAM,UAAU,MAAM;AACpB,eAAW,MAAM,gBAAgB;AAC/B,UAAI;AAAE,WAAG,KAAK,SAAS;AAAA,MAAG,QAAQ;AAAA,MAAC;AAAA,IACrC;AACA,eAAW,MAAM;AACf,iBAAW,MAAM,gBAAgB;AAC/B,YAAI;AAAE,aAAG,KAAK,SAAS;AAAA,QAAG,QAAQ;AAAA,QAAC;AAAA,MACrC;AAAA,IACF,GAAG,GAAI;AAAA,EACT;AACA,UAAQ,KAAK,QAAQ,OAAO;AAC5B,UAAQ,KAAK,UAAU,OAAO;AAC9B,UAAQ,KAAK,WAAW,OAAO;AAG/B,UAAQ;AAAA,IACN,MAAM,IAAI,oCAAoC,IAAI,KAAK;AAAA,EACzD;AAEA,QAAM,OAAO,MAAM,YAAY,MAAM,KAAO,MAAM,WAAW;AAE7D,MAAI,MAAM;AACR,uBAAmB;AACnB,YAAQ,IAAI,EAAE;AACd,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,aAAa;AAChB,UAAM,YAAY,CAAC,MAAM,KAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,KAAM,KAAM,MAAM,MAAM,MAAM,IAAI,EAClG,OAAO,CAAC,GAAG,GAAG,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;AACzC,eAAW,YAAY,WAAW;AAChC,UAAI,MAAM,WAAW,QAAQ,GAAG;AAC9B,cAAM,QAAQ,oBAAoB,UAAU,QAAQ,IAAI,CAAC;AACzD,YAAI,UAAU,MAAO;AACrB,gBAAQ;AAAA,UACN,MAAM,MAAM;AAAA,qCAAmC,QAAQ,GAAG;AAAA,QAC5D;AACA,2BAAmB;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa;AACf,YAAQ;AAAA,MACN,MAAM,IAAI,uCAAkC;AAAA,IAC9C;AACA,YAAQ,IAAI,EAAE;AAGd,QAAI;AACF,YAAM,UAAUD,MAAK,QAAQ,IAAI,GAAG,cAAc;AAClD,UAAIC,YAAW,OAAO,GAAG;AACvB,cAAM,MAAM,KAAK,MAAMC,cAAa,SAAS,OAAO,CAAC;AACrD,YAAI,IAAI,SAAS,MAAM;AACrB,kBAAQ,IAAI,MAAM,OAAO,mCAAmC,IAAI,QAAQ,IAAI,EAAE,CAAC;AAC/E,kBAAQ,IAAI,MAAM,IAAI,6BAA6B,QAAQ,OAAO,EAAE,CAAC;AACrE,kBAAQ,IAAI,EAAE;AAAA,QAChB;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAAC;AAGT,QAAI,QAAQ,WAAW;AACrB,YAAMC,UAAS,uBAAuB,OAAO,SAAS;AACtD,UAAI,CAACA,QAAO,IAAI;AACd,gBAAQ,IAAI,MAAM,OAAO,KAAKA,QAAO,OAAO,EAAE,CAAC;AAC/C,gBAAQ,IAAI,MAAM,IAAI,2BAA2B,CAAC;AAClD,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA,IACF;AAEA,YAAQ,IAAI,MAAM,MAAM,YAAY,CAAC;AACrC,YAAQ,IAAI,MAAM,IAAI,wCAAwC,CAAC;AAC/D,YAAQ,IAAI,MAAM,IAAI,2CAA2C,CAAC;AAClE,YAAQ,IAAI,MAAM,KAAK,uCAAuC,CAAC;AAC/D,YAAQ,IAAI,EAAE;AACd,WAAO;AAAA,EACT;AAGA,UAAQ;AAAA,IACN,MAAM,OAAO;AAAA,mDAAiD;AAAA,EAChE;AACA,UAAQ,IAAI,MAAM,IAAI,yCAAyC,CAAC;AAChE,UAAQ,IAAI,MAAM,IAAI,8CAA8C,CAAC;AACrE,UAAQ,IAAI,MAAM,KAAK,uCAAuC,CAAC;AAC/D,UAAQ,IAAI,EAAE;AACd,SAAO;AACT;AAEA,QAAQ,MAAM;","names":["resolve","join","existsSync","readFileSync","readFileSync","existsSync","join","dirname","readFileSync","writeFileSync","existsSync","mkdirSync","join","modelInfo","dirname","readFileSync","join","existsSync","readFileSync","existsSync","join","resolve","createRequire","_require","VERSION","resolve","VERSION","resolve","join","existsSync","readFileSync","compat"]}
|