when-does-my-quota-refresh 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/quota.ts","../../src/core/platform.ts","../../src/sources/local/process-detector.ts","../../src/sources/local/port-detective.ts","../../src/sources/local/connect-client.ts","../../src/sources/local/parser.ts","../../src/sources/local/index.ts","../../src/sources/cli/index.ts","../../src/sources/oauth/index.ts","../../src/sources/index.ts","../../src/sdk/cache.ts","../../src/sdk/store.ts","../../src/sdk/quota.ts","../../src/cli/render/quota-table.ts","../../src/cli/render/compare-table.ts","../../src/cli/commands/full.ts","../../src/cli/render/full-dashboard.ts","../../src/cli/commands/accounts.ts","../../src/cli/commands/history.ts","../../src/cli/render/history-chart.ts","../../src/cli/commands/doctor.ts","../../src/cli/commands/config.ts","../../src/cli/commands/wakeup.ts","../../src/cli/commands/watch.ts","../../src/cli/commands/plugin.ts"],"sourcesContent":["/**\n * when-does-my-quota-refresh (aq) — CLI entry point\n *\n * Cross-platform CLI + SDK for tracking Antigravity AI model quotas.\n */\n\nimport { Command } from 'commander'\nimport { readFileSync } from 'fs'\nimport { join, dirname } from 'path'\nimport { fileURLToPath } from 'url'\nimport { registerQuotaCommand } from './commands/quota.js'\nimport { executeFullDashboard } from './commands/full.js'\nimport { registerAccountsCommand } from './commands/accounts.js'\nimport { registerHistoryCommand } from './commands/history.js'\nimport { registerDoctorCommand } from './commands/doctor.js'\nimport { registerConfigCommand } from './commands/config.js'\nimport { registerWakeupCommand } from './commands/wakeup.js'\nimport { registerWatchCommand } from './commands/watch.js'\nimport { registerPluginCommand } from './commands/plugin.js'\nimport { setVerbose } from '../core/logger.js'\n\n// Version\nlet VERSION = '1.0.0'\ntry {\n const __dirname = dirname(fileURLToPath(import.meta.url))\n const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'))\n VERSION = pkg.version\n} catch { /* use default */ }\n\n// Build program\nconst program = new Command()\n\nprogram\n .name('aq')\n .description('Cross-platform CLI for tracking Antigravity AI model quotas')\n .version(VERSION)\n .option('--verbose', 'Enable debug output')\n\n// Register subcommands\nregisterQuotaCommand(program)\nregisterAccountsCommand(program)\nregisterHistoryCommand(program)\nregisterDoctorCommand(program)\nregisterConfigCommand(program)\nregisterWakeupCommand(program)\nregisterWatchCommand(program)\nregisterPluginCommand(program)\n\n// Handle --full as a global option\nprogram.option('--full', 'Show full dashboard with all accounts, groups, and sparklines')\nprogram.option('--json', 'Output JSON (global)')\nprogram.option('--no-history', 'Skip history sparkline in full dashboard')\nprogram.option('--watch', 'Auto-refresh mode')\n\n// Override parse to handle --full before subcommand dispatch\nconst args = process.argv.slice(2)\n\n// Set verbose if requested\nif (args.includes('--verbose')) {\n setVerbose(true)\n}\n\n// Check if --full is requested\nconst isFull = args.includes('--full')\n\n// Default action (no subcommand)\nprogram.action(async (opts) => {\n if (isFull || opts.full) {\n await executeFullDashboard({\n json: opts.json,\n watch: opts.watch,\n noHistory: opts.noHistory,\n verbose: opts.verbose,\n })\n } else {\n // Default: run quota command\n await program.parseAsync(['node', 'aq', 'quota', ...args.filter(a => a !== '--full')])\n }\n})\n\nprogram.parse()\n","/**\n * `aq quota` / `aq` — Display current quota\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport { QuotaClient } from '../../sdk/quota.js'\nimport { renderQuotaCompact } from '../render/quota-table.js'\nimport { renderComparisonTable } from '../render/compare-table.js'\n\nexport function registerQuotaCommand(program: Command): void {\n program\n .command('quota')\n .description('Display current quota (default command)')\n .option('-a, --all', 'Fetch all accounts side-by-side')\n .option('-r, --refresh', 'Force fresh fetch (bypass cache)')\n .option('-m, --method <method>', 'Force data source: local, cli, oauth')\n .option('--json', 'Output JSON')\n .action(async (opts) => {\n const spinner = ora('Fetching quota...').start()\n\n try {\n const client = new QuotaClient({ verbose: opts.verbose })\n\n if (opts.all) {\n const snapshots = await client.fetchQuota({ allAccounts: true, source: opts.method, refresh: opts.refresh })\n spinner.stop()\n\n if (opts.json) {\n console.log(JSON.stringify(snapshots, null, 2))\n } else {\n console.log(renderComparisonTable(Array.isArray(snapshots) ? snapshots : [snapshots]))\n }\n } else {\n const snapshot = await client.fetchQuota({ source: opts.method, refresh: opts.refresh })\n spinner.stop()\n\n if (opts.json) {\n console.log(JSON.stringify(snapshot, null, 2))\n } else {\n console.log(renderQuotaCompact(snapshot as any))\n }\n }\n } catch (err) {\n spinner.fail(chalk.red(`Failed to fetch quota: ${(err as Error).message}`))\n process.exit(1)\n }\n })\n}\n","/**\n * Cross-platform platform detection and utilities\n */\n\nimport { exec } from 'child_process'\nimport { promisify } from 'util'\n\nconst execAsync = promisify(exec)\n\nexport type Platform = 'darwin' | 'linux' | 'win32'\n\nexport function getPlatform(): Platform {\n return process.platform as Platform\n}\n\nexport function isWindows(): boolean {\n return process.platform === 'win32'\n}\n\nexport function isMacOS(): boolean {\n return process.platform === 'darwin'\n}\n\nexport function isLinux(): boolean {\n return process.platform === 'linux'\n}\n\n/**\n * Run a shell command and return stdout\n */\nexport async function runCommand(cmd: string): Promise<string> {\n try {\n const { stdout } = await execAsync(cmd, { timeout: 10000 })\n return stdout\n } catch {\n return ''\n }\n}\n\n/**\n * Format milliseconds as human-readable countdown\n */\nexport function formatCountdown(ms: number): string {\n if (ms <= 0) return 'now'\n const totalMinutes = Math.floor(ms / 60000)\n const hours = Math.floor(totalMinutes / 60)\n const minutes = totalMinutes % 60\n if (hours > 0) return `${hours}h ${minutes}m`\n return `${minutes}m`\n}\n\n/**\n * Format a fraction (0–1) as a percentage string\n */\nexport function formatPercentage(fraction: number): string {\n return `${Math.round(fraction * 100)}%`\n}\n\n/**\n * Clamp a number between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max)\n}\n","/**\n * Cross-platform process detection for Antigravity language server\n *\n * Fixes the Windows detection bug in antigravity-usage by using\n * multiple detection strategies per platform.\n */\n\nimport { runCommand, isWindows, isMacOS, isLinux } from '../../core/platform.js'\nimport { debug } from '../../core/logger.js'\nimport type { ProcessInfo } from '../../sdk/types.js'\n\nconst ANTIMATTER_MARKERS = [\n 'antigravity',\n 'language_server',\n 'language-server',\n 'antigravity-cli',\n 'antigravity_cli',\n 'agy',\n]\n\nconst ANTIMATTER_PATH_MARKERS = [\n '/antigravity/',\n 'Antigravity',\n 'antigravity.app',\n 'AntigravityStatusProbe',\n 'app_data_dir antigravity',\n]\n\n/**\n * Detect all running Antigravity language server processes\n */\nexport async function detectAntigravityProcesses(): Promise<ProcessInfo[]> {\n debug('process-detector', `Detecting on platform: ${process.platform}`)\n\n let processes: ProcessInfo[] = []\n\n if (isMacOS()) {\n processes = await detectOnMacOS()\n } else if (isLinux()) {\n processes = await detectOnLinux()\n } else if (isWindows()) {\n processes = await detectOnWindows()\n }\n\n debug('process-detector', `Found ${processes.length} process(es)`)\n return processes\n}\n\n/**\n * macOS: ps -ax with command line parsing\n */\nasync function detectOnMacOS(): Promise<ProcessInfo[]> {\n const output = await runCommand('ps -ax -o pid=,comm=,args=')\n return parsePsOutput(output)\n}\n\n/**\n * Linux: ps with full command line\n */\nasync function detectOnLinux(): Promise<ProcessInfo[]> {\n const output = await runCommand('ps -eo pid,comm,args --no-headers')\n return parsePsOutput(output)\n}\n\n/**\n * Windows: Multiple strategies combined\n * 1. wmic for process listing with command lines\n * 2. PowerShell Get-CimInstance as fallback\n * 3. tasklist as last resort\n */\nasync function detectOnWindows(): Promise<ProcessInfo[]> {\n // Strategy 1: wmic\n let output = await runCommand(\n 'wmic process where \"name like \\'%language%\\' or commandline like \\'%antigravity%\\'\" get ProcessId,Name,CommandLine /format:csv'\n )\n let processes = parseWmicOutput(output)\n if (processes.length > 0) return processes\n\n // Strategy 2: PowerShell\n output = await runCommand(\n 'powershell -Command \"Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match \\'antigravity|language.server\\' } | Select-Object ProcessId,Name,CommandLine | Format-Table -AutoSize\"'\n )\n processes = parsePowerShellOutput(output)\n if (processes.length > 0) return processes\n\n // Strategy 3: netstat scan for known port patterns (fallback)\n // This won't identify the process but can help with port discovery\n debug('process-detector', 'Windows: Falling back to port-based detection')\n return []\n}\n\n/**\n * Parse ps output (macOS/Linux)\n */\nfunction parsePsOutput(output: string): ProcessInfo[] {\n const processes: ProcessInfo[] = []\n const lines = output.split('\\n').filter(Boolean)\n\n for (const line of lines) {\n const trimmed = line.trim()\n if (!trimmed) continue\n\n // ps output format: PID COMM ARGS\n // comm is the short name, args is the full command line\n const parts = trimmed.split(/\\s+/)\n const pid = parseInt(parts[0], 10)\n if (isNaN(pid)) continue\n\n // The rest after PID is comm + args\n const rest = parts.slice(1).join(' ')\n\n if (matchesAntigravity(rest)) {\n processes.push({\n pid,\n name: parts[1] || 'unknown',\n commandLine: rest,\n scope: classifyProcess(rest),\n })\n }\n }\n\n return processes\n}\n\n/**\n * Parse wmic CSV output (Windows)\n */\nfunction parseWmicOutput(output: string): ProcessInfo[] {\n const processes: ProcessInfo[] = []\n const lines = output.split('\\n').filter(Boolean)\n\n for (const line of lines) {\n // wmic CSV format: Node,CommandLine,Name,ProcessId\n const parts = line.split(',').map(p => p.trim().replace(/\"/g, ''))\n if (parts.length < 4) continue\n\n const pid = parseInt(parts[3], 10)\n if (isNaN(pid)) continue\n\n const commandLine = parts[1] || ''\n const name = parts[2] || ''\n\n if (matchesAntigravity(commandLine) || matchesAntigravity(name)) {\n processes.push({\n pid,\n name,\n commandLine,\n scope: classifyProcess(commandLine),\n })\n }\n }\n\n return processes\n}\n\n/**\n * Parse PowerShell output (Windows)\n */\nfunction parsePowerShellOutput(output: string): ProcessInfo[] {\n const processes: ProcessInfo[] = []\n const lines = output.split('\\n').filter(Boolean)\n\n for (const line of lines) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('---') || trimmed.startsWith('ProcessId')) continue\n\n // PowerShell table format: PID Name CommandLine (whitespace-separated)\n const match = trimmed.match(/^\\s*(\\d+)\\s+(\\S+)\\s+(.*)$/)\n if (!match) continue\n\n const pid = parseInt(match[1], 10)\n const name = match[2]\n const commandLine = match[3]\n\n if (matchesAntigravity(commandLine) || matchesAntigravity(name)) {\n processes.push({\n pid,\n name,\n commandLine,\n scope: classifyProcess(commandLine),\n })\n }\n }\n\n return processes\n}\n\n/**\n * Check if a string matches Antigravity markers\n */\nfunction matchesAntigravity(text: string): boolean {\n const lower = text.toLowerCase()\n return ANTIMATTER_PATH_MARKERS.some(marker =>\n lower.includes(marker.toLowerCase())\n ) || (\n lower.includes('language') &&\n lower.includes('server') &&\n ANTIMATTER_MARKERS.some(m => lower.includes(m))\n )\n}\n\n/**\n * Classify process by its command line flags\n */\nfunction classifyProcess(commandLine: string): ProcessInfo['scope'] {\n const lower = commandLine.toLowerCase()\n if (lower.includes('antigravity-cli') || lower.includes('antigravity_cli') || lower.includes('agy')) {\n return 'cli'\n }\n if (lower.includes('antigravity ide') || lower.includes('antigravity-ide') || lower.includes('extensions/antigravity')) {\n return 'ide'\n }\n if (lower.includes('app_data_dir antigravity') || lower.includes('antigravity.app')) {\n return 'app'\n }\n return 'unknown'\n}\n\n/**\n * Extract command-line flags from process command line\n */\nexport function extractFlags(commandLine: string): Map<string, string> {\n const flags = new Map<string, string>()\n if (!commandLine) return flags\n\n // Match --flag value patterns\n const flagRegex = /--(\\S+)\\s+([^\\s-][^\\s]*)/g\n let match\n while ((match = flagRegex.exec(commandLine)) !== null) {\n flags.set(match[1], match[2])\n }\n\n return flags\n}\n","/**\n * Cross-platform port discovery for Antigravity language server\n *\n * Improved Windows support: netstat + PowerShell + port range scanning\n */\n\nimport { runCommand, isWindows, isMacOS, isLinux } from '../../core/platform.js'\nimport { debug } from '../../core/logger.js'\n\n/**\n * Discover all listening ports for a given process PID\n */\nexport async function discoverPorts(pid: number): Promise<number[]> {\n debug('port-detective', `Discovering ports for PID ${pid} on ${process.platform}`)\n\n if (isWindows()) {\n return discoverPortsOnWindows(pid)\n } else if (isMacOS()) {\n return discoverPortsOnMacOS(pid)\n } else {\n return discoverPortsOnLinux(pid)\n }\n}\n\n/**\n * macOS: lsof\n */\nasync function discoverPortsOnMacOS(pid: number): Promise<number[]> {\n try {\n const output = await runCommand(`lsof -nP -iTCP -sTCP:LISTEN -a -p ${pid}`)\n const ports: number[] = []\n for (const line of output.split('\\n')) {\n const match = line.match(/:(\\d+)\\s+\\(LISTEN\\)/)\n if (match) {\n const port = parseInt(match[1], 10)\n if (!isNaN(port) && !ports.includes(port)) {\n ports.push(port)\n }\n }\n }\n debug('port-detective', `macOS ports: ${ports.join(', ')}`)\n return ports\n } catch {\n return []\n }\n}\n\n/**\n * Linux: ss with netstat fallback\n */\nasync function discoverPortsOnLinux(pid: number): Promise<number[]> {\n // Try ss first\n try {\n const output = await runCommand(`ss -tlnp | grep \"pid=${pid},\"`)\n const ports = parseListenPorts(output)\n if (ports.length > 0) {\n debug('port-detective', `Linux ports (ss): ${ports.join(', ')}`)\n return ports\n }\n } catch { /* fall through */ }\n\n // Fallback to netstat\n try {\n const output = await runCommand(`netstat -tlnp 2>/dev/null | grep \"${pid}/\"`)\n const ports = parseListenPorts(output)\n debug('port-detective', `Linux ports (netstat): ${ports.join(', ')}`)\n return ports\n } catch {\n return []\n }\n}\n\n/**\n * Windows: netstat + PowerShell Get-NetTCPConnection\n */\nasync function discoverPortsOnWindows(pid: number): Promise<number[]> {\n // Strategy 1: netstat -ano\n try {\n const output = await runCommand('netstat -ano')\n const ports: number[] = []\n for (const line of output.split('\\n')) {\n if (!line.includes('LISTENING')) continue\n const parts = line.trim().split(/\\s+/)\n const linePid = parseInt(parts[parts.length - 1], 10)\n if (linePid === pid) {\n const localAddr = parts[1]\n const portMatch = localAddr.match(/:(\\d+)$/)\n if (portMatch) {\n const port = parseInt(portMatch[1], 10)\n if (!isNaN(port) && !ports.includes(port)) {\n ports.push(port)\n }\n }\n }\n }\n if (ports.length > 0) {\n debug('port-detective', `Windows ports (netstat): ${ports.join(', ')}`)\n return ports\n }\n } catch { /* fall through */ }\n\n // Strategy 2: PowerShell Get-NetTCPConnection\n try {\n const output = await runCommand(\n `powershell -Command \"Get-NetTCPConnection -OwningProcess ${pid} -State Listen -ErrorAction SilentlyContinue | Select-Object LocalPort | Format-Table -AutoSize\"`\n )\n const ports: number[] = []\n for (const line of output.split('\\n')) {\n const match = line.match(/^\\s*(\\d+)\\s*$/)\n if (match) {\n const port = parseInt(match[1], 10)\n if (!isNaN(port) && !ports.includes(port)) {\n ports.push(port)\n }\n }\n }\n if (ports.length > 0) {\n debug('port-detective', `Windows ports (PowerShell): ${ports.join(', ')}`)\n return ports\n }\n } catch { /* fall through */ }\n\n // Strategy 3: Extract port from process command-line flags\n // The --extension_server_port flag tells us the port directly\n debug('port-detective', 'Windows: Could not find ports via system commands')\n return []\n}\n\n/**\n * Parse port numbers from ss/netstat output lines\n */\nfunction parseListenPorts(output: string): number[] {\n const ports: number[] = []\n for (const line of output.split('\\n')) {\n const match = line.match(/:(\\d+)\\s/)\n if (match) {\n const port = parseInt(match[1], 10)\n if (!isNaN(port) && !ports.includes(port)) {\n ports.push(port)\n }\n }\n }\n return ports\n}\n\n/**\n * Scan a range of ports on localhost to find HTTPS Antigravity servers\n * Last resort for Windows when process-based detection fails\n */\nexport async function scanPortRange(\n startPort: number = 8000,\n endPort: number = 9500\n): Promise<number[]> {\n debug('port-detective', `Scanning port range ${startPort}-${endPort}`)\n const foundPorts: number[] = []\n\n // Use netstat to find all LISTENING ports in the range\n if (isWindows()) {\n const output = await runCommand('netstat -ano')\n for (const line of output.split('\\n')) {\n if (!line.includes('LISTENING')) continue\n const parts = line.trim().split(/\\s+/)\n const localAddr = parts[1]\n const portMatch = localAddr.match(/:(\\d+)$/)\n if (portMatch) {\n const port = parseInt(portMatch[1], 10)\n if (port >= startPort && port <= endPort) {\n foundPorts.push(port)\n }\n }\n }\n } else {\n const cmd = isMacOS()\n ? `lsof -nP -iTCP -sTCP:LISTEN`\n : `ss -tlnp`\n const output = await runCommand(cmd)\n for (const line of output.split('\\n')) {\n const match = line.match(/:(\\d+)\\s/)\n if (match) {\n const port = parseInt(match[1], 10)\n if (port >= startPort && port <= endPort && !foundPorts.includes(port)) {\n foundPorts.push(port)\n }\n }\n }\n }\n\n debug('port-detective', `Found ${foundPorts.length} ports in range`)\n return foundPorts\n}\n","/**\n * Connect RPC client for Antigravity language server\n *\n * Communicates with the local Antigravity server using the Connect protocol\n * to fetch quota data via RetrieveUserQuotaSummary and GetUserStatus endpoints.\n */\n\nimport https from 'https'\nimport http from 'http'\nimport { debug } from '../../core/logger.js'\n\nexport interface ConnectUserStatus {\n isAuthenticated?: boolean\n email?: string\n planType?: string\n quota?: {\n promptCredits?: {\n used?: number\n limit?: number\n remaining?: number\n }\n models?: Array<{\n modelId: string\n displayName?: string\n label?: string\n quota?: {\n remaining?: number\n limit?: number\n usedPercentage?: number\n remainingPercentage?: number\n resetTime?: string\n timeUntilResetMs?: number\n }\n isExhausted?: boolean\n }>\n }\n raw?: unknown\n}\n\nexport interface QuotaSummaryGroup {\n displayName: string\n buckets: QuotaSummaryBucket[]\n}\n\nexport interface QuotaSummaryBucket {\n bucketId: string\n displayName: string\n description: string\n remainingFraction: number\n resetTime?: string\n}\n\nexport interface QuotaSummaryResponse {\n groups: QuotaSummaryGroup[]\n raw?: unknown\n}\n\nconst ENDPOINTS = {\n quotaSummary: '/exa.language_server_pb.LanguageServerService/RetrieveUserQuotaSummary',\n userStatus: '/exa.language_server_pb.LanguageServerService/GetUserStatus',\n modelConfigs: '/exa.language_server_pb.LanguageServerService/GetCommandModelConfigs',\n unleash: '/exa.language_server_pb.LanguageServerService/GetUnleashData',\n availableModels: '/exa.language_server_pb.LanguageServerService/GetAvailableModels',\n}\n\nexport class ConnectClient {\n private baseUrl: string\n private csrfToken: string | undefined\n private isHttps: boolean\n\n constructor(baseUrl: string, csrfToken?: string) {\n this.baseUrl = baseUrl\n this.csrfToken = csrfToken\n this.isHttps = baseUrl.startsWith('https://')\n debug('connect-client', `Init: ${baseUrl}, hasToken: ${!!csrfToken}`)\n }\n\n /**\n * Test if this server is reachable and speaks Connect protocol\n */\n async probe(): Promise<boolean> {\n try {\n await this.request('POST', ENDPOINTS.unleash, {})\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Fetch quota summary (richest data: weekly + session buckets)\n */\n async fetchQuotaSummary(): Promise<QuotaSummaryResponse | null> {\n debug('connect-client', 'Fetching RetrieveUserQuotaSummary')\n try {\n const response = await this.request('POST', ENDPOINTS.quotaSummary, {\n metadata: {\n ideName: 'antigravity',\n extensionName: 'antigravity',\n locale: 'en',\n },\n })\n if (response) {\n return this.parseQuotaSummary(response)\n }\n } catch (err) {\n debug('connect-client', `QuotaSummary failed: ${err}`)\n }\n return null\n }\n\n /**\n * Fetch user status (fallback for older servers)\n */\n async fetchUserStatus(): Promise<ConnectUserStatus | null> {\n debug('connect-client', 'Fetching GetUserStatus')\n try {\n const response = await this.request('POST', ENDPOINTS.userStatus, {\n metadata: {\n ideName: 'antigravity',\n extensionName: 'antigravity',\n locale: 'en',\n },\n })\n if (response) {\n return this.parseUserStatus(response)\n }\n } catch (err) {\n debug('connect-client', `UserStatus failed: ${err}`)\n }\n return null\n }\n\n /**\n * Fetch model configs (last-resort fallback)\n */\n async fetchModelConfigs(): Promise<unknown> {\n debug('connect-client', 'Fetching GetCascadeModelConfigData')\n try {\n return await this.request('POST', ENDPOINTS.modelConfigs, {\n metadata: {\n ideName: 'antigravity',\n extensionName: 'antigravity',\n locale: 'en',\n },\n })\n } catch (err) {\n debug('connect-client', `ModelConfigs failed: ${err}`)\n return null\n }\n }\n\n /**\n * Make a Connect protocol HTTP(S) request\n */\n private request(method: string, path: string, body?: unknown): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const url = new URL(path, this.baseUrl)\n const headers: Record<string, string> = {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n 'Connect-Protocol-Version': '1',\n }\n if (this.csrfToken) {\n headers['X-Codeium-Csrf-Token'] = this.csrfToken\n }\n\n const options = {\n hostname: url.hostname,\n port: url.port,\n path: url.pathname,\n method,\n headers,\n timeout: 5000,\n rejectUnauthorized: false,\n } as https.RequestOptions\n\n const protocol = this.isHttps ? https : http\n const req = protocol.request(options, (res) => {\n let data = ''\n res.on('data', (chunk: Buffer) => { data += chunk })\n res.on('end', () => {\n if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {\n try {\n resolve(JSON.parse(data))\n } catch {\n resolve(data)\n }\n } else if (res.statusCode === 404) {\n reject(new Error(`404: ${path}`))\n } else {\n reject(new Error(`HTTP ${res.statusCode}: ${data.slice(0, 200)}`))\n }\n })\n })\n req.on('error', reject)\n req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')) })\n if (body) req.write(JSON.stringify(body))\n req.end()\n })\n }\n\n /**\n * Parse RetrieveUserQuotaSummary response\n */\n private parseQuotaSummary(response: unknown): QuotaSummaryResponse {\n const result: QuotaSummaryResponse = { groups: [], raw: response }\n\n if (typeof response !== 'object' || response === null) return result\n const data = response as Record<string, unknown>\n\n // Try both response.groups and response.userStatus.groups patterns\n const userStatus = data.userStatus as Record<string, unknown> | undefined\n const groups = (data.groups || userStatus?.groups) as Array<Record<string, unknown>> | undefined\n\n if (Array.isArray(groups)) {\n result.groups = groups.map((group): QuotaSummaryGroup => {\n const buckets = Array.isArray(group.buckets)\n ? group.buckets.map((b: Record<string, unknown>): QuotaSummaryBucket => ({\n bucketId: String(b.bucketId || ''),\n displayName: String(b.displayName || ''),\n description: String(b.description || ''),\n remainingFraction: typeof (b as any).remaining?.remainingFraction === 'number'\n ? (b as any).remaining.remainingFraction as number\n : typeof (b as any).remainingFraction === 'number'\n ? (b as any).remainingFraction as number\n : 1,\n resetTime: typeof b.resetTime === 'string' ? b.resetTime : undefined,\n }))\n : []\n return {\n displayName: String(group.displayName || ''),\n buckets,\n }\n })\n }\n\n debug('connect-client', `Parsed ${result.groups.length} groups from quota summary`)\n return result\n }\n\n /**\n * Parse GetUserStatus response (legacy fallback)\n */\n private parseUserStatus(response: unknown): ConnectUserStatus {\n const status: ConnectUserStatus = { raw: response }\n if (typeof response !== 'object' || response === null) return status\n\n const data = response as Record<string, unknown>\n const userStatus = (data.userStatus as Record<string, unknown>) || data\n\n if (typeof userStatus.email === 'string') status.email = userStatus.email\n if (typeof userStatus.isAuthenticated === 'boolean') status.isAuthenticated = userStatus.isAuthenticated\n if (typeof userStatus.planType === 'string') status.planType = userStatus.planType\n\n // Extract plan/prompt credits\n const planStatus = userStatus.planStatus as Record<string, unknown> | undefined\n if (planStatus) {\n const available = planStatus.availablePromptCredits as number | undefined\n const planInfo = planStatus.planInfo as Record<string, unknown> | undefined\n const monthly = planInfo?.monthlyPromptCredits as number | undefined\n if (typeof available === 'number' && typeof monthly === 'number') {\n status.quota = {\n promptCredits: {\n used: monthly - available,\n limit: monthly,\n remaining: available,\n },\n }\n }\n }\n\n // Extract models from cascadeModelConfigData\n const cascadeData = userStatus.cascadeModelConfigData as Record<string, unknown> | undefined\n const clientModelConfigs = cascadeData?.clientModelConfigs as Array<Record<string, unknown>> | undefined\n if (Array.isArray(clientModelConfigs)) {\n status.quota = status.quota || {}\n status.quota.models = clientModelConfigs.map((m) => {\n const modelOrAlias = m.modelOrAlias as Record<string, unknown> | undefined\n const modelId = typeof modelOrAlias?.model === 'string' ? modelOrAlias.model : 'unknown'\n const quotaInfo = m.quotaInfo as Record<string, unknown> | undefined\n const remainingFraction = typeof quotaInfo?.remainingFraction === 'number' ? quotaInfo.remainingFraction : undefined\n const resetTime = typeof quotaInfo?.resetTime === 'string' ? quotaInfo.resetTime : undefined\n\n return {\n modelId,\n displayName: typeof m.label === 'string' ? m.label : undefined,\n label: typeof m.label === 'string' ? m.label : undefined,\n quota: {\n remainingPercentage: remainingFraction,\n resetTime,\n timeUntilResetMs: resetTime ? new Date(resetTime).getTime() - Date.now() : undefined,\n },\n isExhausted: remainingFraction === 0,\n }\n })\n }\n\n return status\n }\n}\n","/**\n * Parse Connect API responses into SDK QuotaSnapshot format\n */\n\nimport type {\n QuotaSnapshot,\n QuotaGroup,\n QuotaBucket,\n ModelQuotaInfo,\n PromptCreditsInfo,\n} from '../../sdk/types.js'\nimport type { ConnectUserStatus, QuotaSummaryResponse } from './connect-client.js'\nimport { debug } from '../../core/logger.js'\n\n/**\n * Parse RetrieveUserQuotaSummary response (preferred — has weekly + session buckets)\n */\nexport function parseQuotaSummary(\n summary: QuotaSummaryResponse,\n email?: string\n): QuotaSnapshot {\n debug('parser', `Parsing quota summary: ${summary.groups.length} groups`)\n\n return {\n timestamp: new Date().toISOString(),\n method: 'local',\n email,\n groups: summary.groups.map((g): QuotaGroup => ({\n displayName: g.displayName,\n buckets: g.buckets.map((b): QuotaBucket => ({\n bucketId: b.bucketId,\n displayName: b.displayName,\n description: b.description,\n remainingFraction: clampFraction(b.remainingFraction),\n resetTime: b.resetTime,\n timeUntilResetMs: b.resetTime\n ? Math.max(0, new Date(b.resetTime).getTime() - Date.now())\n : undefined,\n })),\n })),\n }\n}\n\n/**\n * Parse GetUserStatus response (fallback — legacy model-level data)\n */\nexport function parseUserStatus(userStatus: ConnectUserStatus): QuotaSnapshot {\n debug('parser', 'Parsing GetUserStatus fallback')\n\n const snapshot: QuotaSnapshot = {\n timestamp: new Date().toISOString(),\n method: 'local',\n email: userStatus.email,\n groups: [],\n }\n\n // Parse prompt credits\n if (userStatus.quota?.promptCredits) {\n snapshot.promptCredits = parsePromptCredits(userStatus.quota.promptCredits)\n }\n\n // Group models into Gemini and Claude+GPT buckets (simulating quota groups)\n if (userStatus.quota?.models) {\n const geminiModels: ModelQuotaInfo[] = []\n const claudeModels: ModelQuotaInfo[] = []\n\n for (const model of userStatus.quota.models) {\n const info: ModelQuotaInfo = {\n label: model.label || model.displayName || model.modelId,\n modelId: model.modelId,\n remainingPercentage: model.quota?.remainingPercentage,\n isExhausted: model.isExhausted ?? (model.quota?.remainingPercentage === 0),\n resetTime: model.quota?.resetTime,\n timeUntilResetMs: model.quota?.timeUntilResetMs,\n isAutocompleteOnly: detectAutocomplete(model.modelId, model.label),\n }\n\n if (info.isAutocompleteOnly) continue\n\n if (isGeminiModel(model.modelId)) {\n geminiModels.push(info)\n } else {\n claudeModels.push(info)\n }\n }\n\n // Create synthetic quota groups from model data\n if (geminiModels.length > 0) {\n snapshot.groups.push(createGroupFromModels('Gemini Models', geminiModels))\n }\n if (claudeModels.length > 0) {\n snapshot.groups.push(createGroupFromModels('Claude + GPT Models', claudeModels))\n }\n }\n\n return snapshot\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\nfunction parsePromptCredits(credits: NonNullable<ConnectUserStatus['quota']>['promptCredits']): PromptCreditsInfo | undefined {\n if (!credits) return undefined\n const limit = credits.limit ?? 0\n const remaining = credits.remaining ?? limit\n const used = credits.used ?? (limit - remaining)\n if (limit === 0) return undefined\n return {\n available: remaining,\n monthly: limit,\n usedPercentage: limit > 0 ? used / limit : 0,\n remainingPercentage: limit > 0 ? remaining / limit : 1,\n }\n}\n\nfunction createGroupFromModels(displayName: string, models: ModelQuotaInfo[]): QuotaGroup {\n // Find the best session/reset bucket from available models\n const bestModel = models.reduce((best, m) => {\n const remaining = m.remainingPercentage ?? 1\n const bestRemaining = best.remainingPercentage ?? 1\n return remaining < bestRemaining ? m : best\n }, models[0])\n\n const bucket: QuotaBucket = {\n bucketId: 'session',\n displayName: 'Session (5-hour)',\n description: bestModel.resetTime\n ? `Resets at ${new Date(bestModel.resetTime).toLocaleTimeString()}`\n : '5-hour session window',\n remainingFraction: bestModel.remainingPercentage ?? 1,\n resetTime: bestModel.resetTime,\n timeUntilResetMs: bestModel.timeUntilResetMs,\n }\n\n return {\n displayName,\n buckets: [bucket],\n }\n}\n\nfunction isGeminiModel(modelId: string): boolean {\n const lower = modelId.toLowerCase()\n return lower.includes('gemini')\n}\n\nfunction detectAutocomplete(modelId: string, label?: string): boolean {\n const text = `${modelId} ${label || ''}`.toLowerCase()\n return text.includes('autocomplete') ||\n text.includes('gemini-2.5') ||\n text.includes('gemini 2.5')\n}\n\nfunction clampFraction(value: number | undefined): number {\n if (value === undefined || value === null) return 1\n return Math.max(0, Math.min(1, value))\n}\n","/**\n * Local data source adapter — connects to Antigravity's local language server\n *\n * This is the preferred source: fast, offline, no login needed.\n * Uses a multi-strategy approach: detect process → discover port → probe → fetch quota.\n */\n\nimport type { DataSourceAdapter, QuotaSnapshot } from '../../sdk/types.js'\nimport { debug } from '../../core/logger.js'\nimport { detectAntigravityProcesses, extractFlags } from './process-detector.js'\nimport { discoverPorts, scanPortRange } from './port-detective.js'\nimport { ConnectClient } from './connect-client.js'\nimport { parseQuotaSummary, parseUserStatus } from './parser.js'\nimport { SourceUnavailableError } from '../../core/errors.js'\n\nexport class LocalSource implements DataSourceAdapter {\n readonly name = 'local' as const\n readonly priority = 1\n\n async isAvailable(): Promise<boolean> {\n try {\n const processes = await detectAntigravityProcesses()\n return processes.length > 0\n } catch {\n return false\n }\n }\n\n async fetchQuota(): Promise<QuotaSnapshot> {\n debug('local', 'Starting local fetch')\n\n // Step 1: Detect processes\n const processes = await detectAntigravityProcesses()\n if (processes.length === 0) {\n throw new SourceUnavailableError('local', 'No Antigravity process found')\n }\n\n // Step 2: Try each process until we get quota data\n for (const proc of processes) {\n debug('local', `Trying PID ${proc.pid} (${proc.scope})`)\n\n // Extract port from command line flags first (most reliable on Windows)\n const flags = extractFlags(proc.commandLine || '')\n let ports: number[] = []\n\n // If --extension_server_port is in command line, use it directly\n const directPort = flags.get('extension_server_port')\n if (directPort) {\n const portNum = parseInt(directPort, 10)\n if (!isNaN(portNum)) {\n ports.push(portNum)\n debug('local', `Found port from command line: ${portNum}`)\n }\n }\n\n // Also discover ports via OS tools\n const discoveredPorts = await discoverPorts(proc.pid)\n for (const p of discoveredPorts) {\n if (!ports.includes(p)) ports.push(p)\n }\n\n // Get CSRF token from command line\n const csrfToken = flags.get('csrf_token') || flags.get('extension_server_csrf_token')\n\n // Step 3: Probe each port\n for (const port of ports) {\n const quota = await this.probePort(port, csrfToken)\n if (quota) return quota\n }\n }\n\n // Step 4: Last resort — scan common port ranges\n debug('local', 'Direct detection failed, scanning port range')\n const scannedPorts = await scanPortRange(8000, 9500)\n for (const port of scannedPorts) {\n const quota = await this.probePort(port)\n if (quota) return quota\n }\n\n throw new SourceUnavailableError('local', 'Could not connect to any local server')\n }\n\n /**\n * Probe a single port and try to fetch quota\n */\n private async probePort(port: number, csrfToken?: string): Promise<QuotaSnapshot | null> {\n for (const scheme of ['https', 'http']) {\n const baseUrl = `${scheme}://127.0.0.1:${port}`\n const client = new ConnectClient(baseUrl, csrfToken)\n\n // Check if server responds\n const reachable = await client.probe()\n if (!reachable) continue\n\n debug('local', `Probing ${baseUrl}`)\n\n // Try quota summary first (richest data)\n const summary = await client.fetchQuotaSummary()\n if (summary && summary.groups.length > 0) {\n const email = (await client.fetchUserStatus())?.email\n debug('local', `Got quota summary from ${baseUrl}`)\n return parseQuotaSummary(summary, email)\n }\n\n // Fallback: GetUserStatus (legacy)\n const userStatus = await client.fetchUserStatus()\n if (userStatus) {\n debug('local', `Got user status from ${baseUrl}`)\n return parseUserStatus(userStatus)\n }\n }\n\n return null\n }\n}\n","/**\n * agy CLI data source adapter\n *\n * When the Antigravity desktop app isn't running, we can launch the agy CLI\n * and use its embedded HTTPS server to fetch quota data.\n * This source requires a signed-in agy session.\n */\n\nimport type { DataSourceAdapter, QuotaSnapshot } from '../../sdk/types.js'\nimport { debug } from '../../core/logger.js'\nimport { ConnectClient } from '../local/connect-client.js'\nimport { parseQuotaSummary, parseUserStatus } from '../local/parser.js'\nimport { discoverPorts } from '../local/port-detective.js'\nimport { SourceUnavailableError } from '../../core/errors.js'\nimport { runCommand, isWindows } from '../../core/platform.js'\nimport { exec, type ChildProcess } from 'child_process'\nimport { promisify } from 'util'\n\nconst execAsync = promisify(exec)\n\nexport class CliSource implements DataSourceAdapter {\n readonly name = 'cli' as const\n readonly priority = 2\n\n private agyProcess: ChildProcess | null = null\n\n async isAvailable(): Promise<boolean> {\n const path = await findAgyBinary()\n return path !== null\n }\n\n async fetchQuota(): Promise<QuotaSnapshot> {\n debug('cli', 'Starting CLI source fetch')\n\n const agyPath = await findAgyBinary()\n if (!agyPath) {\n throw new SourceUnavailableError('cli', 'agy binary not found')\n }\n\n // Try to find an already-running agy first\n const existingQuota = await this.tryExistingAgy()\n if (existingQuota) return existingQuota\n\n // Launch agy and connect\n return await this.launchAndFetch(agyPath)\n }\n\n /**\n * Check if there's already a running agy instance we can reuse\n */\n private async tryExistingAgy(): Promise<QuotaSnapshot | null> {\n // Find agy processes\n const cmd = isWindows()\n ? 'wmic process where \"commandline like \\'%agy%\\'\" get ProcessId,CommandLine /format:csv'\n : 'ps -ax -o pid=,args='\n\n const output = await runCommand(cmd)\n const pids = output.split('\\n')\n .map(line => {\n const match = line.match(/^\\s*(\\d+)/)\n return match ? parseInt(match[1], 10) : NaN\n })\n .filter(p => !isNaN(p))\n\n for (const pid of pids) {\n const ports = await discoverPorts(pid)\n for (const port of ports) {\n const quota = await this.probePort(port)\n if (quota) return quota\n }\n }\n\n return null\n }\n\n /**\n * Launch agy and wait for its server, then fetch quota\n */\n private async launchAndFetch(agyPath: string): Promise<QuotaSnapshot> {\n debug('cli', `Launching agy: ${agyPath}`)\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.agyProcess?.kill()\n reject(new SourceUnavailableError('cli', 'agy startup timed out'))\n }, 15000)\n\n this.agyProcess = exec(agyPath, { env: { ...process.env, NO_COLOR: '1' } })\n\n // Poll for the agy server to come up\n const pollInterval = setInterval(async () => {\n try {\n // agy typically binds to a high port\n if (!this.agyProcess?.pid) return\n const ports = await discoverPorts(this.agyProcess.pid)\n for (const port of ports) {\n const quota = await this.probePort(port)\n if (quota) {\n clearTimeout(timeout)\n clearInterval(pollInterval)\n this.agyProcess?.kill()\n resolve(quota)\n return\n }\n }\n } catch { /* keep trying */ }\n }, 1000)\n\n this.agyProcess.on('error', (err) => {\n clearTimeout(timeout)\n clearInterval(pollInterval)\n reject(new SourceUnavailableError('cli', `agy failed: ${err.message}`))\n })\n\n this.agyProcess.on('exit', () => {\n clearTimeout(timeout)\n clearInterval(pollInterval)\n })\n })\n }\n\n /**\n * Probe a port for quota data\n */\n private async probePort(port: number): Promise<QuotaSnapshot | null> {\n for (const scheme of ['https', 'http']) {\n const baseUrl = `${scheme}://127.0.0.1:${port}`\n const client = new ConnectClient(baseUrl) // agy doesn't need CSRF token\n\n try {\n const reachable = await client.probe()\n if (!reachable) continue\n\n const summary = await client.fetchQuotaSummary()\n if (summary && summary.groups.length > 0) {\n const email = (await client.fetchUserStatus())?.email\n return parseQuotaSummary(summary, email)\n }\n\n const userStatus = await client.fetchUserStatus()\n if (userStatus) return parseUserStatus(userStatus)\n } catch { /* try next */ }\n }\n return null\n }\n\n destroy(): void {\n this.agyProcess?.kill()\n this.agyProcess = null\n }\n}\n\n/**\n * Find the agy binary on PATH or common locations\n */\nasync function findAgyBinary(): Promise<string | null> {\n // Check env override\n if (process.env.ANTIGRAVITY_CLI_PATH) {\n return process.env.ANTIGRAVITY_CLI_PATH\n }\n\n // Check PATH\n try {\n const cmd = isWindows() ? 'where agy' : 'which agy'\n const output = await execAsync(cmd)\n const path = output.stdout.trim()\n if (path) return path\n } catch { /* not on PATH */ }\n\n // Check common locations\n const commonPaths = isWindows()\n ? [\n `${process.env.LOCALAPPDATA || ''}/antigravity-cli/agy.exe`,\n `${process.env.PROGRAMFILES || ''}/antigravity-cli/agy.exe`,\n ]\n : [\n `${process.env.HOME}/.local/bin/agy`,\n '/opt/homebrew/bin/agy',\n '/usr/local/bin/agy',\n ]\n\n for (const p of commonPaths) {\n if (!p) continue\n try {\n await execAsync(`test -x \"${p}\"`)\n return p\n } catch { /* not there */ }\n }\n\n return null\n}\n","/**\n * OAuth/Cloud Code API data source adapter\n *\n * Fetches quota remotely via Google Cloud Code API.\n * Requires a valid OAuth token.\n */\n\nimport type { DataSourceAdapter, QuotaSnapshot } from '../../sdk/types.js'\nimport { debug } from '../../core/logger.js'\nimport { OAuthClient } from './client.js'\nimport { parseQuotaSummary, parseUserStatus } from '../local/parser.js'\nimport { SourceUnavailableError } from '../../core/errors.js'\nimport type { QuotaSummaryResponse, ConnectUserStatus } from '../local/connect-client.js'\n\nexport class OAuthSource implements DataSourceAdapter {\n readonly name = 'oauth' as const\n readonly priority = 3\n\n private client: OAuthClient\n\n constructor(client: OAuthClient) {\n this.client = client\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n await this.client.getAccessToken()\n return true\n } catch {\n return false\n }\n }\n\n async fetchQuota(): Promise<QuotaSnapshot> {\n debug('oauth', 'Fetching quota via Cloud Code API')\n\n try {\n // Try quota summary first\n const summaryRaw = await this.client.fetchQuotaSummary()\n const summary = this.parseRemoteSummary(summaryRaw)\n if (summary && summary.groups.length > 0) {\n // Get email from user status\n const statusRaw = await this.client.fetchUserStatus()\n const email = this.extractEmail(statusRaw)\n debug('oauth', 'Got quota summary via OAuth')\n return parseQuotaSummary(summary, email)\n }\n\n // Fallback: loadCodeAssist for basic info\n const statusRaw = await this.client.fetchUserStatus()\n const status = this.parseRemoteStatus(statusRaw)\n if (status) {\n debug('oauth', 'Got user status via OAuth')\n return parseUserStatus(status)\n }\n } catch (err) {\n debug('oauth', `Fetch failed: ${err}`)\n }\n\n throw new SourceUnavailableError('oauth', 'Could not fetch quota via Cloud Code API')\n }\n\n /**\n * Parse remote summary response into QuotaSummaryResponse format\n */\n private parseRemoteSummary(raw: unknown): QuotaSummaryResponse | null {\n if (typeof raw !== 'object' || raw === null) return null\n const data = raw as Record<string, unknown>\n\n // The response might be wrapped\n const groups = data.groups as Array<Record<string, unknown>> | undefined\n if (!Array.isArray(groups)) return null\n\n return {\n groups: groups.map(g => ({\n displayName: String(g.displayName || ''),\n buckets: Array.isArray(g.buckets)\n ? g.buckets.map((b: Record<string, unknown>) => ({\n bucketId: String(b.bucketId || ''),\n displayName: String(b.displayName || ''),\n description: String(b.description || ''),\n remainingFraction: typeof (b as any).remaining?.remainingFraction === 'number'\n ? (b as any).remaining.remainingFraction as number\n : typeof (b as any).remainingFraction === 'number'\n ? (b as any).remainingFraction as number\n : 1,\n resetTime: typeof b.resetTime === 'string' ? b.resetTime : undefined,\n }))\n : [],\n })),\n raw,\n }\n }\n\n /**\n * Parse remote user status response\n */\n private parseRemoteStatus(raw: unknown): ConnectUserStatus | null {\n if (typeof raw !== 'object' || raw === null) return null\n return { raw }\n }\n\n private extractEmail(raw: unknown): string | undefined {\n if (typeof raw !== 'object' || raw === null) return undefined\n const data = raw as Record<string, unknown>\n const userStatus = data.userStatus as Record<string, unknown> | undefined\n return (userStatus?.email || data.email) as string | undefined\n }\n}\n","/**\n * Source registry — manages data source adapters and implements the fallback chain\n *\n * Priority order:\n * 1. Local (Antigravity app language server) — fastest, offline\n * 2. CLI (agy CLI HTTPS server) — no app needed, requires signed-in agy\n * 3. OAuth (Google Cloud Code API) — works anywhere, requires login\n */\n\nimport type { DataSourceAdapter, QuotaSnapshot, DataSource } from '../sdk/types.js'\nimport { debug } from '../core/logger.js'\nimport { SourceUnavailableError } from '../core/errors.js'\nimport { LocalSource } from './local/index.js'\nimport { CliSource } from './cli/index.js'\n\nexport { LocalSource } from './local/index.js'\nexport { CliSource } from './cli/index.js'\nexport { OAuthSource } from './oauth/index.js'\nexport { OAuthClient } from './oauth/client.js'\n\nexport class SourceRegistry {\n private sources: DataSourceAdapter[] = []\n private health: Map<DataSource, { available: boolean; lastCheck: number }> = new Map()\n\n constructor() {\n // Register built-in sources in priority order\n this.sources.push(new LocalSource())\n this.sources.push(new CliSource())\n // OAuth source is added manually when credentials are available\n }\n\n /**\n * Register an additional data source (e.g., OAuth)\n */\n addSource(source: DataSourceAdapter): void {\n // Insert in priority order\n const idx = this.sources.findIndex(s => s.priority > source.priority)\n if (idx === -1) {\n this.sources.push(source)\n } else {\n this.sources.splice(idx, 0, source)\n }\n debug('registry', `Registered source: ${source.name} (priority ${source.priority})`)\n }\n\n /**\n * Remove a source by name\n */\n removeSource(name: DataSource): void {\n this.sources = this.sources.filter(s => s.name !== name)\n }\n\n /**\n * Fetch quota using the best available source\n *\n * @param preferredSource Force a specific source\n */\n async fetchQuota(preferredSource?: DataSource): Promise<QuotaSnapshot> {\n // If a specific source is requested, use only that\n if (preferredSource) {\n const source = this.sources.find(s => s.name === preferredSource)\n if (!source) throw new Error(`Source \"${preferredSource}\" not registered`)\n const snapshot = await source.fetchQuota()\n this.health.set(preferredSource, { available: true, lastCheck: Date.now() })\n return snapshot\n }\n\n // Otherwise, try sources in priority order\n const errors: string[] = []\n\n for (const source of this.sources) {\n debug('registry', `Trying source: ${source.name}`)\n\n try {\n const available = await source.isAvailable()\n if (!available) {\n debug('registry', `Source ${source.name} not available`)\n this.health.set(source.name, { available: false, lastCheck: Date.now() })\n continue\n }\n\n const snapshot = await source.fetchQuota()\n this.health.set(source.name, { available: true, lastCheck: Date.now() })\n debug('registry', `Success with source: ${source.name}`)\n return snapshot\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n errors.push(`${source.name}: ${msg}`)\n this.health.set(source.name, { available: false, lastCheck: Date.now() })\n debug('registry', `Source ${source.name} failed: ${msg}`)\n }\n }\n\n throw new SourceUnavailableError('all', `No sources available:\\n${errors.map(e => ` • ${e}`).join('\\n')}`)\n }\n\n /**\n * Get health status of all sources\n */\n getHealth(): Map<DataSource, { available: boolean; lastCheck: number }> {\n return new Map(this.health)\n }\n\n /**\n * Get registered source names\n */\n getSourceNames(): DataSource[] {\n return this.sources.map(s => s.name)\n }\n}\n","/**\n * Smart caching layer for quota data\n *\n * Caches quota snapshots to avoid hitting API rate limits.\n * Cache is keyed by email + source combination.\n */\n\nimport { debug } from '../core/logger.js'\nimport type { QuotaSnapshot } from './types.js'\n\ninterface CacheEntry {\n snapshot: QuotaSnapshot\n cachedAt: number\n}\n\nexport class QuotaCache {\n private cache: Map<string, CacheEntry> = new Map()\n private ttlMs: number\n\n constructor(ttlMs: number = 5 * 60 * 1000) {\n this.ttlMs = ttlMs\n }\n\n /**\n * Get cached quota if available and not expired\n */\n get(email: string, source: string): QuotaSnapshot | null {\n const key = `${email}:${source}`\n const entry = this.cache.get(key)\n if (!entry) return null\n\n const age = Date.now() - entry.cachedAt\n if (age > this.ttlMs) {\n this.cache.delete(key)\n debug('cache', `Expired entry for ${email} (age: ${Math.round(age / 1000)}s)`)\n return null\n }\n\n debug('cache', `Cache hit for ${email} (age: ${Math.round(age / 1000)}s)`)\n return entry.snapshot\n }\n\n /**\n * Store a quota snapshot in cache\n */\n set(email: string, source: string, snapshot: QuotaSnapshot): void {\n const key = `${email}:${source}`\n this.cache.set(key, {\n snapshot,\n cachedAt: Date.now(),\n })\n debug('cache', `Cached snapshot for ${email}`)\n }\n\n /**\n * Check if a cached entry is still fresh\n */\n isFresh(email: string, source: string): boolean {\n const key = `${email}:${source}`\n const entry = this.cache.get(key)\n if (!entry) return false\n return (Date.now() - entry.cachedAt) <= this.ttlMs\n }\n\n /**\n * Clear all cached entries\n */\n clear(): void {\n this.cache.clear()\n debug('cache', 'Cleared all cache entries')\n }\n\n /**\n * Get cache age in seconds for a key\n */\n getAgeMs(email: string, source: string): number | null {\n const key = `${email}:${source}`\n const entry = this.cache.get(key)\n if (!entry) return null\n return Date.now() - entry.cachedAt\n }\n}\n","/**\n * SQLite storage for usage history and analytics\n */\n\nimport Database from 'better-sqlite3'\nimport { join } from 'path'\nimport { getDataDirPath, ensureDirs } from '../core/config.js'\nimport { debug } from '../core/logger.js'\nimport type { UsageRecord, QuotaSnapshot } from './types.js'\n\nlet db: Database.Database | null = null\n\nfunction getDb(): Database.Database {\n if (db) return db\n ensureDirs()\n const dbPath = join(getDataDirPath(), 'history.db')\n db = new Database(dbPath)\n db.pragma('journal_mode = WAL')\n initSchema(db)\n debug('store', `Opened database at ${dbPath}`)\n return db\n}\n\nfunction initSchema(database: Database.Database): void {\n database.exec(`\n CREATE TABLE IF NOT EXISTS quota_snapshots (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp TEXT NOT NULL,\n email TEXT NOT NULL,\n method TEXT NOT NULL,\n gemini_weekly_remaining REAL,\n gemini_session_remaining REAL,\n claude_weekly_remaining REAL,\n claude_session_remaining REAL,\n raw_json TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_snapshots_email_ts\n ON quota_snapshots(email, timestamp);\n `)\n}\n\n/**\n * Store a quota snapshot for history tracking\n */\nexport function storeSnapshot(snapshot: QuotaSnapshot): void {\n const database = getDb()\n\n // Extract group data\n let geminiWeekly: number | null = null\n let geminiSession: number | null = null\n let claudeWeekly: number | null = null\n let claudeSession: number | null = null\n\n for (const group of snapshot.groups) {\n const lower = group.displayName.toLowerCase()\n for (const bucket of group.buckets) {\n const bucketLower = bucket.displayName.toLowerCase()\n if (lower.includes('gemini')) {\n if (bucketLower.includes('weekly') || bucketLower.includes('week')) {\n geminiWeekly = bucket.remainingFraction\n } else {\n geminiSession = bucket.remainingFraction\n }\n } else if (lower.includes('claude') || lower.includes('gpt')) {\n if (bucketLower.includes('weekly') || bucketLower.includes('week')) {\n claudeWeekly = bucket.remainingFraction\n } else {\n claudeSession = bucket.remainingFraction\n }\n }\n }\n }\n\n const stmt = database.prepare(`\n INSERT INTO quota_snapshots\n (timestamp, email, method, gemini_weekly_remaining, gemini_session_remaining,\n claude_weekly_remaining, claude_session_remaining, raw_json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `)\n\n stmt.run(\n snapshot.timestamp,\n snapshot.email || 'unknown',\n snapshot.method,\n geminiWeekly,\n geminiSession,\n claudeWeekly,\n claudeSession,\n JSON.stringify(snapshot),\n )\n\n debug('store', `Stored snapshot for ${snapshot.email}`)\n}\n\n/**\n * Retrieve usage history for an account\n */\nexport function getHistory(\n email: string,\n options?: { days?: number; limit?: number }\n): UsageRecord[] {\n const database = getDb()\n const days = options?.days || 7\n const limit = options?.limit || 1000\n\n const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString()\n\n const stmt = database.prepare(`\n SELECT timestamp, email, gemini_weekly_remaining, gemini_session_remaining,\n claude_weekly_remaining, claude_session_remaining\n FROM quota_snapshots\n WHERE email = ? AND timestamp >= ?\n ORDER BY timestamp DESC\n LIMIT ?\n `)\n\n const rows = stmt.all(email, since, limit) as Array<Record<string, unknown>>\n\n return rows.map((row): UsageRecord => ({\n timestamp: String(row.timestamp),\n email: String(row.email),\n geminiWeeklyRemaining: row.gemini_weekly_remaining as number | null,\n geminiSessionRemaining: row.gemini_session_remaining as number | null,\n claudeWeeklyRemaining: row.claude_weekly_remaining as number | null,\n claudeSessionRemaining: row.claude_session_remaining as number | null,\n }))\n}\n\n/**\n * Get the most recent snapshot for an account\n */\nexport function getLatestSnapshot(email: string): UsageRecord | null {\n const history = getHistory(email, { limit: 1 })\n return history[0] || null\n}\n\n/**\n * Get daily usage summary (average remaining per day)\n */\nexport function getDailySummary(email: string, days: number = 7): Array<{\n date: string\n geminiWeeklyAvg: number | null\n geminiSessionAvg: number | null\n claudeWeeklyAvg: number | null\n claudeSessionAvg: number | null\n count: number\n}> {\n const database = getDb()\n const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString()\n\n const stmt = database.prepare(`\n SELECT\n date(timestamp) as date,\n AVG(gemini_weekly_remaining) as gemini_weekly_avg,\n AVG(gemini_session_remaining) as gemini_session_avg,\n AVG(claude_weekly_remaining) as claude_weekly_avg,\n AVG(claude_session_remaining) as claude_session_avg,\n COUNT(*) as count\n FROM quota_snapshots\n WHERE email = ? AND timestamp >= ?\n GROUP BY date(timestamp)\n ORDER BY date(timestamp) ASC\n `)\n\n const rows = stmt.all(email, since) as Array<Record<string, unknown>>\n\n return rows.map(row => ({\n date: String(row.date),\n geminiWeeklyAvg: row.gemini_weekly_avg as number | null,\n geminiSessionAvg: row.gemini_session_avg as number | null,\n claudeWeeklyAvg: row.claude_weekly_avg as number | null,\n claudeSessionAvg: row.claude_session_avg as number | null,\n count: Number(row.count),\n }))\n}\n\n/**\n * Clean up old snapshots (older than N days)\n */\nexport function cleanupHistory(keepDays: number = 90): number {\n const database = getDb()\n const cutoff = new Date(Date.now() - keepDays * 24 * 60 * 60 * 1000).toISOString()\n const result = database.prepare(\n 'DELETE FROM quota_snapshots WHERE timestamp < ?'\n ).run(cutoff)\n return result.changes\n}\n\n/**\n * Close the database connection\n */\nexport function closeStore(): void {\n if (db) {\n db.close()\n db = null\n debug('store', 'Database closed')\n }\n}\n","/**\n * Quota fetching orchestration\n *\n * Coordinates between the source registry, cache, storage, and plugins\n * to provide a unified quota fetching experience.\n */\n\nimport type { QuotaSnapshot, DataSource, ClientOptions, UsageRecord } from './types.js'\nimport { SourceRegistry } from '../sources/index.js'\nimport { QuotaCache } from './cache.js'\nimport { storeSnapshot, getHistory, getDailySummary } from './store.js'\nimport { getAllAccountTokens } from './accounts/index.js'\nimport { OAuthClient } from '../sources/oauth/client.js'\nimport { OAuthSource } from '../sources/oauth/index.js'\nimport { loadConfig } from '../core/config.js'\nimport { debug } from '../core/logger.js'\nimport { setVerbose } from '../core/logger.js'\n\nexport class QuotaClient {\n private registry: SourceRegistry\n private cache: QuotaCache\n private verbose: boolean\n\n constructor(options?: ClientOptions) {\n this.verbose = options?.verbose || false\n setVerbose(this.verbose)\n\n const config = loadConfig()\n this.registry = new SourceRegistry()\n this.cache = new QuotaCache(options?.cacheTtlMs || config.cacheTtlMs)\n\n // Register OAuth sources for all stored accounts\n this.registerOAuthSources()\n }\n\n /**\n * Fetch quota for the active account (or all accounts)\n */\n async fetchQuota(options?: {\n source?: DataSource\n refresh?: boolean\n allAccounts?: boolean\n }): Promise<QuotaSnapshot | QuotaSnapshot[]> {\n if (options?.allAccounts) {\n return this.fetchAllAccounts(options)\n }\n\n // Check cache first (unless refresh requested)\n if (!options?.refresh) {\n // We need the email from any cached entry\n // For now, just try the fetch directly\n }\n\n const snapshot = await this.registry.fetchQuota(options?.source)\n\n // Store in cache and history\n if (snapshot.email) {\n this.cache.set(snapshot.email, snapshot.method, snapshot)\n storeSnapshot(snapshot)\n }\n\n return snapshot\n }\n\n /**\n * Fetch quota for all stored accounts\n */\n private async fetchAllAccounts(options?: {\n source?: DataSource\n refresh?: boolean\n }): Promise<QuotaSnapshot[]> {\n const tokens = getAllAccountTokens()\n const snapshots: QuotaSnapshot[] = []\n\n // Fetch active account via normal registry\n try {\n const snapshot = await this.registry.fetchQuota(options?.source)\n snapshots.push(snapshot)\n } catch (err) {\n debug('quota', `Active account fetch failed: ${err}`)\n }\n\n // Fetch other accounts via their OAuth tokens\n for (const token of tokens) {\n if (!token.email) continue\n // Skip if we already have this email\n if (snapshots.some(s => s.email === token.email)) continue\n\n try {\n const client = new OAuthClient(token)\n const source = new OAuthSource(client)\n const snapshot = await source.fetchQuota()\n snapshots.push(snapshot)\n } catch (err) {\n debug('quota', `Failed to fetch for ${token.email}: ${err}`)\n }\n }\n\n return snapshots\n }\n\n /**\n * Get the full dashboard data for all accounts\n */\n async getFullDashboard(): Promise<{\n snapshots: QuotaSnapshot[]\n history: Record<string, UsageRecord[]>\n dailySummary: Record<string, ReturnType<typeof getDailySummary>>\n }> {\n const snapshots = await this.fetchAllAccounts()\n const history: Record<string, UsageRecord[]> = {}\n const dailySummary: Record<string, ReturnType<typeof getDailySummary>> = {}\n\n for (const snapshot of snapshots) {\n if (!snapshot.email) continue\n history[snapshot.email] = getHistory(snapshot.email, { days: 1, limit: 50 })\n dailySummary[snapshot.email] = getDailySummary(snapshot.email, 7)\n }\n\n return { snapshots, history, dailySummary }\n }\n\n /**\n * Get usage history for an account\n */\n getHistory(email: string, days?: number): UsageRecord[] {\n return getHistory(email, { days })\n }\n\n /**\n * Get daily summary for an account\n */\n getDailySummary(email: string, days?: number) {\n return getDailySummary(email, days)\n }\n\n /**\n * Register OAuth sources for all stored accounts\n */\n private registerOAuthSources(): void {\n const tokens = getAllAccountTokens()\n for (const token of tokens) {\n if (!token.accessToken) continue\n try {\n const client = new OAuthClient(token)\n const source = new OAuthSource(client)\n this.registry.addSource(source)\n debug('quota', `Registered OAuth source for ${token.email}`)\n } catch (err) {\n debug('quota', `Failed to register OAuth for ${token.email}: ${err}`)\n }\n }\n }\n\n /**\n * Get the source registry (for doctor/status checks)\n */\n getRegistry(): SourceRegistry {\n return this.registry\n }\n}\n","/**\n * Rich quota display rendering with ASCII progress bars and colors\n */\n\nimport chalk from 'chalk'\nimport type { QuotaSnapshot, QuotaGroup, QuotaBucket } from '../../sdk/types.js'\nimport { formatCountdown, formatPercentage } from '../../core/platform.js'\n\nconst BAR_WIDTH = 30\n\n/**\n * Render a single quota snapshot as a formatted string\n */\nexport function renderQuotaCompact(snapshot: QuotaSnapshot): string {\n const lines: string[] = []\n\n // Header\n const email = snapshot.email || 'unknown'\n const method = snapshot.method === 'local' ? '🟢' : snapshot.method === 'oauth' ? '🔵' : '🟡'\n lines.push(`${method} ${chalk.bold(email)}`)\n lines.push('')\n\n if (snapshot.groups.length === 0) {\n lines.push(chalk.dim(' No quota data available'))\n return lines.join('\\n')\n }\n\n for (const group of snapshot.groups) {\n lines.push(chalk.bold(` ${group.displayName}`))\n for (const bucket of group.buckets) {\n lines.push(renderBucketLine(bucket))\n }\n lines.push('')\n }\n\n return lines.join('\\n').trimEnd()\n}\n\n/**\n * Render a single bucket as a colored progress bar line\n */\nfunction renderBucketLine(bucket: QuotaBucket): string {\n const pct = Math.round(bucket.remainingFraction * 100)\n const bar = renderProgressBar(bucket.remainingFraction)\n const resetText = bucket.timeUntilResetMs\n ? chalk.dim(`resets ${formatCountdown(bucket.timeUntilResetMs)}`)\n : ''\n\n return ` ${bar} ${colorPct(pct)} ${resetText}`\n}\n\n/**\n * Render an ASCII progress bar with color coding\n */\nexport function renderProgressBar(fraction: number, width: number = BAR_WIDTH): string {\n const filled = Math.round(fraction * width)\n const empty = width - filled\n\n const barChar = '█'\n const emptyChar = '░'\n\n const color = getQuotaColor(fraction)\n const filledStr = color(Array(filled).fill(barChar).join(''))\n const emptyStr = chalk.dim(Array(empty).fill(emptyChar).join(''))\n\n return `[${filledStr}${emptyStr}]`\n}\n\n/**\n * Color a percentage based on remaining quota\n */\nfunction colorPct(pct: number): string {\n if (pct >= 70) return chalk.green(`${pct}%`)\n if (pct >= 30) return chalk.yellow(`${pct}%`)\n return chalk.red.bold(`${pct}%`)\n}\n\n/**\n * Get color function based on remaining fraction\n */\nexport function getQuotaColor(fraction: number): typeof chalk.green {\n if (fraction >= 0.7) return chalk.green\n if (fraction >= 0.3) return chalk.yellow\n return chalk.red\n}\n","/**\n * Cross-account comparison table renderer\n */\n\nimport Table from 'cli-table3'\nimport chalk from 'chalk'\nimport type { QuotaSnapshot } from '../../sdk/types.js'\nimport { formatCountdown } from '../../core/platform.js'\n\n/**\n * Render a side-by-side comparison of multiple accounts\n */\nexport function renderComparisonTable(snapshots: QuotaSnapshot[]): string {\n if (snapshots.length === 0) {\n return chalk.dim(' No accounts to compare')\n }\n\n const table = new Table({\n head: ['Account', 'Gemini 5h', 'Gemini Week', 'Claude 5h', 'Claude Week'],\n style: { head: ['cyan', 'cyan', 'cyan', 'cyan', 'cyan'] },\n colWidths: [25, 16, 16, 16, 16],\n })\n\n for (const snapshot of snapshots) {\n const email = snapshot.email || 'unknown'\n const vals = extractValues(snapshot)\n table.push([\n chalk.bold(email),\n formatCell(vals.geminiSession, vals.geminiSessionReset),\n formatCell(vals.geminiWeekly, vals.geminiWeeklyReset),\n formatCell(vals.claudeSession, vals.claudeSessionReset),\n formatCell(vals.claudeWeekly, vals.claudeWeeklyReset),\n ])\n }\n\n return table.toString()\n}\n\nfunction extractValues(snapshot: QuotaSnapshot) {\n let geminiSession: number | null = null\n let geminiSessionReset: number | undefined\n let geminiWeekly: number | null = null\n let geminiWeeklyReset: number | undefined\n let claudeSession: number | null = null\n let claudeSessionReset: number | undefined\n let claudeWeekly: number | null = null\n let claudeWeeklyReset: number | undefined\n\n for (const group of snapshot.groups) {\n const lower = group.displayName.toLowerCase()\n for (const bucket of group.buckets) {\n const bLower = bucket.displayName.toLowerCase()\n const isWeekly = bLower.includes('weekly') || bLower.includes('week')\n\n if (lower.includes('gemini')) {\n if (isWeekly) {\n geminiWeekly = bucket.remainingFraction\n geminiWeeklyReset = bucket.timeUntilResetMs\n } else {\n geminiSession = bucket.remainingFraction\n geminiSessionReset = bucket.timeUntilResetMs\n }\n } else if (lower.includes('claude') || lower.includes('gpt')) {\n if (isWeekly) {\n claudeWeekly = bucket.remainingFraction\n claudeWeeklyReset = bucket.timeUntilResetMs\n } else {\n claudeSession = bucket.remainingFraction\n claudeSessionReset = bucket.timeUntilResetMs\n }\n }\n }\n }\n\n return {\n geminiSession, geminiSessionReset,\n geminiWeekly, geminiWeeklyReset,\n claudeSession, claudeSessionReset,\n claudeWeekly, claudeWeeklyReset,\n }\n}\n\nfunction formatCell(fraction: number | null, resetMs?: number): string {\n if (fraction === null) return chalk.dim('—')\n const pct = Math.round(fraction * 100)\n const reset = resetMs ? chalk.dim(` ${formatCountdown(resetMs)}`) : ''\n if (pct >= 70) return chalk.green(`${pct}%`) + reset\n if (pct >= 30) return chalk.yellow(`${pct}%`) + reset\n return chalk.red.bold(`${pct}%`) + reset\n}\n","/**\n * `aq --full` — Full dashboard showing all accounts, groups, windows, sparklines\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport { QuotaClient } from '../../sdk/quota.js'\nimport { renderFullDashboard, renderFullDashboardJson } from '../render/full-dashboard.js'\n\nexport function registerFullCommand(program: Command): void {\n // --full is a global option, not a subcommand\n // It's handled in the main index.ts dispatch\n}\n\n/**\n * Execute the full dashboard display\n */\nexport async function executeFullDashboard(opts: {\n json?: boolean\n watch?: boolean\n noHistory?: boolean\n verbose?: boolean\n}): Promise<void> {\n const spinner = ora('Loading full dashboard...').start()\n\n try {\n const client = new QuotaClient({ verbose: opts.verbose })\n\n if (opts.watch) {\n spinner.stop()\n await runWatchMode(client, opts)\n return\n }\n\n const { snapshots, history } = await client.getFullDashboard()\n spinner.stop()\n\n if (opts.json) {\n console.log(renderFullDashboardJson(snapshots, opts.noHistory ? {} : history))\n } else {\n console.log(renderFullDashboard(snapshots, opts.noHistory ? {} : history))\n }\n } catch (err) {\n spinner.fail(chalk.red(`Failed: ${(err as Error).message}`))\n process.exit(1)\n }\n}\n\n/**\n * Watch mode: refresh dashboard every 30 seconds\n */\nasync function runWatchMode(\n client: QuotaClient,\n opts: { json?: boolean; noHistory?: boolean }\n): Promise<void> {\n const REFRESH_MS = 30_000\n\n const refresh = async () => {\n try {\n const { snapshots, history } = await client.getFullDashboard()\n // Clear screen\n process.stdout.write('\\x1B[2J\\x1B[0f')\n if (opts.json) {\n console.log(renderFullDashboardJson(snapshots, opts.noHistory ? {} : history))\n } else {\n console.log(renderFullDashboard(snapshots, opts.noHistory ? {} : history))\n }\n console.log(chalk.dim(`\\n Auto-refreshing every ${REFRESH_MS / 1000}s — Press Ctrl+C to exit`))\n } catch (err) {\n console.error(chalk.red(`Refresh error: ${(err as Error).message}`))\n }\n }\n\n await refresh()\n setInterval(refresh, REFRESH_MS)\n\n // Keep process alive\n await new Promise(() => {})\n}\n","/**\n * Full dashboard renderer — the flagship `aq --full` view\n *\n * Shows all accounts, both quota groups, both time windows,\n * mini usage sparklines, and status footer.\n */\n\nimport chalk from 'chalk'\nimport boxen from 'boxen'\nimport type { QuotaSnapshot, UsageRecord } from '../../sdk/types.js'\nimport { renderProgressBar, getQuotaColor } from './quota-table.js'\nimport { formatCountdown } from '../../core/platform.js'\n\nconst SPARKLINE_WIDTH = 24\n\n/**\n * Render the full dashboard\n */\nexport function renderFullDashboard(\n snapshots: QuotaSnapshot[],\n history: Record<string, UsageRecord[]>\n): string {\n const now = new Date().toLocaleTimeString()\n const parts: string[] = []\n\n // Title\n parts.push(chalk.bold.cyan(` when-does-my-quota-refresh — Full Dashboard`) + chalk.dim(` ${now}`))\n parts.push('')\n\n if (snapshots.length === 0) {\n parts.push(chalk.dim(' No accounts configured. Run `aq accounts add` to get started.'))\n return boxen(parts.join('\\n'), {\n padding: 1,\n margin: 0,\n borderStyle: 'round',\n title: 'aq',\n titleAlignment: 'center',\n })\n }\n\n for (let i = 0; i < snapshots.length; i++) {\n const snapshot = snapshots[i]\n parts.push(renderAccountSection(snapshot, history[snapshot.email || '']))\n\n if (i < snapshots.length - 1) {\n parts.push(chalk.dim(' ─'.repeat(24)))\n }\n }\n\n // Footer\n parts.push('')\n parts.push(chalk.dim(` Source: ${snapshots[0]?.method || 'unknown'}`))\n\n return boxen(parts.join('\\n'), {\n padding: { top: 1, bottom: 1, left: 2, right: 2 },\n margin: 0,\n borderStyle: 'round',\n title: 'aq',\n titleAlignment: 'center',\n })\n}\n\n/**\n * Render a single account section\n */\nfunction renderAccountSection(\n snapshot: QuotaSnapshot,\n accountHistory?: UsageRecord[]\n): string {\n const lines: string[] = []\n const email = snapshot.email || 'unknown'\n const method = snapshot.method === 'local' ? chalk.green('●') :\n snapshot.method === 'oauth' ? chalk.blue('●') :\n chalk.yellow('●')\n\n // Account header\n lines.push(`${method} ${chalk.bold(email)}`)\n\n if (snapshot.groups.length === 0) {\n lines.push(chalk.dim(' No quota data available'))\n return lines.join('\\n')\n }\n\n // Render each quota group\n for (const group of snapshot.groups) {\n lines.push('')\n lines.push(chalk.underline(` ${group.displayName}`))\n\n for (const bucket of group.buckets) {\n const pct = Math.round(bucket.remainingFraction * 100)\n const bar = renderProgressBar(bucket.remainingFraction, 28)\n const resetText = bucket.timeUntilResetMs\n ? chalk.dim(`resets ${formatCountdown(bucket.timeUntilResetMs)}`)\n : ''\n\n const colorFn = getQuotaColor(bucket.remainingFraction)\n const label = bucket.displayName.length > 12\n ? bucket.displayName.slice(0, 12)\n : bucket.displayName.padEnd(12)\n\n lines.push(` ${chalk.dim(label)} ${bar} ${colorFn(pct.toString().padStart(3))}% ${resetText}`)\n }\n }\n\n // Mini sparkline from history\n if (accountHistory && accountHistory.length > 0) {\n lines.push('')\n lines.push(` ${chalk.dim('📈 Recent')} ${renderSparkline(accountHistory)}`)\n }\n\n return lines.join('\\n')\n}\n\n/**\n * Render a mini ASCII sparkline from recent usage data\n */\nfunction renderSparkline(records: UsageRecord[]): string {\n // Get the most recent session remaining values\n const values = records\n .slice(-SPARKLINE_WIDTH)\n .map(r => {\n const vals = [r.geminiSessionRemaining, r.claudeSessionRemaining]\n .filter(v => v !== null) as number[]\n return vals.length > 0 ? Math.max(...vals) : 0\n })\n\n if (values.length === 0) return chalk.dim('no data')\n\n const blocks = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█']\n return values.map(v => {\n const idx = Math.min(Math.round(v * (blocks.length - 1)), blocks.length - 1)\n const colorFn = getQuotaColor(v)\n return colorFn(blocks[idx])\n }).join('')\n}\n\n/**\n * Render full dashboard as JSON (for --json flag)\n */\nexport function renderFullDashboardJson(\n snapshots: QuotaSnapshot[],\n history: Record<string, UsageRecord[]>\n): string {\n return JSON.stringify({\n timestamp: new Date().toISOString(),\n accounts: snapshots.map(s => ({\n email: s.email,\n method: s.method,\n groups: s.groups,\n promptCredits: s.promptCredits,\n recentHistory: history[s.email || '']?.slice(0, 10) || [],\n })),\n }, null, 2)\n}\n","/**\n * `aq accounts` — Manage Google accounts\n */\n\nimport { Command } from 'commander'\nimport inquirer from 'inquirer'\nimport chalk from 'chalk'\nimport Table from 'cli-table3'\nimport {\n listAccounts,\n setActiveAccount,\n removeAccount,\n loginAccount,\n} from '../../sdk/accounts/index.js'\n\nexport function registerAccountsCommand(program: Command): void {\n const accounts = program\n .command('accounts')\n .description('Manage Google accounts')\n\n accounts\n .command('list')\n .description('List all managed accounts')\n .action(() => {\n const accounts = listAccounts()\n if (accounts.length === 0) {\n console.log(chalk.dim(' No accounts configured. Run `aq accounts add` to get started.'))\n return\n }\n\n const table = new Table({\n head: ['Email', 'Status', 'Added'],\n style: { head: ['cyan'] },\n })\n\n for (const acct of accounts) {\n table.push([\n acct.email,\n acct.isActive ? chalk.green('● Active') : chalk.dim('○ Inactive'),\n new Date(acct.addedAt).toLocaleDateString(),\n ])\n }\n\n console.log(table.toString())\n })\n\n accounts\n .command('add')\n .description('Login a new Google account')\n .option('--manual', 'Manual login for headless/SSH (get URL instead of browser)')\n .action(async (opts) => {\n try {\n if (opts.manual) {\n const { getManualLoginUrl, completeManualLogin } = await import('../../sdk/accounts/auth.js')\n const url = getManualLoginUrl()\n console.log(chalk.bold('\\nOpen this URL in your browser:\\n'))\n console.log(chalk.cyan(url))\n console.log(chalk.dim('\\nPaste the authorization code here:'))\n\n const { code } = await inquirer.prompt([{\n type: 'input',\n name: 'code',\n message: 'Authorization code:',\n }])\n\n const email = await completeManualLogin(code)\n console.log(chalk.green(`\\n✓ Logged in as ${email}`))\n } else {\n const email = await loginAccount()\n console.log(chalk.green(`\\n✓ Logged in as ${email}`))\n }\n } catch (err) {\n console.error(chalk.red(`\\n✗ Login failed: ${(err as Error).message}`))\n process.exit(1)\n }\n })\n\n accounts\n .command('switch <email>')\n .description('Set the active account')\n .action((email: string) => {\n if (setActiveAccount(email)) {\n console.log(chalk.green(`✓ Switched to ${email}`))\n } else {\n console.error(chalk.red(`✗ Account \"${email}\" not found`))\n process.exit(1)\n }\n })\n\n accounts\n .command('remove <email>')\n .description('Remove an account')\n .action(async (email: string) => {\n const { confirm } = await inquirer.prompt([{\n type: 'confirm',\n name: 'confirm',\n message: `Remove account ${email}?`,\n default: false,\n }])\n\n if (confirm) {\n if (removeAccount(email)) {\n console.log(chalk.green(`✓ Removed ${email}`))\n } else {\n console.error(chalk.red(`✗ Account \"${email}\" not found`))\n }\n }\n })\n}\n","/**\n * `aq history` — Usage history and analytics\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport { QuotaClient } from '../../sdk/quota.js'\nimport { renderHistoryChart } from '../render/history-chart.js'\nimport { renderComparisonChart } from '../render/history-chart.js'\nimport { listAccounts } from '../../sdk/accounts/index.js'\n\nexport function registerHistoryCommand(program: Command): void {\n program\n .command('history')\n .description('Show usage history and trends')\n .option('-e, --email <email>', 'Account email (default: active account)')\n .option('-d, --days <days>', 'Number of days to show', '7')\n .option('--group <group>', 'Filter: gemini, claude, all', 'all')\n .option('--json', 'Output JSON')\n .option('--compare', 'Compare all accounts')\n .action(async (opts) => {\n try {\n const client = new QuotaClient({ verbose: opts.verbose })\n\n // Determine email\n const email = opts.email || getActiveEmail()\n if (!email) {\n console.log(chalk.dim(' No active account. Run `aq accounts add` or use --email.'))\n return\n }\n\n const days = parseInt(opts.days, 10)\n const history = client.getHistory(email, days)\n const summary = client.getDailySummary(email, days)\n\n if (opts.json) {\n console.log(JSON.stringify({ email, days, history, summary }, null, 2))\n return\n }\n\n if (opts.compare) {\n const allAccounts = listAccounts()\n const allHistory: Record<string, any[]> = {}\n for (const acct of allAccounts) {\n allHistory[acct.email] = client.getHistory(acct.email, days)\n }\n console.log(renderComparisonChart(allHistory, 'geminiSession'))\n console.log('')\n console.log(renderComparisonChart(allHistory, 'claudeSession'))\n return\n }\n\n // Show charts based on group filter\n console.log(chalk.bold(`\\n 📊 Usage History — ${email} (last ${days} days)\\n`))\n\n if (opts.group === 'all' || opts.group === 'gemini') {\n console.log(renderHistoryChart(history, 'Gemini Session (5-hour)'))\n console.log('')\n console.log(renderHistoryChart(history, 'Gemini Weekly'))\n console.log('')\n }\n\n if (opts.group === 'all' || opts.group === 'claude') {\n console.log(renderHistoryChart(history, 'Claude + GPT Session (5-hour)'))\n console.log('')\n console.log(renderHistoryChart(history, 'Claude + GPT Weekly'))\n console.log('')\n }\n\n // Daily summary table\n if (summary.length > 0) {\n console.log(chalk.bold(' 📅 Daily Summary'))\n for (const day of summary) {\n const gemini = day.geminiSessionAvg !== null ? `${Math.round(day.geminiSessionAvg! * 100)}%` : '—'\n const claude = day.claudeSessionAvg !== null ? `${Math.round(day.claudeSessionAvg! * 100)}%` : '—'\n console.log(chalk.dim(` ${day.date} `) + `Gemini: ${gemini} Claude: ${claude} (${day.count} readings)`)\n }\n }\n } catch (err) {\n console.error(chalk.red(`Error: ${(err as Error).message}`))\n process.exit(1)\n }\n })\n}\n\nfunction getActiveEmail(): string | null {\n const accounts = listAccounts()\n const active = accounts.find(a => a.isActive)\n return active?.email || null\n}\n","/**\n * ASCII chart renderer for usage history\n */\n\nimport chalk from 'chalk'\nimport type { UsageRecord } from '../../sdk/types.js'\nimport { getQuotaColor } from './quota-table.js'\n\nconst CHART_HEIGHT = 10\nconst CHART_WIDTH = 40\n\n/**\n * Render a history chart showing quota trends over time\n */\nexport function renderHistoryChart(\n records: UsageRecord[],\n label: string = 'Gemini Session'\n): string {\n if (records.length === 0) {\n return chalk.dim(' No history data available')\n }\n\n // Sort by timestamp ascending\n const sorted = [...records].sort((a, b) =>\n new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n )\n\n // Extract values\n const values = sorted.map(r => {\n if (label.toLowerCase().includes('gemini')) {\n if (label.toLowerCase().includes('weekly')) return r.geminiWeeklyRemaining\n return r.geminiSessionRemaining\n } else {\n if (label.toLowerCase().includes('weekly')) return r.claudeWeeklyRemaining\n return r.claudeSessionRemaining\n }\n }).filter(v => v !== null) as number[]\n\n if (values.length === 0) {\n return chalk.dim(` No ${label} data available`)\n }\n\n // Build chart\n const lines: string[] = []\n lines.push(chalk.bold(` 📊 ${label} — Last ${values.length} readings`))\n lines.push('')\n\n // Downsample to CHART_WIDTH\n const sampled = downsample(values, CHART_WIDTH)\n\n // Build chart rows (top to bottom)\n for (let row = CHART_HEIGHT; row >= 0; row--) {\n const threshold = row / CHART_HEIGHT\n const isAxis = row === 0\n\n let line = isAxis ? chalk.dim(' 0% ') : chalk.dim(' ')\n for (const val of sampled) {\n if (val >= threshold) {\n line += getQuotaColor(val)('█')\n } else {\n line += chalk.dim('·')\n }\n }\n if (row === CHART_HEIGHT) line += chalk.dim(' 100%')\n lines.push(line)\n }\n\n // Time labels\n if (sorted.length >= 2) {\n const first = new Date(sorted[0].timestamp)\n const last = new Date(sorted[sorted.length - 1].timestamp)\n lines.push(chalk.dim(\n ` ${formatTime(first)}${' '.repeat(Math.max(0, CHART_WIDTH - 12))}${formatTime(last)}`\n ))\n }\n\n return lines.join('\\n')\n}\n\n/**\n * Render a comparison chart for multiple accounts\n */\nexport function renderComparisonChart(\n recordsByEmail: Record<string, UsageRecord[]>,\n metric: 'geminiSession' | 'claudeSession' | 'geminiWeekly' | 'claudeWeekly'\n): string {\n const lines: string[] = []\n const emails = Object.keys(recordsByEmail)\n\n lines.push(chalk.bold(` 📊 Cross-Account Comparison — ${metricLabel(metric)}`))\n lines.push('')\n\n const maxEmailLen = Math.max(...emails.map(e => e.length), 8)\n\n for (const email of emails) {\n const records = recordsByEmail[email]\n const latest = records[0] // Already sorted desc\n if (!latest) continue\n\n let value: number | null = null\n switch (metric) {\n case 'geminiSession': value = latest.geminiSessionRemaining; break\n case 'claudeSession': value = latest.claudeSessionRemaining; break\n case 'geminiWeekly': value = latest.geminiWeeklyRemaining; break\n case 'claudeWeekly': value = latest.claudeWeeklyRemaining; break\n }\n\n const label = email.slice(0, maxEmailLen).padEnd(maxEmailLen)\n const pct = value !== null ? Math.round(value * 100) : -1\n const bar = value !== null\n ? renderMiniBar(value, 20)\n : chalk.dim('░'.repeat(20))\n const pctStr = pct >= 0 ? `${pct}%` : 'N/A'\n\n lines.push(` ${chalk.dim(label)} ${bar} ${pctStr}`)\n }\n\n return lines.join('\\n')\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\nfunction renderMiniBar(fraction: number, width: number): string {\n const filled = Math.round(fraction * width)\n const colorFn = getQuotaColor(fraction)\n return colorFn('█'.repeat(filled)) + chalk.dim('░'.repeat(width - filled))\n}\n\nfunction downsample(values: number[], targetWidth: number): number[] {\n if (values.length <= targetWidth) return values\n const result: number[] = []\n const step = values.length / targetWidth\n for (let i = 0; i < targetWidth; i++) {\n const idx = Math.round(i * step)\n result.push(values[Math.min(idx, values.length - 1)])\n }\n return result\n}\n\nfunction formatTime(date: Date): string {\n return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`\n}\n\nfunction metricLabel(metric: string): string {\n switch (metric) {\n case 'geminiSession': return 'Gemini 5-Hour'\n case 'claudeSession': return 'Claude + GPT 5-Hour'\n case 'geminiWeekly': return 'Gemini Weekly'\n case 'claudeWeekly': return 'Claude + GPT Weekly'\n default: return metric\n }\n}\n","/**\n * `aq doctor` — Diagnose setup issues\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport { QuotaClient } from '../../sdk/quota.js'\nimport { detectAntigravityProcesses } from '../../sources/local/process-detector.js'\nimport { listAccounts, getActiveAccountTokens } from '../../sdk/accounts/index.js'\nimport { isWindows, isMacOS, isLinux } from '../../core/platform.js'\nimport { loadConfig, getConfigDirPath } from '../../core/config.js'\nimport { closeStore } from '../../sdk/store.js'\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command('doctor')\n .description('Diagnose setup issues')\n .action(async () => {\n console.log(chalk.bold.cyan('\\n when-does-my-quota-refresh — Doctor\\n'))\n\n const checks: Array<{ label: string; status: 'ok' | 'warn' | 'error'; detail: string }> = []\n\n // 1. Platform info\n const platform = isMacOS() ? 'macOS' : isLinux() ? 'Linux' : isWindows() ? 'Windows' : process.platform\n checks.push({\n label: 'Platform',\n status: 'ok',\n detail: platform,\n })\n\n // 2. Node.js version\n checks.push({\n label: 'Node.js',\n status: process.version >= 'v18' ? 'ok' : 'warn',\n detail: process.version,\n })\n\n // 3. Config directory\n try {\n const configDir = getConfigDirPath()\n checks.push({ label: 'Config directory', status: 'ok', detail: configDir })\n } catch (err) {\n checks.push({ label: 'Config directory', status: 'error', detail: (err as Error).message })\n }\n\n // 4. Config file\n const config = loadConfig()\n checks.push({\n label: 'Config loaded',\n status: 'ok',\n detail: `mode=${config.defaultMode}, cache=${config.cacheTtlMs / 1000}s`,\n })\n\n // 5. Accounts\n const accounts = listAccounts()\n if (accounts.length > 0) {\n checks.push({\n label: 'Accounts',\n status: 'ok',\n detail: `${accounts.length} configured (${accounts.find(a => a.isActive)?.email || 'none active'})`,\n })\n } else {\n checks.push({\n label: 'Accounts',\n status: 'warn',\n detail: 'No accounts configured (local mode may still work)',\n })\n }\n\n // 6. Token validity\n const tokens = getActiveAccountTokens()\n if (tokens) {\n const expired = Date.now() >= (tokens.expiresAt || 0)\n checks.push({\n label: 'Token status',\n status: expired ? 'warn' : 'ok',\n detail: expired ? 'Access token expired (will refresh)' : 'Valid',\n })\n }\n\n // 7. Process detection\n try {\n const processes = await detectAntigravityProcesses()\n if (processes.length > 0) {\n checks.push({\n label: 'Antigravity process',\n status: 'ok',\n detail: `Found ${processes.length} process(es): ${processes.map(p => `PID ${p.pid} (${p.scope})`).join(', ')}`,\n })\n } else {\n checks.push({\n label: 'Antigravity process',\n status: 'warn',\n detail: 'No process found (try opening Antigravity in your IDE)',\n })\n }\n } catch (err) {\n checks.push({\n label: 'Process detection',\n status: 'error',\n detail: (err as Error).message,\n })\n }\n\n // 8. Quota fetch test\n try {\n const client = new QuotaClient()\n const snapshot = await client.fetchQuota() as any\n checks.push({\n label: 'Quota fetch',\n status: 'ok',\n detail: `Source: ${snapshot.method}, Email: ${snapshot.email || 'unknown'}, Groups: ${snapshot.groups.length}`,\n })\n } catch (err) {\n checks.push({\n label: 'Quota fetch',\n status: 'error',\n detail: (err as Error).message,\n })\n }\n\n // Render results\n for (const check of checks) {\n const icon = check.status === 'ok' ? chalk.green('✓') :\n check.status === 'warn' ? chalk.yellow('⚠') :\n chalk.red('✗')\n const label = chalk.bold(check.label.padEnd(22))\n console.log(` ${icon} ${label} ${check.detail}`)\n }\n\n console.log('')\n\n // Summary\n const errors = checks.filter(c => c.status === 'error').length\n const warnings = checks.filter(c => c.status === 'warn').length\n if (errors === 0 && warnings === 0) {\n console.log(chalk.green.bold(' ✅ Everything looks good!'))\n } else {\n console.log(chalk.yellow(` ${errors} error(s), ${warnings} warning(s)`))\n }\n console.log('')\n\n closeStore()\n })\n}\n","/**\n * `aq config` — Settings management\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport { loadConfig, saveConfig, getConfigDirPath } from '../../sdk/index.js'\nimport type { AppConfig } from '../../sdk/types.js'\n\nexport function registerConfigCommand(program: Command): void {\n const config = program\n .command('config')\n .description('Manage settings')\n\n config\n .command('show')\n .description('Show current configuration')\n .action(() => {\n const cfg = loadConfig()\n console.log(chalk.bold('\\n Current Configuration\\n'))\n console.log(JSON.stringify(cfg, null, 2))\n console.log(chalk.dim(`\\n Config path: ${getConfigDirPath()}/config.json`))\n })\n\n config\n .command('set <key> <value>')\n .description('Set a config value')\n .action((key: string, value: string) => {\n const cfg = loadConfig()\n const keys = key.split('.')\n let target: any = cfg\n for (let i = 0; i < keys.length - 1; i++) {\n if (!(keys[i] in target)) {\n target[keys[i]] = {}\n }\n target = target[keys[i]]\n }\n\n // Type coercion\n if (value === 'true') value = true as any\n else if (value === 'false') value = false as any\n else if (!isNaN(Number(value))) value = Number(value) as any\n\n target[keys[keys.length - 1]] = value\n saveConfig(cfg as AppConfig)\n console.log(chalk.green(`✓ Set ${key} = ${value}`))\n })\n\n config\n .command('get <key>')\n .description('Get a config value')\n .action((key: string) => {\n const cfg = loadConfig() as any\n const keys = key.split('.')\n let target = cfg\n for (const k of keys) {\n if (target === undefined || target === null) break\n target = target[k]\n }\n console.log(target !== undefined ? String(target) : chalk.dim('not set'))\n })\n\n config\n .command('path')\n .description('Show config directory path')\n .action(() => {\n console.log(getConfigDirPath())\n })\n}\n","/**\n * `aq wakeup` — Auto-trigger quota refresh to maximize daily limits\n *\n * Cross-platform: crontab on macOS/Linux, Task Scheduler on Windows.\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport { execSync } from 'child_process'\nimport { existsSync, writeFileSync, readFileSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport { loadConfig, saveConfig } from '../../core/config.js'\nimport { isWindows, isMacOS } from '../../core/platform.js'\nimport inquirer from 'inquirer'\nimport type { AppConfig } from '../../sdk/types.js'\n\nconst CRON_MARKER = '# when-does-my-quota-refresh-wakeup'\nconst TASK_NAME = 'when-does-my-quota-refresh-wakeup'\n\nexport function registerWakeupCommand(program: Command): void {\n const wakeup = program\n .command('wakeup')\n .description('Auto-trigger quota refresh to maximize daily limits')\n\n wakeup\n .command('config')\n .description('Interactive wakeup setup')\n .action(async () => {\n console.log(chalk.bold.cyan('\\n Wakeup Configuration\\n'))\n\n const config = loadConfig()\n\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'mode',\n message: 'Trigger mode:',\n choices: [\n { name: 'Smart detection — trigger when quota resets (Recommended)', value: 'smart' },\n { name: 'Interval — trigger every N hours', value: 'interval' },\n { name: 'Daily — trigger at specific times', value: 'daily' },\n ],\n },\n {\n type: 'number',\n name: 'intervalHours',\n message: 'Interval in hours:',\n default: 6,\n when: (a) => a.mode === 'interval',\n },\n {\n type: 'input',\n name: 'dailyTimes',\n message: 'Times to trigger (comma-separated, e.g. 9,17):',\n default: '9,17',\n when: (a) => a.mode === 'daily',\n },\n {\n type: 'confirm',\n name: 'allAccounts',\n message: 'Trigger for all accounts?',\n default: true,\n },\n ])\n\n // Save config\n config.wakeupAccounts = answers.allAccounts ? [] : [] // Will be filled from accounts list\n saveConfig(config)\n\n console.log(chalk.green('\\n ✓ Configuration saved'))\n console.log(chalk.dim(` Run \\`aq wakeup install\\` to activate`))\n })\n\n wakeup\n .command('install')\n .description('Install wakeup to system scheduler')\n .action(async () => {\n try {\n if (isWindows()) {\n installWindowsTask()\n } else {\n installCrontab()\n }\n console.log(chalk.green('\\n ✓ Wakeup installed to system scheduler'))\n } catch (err) {\n console.error(chalk.red(`\\n ✗ Failed: ${(err as Error).message}`))\n }\n })\n\n wakeup\n .command('uninstall')\n .description('Remove wakeup from system scheduler')\n .action(() => {\n try {\n if (isWindows()) {\n uninstallWindowsTask()\n } else {\n uninstallCrontab()\n }\n console.log(chalk.green('\\n ✓ Wakeup removed from system scheduler'))\n } catch (err) {\n console.error(chalk.red(`\\n ✗ Failed: ${(err as Error).message}`))\n }\n })\n\n wakeup\n .command('status')\n .description('Check wakeup status')\n .action(() => {\n const config = loadConfig()\n console.log(chalk.bold('\\n Wakeup Status\\n'))\n console.log(` Models: ${config.wakeupModels.join(', ')}`)\n console.log(` Accounts: ${config.wakeupAccounts.length > 0 ? config.wakeupAccounts.join(', ') : 'all'}`)\n\n if (isWindows()) {\n const installed = checkWindowsTask()\n console.log(` Scheduler: ${installed ? chalk.green('Installed') : chalk.dim('Not installed')}`)\n } else {\n const installed = checkCrontab()\n console.log(` Cron: ${installed ? chalk.green('Installed') : chalk.dim('Not installed')}`)\n }\n })\n\n wakeup\n .command('test')\n .description('Test wakeup trigger manually')\n .option('-e, --email <email>', 'Account email')\n .option('-m, --model <model>', 'Model to test')\n .option('-p, --prompt <prompt>', 'Test prompt', 'hi')\n .action(async (opts) => {\n console.log(chalk.cyan('\\n Testing wakeup trigger...\\n'))\n try {\n const aqPath = process.argv[1]\n execSync(`\"${aqPath}\" quota --refresh`, { stdio: 'inherit' })\n console.log(chalk.green('\\n ✓ Wakeup test completed'))\n } catch (err) {\n console.error(chalk.red(`\\n ✗ Test failed: ${(err as Error).message}`))\n }\n })\n}\n\n// ── Crontab (macOS/Linux) ─────────────────────────────────────────\n\nfunction installCrontab(): void {\n const aqPath = process.argv[1]\n const config = loadConfig()\n\n // Remove existing entry\n uninstallCrontab()\n\n const intervalHours = 6 // Default\n const cronLine = `0 */${intervalHours} * * * \"${aqPath}\" quota --refresh --json > /dev/null 2>&1 ${CRON_MARKER}`\n\n try {\n const existing = execSync('crontab -l 2>/dev/null', { encoding: 'utf-8' }).trim()\n const newCron = existing ? `${existing}\\n${cronLine}` : cronLine\n execSync(`echo '${newCron}' | crontab -`, { encoding: 'utf-8' })\n } catch {\n execSync(`echo '${cronLine}' | crontab -`, { encoding: 'utf-8' })\n }\n}\n\nfunction uninstallCrontab(): void {\n try {\n const existing = execSync('crontab -l 2>/dev/null', { encoding: 'utf-8' })\n const filtered = existing.split('\\n').filter(l => !l.includes(CRON_MARKER)).join('\\n').trim()\n execSync(`echo '${filtered}' | crontab -`, { encoding: 'utf-8' })\n } catch { /* no crontab */ }\n}\n\nfunction checkCrontab(): boolean {\n try {\n const output = execSync('crontab -l 2>/dev/null', { encoding: 'utf-8' })\n return output.includes(CRON_MARKER)\n } catch {\n return false\n }\n}\n\n// ── Windows Task Scheduler ─────────────────────────────────────────\n\nfunction installWindowsTask(): void {\n const aqPath = process.argv[1]\n const xmlPath = join(homedir(), 'when-does-my-quota-refresh-wakeup.xml')\n\n // Remove existing\n uninstallWindowsTask()\n\n // Create task XML\n const xml = `<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<Task version=\"1.4\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n <Triggers>\n <TimeTrigger>\n <Repetition>\n <Interval>PT6H</Interval>\n </Repetition>\n <StartBoundary>2024-01-01T09:00:00</StartBoundary>\n </TimeTrigger>\n </Triggers>\n <Actions>\n <Exec>\n <Command>node</Command>\n <Arguments>\"${aqPath}\" quota --refresh</Arguments>\n </Exec>\n </Actions>\n <Settings>\n <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>\n <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>\n </Settings>\n</Task>`\n\n writeFileSync(xmlPath, xml)\n execSync(`schtasks /create /tn \"${TASK_NAME}\" /xml \"${xmlPath}\" /f`, { encoding: 'utf-8' })\n}\n\nfunction uninstallWindowsTask(): void {\n try {\n execSync(`schtasks /delete /tn \"${TASK_NAME}\" /f`, { encoding: 'utf-8', stdio: 'ignore' })\n } catch { /* task doesn't exist */ }\n}\n\nfunction checkWindowsTask(): boolean {\n try {\n execSync(`schtasks /query /tn \"${TASK_NAME}\"`, { encoding: 'utf-8', stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n","/**\n * `aq watch` — Real-time monitoring daemon\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport { QuotaClient } from '../../sdk/quota.js'\nimport { loadConfig, saveConfig } from '../../core/config.js'\nimport { renderFullDashboard } from '../render/full-dashboard.js'\n\nexport function registerWatchCommand(program: Command): void {\n const watch = program\n .command('watch')\n .description('Real-time quota monitoring daemon')\n\n watch\n .command('start')\n .description('Start watching in the foreground')\n .option('--interval <seconds>', 'Poll interval in seconds', '60')\n .action(async (opts) => {\n const client = new QuotaClient({ verbose: opts.verbose })\n const interval = parseInt(opts.interval, 10) * 1000\n\n console.log(chalk.bold.cyan(`\\n 🔄 Starting watch mode (every ${interval / 1000}s)\\n`))\n\n const refresh = async () => {\n try {\n const { snapshots, history } = await client.getFullDashboard()\n process.stdout.write('\\x1B[2J\\x1B[0f')\n console.log(renderFullDashboard(snapshots, history))\n console.log(chalk.dim(`\\n Polling every ${interval / 1000}s — Ctrl+C to exit`))\n } catch (err) {\n console.error(chalk.red(` Error: ${(err as Error).message}`))\n }\n }\n\n await refresh()\n setInterval(refresh, interval)\n await new Promise(() => {})\n })\n\n watch\n .command('status')\n .description('Check daemon status')\n .action(() => {\n // In v1, just check if a watch process is running\n console.log(chalk.bold('\\n Watch Status\\n'))\n console.log(chalk.dim(' Use `aq watch start` to start monitoring in foreground'))\n })\n}\n","/**\n * `aq plugin` — Plugin management\n */\n\nimport { Command } from 'commander'\nimport chalk from 'chalk'\nimport { loadConfig, saveConfig } from '../../core/config.js'\nimport type { AppConfig } from '../../sdk/types.js'\n\nexport function registerPluginCommand(program: Command): void {\n const plugin = program\n .command('plugin')\n .description('Manage plugins')\n\n plugin\n .command('list')\n .description('List installed plugins')\n .action(() => {\n const config = loadConfig()\n if (config.plugins.length === 0) {\n console.log(chalk.dim(' No plugins installed'))\n return\n }\n console.log(chalk.bold('\\n Installed Plugins\\n'))\n for (const p of config.plugins) {\n console.log(` 📦 ${p}`)\n }\n })\n\n plugin\n .command('install <name>')\n .description('Install a plugin')\n .action((name: string) => {\n const config = loadConfig()\n if (config.plugins.includes(name)) {\n console.log(chalk.yellow(` Plugin \"${name}\" already installed`))\n return\n }\n config.plugins.push(name)\n saveConfig(config)\n console.log(chalk.green(`✓ Plugin \"${name}\" installed`))\n })\n\n plugin\n .command('remove <name>')\n .description('Remove a plugin')\n .action((name: string) => {\n const config = loadConfig()\n const idx = config.plugins.indexOf(name)\n if (idx < 0) {\n console.log(chalk.red(` Plugin \"${name}\" not found`))\n return\n }\n config.plugins.splice(idx, 1)\n saveConfig(config)\n console.log(chalk.green(`✓ Plugin \"${name}\" removed`))\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAMA,SAAS,eAAe;AACxB,SAAS,gBAAAA,qBAAoB;AAC7B,SAAS,QAAAC,OAAM,eAAe;AAC9B,SAAS,qBAAqB;;;ACJ9B,OAAOC,YAAW;AAClB,OAAO,SAAS;;;ACFhB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAE1B,IAAM,YAAY,UAAU,IAAI;AAQzB,SAAS,YAAqB;AACnC,SAAO,QAAQ,aAAa;AAC9B;AAEO,SAAS,UAAmB;AACjC,SAAO,QAAQ,aAAa;AAC9B;AAEO,SAAS,UAAmB;AACjC,SAAO,QAAQ,aAAa;AAC9B;AAKA,eAAsB,WAAW,KAA8B;AAC7D,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,UAAU,KAAK,EAAE,SAAS,IAAM,CAAC;AAC1D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,gBAAgB,IAAoB;AAClD,MAAI,MAAM,EAAG,QAAO;AACpB,QAAM,eAAe,KAAK,MAAM,KAAK,GAAK;AAC1C,QAAM,QAAQ,KAAK,MAAM,eAAe,EAAE;AAC1C,QAAM,UAAU,eAAe;AAC/B,MAAI,QAAQ,EAAG,QAAO,GAAG,KAAK,KAAK,OAAO;AAC1C,SAAO,GAAG,OAAO;AACnB;;;ACtCA,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKA,eAAsB,6BAAqD;AACzE,QAAM,oBAAoB,0BAA0B,QAAQ,QAAQ,EAAE;AAEtE,MAAI,YAA2B,CAAC;AAEhC,MAAI,QAAQ,GAAG;AACb,gBAAY,MAAM,cAAc;AAAA,EAClC,WAAW,QAAQ,GAAG;AACpB,gBAAY,MAAM,cAAc;AAAA,EAClC,WAAW,UAAU,GAAG;AACtB,gBAAY,MAAM,gBAAgB;AAAA,EACpC;AAEA,QAAM,oBAAoB,SAAS,UAAU,MAAM,cAAc;AACjE,SAAO;AACT;AAKA,eAAe,gBAAwC;AACrD,QAAM,SAAS,MAAM,WAAW,4BAA4B;AAC5D,SAAO,cAAc,MAAM;AAC7B;AAKA,eAAe,gBAAwC;AACrD,QAAM,SAAS,MAAM,WAAW,mCAAmC;AACnE,SAAO,cAAc,MAAM;AAC7B;AAQA,eAAe,kBAA0C;AAEvD,MAAI,SAAS,MAAM;AAAA,IACjB;AAAA,EACF;AACA,MAAI,YAAY,gBAAgB,MAAM;AACtC,MAAI,UAAU,SAAS,EAAG,QAAO;AAGjC,WAAS,MAAM;AAAA,IACb;AAAA,EACF;AACA,cAAY,sBAAsB,MAAM;AACxC,MAAI,UAAU,SAAS,EAAG,QAAO;AAIjC,QAAM,oBAAoB,+CAA+C;AACzE,SAAO,CAAC;AACV;AAKA,SAAS,cAAc,QAA+B;AACpD,QAAM,YAA2B,CAAC;AAClC,QAAM,QAAQ,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO;AAE/C,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AAId,UAAM,QAAQ,QAAQ,MAAM,KAAK;AACjC,UAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AACjC,QAAI,MAAM,GAAG,EAAG;AAGhB,UAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAEpC,QAAI,mBAAmB,IAAI,GAAG;AAC5B,gBAAU,KAAK;AAAA,QACb;AAAA,QACA,MAAM,MAAM,CAAC,KAAK;AAAA,QAClB,aAAa;AAAA,QACb,OAAO,gBAAgB,IAAI;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,gBAAgB,QAA+B;AACtD,QAAM,YAA2B,CAAC;AAClC,QAAM,QAAQ,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO;AAE/C,aAAW,QAAQ,OAAO;AAExB,UAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,EAAE,QAAQ,MAAM,EAAE,CAAC;AACjE,QAAI,MAAM,SAAS,EAAG;AAEtB,UAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AACjC,QAAI,MAAM,GAAG,EAAG;AAEhB,UAAM,cAAc,MAAM,CAAC,KAAK;AAChC,UAAM,OAAO,MAAM,CAAC,KAAK;AAEzB,QAAI,mBAAmB,WAAW,KAAK,mBAAmB,IAAI,GAAG;AAC/D,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,gBAAgB,WAAW;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,sBAAsB,QAA+B;AAC5D,QAAM,YAA2B,CAAC;AAClC,QAAM,QAAQ,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO;AAE/C,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,WAAW,QAAQ,WAAW,KAAK,KAAK,QAAQ,WAAW,WAAW,EAAG;AAG9E,UAAM,QAAQ,QAAQ,MAAM,2BAA2B;AACvD,QAAI,CAAC,MAAO;AAEZ,UAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AACjC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,cAAc,MAAM,CAAC;AAE3B,QAAI,mBAAmB,WAAW,KAAK,mBAAmB,IAAI,GAAG;AAC/D,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,gBAAgB,WAAW;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,mBAAmB,MAAuB;AACjD,QAAM,QAAQ,KAAK,YAAY;AAC/B,SAAO,wBAAwB;AAAA,IAAK,YAClC,MAAM,SAAS,OAAO,YAAY,CAAC;AAAA,EACrC,KACE,MAAM,SAAS,UAAU,KACzB,MAAM,SAAS,QAAQ,KACvB,mBAAmB,KAAK,OAAK,MAAM,SAAS,CAAC,CAAC;AAElD;AAKA,SAAS,gBAAgB,aAA2C;AAClE,QAAM,QAAQ,YAAY,YAAY;AACtC,MAAI,MAAM,SAAS,iBAAiB,KAAK,MAAM,SAAS,iBAAiB,KAAK,MAAM,SAAS,KAAK,GAAG;AACnG,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,iBAAiB,KAAK,MAAM,SAAS,iBAAiB,KAAK,MAAM,SAAS,wBAAwB,GAAG;AACtH,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,0BAA0B,KAAK,MAAM,SAAS,iBAAiB,GAAG;AACnF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,aAAa,aAA0C;AACrE,QAAM,QAAQ,oBAAI,IAAoB;AACtC,MAAI,CAAC,YAAa,QAAO;AAGzB,QAAM,YAAY;AAClB,MAAI;AACJ,UAAQ,QAAQ,UAAU,KAAK,WAAW,OAAO,MAAM;AACrD,UAAM,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAAA,EAC9B;AAEA,SAAO;AACT;;;AC7NA,eAAsB,cAAc,KAAgC;AAClE,QAAM,kBAAkB,6BAA6B,GAAG,OAAO,QAAQ,QAAQ,EAAE;AAEjF,MAAI,UAAU,GAAG;AACf,WAAO,uBAAuB,GAAG;AAAA,EACnC,WAAW,QAAQ,GAAG;AACpB,WAAO,qBAAqB,GAAG;AAAA,EACjC,OAAO;AACL,WAAO,qBAAqB,GAAG;AAAA,EACjC;AACF;AAKA,eAAe,qBAAqB,KAAgC;AAClE,MAAI;AACF,UAAM,SAAS,MAAM,WAAW,qCAAqC,GAAG,EAAE;AAC1E,UAAM,QAAkB,CAAC;AACzB,eAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,YAAM,QAAQ,KAAK,MAAM,qBAAqB;AAC9C,UAAI,OAAO;AACT,cAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,YAAI,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG;AACzC,gBAAM,KAAK,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,UAAM,kBAAkB,gBAAgB,MAAM,KAAK,IAAI,CAAC,EAAE;AAC1D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAKA,eAAe,qBAAqB,KAAgC;AAElE,MAAI;AACF,UAAM,SAAS,MAAM,WAAW,wBAAwB,GAAG,IAAI;AAC/D,UAAM,QAAQ,iBAAiB,MAAM;AACrC,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,kBAAkB,qBAAqB,MAAM,KAAK,IAAI,CAAC,EAAE;AAC/D,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAAqB;AAG7B,MAAI;AACF,UAAM,SAAS,MAAM,WAAW,qCAAqC,GAAG,IAAI;AAC5E,UAAM,QAAQ,iBAAiB,MAAM;AACrC,UAAM,kBAAkB,0BAA0B,MAAM,KAAK,IAAI,CAAC,EAAE;AACpE,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAKA,eAAe,uBAAuB,KAAgC;AAEpE,MAAI;AACF,UAAM,SAAS,MAAM,WAAW,cAAc;AAC9C,UAAM,QAAkB,CAAC;AACzB,eAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,UAAI,CAAC,KAAK,SAAS,WAAW,EAAG;AACjC,YAAM,QAAQ,KAAK,KAAK,EAAE,MAAM,KAAK;AACrC,YAAM,UAAU,SAAS,MAAM,MAAM,SAAS,CAAC,GAAG,EAAE;AACpD,UAAI,YAAY,KAAK;AACnB,cAAM,YAAY,MAAM,CAAC;AACzB,cAAM,YAAY,UAAU,MAAM,SAAS;AAC3C,YAAI,WAAW;AACb,gBAAM,OAAO,SAAS,UAAU,CAAC,GAAG,EAAE;AACtC,cAAI,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG;AACzC,kBAAM,KAAK,IAAI;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,kBAAkB,4BAA4B,MAAM,KAAK,IAAI,CAAC,EAAE;AACtE,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAAqB;AAG7B,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB,4DAA4D,GAAG;AAAA,IACjE;AACA,UAAM,QAAkB,CAAC;AACzB,eAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,YAAM,QAAQ,KAAK,MAAM,eAAe;AACxC,UAAI,OAAO;AACT,cAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,YAAI,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG;AACzC,gBAAM,KAAK,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,kBAAkB,+BAA+B,MAAM,KAAK,IAAI,CAAC,EAAE;AACzE,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAAqB;AAI7B,QAAM,kBAAkB,mDAAmD;AAC3E,SAAO,CAAC;AACV;AAKA,SAAS,iBAAiB,QAA0B;AAClD,QAAM,QAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,UAAM,QAAQ,KAAK,MAAM,UAAU;AACnC,QAAI,OAAO;AACT,YAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,UAAI,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG;AACzC,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAMA,eAAsB,cACpB,YAAoB,KACpB,UAAkB,MACC;AACnB,QAAM,kBAAkB,uBAAuB,SAAS,IAAI,OAAO,EAAE;AACrE,QAAM,aAAuB,CAAC;AAG9B,MAAI,UAAU,GAAG;AACf,UAAM,SAAS,MAAM,WAAW,cAAc;AAC9C,eAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,UAAI,CAAC,KAAK,SAAS,WAAW,EAAG;AACjC,YAAM,QAAQ,KAAK,KAAK,EAAE,MAAM,KAAK;AACrC,YAAM,YAAY,MAAM,CAAC;AACzB,YAAM,YAAY,UAAU,MAAM,SAAS;AAC3C,UAAI,WAAW;AACb,cAAM,OAAO,SAAS,UAAU,CAAC,GAAG,EAAE;AACtC,YAAI,QAAQ,aAAa,QAAQ,SAAS;AACxC,qBAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,MAAM,QAAQ,IAChB,gCACA;AACJ,UAAM,SAAS,MAAM,WAAW,GAAG;AACnC,eAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,YAAM,QAAQ,KAAK,MAAM,UAAU;AACnC,UAAI,OAAO;AACT,cAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,YAAI,QAAQ,aAAa,QAAQ,WAAW,CAAC,WAAW,SAAS,IAAI,GAAG;AACtE,qBAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,kBAAkB,SAAS,WAAW,MAAM,iBAAiB;AACnE,SAAO;AACT;;;ACtLA,OAAO,WAAW;AAClB,OAAO,UAAU;AAiDjB,IAAM,YAAY;AAAA,EAChB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,SAAS;AAAA,EACT,iBAAiB;AACnB;AAEO,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAiB,WAAoB;AAC/C,SAAK,UAAU;AACf,SAAK,YAAY;AACjB,SAAK,UAAU,QAAQ,WAAW,UAAU;AAC5C,UAAM,kBAAkB,SAAS,OAAO,eAAe,CAAC,CAAC,SAAS,EAAE;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAA0B;AAC9B,QAAI;AACF,YAAM,KAAK,QAAQ,QAAQ,UAAU,SAAS,CAAC,CAAC;AAChD,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAA0D;AAC9D,UAAM,kBAAkB,mCAAmC;AAC3D,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,UAAU,cAAc;AAAA,QAClE,UAAU;AAAA,UACR,SAAS;AAAA,UACT,eAAe;AAAA,UACf,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AACD,UAAI,UAAU;AACZ,eAAO,KAAK,kBAAkB,QAAQ;AAAA,MACxC;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,kBAAkB,wBAAwB,GAAG,EAAE;AAAA,IACvD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAqD;AACzD,UAAM,kBAAkB,wBAAwB;AAChD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,UAAU,YAAY;AAAA,QAChE,UAAU;AAAA,UACR,SAAS;AAAA,UACT,eAAe;AAAA,UACf,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AACD,UAAI,UAAU;AACZ,eAAO,KAAK,gBAAgB,QAAQ;AAAA,MACtC;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,kBAAkB,sBAAsB,GAAG,EAAE;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAsC;AAC1C,UAAM,kBAAkB,oCAAoC;AAC5D,QAAI;AACF,aAAO,MAAM,KAAK,QAAQ,QAAQ,UAAU,cAAc;AAAA,QACxD,UAAU;AAAA,UACR,SAAS;AAAA,UACT,eAAe;AAAA,UACf,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,kBAAkB,wBAAwB,GAAG,EAAE;AACrD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAQ,QAAgB,MAAc,MAAkC;AAC9E,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,MAAM,IAAI,IAAI,MAAM,KAAK,OAAO;AACtC,YAAM,UAAkC;AAAA,QACtC,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,4BAA4B;AAAA,MAC9B;AACA,UAAI,KAAK,WAAW;AAClB,gBAAQ,sBAAsB,IAAI,KAAK;AAAA,MACzC;AAEA,YAAM,UAAU;AAAA,QACd,UAAU,IAAI;AAAA,QACd,MAAM,IAAI;AAAA,QACV,MAAM,IAAI;AAAA,QACV;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,oBAAoB;AAAA,MACtB;AAEA,YAAM,WAAW,KAAK,UAAU,QAAQ;AACxC,YAAM,MAAM,SAAS,QAAQ,SAAS,CAAC,QAAQ;AAC7C,YAAI,OAAO;AACX,YAAI,GAAG,QAAQ,CAAC,UAAkB;AAAE,kBAAQ;AAAA,QAAM,CAAC;AACnD,YAAI,GAAG,OAAO,MAAM;AAClB,cAAI,IAAI,cAAc,IAAI,cAAc,OAAO,IAAI,aAAa,KAAK;AACnE,gBAAI;AACF,sBAAQ,KAAK,MAAM,IAAI,CAAC;AAAA,YAC1B,QAAQ;AACN,sBAAQ,IAAI;AAAA,YACd;AAAA,UACF,WAAW,IAAI,eAAe,KAAK;AACjC,mBAAO,IAAI,MAAM,QAAQ,IAAI,EAAE,CAAC;AAAA,UAClC,OAAO;AACL,mBAAO,IAAI,MAAM,QAAQ,IAAI,UAAU,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;AAAA,UACnE;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AACD,UAAI,GAAG,SAAS,MAAM;AACtB,UAAI,GAAG,WAAW,MAAM;AAAE,YAAI,QAAQ;AAAG,eAAO,IAAI,MAAM,SAAS,CAAC;AAAA,MAAE,CAAC;AACvE,UAAI,KAAM,KAAI,MAAM,KAAK,UAAU,IAAI,CAAC;AACxC,UAAI,IAAI;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,UAAyC;AACjE,UAAM,SAA+B,EAAE,QAAQ,CAAC,GAAG,KAAK,SAAS;AAEjE,QAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;AAC9D,UAAM,OAAO;AAGb,UAAM,aAAa,KAAK;AACxB,UAAM,SAAU,KAAK,UAAU,YAAY;AAE3C,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,aAAO,SAAS,OAAO,IAAI,CAAC,UAA6B;AACvD,cAAM,UAAU,MAAM,QAAQ,MAAM,OAAO,IACvC,MAAM,QAAQ,IAAI,CAAC,OAAoD;AAAA,UACrE,UAAU,OAAO,EAAE,YAAY,EAAE;AAAA,UACjC,aAAa,OAAO,EAAE,eAAe,EAAE;AAAA,UACvC,aAAa,OAAO,EAAE,eAAe,EAAE;AAAA,UACvC,mBAAmB,OAAQ,EAAU,WAAW,sBAAsB,WACjE,EAAU,UAAU,oBACrB,OAAQ,EAAU,sBAAsB,WACrC,EAAU,oBACX;AAAA,UACN,WAAW,OAAO,EAAE,cAAc,WAAW,EAAE,YAAY;AAAA,QAC7D,EAAE,IACF,CAAC;AACL,eAAO;AAAA,UACL,aAAa,OAAO,MAAM,eAAe,EAAE;AAAA,UAC3C;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,kBAAkB,UAAU,OAAO,OAAO,MAAM,4BAA4B;AAClF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,UAAsC;AAC5D,UAAM,SAA4B,EAAE,KAAK,SAAS;AAClD,QAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;AAE9D,UAAM,OAAO;AACb,UAAM,aAAc,KAAK,cAA0C;AAEnE,QAAI,OAAO,WAAW,UAAU,SAAU,QAAO,QAAQ,WAAW;AACpE,QAAI,OAAO,WAAW,oBAAoB,UAAW,QAAO,kBAAkB,WAAW;AACzF,QAAI,OAAO,WAAW,aAAa,SAAU,QAAO,WAAW,WAAW;AAG1E,UAAM,aAAa,WAAW;AAC9B,QAAI,YAAY;AACd,YAAM,YAAY,WAAW;AAC7B,YAAM,WAAW,WAAW;AAC5B,YAAM,UAAU,UAAU;AAC1B,UAAI,OAAO,cAAc,YAAY,OAAO,YAAY,UAAU;AAChE,eAAO,QAAQ;AAAA,UACb,eAAe;AAAA,YACb,MAAM,UAAU;AAAA,YAChB,OAAO;AAAA,YACP,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,cAAc,WAAW;AAC/B,UAAM,qBAAqB,aAAa;AACxC,QAAI,MAAM,QAAQ,kBAAkB,GAAG;AACrC,aAAO,QAAQ,OAAO,SAAS,CAAC;AAChC,aAAO,MAAM,SAAS,mBAAmB,IAAI,CAAC,MAAM;AAClD,cAAM,eAAe,EAAE;AACvB,cAAM,UAAU,OAAO,cAAc,UAAU,WAAW,aAAa,QAAQ;AAC/E,cAAM,YAAY,EAAE;AACpB,cAAM,oBAAoB,OAAO,WAAW,sBAAsB,WAAW,UAAU,oBAAoB;AAC3G,cAAM,YAAY,OAAO,WAAW,cAAc,WAAW,UAAU,YAAY;AAEnF,eAAO;AAAA,UACL;AAAA,UACA,aAAa,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ;AAAA,UACrD,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ;AAAA,UAC/C,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,YACA,kBAAkB,YAAY,IAAI,KAAK,SAAS,EAAE,QAAQ,IAAI,KAAK,IAAI,IAAI;AAAA,UAC7E;AAAA,UACA,aAAa,sBAAsB;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AACF;;;AC3RO,SAAS,kBACd,SACA,OACe;AACf,QAAM,UAAU,0BAA0B,QAAQ,OAAO,MAAM,SAAS;AAExE,SAAO;AAAA,IACL,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,QAAQ;AAAA,IACR;AAAA,IACA,QAAQ,QAAQ,OAAO,IAAI,CAAC,OAAmB;AAAA,MAC7C,aAAa,EAAE;AAAA,MACf,SAAS,EAAE,QAAQ,IAAI,CAAC,OAAoB;AAAA,QAC1C,UAAU,EAAE;AAAA,QACZ,aAAa,EAAE;AAAA,QACf,aAAa,EAAE;AAAA,QACf,mBAAmB,cAAc,EAAE,iBAAiB;AAAA,QACpD,WAAW,EAAE;AAAA,QACb,kBAAkB,EAAE,YAChB,KAAK,IAAI,GAAG,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,KAAK,IAAI,CAAC,IACxD;AAAA,MACN,EAAE;AAAA,IACJ,EAAE;AAAA,EACJ;AACF;AAKO,SAAS,gBAAgB,YAA8C;AAC5E,QAAM,UAAU,gCAAgC;AAEhD,QAAM,WAA0B;AAAA,IAC9B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,QAAQ;AAAA,IACR,OAAO,WAAW;AAAA,IAClB,QAAQ,CAAC;AAAA,EACX;AAGA,MAAI,WAAW,OAAO,eAAe;AACnC,aAAS,gBAAgB,mBAAmB,WAAW,MAAM,aAAa;AAAA,EAC5E;AAGA,MAAI,WAAW,OAAO,QAAQ;AAC5B,UAAM,eAAiC,CAAC;AACxC,UAAM,eAAiC,CAAC;AAExC,eAAW,SAAS,WAAW,MAAM,QAAQ;AAC3C,YAAM,OAAuB;AAAA,QAC3B,OAAO,MAAM,SAAS,MAAM,eAAe,MAAM;AAAA,QACjD,SAAS,MAAM;AAAA,QACf,qBAAqB,MAAM,OAAO;AAAA,QAClC,aAAa,MAAM,eAAgB,MAAM,OAAO,wBAAwB;AAAA,QACxE,WAAW,MAAM,OAAO;AAAA,QACxB,kBAAkB,MAAM,OAAO;AAAA,QAC/B,oBAAoB,mBAAmB,MAAM,SAAS,MAAM,KAAK;AAAA,MACnE;AAEA,UAAI,KAAK,mBAAoB;AAE7B,UAAI,cAAc,MAAM,OAAO,GAAG;AAChC,qBAAa,KAAK,IAAI;AAAA,MACxB,OAAO;AACL,qBAAa,KAAK,IAAI;AAAA,MACxB;AAAA,IACF;AAGA,QAAI,aAAa,SAAS,GAAG;AAC3B,eAAS,OAAO,KAAK,sBAAsB,iBAAiB,YAAY,CAAC;AAAA,IAC3E;AACA,QAAI,aAAa,SAAS,GAAG;AAC3B,eAAS,OAAO,KAAK,sBAAsB,uBAAuB,YAAY,CAAC;AAAA,IACjF;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,mBAAmB,SAAkG;AAC5H,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,OAAO,QAAQ,QAAS,QAAQ;AACtC,MAAI,UAAU,EAAG,QAAO;AACxB,SAAO;AAAA,IACL,WAAW;AAAA,IACX,SAAS;AAAA,IACT,gBAAgB,QAAQ,IAAI,OAAO,QAAQ;AAAA,IAC3C,qBAAqB,QAAQ,IAAI,YAAY,QAAQ;AAAA,EACvD;AACF;AAEA,SAAS,sBAAsB,aAAqB,QAAsC;AAExF,QAAM,YAAY,OAAO,OAAO,CAAC,MAAM,MAAM;AAC3C,UAAM,YAAY,EAAE,uBAAuB;AAC3C,UAAM,gBAAgB,KAAK,uBAAuB;AAClD,WAAO,YAAY,gBAAgB,IAAI;AAAA,EACzC,GAAG,OAAO,CAAC,CAAC;AAEZ,QAAM,SAAsB;AAAA,IAC1B,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa,UAAU,YACnB,aAAa,IAAI,KAAK,UAAU,SAAS,EAAE,mBAAmB,CAAC,KAC/D;AAAA,IACJ,mBAAmB,UAAU,uBAAuB;AAAA,IACpD,WAAW,UAAU;AAAA,IACrB,kBAAkB,UAAU;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS,CAAC,MAAM;AAAA,EAClB;AACF;AAEA,SAAS,cAAc,SAA0B;AAC/C,QAAM,QAAQ,QAAQ,YAAY;AAClC,SAAO,MAAM,SAAS,QAAQ;AAChC;AAEA,SAAS,mBAAmB,SAAiB,OAAyB;AACpE,QAAM,OAAO,GAAG,OAAO,IAAI,SAAS,EAAE,GAAG,YAAY;AACrD,SAAO,KAAK,SAAS,cAAc,KACjC,KAAK,SAAS,YAAY,KAC1B,KAAK,SAAS,YAAY;AAC9B;AAEA,SAAS,cAAc,OAAmC;AACxD,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;;;AC3IO,IAAM,cAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EACP,WAAW;AAAA,EAEpB,MAAM,cAAgC;AACpC,QAAI;AACF,YAAM,YAAY,MAAM,2BAA2B;AACnD,aAAO,UAAU,SAAS;AAAA,IAC5B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,aAAqC;AACzC,UAAM,SAAS,sBAAsB;AAGrC,UAAM,YAAY,MAAM,2BAA2B;AACnD,QAAI,UAAU,WAAW,GAAG;AAC1B,YAAM,IAAI,uBAAuB,SAAS,8BAA8B;AAAA,IAC1E;AAGA,eAAW,QAAQ,WAAW;AAC5B,YAAM,SAAS,cAAc,KAAK,GAAG,KAAK,KAAK,KAAK,GAAG;AAGvD,YAAM,QAAQ,aAAa,KAAK,eAAe,EAAE;AACjD,UAAI,QAAkB,CAAC;AAGvB,YAAM,aAAa,MAAM,IAAI,uBAAuB;AACpD,UAAI,YAAY;AACd,cAAM,UAAU,SAAS,YAAY,EAAE;AACvC,YAAI,CAAC,MAAM,OAAO,GAAG;AACnB,gBAAM,KAAK,OAAO;AAClB,gBAAM,SAAS,iCAAiC,OAAO,EAAE;AAAA,QAC3D;AAAA,MACF;AAGA,YAAM,kBAAkB,MAAM,cAAc,KAAK,GAAG;AACpD,iBAAW,KAAK,iBAAiB;AAC/B,YAAI,CAAC,MAAM,SAAS,CAAC,EAAG,OAAM,KAAK,CAAC;AAAA,MACtC;AAGA,YAAM,YAAY,MAAM,IAAI,YAAY,KAAK,MAAM,IAAI,6BAA6B;AAGpF,iBAAW,QAAQ,OAAO;AACxB,cAAM,QAAQ,MAAM,KAAK,UAAU,MAAM,SAAS;AAClD,YAAI,MAAO,QAAO;AAAA,MACpB;AAAA,IACF;AAGA,UAAM,SAAS,8CAA8C;AAC7D,UAAM,eAAe,MAAM,cAAc,KAAM,IAAI;AACnD,eAAW,QAAQ,cAAc;AAC/B,YAAM,QAAQ,MAAM,KAAK,UAAU,IAAI;AACvC,UAAI,MAAO,QAAO;AAAA,IACpB;AAEA,UAAM,IAAI,uBAAuB,SAAS,uCAAuC;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,UAAU,MAAc,WAAmD;AACvF,eAAW,UAAU,CAAC,SAAS,MAAM,GAAG;AACtC,YAAM,UAAU,GAAG,MAAM,gBAAgB,IAAI;AAC7C,YAAM,SAAS,IAAI,cAAc,SAAS,SAAS;AAGnD,YAAM,YAAY,MAAM,OAAO,MAAM;AACrC,UAAI,CAAC,UAAW;AAEhB,YAAM,SAAS,WAAW,OAAO,EAAE;AAGnC,YAAM,UAAU,MAAM,OAAO,kBAAkB;AAC/C,UAAI,WAAW,QAAQ,OAAO,SAAS,GAAG;AACxC,cAAM,SAAS,MAAM,OAAO,gBAAgB,IAAI;AAChD,cAAM,SAAS,0BAA0B,OAAO,EAAE;AAClD,eAAO,kBAAkB,SAAS,KAAK;AAAA,MACzC;AAGA,YAAM,aAAa,MAAM,OAAO,gBAAgB;AAChD,UAAI,YAAY;AACd,cAAM,SAAS,wBAAwB,OAAO,EAAE;AAChD,eAAO,gBAAgB,UAAU;AAAA,MACnC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;ACnGA,SAAS,QAAAC,aAA+B;AACxC,SAAS,aAAAC,kBAAiB;AAE1B,IAAMC,aAAYD,WAAUD,KAAI;AAEzB,IAAM,YAAN,MAA6C;AAAA,EACzC,OAAO;AAAA,EACP,WAAW;AAAA,EAEZ,aAAkC;AAAA,EAE1C,MAAM,cAAgC;AACpC,UAAM,OAAO,MAAM,cAAc;AACjC,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,aAAqC;AACzC,UAAM,OAAO,2BAA2B;AAExC,UAAM,UAAU,MAAM,cAAc;AACpC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,uBAAuB,OAAO,sBAAsB;AAAA,IAChE;AAGA,UAAM,gBAAgB,MAAM,KAAK,eAAe;AAChD,QAAI,cAAe,QAAO;AAG1B,WAAO,MAAM,KAAK,eAAe,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAgD;AAE5D,UAAM,MAAM,UAAU,IAClB,wFACA;AAEJ,UAAM,SAAS,MAAM,WAAW,GAAG;AACnC,UAAM,OAAO,OAAO,MAAM,IAAI,EAC3B,IAAI,UAAQ;AACX,YAAM,QAAQ,KAAK,MAAM,WAAW;AACpC,aAAO,QAAQ,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI;AAAA,IAC1C,CAAC,EACA,OAAO,OAAK,CAAC,MAAM,CAAC,CAAC;AAExB,eAAW,OAAO,MAAM;AACtB,YAAM,QAAQ,MAAM,cAAc,GAAG;AACrC,iBAAW,QAAQ,OAAO;AACxB,cAAM,QAAQ,MAAM,KAAK,UAAU,IAAI;AACvC,YAAI,MAAO,QAAO;AAAA,MACpB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAe,SAAyC;AACpE,UAAM,OAAO,kBAAkB,OAAO,EAAE;AAExC,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,UAAU,WAAW,MAAM;AAC/B,aAAK,YAAY,KAAK;AACtB,eAAO,IAAI,uBAAuB,OAAO,uBAAuB,CAAC;AAAA,MACnE,GAAG,IAAK;AAER,WAAK,aAAaA,MAAK,SAAS,EAAE,KAAK,EAAE,GAAG,QAAQ,KAAK,UAAU,IAAI,EAAE,CAAC;AAG1E,YAAM,eAAe,YAAY,YAAY;AAC3C,YAAI;AAEF,cAAI,CAAC,KAAK,YAAY,IAAK;AAC3B,gBAAM,QAAQ,MAAM,cAAc,KAAK,WAAW,GAAG;AACrD,qBAAW,QAAQ,OAAO;AACxB,kBAAM,QAAQ,MAAM,KAAK,UAAU,IAAI;AACvC,gBAAI,OAAO;AACT,2BAAa,OAAO;AACpB,4BAAc,YAAY;AAC1B,mBAAK,YAAY,KAAK;AACtB,sBAAQ,KAAK;AACb;AAAA,YACF;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAAoB;AAAA,MAC9B,GAAG,GAAI;AAEP,WAAK,WAAW,GAAG,SAAS,CAAC,QAAQ;AACnC,qBAAa,OAAO;AACpB,sBAAc,YAAY;AAC1B,eAAO,IAAI,uBAAuB,OAAO,eAAe,IAAI,OAAO,EAAE,CAAC;AAAA,MACxE,CAAC;AAED,WAAK,WAAW,GAAG,QAAQ,MAAM;AAC/B,qBAAa,OAAO;AACpB,sBAAc,YAAY;AAAA,MAC5B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,UAAU,MAA6C;AACnE,eAAW,UAAU,CAAC,SAAS,MAAM,GAAG;AACtC,YAAM,UAAU,GAAG,MAAM,gBAAgB,IAAI;AAC7C,YAAM,SAAS,IAAI,cAAc,OAAO;AAExC,UAAI;AACF,cAAM,YAAY,MAAM,OAAO,MAAM;AACrC,YAAI,CAAC,UAAW;AAEhB,cAAM,UAAU,MAAM,OAAO,kBAAkB;AAC/C,YAAI,WAAW,QAAQ,OAAO,SAAS,GAAG;AACxC,gBAAM,SAAS,MAAM,OAAO,gBAAgB,IAAI;AAChD,iBAAO,kBAAkB,SAAS,KAAK;AAAA,QACzC;AAEA,cAAM,aAAa,MAAM,OAAO,gBAAgB;AAChD,YAAI,WAAY,QAAO,gBAAgB,UAAU;AAAA,MACnD,QAAQ;AAAA,MAAiB;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,UAAgB;AACd,SAAK,YAAY,KAAK;AACtB,SAAK,aAAa;AAAA,EACpB;AACF;AAKA,eAAe,gBAAwC;AAErD,MAAI,QAAQ,IAAI,sBAAsB;AACpC,WAAO,QAAQ,IAAI;AAAA,EACrB;AAGA,MAAI;AACF,UAAM,MAAM,UAAU,IAAI,cAAc;AACxC,UAAM,SAAS,MAAME,WAAU,GAAG;AAClC,UAAM,OAAO,OAAO,OAAO,KAAK;AAChC,QAAI,KAAM,QAAO;AAAA,EACnB,QAAQ;AAAA,EAAoB;AAG5B,QAAM,cAAc,UAAU,IAC1B;AAAA,IACE,GAAG,QAAQ,IAAI,gBAAgB,EAAE;AAAA,IACjC,GAAG,QAAQ,IAAI,gBAAgB,EAAE;AAAA,EACnC,IACA;AAAA,IACE,GAAG,QAAQ,IAAI,IAAI;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AAEJ,aAAW,KAAK,aAAa;AAC3B,QAAI,CAAC,EAAG;AACR,QAAI;AACF,YAAMA,WAAU,YAAY,CAAC,GAAG;AAChC,aAAO;AAAA,IACT,QAAQ;AAAA,IAAkB;AAAA,EAC5B;AAEA,SAAO;AACT;;;AChLO,IAAM,cAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EACP,WAAW;AAAA,EAEZ;AAAA,EAER,YAAY,QAAqB;AAC/B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,cAAgC;AACpC,QAAI;AACF,YAAM,KAAK,OAAO,eAAe;AACjC,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,aAAqC;AACzC,UAAM,SAAS,mCAAmC;AAElD,QAAI;AAEF,YAAM,aAAa,MAAM,KAAK,OAAO,kBAAkB;AACvD,YAAM,UAAU,KAAK,mBAAmB,UAAU;AAClD,UAAI,WAAW,QAAQ,OAAO,SAAS,GAAG;AAExC,cAAMC,aAAY,MAAM,KAAK,OAAO,gBAAgB;AACpD,cAAM,QAAQ,KAAK,aAAaA,UAAS;AACzC,cAAM,SAAS,6BAA6B;AAC5C,eAAO,kBAAkB,SAAS,KAAK;AAAA,MACzC;AAGA,YAAM,YAAY,MAAM,KAAK,OAAO,gBAAgB;AACpD,YAAM,SAAS,KAAK,kBAAkB,SAAS;AAC/C,UAAI,QAAQ;AACV,cAAM,SAAS,2BAA2B;AAC1C,eAAO,gBAAgB,MAAM;AAAA,MAC/B;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,SAAS,iBAAiB,GAAG,EAAE;AAAA,IACvC;AAEA,UAAM,IAAI,uBAAuB,SAAS,0CAA0C;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,KAA2C;AACpE,QAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AACpD,UAAM,OAAO;AAGb,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO;AAEnC,WAAO;AAAA,MACL,QAAQ,OAAO,IAAI,QAAM;AAAA,QACvB,aAAa,OAAO,EAAE,eAAe,EAAE;AAAA,QACvC,SAAS,MAAM,QAAQ,EAAE,OAAO,IAC5B,EAAE,QAAQ,IAAI,CAAC,OAAgC;AAAA,UAC7C,UAAU,OAAO,EAAE,YAAY,EAAE;AAAA,UACjC,aAAa,OAAO,EAAE,eAAe,EAAE;AAAA,UACvC,aAAa,OAAO,EAAE,eAAe,EAAE;AAAA,UACvC,mBAAmB,OAAQ,EAAU,WAAW,sBAAsB,WACjE,EAAU,UAAU,oBACrB,OAAQ,EAAU,sBAAsB,WACrC,EAAU,oBACX;AAAA,UACN,WAAW,OAAO,EAAE,cAAc,WAAW,EAAE,YAAY;AAAA,QAC7D,EAAE,IACF,CAAC;AAAA,MACP,EAAE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,KAAwC;AAChE,QAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AACpD,WAAO,EAAE,IAAI;AAAA,EACf;AAAA,EAEQ,aAAa,KAAkC;AACrD,QAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AACpD,UAAM,OAAO;AACb,UAAM,aAAa,KAAK;AACxB,WAAQ,YAAY,SAAS,KAAK;AAAA,EACpC;AACF;;;ACxFO,IAAM,iBAAN,MAAqB;AAAA,EAClB,UAA+B,CAAC;AAAA,EAChC,SAAqE,oBAAI,IAAI;AAAA,EAErF,cAAc;AAEZ,SAAK,QAAQ,KAAK,IAAI,YAAY,CAAC;AACnC,SAAK,QAAQ,KAAK,IAAI,UAAU,CAAC;AAAA,EAEnC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,QAAiC;AAEzC,UAAM,MAAM,KAAK,QAAQ,UAAU,OAAK,EAAE,WAAW,OAAO,QAAQ;AACpE,QAAI,QAAQ,IAAI;AACd,WAAK,QAAQ,KAAK,MAAM;AAAA,IAC1B,OAAO;AACL,WAAK,QAAQ,OAAO,KAAK,GAAG,MAAM;AAAA,IACpC;AACA,UAAM,YAAY,sBAAsB,OAAO,IAAI,cAAc,OAAO,QAAQ,GAAG;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,MAAwB;AACnC,SAAK,UAAU,KAAK,QAAQ,OAAO,OAAK,EAAE,SAAS,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,iBAAsD;AAErE,QAAI,iBAAiB;AACnB,YAAM,SAAS,KAAK,QAAQ,KAAK,OAAK,EAAE,SAAS,eAAe;AAChE,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,WAAW,eAAe,kBAAkB;AACzE,YAAM,WAAW,MAAM,OAAO,WAAW;AACzC,WAAK,OAAO,IAAI,iBAAiB,EAAE,WAAW,MAAM,WAAW,KAAK,IAAI,EAAE,CAAC;AAC3E,aAAO;AAAA,IACT;AAGA,UAAM,SAAmB,CAAC;AAE1B,eAAW,UAAU,KAAK,SAAS;AACjC,YAAM,YAAY,kBAAkB,OAAO,IAAI,EAAE;AAEjD,UAAI;AACF,cAAM,YAAY,MAAM,OAAO,YAAY;AAC3C,YAAI,CAAC,WAAW;AACd,gBAAM,YAAY,UAAU,OAAO,IAAI,gBAAgB;AACvD,eAAK,OAAO,IAAI,OAAO,MAAM,EAAE,WAAW,OAAO,WAAW,KAAK,IAAI,EAAE,CAAC;AACxE;AAAA,QACF;AAEA,cAAM,WAAW,MAAM,OAAO,WAAW;AACzC,aAAK,OAAO,IAAI,OAAO,MAAM,EAAE,WAAW,MAAM,WAAW,KAAK,IAAI,EAAE,CAAC;AACvE,cAAM,YAAY,wBAAwB,OAAO,IAAI,EAAE;AACvD,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO,KAAK,GAAG,OAAO,IAAI,KAAK,GAAG,EAAE;AACpC,aAAK,OAAO,IAAI,OAAO,MAAM,EAAE,WAAW,OAAO,WAAW,KAAK,IAAI,EAAE,CAAC;AACxE,cAAM,YAAY,UAAU,OAAO,IAAI,YAAY,GAAG,EAAE;AAAA,MAC1D;AAAA,IACF;AAEA,UAAM,IAAI,uBAAuB,OAAO;AAAA,EAA0B,OAAO,IAAI,OAAK,YAAO,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC5G;AAAA;AAAA;AAAA;AAAA,EAKA,YAAwE;AACtE,WAAO,IAAI,IAAI,KAAK,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,iBAA+B;AAC7B,WAAO,KAAK,QAAQ,IAAI,OAAK,EAAE,IAAI;AAAA,EACrC;AACF;;;AC9FO,IAAM,aAAN,MAAiB;AAAA,EACd,QAAiC,oBAAI,IAAI;AAAA,EACzC;AAAA,EAER,YAAY,QAAgB,IAAI,KAAK,KAAM;AACzC,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe,QAAsC;AACvD,UAAM,MAAM,GAAG,KAAK,IAAI,MAAM;AAC9B,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,MAAM,KAAK,IAAI,IAAI,MAAM;AAC/B,QAAI,MAAM,KAAK,OAAO;AACpB,WAAK,MAAM,OAAO,GAAG;AACrB,YAAM,SAAS,qBAAqB,KAAK,UAAU,KAAK,MAAM,MAAM,GAAI,CAAC,IAAI;AAC7E,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,iBAAiB,KAAK,UAAU,KAAK,MAAM,MAAM,GAAI,CAAC,IAAI;AACzE,WAAO,MAAM;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe,QAAgB,UAA+B;AAChE,UAAM,MAAM,GAAG,KAAK,IAAI,MAAM;AAC9B,SAAK,MAAM,IAAI,KAAK;AAAA,MAClB;AAAA,MACA,UAAU,KAAK,IAAI;AAAA,IACrB,CAAC;AACD,UAAM,SAAS,uBAAuB,KAAK,EAAE;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,OAAe,QAAyB;AAC9C,UAAM,MAAM,GAAG,KAAK,IAAI,MAAM;AAC9B,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,CAAC,MAAO,QAAO;AACnB,WAAQ,KAAK,IAAI,IAAI,MAAM,YAAa,KAAK;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,MAAM,MAAM;AACjB,UAAM,SAAS,2BAA2B;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,OAAe,QAA+B;AACrD,UAAM,MAAM,GAAG,KAAK,IAAI,MAAM;AAC9B,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,KAAK,IAAI,IAAI,MAAM;AAAA,EAC5B;AACF;;;AC7EA,OAAO,cAAc;AACrB,SAAS,YAAY;AAKrB,IAAI,KAA+B;AAEnC,SAAS,QAA2B;AAClC,MAAI,GAAI,QAAO;AACf,aAAW;AACX,QAAM,SAAS,KAAK,eAAe,GAAG,YAAY;AAClD,OAAK,IAAI,SAAS,MAAM;AACxB,KAAG,OAAO,oBAAoB;AAC9B,aAAW,EAAE;AACb,QAAM,SAAS,sBAAsB,MAAM,EAAE;AAC7C,SAAO;AACT;AAEA,SAAS,WAAW,UAAmC;AACrD,WAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAeb;AACH;AAKO,SAAS,cAAc,UAA+B;AAC3D,QAAM,WAAW,MAAM;AAGvB,MAAI,eAA8B;AAClC,MAAI,gBAA+B;AACnC,MAAI,eAA8B;AAClC,MAAI,gBAA+B;AAEnC,aAAW,SAAS,SAAS,QAAQ;AACnC,UAAM,QAAQ,MAAM,YAAY,YAAY;AAC5C,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,cAAc,OAAO,YAAY,YAAY;AACnD,UAAI,MAAM,SAAS,QAAQ,GAAG;AAC5B,YAAI,YAAY,SAAS,QAAQ,KAAK,YAAY,SAAS,MAAM,GAAG;AAClE,yBAAe,OAAO;AAAA,QACxB,OAAO;AACL,0BAAgB,OAAO;AAAA,QACzB;AAAA,MACF,WAAW,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,KAAK,GAAG;AAC5D,YAAI,YAAY,SAAS,QAAQ,KAAK,YAAY,SAAS,MAAM,GAAG;AAClE,yBAAe,OAAO;AAAA,QACxB,OAAO;AACL,0BAAgB,OAAO;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,SAAS,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,GAK7B;AAED,OAAK;AAAA,IACH,SAAS;AAAA,IACT,SAAS,SAAS;AAAA,IAClB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,UAAU,QAAQ;AAAA,EACzB;AAEA,QAAM,SAAS,uBAAuB,SAAS,KAAK,EAAE;AACxD;AAKO,SAAS,WACd,OACA,SACe;AACf,QAAM,WAAW,MAAM;AACvB,QAAM,OAAO,SAAS,QAAQ;AAC9B,QAAM,QAAQ,SAAS,SAAS;AAEhC,QAAM,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,KAAK,GAAI,EAAE,YAAY;AAE5E,QAAM,OAAO,SAAS,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAO7B;AAED,QAAM,OAAO,KAAK,IAAI,OAAO,OAAO,KAAK;AAEzC,SAAO,KAAK,IAAI,CAAC,SAAsB;AAAA,IACrC,WAAW,OAAO,IAAI,SAAS;AAAA,IAC/B,OAAO,OAAO,IAAI,KAAK;AAAA,IACvB,uBAAuB,IAAI;AAAA,IAC3B,wBAAwB,IAAI;AAAA,IAC5B,uBAAuB,IAAI;AAAA,IAC3B,wBAAwB,IAAI;AAAA,EAC9B,EAAE;AACJ;AAaO,SAAS,gBAAgB,OAAe,OAAe,GAO3D;AACD,QAAM,WAAW,MAAM;AACvB,QAAM,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,KAAK,GAAI,EAAE,YAAY;AAE5E,QAAM,OAAO,SAAS,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAY7B;AAED,QAAM,OAAO,KAAK,IAAI,OAAO,KAAK;AAElC,SAAO,KAAK,IAAI,UAAQ;AAAA,IACtB,MAAM,OAAO,IAAI,IAAI;AAAA,IACrB,iBAAiB,IAAI;AAAA,IACrB,kBAAkB,IAAI;AAAA,IACtB,iBAAiB,IAAI;AAAA,IACrB,kBAAkB,IAAI;AAAA,IACtB,OAAO,OAAO,IAAI,KAAK;AAAA,EACzB,EAAE;AACJ;AAiBO,SAAS,aAAmB;AACjC,MAAI,IAAI;AACN,OAAG,MAAM;AACT,SAAK;AACL,UAAM,SAAS,iBAAiB;AAAA,EAClC;AACF;;;ACpLO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAyB;AACnC,SAAK,UAAU,SAAS,WAAW;AACnC,eAAW,KAAK,OAAO;AAEvB,UAAM,SAAS,WAAW;AAC1B,SAAK,WAAW,IAAI,eAAe;AACnC,SAAK,QAAQ,IAAI,WAAW,SAAS,cAAc,OAAO,UAAU;AAGpE,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,SAI4B;AAC3C,QAAI,SAAS,aAAa;AACxB,aAAO,KAAK,iBAAiB,OAAO;AAAA,IACtC;AAGA,QAAI,CAAC,SAAS,SAAS;AAAA,IAGvB;AAEA,UAAM,WAAW,MAAM,KAAK,SAAS,WAAW,SAAS,MAAM;AAG/D,QAAI,SAAS,OAAO;AAClB,WAAK,MAAM,IAAI,SAAS,OAAO,SAAS,QAAQ,QAAQ;AACxD,oBAAc,QAAQ;AAAA,IACxB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAiB,SAGF;AAC3B,UAAM,SAAS,oBAAoB;AACnC,UAAM,YAA6B,CAAC;AAGpC,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,SAAS,WAAW,SAAS,MAAM;AAC/D,gBAAU,KAAK,QAAQ;AAAA,IACzB,SAAS,KAAK;AACZ,YAAM,SAAS,gCAAgC,GAAG,EAAE;AAAA,IACtD;AAGA,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAC,MAAM,MAAO;AAElB,UAAI,UAAU,KAAK,OAAK,EAAE,UAAU,MAAM,KAAK,EAAG;AAElD,UAAI;AACF,cAAM,SAAS,IAAI,YAAY,KAAK;AACpC,cAAM,SAAS,IAAI,YAAY,MAAM;AACrC,cAAM,WAAW,MAAM,OAAO,WAAW;AACzC,kBAAU,KAAK,QAAQ;AAAA,MACzB,SAAS,KAAK;AACZ,cAAM,SAAS,uBAAuB,MAAM,KAAK,KAAK,GAAG,EAAE;AAAA,MAC7D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAIH;AACD,UAAM,YAAY,MAAM,KAAK,iBAAiB;AAC9C,UAAM,UAAyC,CAAC;AAChD,UAAM,eAAmE,CAAC;AAE1E,eAAW,YAAY,WAAW;AAChC,UAAI,CAAC,SAAS,MAAO;AACrB,cAAQ,SAAS,KAAK,IAAI,WAAW,SAAS,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,CAAC;AAC3E,mBAAa,SAAS,KAAK,IAAI,gBAAgB,SAAS,OAAO,CAAC;AAAA,IAClE;AAEA,WAAO,EAAE,WAAW,SAAS,aAAa;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAe,MAA8B;AACtD,WAAO,WAAW,OAAO,EAAE,KAAK,CAAC;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,OAAe,MAAe;AAC5C,WAAO,gBAAgB,OAAO,IAAI;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA6B;AACnC,UAAM,SAAS,oBAAoB;AACnC,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAC,MAAM,YAAa;AACxB,UAAI;AACF,cAAM,SAAS,IAAI,YAAY,KAAK;AACpC,cAAM,SAAS,IAAI,YAAY,MAAM;AACrC,aAAK,SAAS,UAAU,MAAM;AAC9B,cAAM,SAAS,+BAA+B,MAAM,KAAK,EAAE;AAAA,MAC7D,SAAS,KAAK;AACZ,cAAM,SAAS,gCAAgC,MAAM,KAAK,KAAK,GAAG,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AACF;;;AC5JA,OAAO,WAAW;AAIlB,IAAM,YAAY;AAKX,SAAS,mBAAmB,UAAiC;AAClE,QAAM,QAAkB,CAAC;AAGzB,QAAM,QAAQ,SAAS,SAAS;AAChC,QAAM,SAAS,SAAS,WAAW,UAAU,cAAO,SAAS,WAAW,UAAU,cAAO;AACzF,QAAM,KAAK,GAAG,MAAM,IAAI,MAAM,KAAK,KAAK,CAAC,EAAE;AAC3C,QAAM,KAAK,EAAE;AAEb,MAAI,SAAS,OAAO,WAAW,GAAG;AAChC,UAAM,KAAK,MAAM,IAAI,2BAA2B,CAAC;AACjD,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAEA,aAAW,SAAS,SAAS,QAAQ;AACnC,UAAM,KAAK,MAAM,KAAK,KAAK,MAAM,WAAW,EAAE,CAAC;AAC/C,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,KAAK,iBAAiB,MAAM,CAAC;AAAA,IACrC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI,EAAE,QAAQ;AAClC;AAKA,SAAS,iBAAiB,QAA6B;AACrD,QAAM,MAAM,KAAK,MAAM,OAAO,oBAAoB,GAAG;AACrD,QAAM,MAAM,kBAAkB,OAAO,iBAAiB;AACtD,QAAM,YAAY,OAAO,mBACrB,MAAM,IAAI,UAAU,gBAAgB,OAAO,gBAAgB,CAAC,EAAE,IAC9D;AAEJ,SAAO,OAAO,GAAG,IAAI,SAAS,GAAG,CAAC,KAAK,SAAS;AAClD;AAKO,SAAS,kBAAkB,UAAkB,QAAgB,WAAmB;AACrF,QAAM,SAAS,KAAK,MAAM,WAAW,KAAK;AAC1C,QAAM,QAAQ,QAAQ;AAEtB,QAAM,UAAU;AAChB,QAAM,YAAY;AAElB,QAAM,QAAQ,cAAc,QAAQ;AACpC,QAAM,YAAY,MAAM,MAAM,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5D,QAAM,WAAW,MAAM,IAAI,MAAM,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,EAAE,CAAC;AAEhE,SAAO,IAAI,SAAS,GAAG,QAAQ;AACjC;AAKA,SAAS,SAAS,KAAqB;AACrC,MAAI,OAAO,GAAI,QAAO,MAAM,MAAM,GAAG,GAAG,GAAG;AAC3C,MAAI,OAAO,GAAI,QAAO,MAAM,OAAO,GAAG,GAAG,GAAG;AAC5C,SAAO,MAAM,IAAI,KAAK,GAAG,GAAG,GAAG;AACjC;AAKO,SAAS,cAAc,UAAsC;AAClE,MAAI,YAAY,IAAK,QAAO,MAAM;AAClC,MAAI,YAAY,IAAK,QAAO,MAAM;AAClC,SAAO,MAAM;AACf;;;AChFA,OAAO,WAAW;AAClB,OAAOC,YAAW;AAOX,SAAS,sBAAsB,WAAoC;AACxE,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAOC,OAAM,IAAI,0BAA0B;AAAA,EAC7C;AAEA,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB,MAAM,CAAC,WAAW,aAAa,eAAe,aAAa,aAAa;AAAA,IACxE,OAAO,EAAE,MAAM,CAAC,QAAQ,QAAQ,QAAQ,QAAQ,MAAM,EAAE;AAAA,IACxD,WAAW,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE;AAAA,EAChC,CAAC;AAED,aAAW,YAAY,WAAW;AAChC,UAAM,QAAQ,SAAS,SAAS;AAChC,UAAM,OAAO,cAAc,QAAQ;AACnC,UAAM,KAAK;AAAA,MACTA,OAAM,KAAK,KAAK;AAAA,MAChB,WAAW,KAAK,eAAe,KAAK,kBAAkB;AAAA,MACtD,WAAW,KAAK,cAAc,KAAK,iBAAiB;AAAA,MACpD,WAAW,KAAK,eAAe,KAAK,kBAAkB;AAAA,MACtD,WAAW,KAAK,cAAc,KAAK,iBAAiB;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,SAAS;AACxB;AAEA,SAAS,cAAc,UAAyB;AAC9C,MAAI,gBAA+B;AACnC,MAAI;AACJ,MAAI,eAA8B;AAClC,MAAI;AACJ,MAAI,gBAA+B;AACnC,MAAI;AACJ,MAAI,eAA8B;AAClC,MAAI;AAEJ,aAAW,SAAS,SAAS,QAAQ;AACnC,UAAM,QAAQ,MAAM,YAAY,YAAY;AAC5C,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,SAAS,OAAO,YAAY,YAAY;AAC9C,YAAM,WAAW,OAAO,SAAS,QAAQ,KAAK,OAAO,SAAS,MAAM;AAEpE,UAAI,MAAM,SAAS,QAAQ,GAAG;AAC5B,YAAI,UAAU;AACZ,yBAAe,OAAO;AACtB,8BAAoB,OAAO;AAAA,QAC7B,OAAO;AACL,0BAAgB,OAAO;AACvB,+BAAqB,OAAO;AAAA,QAC9B;AAAA,MACF,WAAW,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,KAAK,GAAG;AAC5D,YAAI,UAAU;AACZ,yBAAe,OAAO;AACtB,8BAAoB,OAAO;AAAA,QAC7B,OAAO;AACL,0BAAgB,OAAO;AACvB,+BAAqB,OAAO;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IAAe;AAAA,IACf;AAAA,IAAc;AAAA,IACd;AAAA,IAAe;AAAA,IACf;AAAA,IAAc;AAAA,EAChB;AACF;AAEA,SAAS,WAAW,UAAyB,SAA0B;AACrE,MAAI,aAAa,KAAM,QAAOA,OAAM,IAAI,QAAG;AAC3C,QAAM,MAAM,KAAK,MAAM,WAAW,GAAG;AACrC,QAAM,QAAQ,UAAUA,OAAM,IAAI,IAAI,gBAAgB,OAAO,CAAC,EAAE,IAAI;AACpE,MAAI,OAAO,GAAI,QAAOA,OAAM,MAAM,GAAG,GAAG,GAAG,IAAI;AAC/C,MAAI,OAAO,GAAI,QAAOA,OAAM,OAAO,GAAG,GAAG,GAAG,IAAI;AAChD,SAAOA,OAAM,IAAI,KAAK,GAAG,GAAG,GAAG,IAAI;AACrC;;;Ad9EO,SAAS,qBAAqBC,UAAwB;AAC3D,EAAAA,SACG,QAAQ,OAAO,EACf,YAAY,yCAAyC,EACrD,OAAO,aAAa,iCAAiC,EACrD,OAAO,iBAAiB,kCAAkC,EAC1D,OAAO,yBAAyB,sCAAsC,EACtE,OAAO,UAAU,aAAa,EAC9B,OAAO,OAAO,SAAS;AACtB,UAAM,UAAU,IAAI,mBAAmB,EAAE,MAAM;AAE/C,QAAI;AACF,YAAM,SAAS,IAAI,YAAY,EAAE,SAAS,KAAK,QAAQ,CAAC;AAExD,UAAI,KAAK,KAAK;AACZ,cAAM,YAAY,MAAM,OAAO,WAAW,EAAE,aAAa,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ,CAAC;AAC3G,gBAAQ,KAAK;AAEb,YAAI,KAAK,MAAM;AACb,kBAAQ,IAAI,KAAK,UAAU,WAAW,MAAM,CAAC,CAAC;AAAA,QAChD,OAAO;AACL,kBAAQ,IAAI,sBAAsB,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;AAAA,QACvF;AAAA,MACF,OAAO;AACL,cAAM,WAAW,MAAM,OAAO,WAAW,EAAE,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ,CAAC;AACvF,gBAAQ,KAAK;AAEb,YAAI,KAAK,MAAM;AACb,kBAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,QAC/C,OAAO;AACL,kBAAQ,IAAI,mBAAmB,QAAe,CAAC;AAAA,QACjD;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAKC,OAAM,IAAI,0BAA2B,IAAc,OAAO,EAAE,CAAC;AAC1E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;Ae5CA,OAAOC,YAAW;AAClB,OAAOC,UAAS;;;ACChB,OAAOC,YAAW;AAClB,OAAO,WAAW;AAKlB,IAAM,kBAAkB;AAKjB,SAAS,oBACd,WACA,SACQ;AACR,QAAM,OAAM,oBAAI,KAAK,GAAE,mBAAmB;AAC1C,QAAM,QAAkB,CAAC;AAGzB,QAAM,KAAKC,OAAM,KAAK,KAAK,oDAA+C,IAAIA,OAAM,IAAI,KAAK,GAAG,EAAE,CAAC;AACnG,QAAM,KAAK,EAAE;AAEb,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,KAAKA,OAAM,IAAI,iEAAiE,CAAC;AACvF,WAAO,MAAM,MAAM,KAAK,IAAI,GAAG;AAAA,MAC7B,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AAEA,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,UAAM,WAAW,UAAU,CAAC;AAC5B,UAAM,KAAK,qBAAqB,UAAU,QAAQ,SAAS,SAAS,EAAE,CAAC,CAAC;AAExE,QAAI,IAAI,UAAU,SAAS,GAAG;AAC5B,YAAM,KAAKA,OAAM,IAAI,WAAM,OAAO,EAAE,CAAC,CAAC;AAAA,IACxC;AAAA,EACF;AAGA,QAAM,KAAK,EAAE;AACb,QAAM,KAAKA,OAAM,IAAI,aAAa,UAAU,CAAC,GAAG,UAAU,SAAS,EAAE,CAAC;AAEtE,SAAO,MAAM,MAAM,KAAK,IAAI,GAAG;AAAA,IAC7B,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,EAAE;AAAA,IAChD,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,OAAO;AAAA,IACP,gBAAgB;AAAA,EAClB,CAAC;AACH;AAKA,SAAS,qBACP,UACA,gBACQ;AACR,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAQ,SAAS,SAAS;AAChC,QAAM,SAAS,SAAS,WAAW,UAAUA,OAAM,MAAM,QAAG,IAC7C,SAAS,WAAW,UAAUA,OAAM,KAAK,QAAG,IAC5CA,OAAM,OAAO,QAAG;AAG/B,QAAM,KAAK,GAAG,MAAM,IAAIA,OAAM,KAAK,KAAK,CAAC,EAAE;AAE3C,MAAI,SAAS,OAAO,WAAW,GAAG;AAChC,UAAM,KAAKA,OAAM,IAAI,6BAA6B,CAAC;AACnD,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAGA,aAAW,SAAS,SAAS,QAAQ;AACnC,UAAM,KAAK,EAAE;AACb,UAAM,KAAKA,OAAM,UAAU,KAAK,MAAM,WAAW,EAAE,CAAC;AAEpD,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,MAAM,KAAK,MAAM,OAAO,oBAAoB,GAAG;AACrD,YAAM,MAAM,kBAAkB,OAAO,mBAAmB,EAAE;AAC1D,YAAM,YAAY,OAAO,mBACrBA,OAAM,IAAI,UAAU,gBAAgB,OAAO,gBAAgB,CAAC,EAAE,IAC9D;AAEJ,YAAM,UAAU,cAAc,OAAO,iBAAiB;AACtD,YAAM,QAAQ,OAAO,YAAY,SAAS,KACtC,OAAO,YAAY,MAAM,GAAG,EAAE,IAC9B,OAAO,YAAY,OAAO,EAAE;AAEhC,YAAM,KAAK,OAAOA,OAAM,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,QAAQ,IAAI,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,SAAS,EAAE;AAAA,IACnG;AAAA,EACF;AAGA,MAAI,kBAAkB,eAAe,SAAS,GAAG;AAC/C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,OAAOA,OAAM,IAAI,kBAAW,CAAC,IAAI,gBAAgB,cAAc,CAAC,EAAE;AAAA,EAC/E;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAKA,SAAS,gBAAgB,SAAgC;AAEvD,QAAM,SAAS,QACZ,MAAM,CAAC,eAAe,EACtB,IAAI,OAAK;AACR,UAAM,OAAO,CAAC,EAAE,wBAAwB,EAAE,sBAAsB,EAC7D,OAAO,OAAK,MAAM,IAAI;AACzB,WAAO,KAAK,SAAS,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI;AAAA,EAC/C,CAAC;AAEH,MAAI,OAAO,WAAW,EAAG,QAAOA,OAAM,IAAI,SAAS;AAEnD,QAAM,SAAS,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AACtD,SAAO,OAAO,IAAI,OAAK;AACrB,UAAM,MAAM,KAAK,IAAI,KAAK,MAAM,KAAK,OAAO,SAAS,EAAE,GAAG,OAAO,SAAS,CAAC;AAC3E,UAAM,UAAU,cAAc,CAAC;AAC/B,WAAO,QAAQ,OAAO,GAAG,CAAC;AAAA,EAC5B,CAAC,EAAE,KAAK,EAAE;AACZ;AAKO,SAAS,wBACd,WACA,SACQ;AACR,SAAO,KAAK,UAAU;AAAA,IACpB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,UAAU,UAAU,IAAI,QAAM;AAAA,MAC5B,OAAO,EAAE;AAAA,MACT,QAAQ,EAAE;AAAA,MACV,QAAQ,EAAE;AAAA,MACV,eAAe,EAAE;AAAA,MACjB,eAAe,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,EAAE,KAAK,CAAC;AAAA,IAC1D,EAAE;AAAA,EACJ,GAAG,MAAM,CAAC;AACZ;;;ADvIA,eAAsB,qBAAqB,MAKzB;AAChB,QAAM,UAAUC,KAAI,2BAA2B,EAAE,MAAM;AAEvD,MAAI;AACF,UAAM,SAAS,IAAI,YAAY,EAAE,SAAS,KAAK,QAAQ,CAAC;AAExD,QAAI,KAAK,OAAO;AACd,cAAQ,KAAK;AACb,YAAM,aAAa,QAAQ,IAAI;AAC/B;AAAA,IACF;AAEA,UAAM,EAAE,WAAW,QAAQ,IAAI,MAAM,OAAO,iBAAiB;AAC7D,YAAQ,KAAK;AAEb,QAAI,KAAK,MAAM;AACb,cAAQ,IAAI,wBAAwB,WAAW,KAAK,YAAY,CAAC,IAAI,OAAO,CAAC;AAAA,IAC/E,OAAO;AACL,cAAQ,IAAI,oBAAoB,WAAW,KAAK,YAAY,CAAC,IAAI,OAAO,CAAC;AAAA,IAC3E;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAKC,OAAM,IAAI,WAAY,IAAc,OAAO,EAAE,CAAC;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,eAAe,aACb,QACA,MACe;AACf,QAAM,aAAa;AAEnB,QAAM,UAAU,YAAY;AAC1B,QAAI;AACF,YAAM,EAAE,WAAW,QAAQ,IAAI,MAAM,OAAO,iBAAiB;AAE7D,cAAQ,OAAO,MAAM,gBAAgB;AACrC,UAAI,KAAK,MAAM;AACb,gBAAQ,IAAI,wBAAwB,WAAW,KAAK,YAAY,CAAC,IAAI,OAAO,CAAC;AAAA,MAC/E,OAAO;AACL,gBAAQ,IAAI,oBAAoB,WAAW,KAAK,YAAY,CAAC,IAAI,OAAO,CAAC;AAAA,MAC3E;AACA,cAAQ,IAAIA,OAAM,IAAI;AAAA,0BAA6B,aAAa,GAAI,+BAA0B,CAAC;AAAA,IACjG,SAAS,KAAK;AACZ,cAAQ,MAAMA,OAAM,IAAI,kBAAmB,IAAc,OAAO,EAAE,CAAC;AAAA,IACrE;AAAA,EACF;AAEA,QAAM,QAAQ;AACd,cAAY,SAAS,UAAU;AAG/B,QAAM,IAAI,QAAQ,MAAM;AAAA,EAAC,CAAC;AAC5B;;;AE1EA,OAAO,cAAc;AACrB,OAAOC,YAAW;AAClB,OAAOC,YAAW;AAQX,SAAS,wBAAwBC,UAAwB;AAC9D,QAAM,WAAWA,SACd,QAAQ,UAAU,EAClB,YAAY,wBAAwB;AAEvC,WACG,QAAQ,MAAM,EACd,YAAY,2BAA2B,EACvC,OAAO,MAAM;AACZ,UAAMC,YAAW,aAAa;AAC9B,QAAIA,UAAS,WAAW,GAAG;AACzB,cAAQ,IAAIC,OAAM,IAAI,iEAAiE,CAAC;AACxF;AAAA,IACF;AAEA,UAAM,QAAQ,IAAIC,OAAM;AAAA,MACtB,MAAM,CAAC,SAAS,UAAU,OAAO;AAAA,MACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;AAAA,IAC1B,CAAC;AAED,eAAW,QAAQF,WAAU;AAC3B,YAAM,KAAK;AAAA,QACT,KAAK;AAAA,QACL,KAAK,WAAWC,OAAM,MAAM,eAAU,IAAIA,OAAM,IAAI,iBAAY;AAAA,QAChE,IAAI,KAAK,KAAK,OAAO,EAAE,mBAAmB;AAAA,MAC5C,CAAC;AAAA,IACH;AAEA,YAAQ,IAAI,MAAM,SAAS,CAAC;AAAA,EAC9B,CAAC;AAEH,WACG,QAAQ,KAAK,EACb,YAAY,4BAA4B,EACxC,OAAO,YAAY,4DAA4D,EAC/E,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,UAAI,KAAK,QAAQ;AACf,cAAM,EAAE,mBAAAE,oBAAmB,qBAAAC,qBAAoB,IAAI,MAAM,OAAO,qBAA4B;AAC5F,cAAM,MAAMD,mBAAkB;AAC9B,gBAAQ,IAAIF,OAAM,KAAK,oCAAoC,CAAC;AAC5D,gBAAQ,IAAIA,OAAM,KAAK,GAAG,CAAC;AAC3B,gBAAQ,IAAIA,OAAM,IAAI,sCAAsC,CAAC;AAE7D,cAAM,EAAE,KAAK,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,UACtC,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC,CAAC;AAEF,cAAM,QAAQ,MAAMG,qBAAoB,IAAI;AAC5C,gBAAQ,IAAIH,OAAM,MAAM;AAAA,sBAAoB,KAAK,EAAE,CAAC;AAAA,MACtD,OAAO;AACL,cAAM,QAAQ,MAAM,aAAa;AACjC,gBAAQ,IAAIA,OAAM,MAAM;AAAA,sBAAoB,KAAK,EAAE,CAAC;AAAA,MACtD;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAMA,OAAM,IAAI;AAAA,uBAAsB,IAAc,OAAO,EAAE,CAAC;AACtE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,gBAAgB,EACxB,YAAY,wBAAwB,EACpC,OAAO,CAAC,UAAkB;AACzB,QAAI,iBAAiB,KAAK,GAAG;AAC3B,cAAQ,IAAIA,OAAM,MAAM,sBAAiB,KAAK,EAAE,CAAC;AAAA,IACnD,OAAO;AACL,cAAQ,MAAMA,OAAM,IAAI,mBAAc,KAAK,aAAa,CAAC;AACzD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,gBAAgB,EACxB,YAAY,mBAAmB,EAC/B,OAAO,OAAO,UAAkB;AAC/B,UAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,MACzC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,kBAAkB,KAAK;AAAA,MAChC,SAAS;AAAA,IACX,CAAC,CAAC;AAEF,QAAI,SAAS;AACX,UAAI,cAAc,KAAK,GAAG;AACxB,gBAAQ,IAAIA,OAAM,MAAM,kBAAa,KAAK,EAAE,CAAC;AAAA,MAC/C,OAAO;AACL,gBAAQ,MAAMA,OAAM,IAAI,mBAAc,KAAK,aAAa,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF,CAAC;AACL;;;ACvGA,OAAOI,YAAW;;;ACDlB,OAAOC,YAAW;AAIlB,IAAM,eAAe;AACrB,IAAM,cAAc;AAKb,SAAS,mBACd,SACA,QAAgB,kBACR;AACR,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAOC,OAAM,IAAI,6BAA6B;AAAA,EAChD;AAGA,QAAM,SAAS,CAAC,GAAG,OAAO,EAAE;AAAA,IAAK,CAAC,GAAG,MACnC,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ;AAAA,EAClE;AAGA,QAAM,SAAS,OAAO,IAAI,OAAK;AAC7B,QAAI,MAAM,YAAY,EAAE,SAAS,QAAQ,GAAG;AAC1C,UAAI,MAAM,YAAY,EAAE,SAAS,QAAQ,EAAG,QAAO,EAAE;AACrD,aAAO,EAAE;AAAA,IACX,OAAO;AACL,UAAI,MAAM,YAAY,EAAE,SAAS,QAAQ,EAAG,QAAO,EAAE;AACrD,aAAO,EAAE;AAAA,IACX;AAAA,EACF,CAAC,EAAE,OAAO,OAAK,MAAM,IAAI;AAEzB,MAAI,OAAO,WAAW,GAAG;AACvB,WAAOA,OAAM,IAAI,QAAQ,KAAK,iBAAiB;AAAA,EACjD;AAGA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAKA,OAAM,KAAK,eAAQ,KAAK,gBAAW,OAAO,MAAM,WAAW,CAAC;AACvE,QAAM,KAAK,EAAE;AAGb,QAAM,UAAU,WAAW,QAAQ,WAAW;AAG9C,WAAS,MAAM,cAAc,OAAO,GAAG,OAAO;AAC5C,UAAM,YAAY,MAAM;AACxB,UAAM,SAAS,QAAQ;AAEvB,QAAI,OAAO,SAASA,OAAM,IAAI,OAAO,IAAIA,OAAM,IAAI,OAAO;AAC1D,eAAW,OAAO,SAAS;AACzB,UAAI,OAAO,WAAW;AACpB,gBAAQ,cAAc,GAAG,EAAE,QAAG;AAAA,MAChC,OAAO;AACL,gBAAQA,OAAM,IAAI,MAAG;AAAA,MACvB;AAAA,IACF;AACA,QAAI,QAAQ,aAAc,SAAQA,OAAM,IAAI,OAAO;AACnD,UAAM,KAAK,IAAI;AAAA,EACjB;AAGA,MAAI,OAAO,UAAU,GAAG;AACtB,UAAM,QAAQ,IAAI,KAAK,OAAO,CAAC,EAAE,SAAS;AAC1C,UAAM,OAAO,IAAI,KAAK,OAAO,OAAO,SAAS,CAAC,EAAE,SAAS;AACzD,UAAM,KAAKA,OAAM;AAAA,MACf,UAAU,WAAW,KAAK,CAAC,GAAG,IAAI,OAAO,KAAK,IAAI,GAAG,cAAc,EAAE,CAAC,CAAC,GAAG,WAAW,IAAI,CAAC;AAAA,IAC5F,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAKO,SAAS,sBACd,gBACA,QACQ;AACR,QAAM,QAAkB,CAAC;AACzB,QAAM,SAAS,OAAO,KAAK,cAAc;AAEzC,QAAM,KAAKA,OAAM,KAAK,+CAAmC,YAAY,MAAM,CAAC,EAAE,CAAC;AAC/E,QAAM,KAAK,EAAE;AAEb,QAAM,cAAc,KAAK,IAAI,GAAG,OAAO,IAAI,OAAK,EAAE,MAAM,GAAG,CAAC;AAE5D,aAAW,SAAS,QAAQ;AAC1B,UAAM,UAAU,eAAe,KAAK;AACpC,UAAM,SAAS,QAAQ,CAAC;AACxB,QAAI,CAAC,OAAQ;AAEb,QAAI,QAAuB;AAC3B,YAAQ,QAAQ;AAAA,MACd,KAAK;AAAiB,gBAAQ,OAAO;AAAwB;AAAA,MAC7D,KAAK;AAAiB,gBAAQ,OAAO;AAAwB;AAAA,MAC7D,KAAK;AAAgB,gBAAQ,OAAO;AAAuB;AAAA,MAC3D,KAAK;AAAgB,gBAAQ,OAAO;AAAuB;AAAA,IAC7D;AAEA,UAAM,QAAQ,MAAM,MAAM,GAAG,WAAW,EAAE,OAAO,WAAW;AAC5D,UAAM,MAAM,UAAU,OAAO,KAAK,MAAM,QAAQ,GAAG,IAAI;AACvD,UAAM,MAAM,UAAU,OAClB,cAAc,OAAO,EAAE,IACvBA,OAAM,IAAI,SAAI,OAAO,EAAE,CAAC;AAC5B,UAAM,SAAS,OAAO,IAAI,GAAG,GAAG,MAAM;AAEtC,UAAM,KAAK,OAAOA,OAAM,IAAI,KAAK,CAAC,KAAK,GAAG,IAAI,MAAM,EAAE;AAAA,EACxD;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAIA,SAAS,cAAc,UAAkB,OAAuB;AAC9D,QAAM,SAAS,KAAK,MAAM,WAAW,KAAK;AAC1C,QAAM,UAAU,cAAc,QAAQ;AACtC,SAAO,QAAQ,SAAI,OAAO,MAAM,CAAC,IAAIA,OAAM,IAAI,SAAI,OAAO,QAAQ,MAAM,CAAC;AAC3E;AAEA,SAAS,WAAW,QAAkB,aAA+B;AACnE,MAAI,OAAO,UAAU,YAAa,QAAO;AACzC,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,OAAO,SAAS;AAC7B,WAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAM,MAAM,KAAK,MAAM,IAAI,IAAI;AAC/B,WAAO,KAAK,OAAO,KAAK,IAAI,KAAK,OAAO,SAAS,CAAC,CAAC,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAAoB;AACtC,SAAO,GAAG,KAAK,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AACxG;AAEA,SAAS,YAAY,QAAwB;AAC3C,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAiB,aAAO;AAAA,IAC7B,KAAK;AAAiB,aAAO;AAAA,IAC7B,KAAK;AAAgB,aAAO;AAAA,IAC5B,KAAK;AAAgB,aAAO;AAAA,IAC5B;AAAS,aAAO;AAAA,EAClB;AACF;;;AD5IO,SAAS,uBAAuBC,UAAwB;AAC7D,EAAAA,SACG,QAAQ,SAAS,EACjB,YAAY,+BAA+B,EAC3C,OAAO,uBAAuB,yCAAyC,EACvE,OAAO,qBAAqB,0BAA0B,GAAG,EACzD,OAAO,mBAAmB,+BAA+B,KAAK,EAC9D,OAAO,UAAU,aAAa,EAC9B,OAAO,aAAa,sBAAsB,EAC1C,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,YAAM,SAAS,IAAI,YAAY,EAAE,SAAS,KAAK,QAAQ,CAAC;AAGxD,YAAM,QAAQ,KAAK,SAAS,eAAe;AAC3C,UAAI,CAAC,OAAO;AACV,gBAAQ,IAAIC,OAAM,IAAI,4DAA4D,CAAC;AACnF;AAAA,MACF;AAEA,YAAM,OAAO,SAAS,KAAK,MAAM,EAAE;AACnC,YAAM,UAAU,OAAO,WAAW,OAAO,IAAI;AAC7C,YAAM,UAAU,OAAO,gBAAgB,OAAO,IAAI;AAElD,UAAI,KAAK,MAAM;AACb,gBAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,MAAM,SAAS,QAAQ,GAAG,MAAM,CAAC,CAAC;AACtE;AAAA,MACF;AAEA,UAAI,KAAK,SAAS;AAChB,cAAM,cAAc,aAAa;AACjC,cAAM,aAAoC,CAAC;AAC3C,mBAAW,QAAQ,aAAa;AAC9B,qBAAW,KAAK,KAAK,IAAI,OAAO,WAAW,KAAK,OAAO,IAAI;AAAA,QAC7D;AACA,gBAAQ,IAAI,sBAAsB,YAAY,eAAe,CAAC;AAC9D,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,sBAAsB,YAAY,eAAe,CAAC;AAC9D;AAAA,MACF;AAGA,cAAQ,IAAIA,OAAM,KAAK;AAAA,mCAA0B,KAAK,UAAU,IAAI;AAAA,CAAU,CAAC;AAE/E,UAAI,KAAK,UAAU,SAAS,KAAK,UAAU,UAAU;AACnD,gBAAQ,IAAI,mBAAmB,SAAS,yBAAyB,CAAC;AAClE,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,mBAAmB,SAAS,eAAe,CAAC;AACxD,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAEA,UAAI,KAAK,UAAU,SAAS,KAAK,UAAU,UAAU;AACnD,gBAAQ,IAAI,mBAAmB,SAAS,+BAA+B,CAAC;AACxE,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,mBAAmB,SAAS,qBAAqB,CAAC;AAC9D,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAGA,UAAI,QAAQ,SAAS,GAAG;AACtB,gBAAQ,IAAIA,OAAM,KAAK,2BAAoB,CAAC;AAC5C,mBAAW,OAAO,SAAS;AACzB,gBAAM,SAAS,IAAI,qBAAqB,OAAO,GAAG,KAAK,MAAM,IAAI,mBAAoB,GAAG,CAAC,MAAM;AAC/F,gBAAM,SAAS,IAAI,qBAAqB,OAAO,GAAG,KAAK,MAAM,IAAI,mBAAoB,GAAG,CAAC,MAAM;AAC/F,kBAAQ,IAAIA,OAAM,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,WAAW,MAAM,aAAa,MAAM,MAAM,IAAI,KAAK,YAAY;AAAA,QAC9G;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAMA,OAAM,IAAI,UAAW,IAAc,OAAO,EAAE,CAAC;AAC3D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;AAEA,SAAS,iBAAgC;AACvC,QAAM,WAAW,aAAa;AAC9B,QAAM,SAAS,SAAS,KAAK,OAAK,EAAE,QAAQ;AAC5C,SAAO,QAAQ,SAAS;AAC1B;;;AEpFA,OAAOC,YAAW;AAQX,SAAS,sBAAsBC,UAAwB;AAC5D,EAAAA,SACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,OAAO,YAAY;AAClB,YAAQ,IAAIC,OAAM,KAAK,KAAK,gDAA2C,CAAC;AAExE,UAAM,SAAoF,CAAC;AAG3F,UAAM,WAAW,QAAQ,IAAI,UAAU,QAAQ,IAAI,UAAU,UAAU,IAAI,YAAY,QAAQ;AAC/F,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AAGD,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,QAAQ,WAAW,QAAQ,OAAO;AAAA,MAC1C,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAGD,QAAI;AACF,YAAM,YAAY,iBAAiB;AACnC,aAAO,KAAK,EAAE,OAAO,oBAAoB,QAAQ,MAAM,QAAQ,UAAU,CAAC;AAAA,IAC5E,SAAS,KAAK;AACZ,aAAO,KAAK,EAAE,OAAO,oBAAoB,QAAQ,SAAS,QAAS,IAAc,QAAQ,CAAC;AAAA,IAC5F;AAGA,UAAM,SAAS,WAAW;AAC1B,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ,QAAQ,OAAO,WAAW,WAAW,OAAO,aAAa,GAAI;AAAA,IACvE,CAAC;AAGD,UAAM,WAAW,aAAa;AAC9B,QAAI,SAAS,SAAS,GAAG;AACvB,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ,GAAG,SAAS,MAAM,gBAAgB,SAAS,KAAK,OAAK,EAAE,QAAQ,GAAG,SAAS,aAAa;AAAA,MAClG,CAAC;AAAA,IACH,OAAO;AACL,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,UAAM,SAAS,uBAAuB;AACtC,QAAI,QAAQ;AACV,YAAM,UAAU,KAAK,IAAI,MAAM,OAAO,aAAa;AACnD,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,QAAQ,UAAU,SAAS;AAAA,QAC3B,QAAQ,UAAU,wCAAwC;AAAA,MAC5D,CAAC;AAAA,IACH;AAGA,QAAI;AACF,YAAM,YAAY,MAAM,2BAA2B;AACnD,UAAI,UAAU,SAAS,GAAG;AACxB,eAAO,KAAK;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,QAAQ,SAAS,UAAU,MAAM,iBAAiB,UAAU,IAAI,OAAK,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,QAC9G,CAAC;AAAA,MACH,OAAO;AACL,eAAO,KAAK;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAS,IAAc;AAAA,MACzB,CAAC;AAAA,IACH;AAGA,QAAI;AACF,YAAM,SAAS,IAAI,YAAY;AAC/B,YAAM,WAAW,MAAM,OAAO,WAAW;AACzC,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ,WAAW,SAAS,MAAM,YAAY,SAAS,SAAS,SAAS,aAAa,SAAS,OAAO,MAAM;AAAA,MAC9G,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAS,IAAc;AAAA,MACzB,CAAC;AAAA,IACH;AAGA,eAAW,SAAS,QAAQ;AAC1B,YAAM,OAAO,MAAM,WAAW,OAAOA,OAAM,MAAM,QAAG,IACvC,MAAM,WAAW,SAASA,OAAM,OAAO,QAAG,IAC1CA,OAAM,IAAI,QAAG;AAC1B,YAAM,QAAQA,OAAM,KAAK,MAAM,MAAM,OAAO,EAAE,CAAC;AAC/C,cAAQ,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,MAAM,MAAM,EAAE;AAAA,IAClD;AAEA,YAAQ,IAAI,EAAE;AAGd,UAAM,SAAS,OAAO,OAAO,OAAK,EAAE,WAAW,OAAO,EAAE;AACxD,UAAM,WAAW,OAAO,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AACzD,QAAI,WAAW,KAAK,aAAa,GAAG;AAClC,cAAQ,IAAIA,OAAM,MAAM,KAAK,iCAA4B,CAAC;AAAA,IAC5D,OAAO;AACL,cAAQ,IAAIA,OAAM,OAAO,KAAK,MAAM,cAAc,QAAQ,aAAa,CAAC;AAAA,IAC1E;AACA,YAAQ,IAAI,EAAE;AAEd,eAAW;AAAA,EACb,CAAC;AACL;;;AC3IA,OAAOC,aAAW;AAIX,SAAS,sBAAsBC,UAAwB;AAC5D,QAAM,SAASA,SACZ,QAAQ,QAAQ,EAChB,YAAY,iBAAiB;AAEhC,SACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,OAAO,MAAM;AACZ,UAAM,MAAM,WAAW;AACvB,YAAQ,IAAIC,QAAM,KAAK,6BAA6B,CAAC;AACrD,YAAQ,IAAI,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC;AACxC,YAAQ,IAAIA,QAAM,IAAI;AAAA,iBAAoB,iBAAiB,CAAC,cAAc,CAAC;AAAA,EAC7E,CAAC;AAEH,SACG,QAAQ,mBAAmB,EAC3B,YAAY,oBAAoB,EAChC,OAAO,CAAC,KAAa,UAAkB;AACtC,UAAM,MAAM,WAAW;AACvB,UAAM,OAAO,IAAI,MAAM,GAAG;AAC1B,QAAI,SAAc;AAClB,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;AACxC,UAAI,EAAE,KAAK,CAAC,KAAK,SAAS;AACxB,eAAO,KAAK,CAAC,CAAC,IAAI,CAAC;AAAA,MACrB;AACA,eAAS,OAAO,KAAK,CAAC,CAAC;AAAA,IACzB;AAGA,QAAI,UAAU,OAAQ,SAAQ;AAAA,aACrB,UAAU,QAAS,SAAQ;AAAA,aAC3B,CAAC,MAAM,OAAO,KAAK,CAAC,EAAG,SAAQ,OAAO,KAAK;AAEpD,WAAO,KAAK,KAAK,SAAS,CAAC,CAAC,IAAI;AAChC,eAAW,GAAgB;AAC3B,YAAQ,IAAIA,QAAM,MAAM,cAAS,GAAG,MAAM,KAAK,EAAE,CAAC;AAAA,EACpD,CAAC;AAEH,SACG,QAAQ,WAAW,EACnB,YAAY,oBAAoB,EAChC,OAAO,CAAC,QAAgB;AACvB,UAAM,MAAM,WAAW;AACvB,UAAM,OAAO,IAAI,MAAM,GAAG;AAC1B,QAAI,SAAS;AACb,eAAW,KAAK,MAAM;AACpB,UAAI,WAAW,UAAa,WAAW,KAAM;AAC7C,eAAS,OAAO,CAAC;AAAA,IACnB;AACA,YAAQ,IAAI,WAAW,SAAY,OAAO,MAAM,IAAIA,QAAM,IAAI,SAAS,CAAC;AAAA,EAC1E,CAAC;AAEH,SACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,OAAO,MAAM;AACZ,YAAQ,IAAI,iBAAiB,CAAC;AAAA,EAChC,CAAC;AACL;;;AC7DA,OAAOC,aAAW;AAClB,SAAS,gBAAgB;AACzB,SAAqB,qBAAmC;AACxD,SAAS,QAAAC,aAAY;AACrB,SAAS,eAAe;AAGxB,OAAOC,eAAc;AAGrB,IAAM,cAAc;AACpB,IAAM,YAAY;AAEX,SAAS,sBAAsBC,UAAwB;AAC5D,QAAM,SAASA,SACZ,QAAQ,QAAQ,EAChB,YAAY,qDAAqD;AAEpE,SACG,QAAQ,QAAQ,EAChB,YAAY,0BAA0B,EACtC,OAAO,YAAY;AAClB,YAAQ,IAAIC,QAAM,KAAK,KAAK,4BAA4B,CAAC;AAEzD,UAAM,SAAS,WAAW;AAE1B,UAAM,UAAU,MAAMF,UAAS,OAAO;AAAA,MACpC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,MAAM,kEAA6D,OAAO,QAAQ;AAAA,UACpF,EAAE,MAAM,yCAAoC,OAAO,WAAW;AAAA,UAC9D,EAAE,MAAM,0CAAqC,OAAO,QAAQ;AAAA,QAC9D;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,MAAM,CAAC,MAAM,EAAE,SAAS;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,MAAM,CAAC,MAAM,EAAE,SAAS;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAGD,WAAO,iBAAiB,QAAQ,cAAc,CAAC,IAAI,CAAC;AACpD,eAAW,MAAM;AAEjB,YAAQ,IAAIE,QAAM,MAAM,gCAA2B,CAAC;AACpD,YAAQ,IAAIA,QAAM,IAAI,yCAAyC,CAAC;AAAA,EAClE,CAAC;AAEH,SACG,QAAQ,SAAS,EACjB,YAAY,oCAAoC,EAChD,OAAO,YAAY;AAClB,QAAI;AACF,UAAI,UAAU,GAAG;AACf,2BAAmB;AAAA,MACrB,OAAO;AACL,uBAAe;AAAA,MACjB;AACA,cAAQ,IAAIA,QAAM,MAAM,iDAA4C,CAAC;AAAA,IACvE,SAAS,KAAK;AACZ,cAAQ,MAAMA,QAAM,IAAI;AAAA,mBAAkB,IAAc,OAAO,EAAE,CAAC;AAAA,IACpE;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,WAAW,EACnB,YAAY,qCAAqC,EACjD,OAAO,MAAM;AACZ,QAAI;AACF,UAAI,UAAU,GAAG;AACf,6BAAqB;AAAA,MACvB,OAAO;AACL,yBAAiB;AAAA,MACnB;AACA,cAAQ,IAAIA,QAAM,MAAM,iDAA4C,CAAC;AAAA,IACvE,SAAS,KAAK;AACZ,cAAQ,MAAMA,QAAM,IAAI;AAAA,mBAAkB,IAAc,OAAO,EAAE,CAAC;AAAA,IACpE;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,QAAQ,EAChB,YAAY,qBAAqB,EACjC,OAAO,MAAM;AACZ,UAAM,SAAS,WAAW;AAC1B,YAAQ,IAAIA,QAAM,KAAK,qBAAqB,CAAC;AAC7C,YAAQ,IAAI,aAAa,OAAO,aAAa,KAAK,IAAI,CAAC,EAAE;AACzD,YAAQ,IAAI,eAAe,OAAO,eAAe,SAAS,IAAI,OAAO,eAAe,KAAK,IAAI,IAAI,KAAK,EAAE;AAExG,QAAI,UAAU,GAAG;AACf,YAAM,YAAY,iBAAiB;AACnC,cAAQ,IAAI,gBAAgB,YAAYA,QAAM,MAAM,WAAW,IAAIA,QAAM,IAAI,eAAe,CAAC,EAAE;AAAA,IACjG,OAAO;AACL,YAAM,YAAY,aAAa;AAC/B,cAAQ,IAAI,WAAW,YAAYA,QAAM,MAAM,WAAW,IAAIA,QAAM,IAAI,eAAe,CAAC,EAAE;AAAA,IAC5F;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,MAAM,EACd,YAAY,8BAA8B,EAC1C,OAAO,uBAAuB,eAAe,EAC7C,OAAO,uBAAuB,eAAe,EAC7C,OAAO,yBAAyB,eAAe,IAAI,EACnD,OAAO,OAAO,SAAS;AACtB,YAAQ,IAAIA,QAAM,KAAK,iCAAiC,CAAC;AACzD,QAAI;AACF,YAAM,SAAS,QAAQ,KAAK,CAAC;AAC7B,eAAS,IAAI,MAAM,qBAAqB,EAAE,OAAO,UAAU,CAAC;AAC5D,cAAQ,IAAIA,QAAM,MAAM,kCAA6B,CAAC;AAAA,IACxD,SAAS,KAAK;AACZ,cAAQ,MAAMA,QAAM,IAAI;AAAA,wBAAuB,IAAc,OAAO,EAAE,CAAC;AAAA,IACzE;AAAA,EACF,CAAC;AACL;AAIA,SAAS,iBAAuB;AAC9B,QAAM,SAAS,QAAQ,KAAK,CAAC;AAC7B,QAAM,SAAS,WAAW;AAG1B,mBAAiB;AAEjB,QAAM,gBAAgB;AACtB,QAAM,WAAW,OAAO,aAAa,WAAW,MAAM,6CAA6C,WAAW;AAE9G,MAAI;AACF,UAAM,WAAW,SAAS,0BAA0B,EAAE,UAAU,QAAQ,CAAC,EAAE,KAAK;AAChF,UAAM,UAAU,WAAW,GAAG,QAAQ;AAAA,EAAK,QAAQ,KAAK;AACxD,aAAS,SAAS,OAAO,iBAAiB,EAAE,UAAU,QAAQ,CAAC;AAAA,EACjE,QAAQ;AACN,aAAS,SAAS,QAAQ,iBAAiB,EAAE,UAAU,QAAQ,CAAC;AAAA,EAClE;AACF;AAEA,SAAS,mBAAyB;AAChC,MAAI;AACF,UAAM,WAAW,SAAS,0BAA0B,EAAE,UAAU,QAAQ,CAAC;AACzE,UAAM,WAAW,SAAS,MAAM,IAAI,EAAE,OAAO,OAAK,CAAC,EAAE,SAAS,WAAW,CAAC,EAAE,KAAK,IAAI,EAAE,KAAK;AAC5F,aAAS,SAAS,QAAQ,iBAAiB,EAAE,UAAU,QAAQ,CAAC;AAAA,EAClE,QAAQ;AAAA,EAAmB;AAC7B;AAEA,SAAS,eAAwB;AAC/B,MAAI;AACF,UAAM,SAAS,SAAS,0BAA0B,EAAE,UAAU,QAAQ,CAAC;AACvE,WAAO,OAAO,SAAS,WAAW;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,qBAA2B;AAClC,QAAM,SAAS,QAAQ,KAAK,CAAC;AAC7B,QAAM,UAAUC,MAAK,QAAQ,GAAG,uCAAuC;AAGvE,uBAAqB;AAGrB,QAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAaM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASxB,gBAAc,SAAS,GAAG;AAC1B,WAAS,yBAAyB,SAAS,WAAW,OAAO,QAAQ,EAAE,UAAU,QAAQ,CAAC;AAC5F;AAEA,SAAS,uBAA6B;AACpC,MAAI;AACF,aAAS,yBAAyB,SAAS,QAAQ,EAAE,UAAU,SAAS,OAAO,SAAS,CAAC;AAAA,EAC3F,QAAQ;AAAA,EAA2B;AACrC;AAEA,SAAS,mBAA4B;AACnC,MAAI;AACF,aAAS,wBAAwB,SAAS,KAAK,EAAE,UAAU,SAAS,OAAO,SAAS,CAAC;AACrF,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AChOA,OAAOC,aAAW;AAKX,SAAS,qBAAqBC,UAAwB;AAC3D,QAAM,QAAQA,SACX,QAAQ,OAAO,EACf,YAAY,mCAAmC;AAElD,QACG,QAAQ,OAAO,EACf,YAAY,kCAAkC,EAC9C,OAAO,wBAAwB,4BAA4B,IAAI,EAC/D,OAAO,OAAO,SAAS;AACtB,UAAM,SAAS,IAAI,YAAY,EAAE,SAAS,KAAK,QAAQ,CAAC;AACxD,UAAM,WAAW,SAAS,KAAK,UAAU,EAAE,IAAI;AAE/C,YAAQ,IAAIC,QAAM,KAAK,KAAK;AAAA,yCAAqC,WAAW,GAAI;AAAA,CAAM,CAAC;AAEvF,UAAM,UAAU,YAAY;AAC1B,UAAI;AACF,cAAM,EAAE,WAAW,QAAQ,IAAI,MAAM,OAAO,iBAAiB;AAC7D,gBAAQ,OAAO,MAAM,gBAAgB;AACrC,gBAAQ,IAAI,oBAAoB,WAAW,OAAO,CAAC;AACnD,gBAAQ,IAAIA,QAAM,IAAI;AAAA,kBAAqB,WAAW,GAAI,yBAAoB,CAAC;AAAA,MACjF,SAAS,KAAK;AACZ,gBAAQ,MAAMA,QAAM,IAAI,YAAa,IAAc,OAAO,EAAE,CAAC;AAAA,MAC/D;AAAA,IACF;AAEA,UAAM,QAAQ;AACd,gBAAY,SAAS,QAAQ;AAC7B,UAAM,IAAI,QAAQ,MAAM;AAAA,IAAC,CAAC;AAAA,EAC5B,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,qBAAqB,EACjC,OAAO,MAAM;AAEZ,YAAQ,IAAIA,QAAM,KAAK,oBAAoB,CAAC;AAC5C,YAAQ,IAAIA,QAAM,IAAI,0DAA0D,CAAC;AAAA,EACnF,CAAC;AACL;;;AC5CA,OAAOC,aAAW;AAIX,SAAS,sBAAsBC,UAAwB;AAC5D,QAAM,SAASA,SACZ,QAAQ,QAAQ,EAChB,YAAY,gBAAgB;AAE/B,SACG,QAAQ,MAAM,EACd,YAAY,wBAAwB,EACpC,OAAO,MAAM;AACZ,UAAM,SAAS,WAAW;AAC1B,QAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,cAAQ,IAAIC,QAAM,IAAI,wBAAwB,CAAC;AAC/C;AAAA,IACF;AACA,YAAQ,IAAIA,QAAM,KAAK,yBAAyB,CAAC;AACjD,eAAW,KAAK,OAAO,SAAS;AAC9B,cAAQ,IAAI,eAAQ,CAAC,EAAE;AAAA,IACzB;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,gBAAgB,EACxB,YAAY,kBAAkB,EAC9B,OAAO,CAAC,SAAiB;AACxB,UAAM,SAAS,WAAW;AAC1B,QAAI,OAAO,QAAQ,SAAS,IAAI,GAAG;AACjC,cAAQ,IAAIA,QAAM,OAAO,aAAa,IAAI,qBAAqB,CAAC;AAChE;AAAA,IACF;AACA,WAAO,QAAQ,KAAK,IAAI;AACxB,eAAW,MAAM;AACjB,YAAQ,IAAIA,QAAM,MAAM,kBAAa,IAAI,aAAa,CAAC;AAAA,EACzD,CAAC;AAEH,SACG,QAAQ,eAAe,EACvB,YAAY,iBAAiB,EAC7B,OAAO,CAAC,SAAiB;AACxB,UAAM,SAAS,WAAW;AAC1B,UAAM,MAAM,OAAO,QAAQ,QAAQ,IAAI;AACvC,QAAI,MAAM,GAAG;AACX,cAAQ,IAAIA,QAAM,IAAI,aAAa,IAAI,aAAa,CAAC;AACrD;AAAA,IACF;AACA,WAAO,QAAQ,OAAO,KAAK,CAAC;AAC5B,eAAW,MAAM;AACjB,YAAQ,IAAIA,QAAM,MAAM,kBAAa,IAAI,WAAW,CAAC;AAAA,EACvD,CAAC;AACL;;;AzBnCA,IAAI,UAAU;AACd,IAAI;AACF,QAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,MAAM,KAAK,MAAMC,cAAaC,MAAK,WAAW,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC;AACzF,YAAU,IAAI;AAChB,QAAQ;AAAoB;AAG5B,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,IAAI,EACT,YAAY,6DAA6D,EACzE,QAAQ,OAAO,EACf,OAAO,aAAa,qBAAqB;AAG5C,qBAAqB,OAAO;AAC5B,wBAAwB,OAAO;AAC/B,uBAAuB,OAAO;AAC9B,sBAAsB,OAAO;AAC7B,sBAAsB,OAAO;AAC7B,sBAAsB,OAAO;AAC7B,qBAAqB,OAAO;AAC5B,sBAAsB,OAAO;AAG7B,QAAQ,OAAO,UAAU,+DAA+D;AACxF,QAAQ,OAAO,UAAU,sBAAsB;AAC/C,QAAQ,OAAO,gBAAgB,0CAA0C;AACzE,QAAQ,OAAO,WAAW,mBAAmB;AAG7C,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AAGjC,IAAI,KAAK,SAAS,WAAW,GAAG;AAC9B,aAAW,IAAI;AACjB;AAGA,IAAM,SAAS,KAAK,SAAS,QAAQ;AAGrC,QAAQ,OAAO,OAAO,SAAS;AAC7B,MAAI,UAAU,KAAK,MAAM;AACvB,UAAM,qBAAqB;AAAA,MACzB,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,MAChB,SAAS,KAAK;AAAA,IAChB,CAAC;AAAA,EACH,OAAO;AAEL,UAAM,QAAQ,WAAW,CAAC,QAAQ,MAAM,SAAS,GAAG,KAAK,OAAO,OAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,EACvF;AACF,CAAC;AAED,QAAQ,MAAM;","names":["readFileSync","join","chalk","exec","promisify","execAsync","statusRaw","chalk","chalk","program","chalk","chalk","ora","chalk","chalk","ora","chalk","chalk","Table","program","accounts","chalk","Table","getManualLoginUrl","completeManualLogin","chalk","chalk","chalk","program","chalk","chalk","program","chalk","chalk","program","chalk","chalk","join","inquirer","program","chalk","join","chalk","program","chalk","chalk","program","chalk","readFileSync","join"]}