@vocoder/cli 0.1.4 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -45
- package/dist/bin.mjs +1803 -1679
- package/dist/bin.mjs.map +1 -1
- package/dist/chunk-OC5N5C5X.mjs +546 -0
- package/dist/chunk-OC5N5C5X.mjs.map +1 -0
- package/dist/lib.d.mts +175 -0
- package/dist/lib.mjs +15 -0
- package/dist/lib.mjs.map +1 -0
- package/package.json +8 -2
package/dist/bin.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin.ts","../src/commands/init.ts","../src/utils/api.ts","../src/utils/git-identity.ts","../src/commands/sync.ts","../src/utils/branch.ts","../src/utils/config.ts","../src/utils/extract.ts","../src/commands/wrap.ts","../src/utils/wrap/analyzer.ts","../src/utils/wrap/heuristics.ts","../src/utils/wrap/transformer.ts","../src/utils/wrap/adapters/react.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { init } from './commands/init.js';\nimport { sync } from './commands/sync.js';\nimport { wrap } from './commands/wrap.js';\n\n/**\n * Collector function for repeated CLI options\n * Allows multiple --include or --exclude flags\n */\nfunction collect(value: string, previous: string[] = []): string[] {\n return previous.concat([value]);\n}\n\nasync function runCommand(command: (options: any) => Promise<number>, options: any): Promise<void> {\n const exitCode = await command(options);\n process.exitCode = exitCode;\n}\n\nconst program = new Command();\n\nprogram\n .name('vocoder')\n .description('Vocoder CLI - Sync translations for your application')\n .version('0.1.2');\n\nprogram\n .command('sync')\n .description('Extract strings and sync translations')\n .option('--include <pattern>', 'Glob pattern(s) to include (can be used multiple times)', collect, [])\n .option('--exclude <pattern>', 'Glob pattern(s) to exclude (can be used multiple times)', collect, [])\n .option('--branch <name>', 'Override branch detection')\n .option('--force', 'Sync even if not a target branch')\n .option('--mode <mode>', 'Sync mode: auto|required|best-effort')\n .option('--max-wait-ms <ms>', 'Max wait time before fallback (ms)', (value) => Number.parseInt(value, 10))\n .option('--no-fallback', 'Fail instead of using fallback artifacts')\n .option('--dry-run', 'Show what would be synced without doing it')\n .option('--verbose', 'Show detailed progress')\n .action((options) => runCommand(sync, {\n ...options,\n noFallback: options.noFallback ? true : undefined,\n }));\n\nprogram\n .command('wrap')\n .description('Auto-wrap strings with <T> and t() for translation')\n .option('--include <pattern>', 'Glob pattern(s) to include (can be used multiple times)', collect, [])\n .option('--exclude <pattern>', 'Glob pattern(s) to exclude (can be used multiple times)', collect, [])\n .option('--dry-run', 'Preview changes without modifying files')\n .option('--interactive', 'Confirm each string interactively')\n .option('--confidence <level>', 'Minimum confidence: high, medium, low', 'high')\n .option('--verbose', 'Detailed output')\n .action((options) => runCommand(wrap, options));\n\nprogram\n .command('init')\n .description('Authenticate and provision Vocoder for this project')\n .option('--api-url <url>', 'Override Vocoder API URL')\n .option('--yes', 'Allow overwriting existing local config values')\n .option('--project-name <name>', 'Starter project name to create')\n .option('--source-locale <locale>', 'Source locale for the starter project')\n .option('--target-locales <list>', 'Comma-separated target locales (e.g. es,fr,de)')\n .action((options) => runCommand(init, options));\n\nprogram.parse(process.argv);\n","import * as p from '@clack/prompts';\nimport chalk from 'chalk';\n\nimport { VocoderAPI } from '../utils/api.js';\n\nimport type { InitOptions } from '../types.js';\nimport { resolveGitContext } from '../utils/git-identity.js';\nimport { spawn } from 'node:child_process';\n\nconst SUBSCRIPTION_SETTINGS_PATH = '/dashboard/workspace/settings?tab=subscription';\n\nfunction parseTargetLocales(value?: string): string[] | undefined {\n if (!value) return undefined;\n\n const locales = value\n .split(',')\n .map((locale: string) => locale.trim())\n .filter(Boolean);\n\n return locales.length > 0 ? locales : undefined;\n}\n\nasync function sleep(ms: number): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function tryOpenBrowser(url: string): Promise<boolean> {\n if (!process.stdout.isTTY || process.env.CI === 'true') {\n return false;\n }\n\n let command: string;\n let args: string[];\n\n if (process.platform === 'darwin') {\n command = 'open';\n args = [url];\n } else if (process.platform === 'win32') {\n command = 'rundll32';\n args = ['url.dll,FileProtocolHandler', url];\n } else {\n command = 'xdg-open';\n args = [url];\n }\n\n return await new Promise<boolean>((resolve) => {\n try {\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n windowsHide: true,\n });\n\n let settled = false;\n child.once('spawn', () => {\n if (settled) return;\n settled = true;\n child.unref();\n resolve(true);\n });\n child.once('error', () => {\n if (settled) return;\n settled = true;\n resolve(false);\n });\n setTimeout(() => {\n if (settled) return;\n settled = true;\n resolve(false);\n }, 300);\n } catch {\n resolve(false);\n }\n });\n}\n\nfunction isPlanLimitFailure(message?: string): boolean {\n if (!message) return false;\n return /limit|upgrade/i.test(message);\n}\n\nfunction getSubscriptionSettingsUrl(apiUrl: string): string {\n return new URL(SUBSCRIPTION_SETTINGS_PATH, apiUrl).toString();\n}\n\nfunction printPlanLimitMessage(apiUrl: string, message: string): void {\n p.log.error(`You are over your plan limits.\\n ${message}`);\n p.log.info(`Manage subscription: ${getSubscriptionSettingsUrl(apiUrl)}`);\n}\n\nfunction printNextSteps(projectName: string, organizationName: string): void {\n p.log.info(`Project: ${chalk.bold(projectName)}`);\n p.log.info(`Workspace: ${chalk.bold(organizationName)}`);\n p.log.info('');\n p.log.info('Next steps:');\n p.log.info(` 1. Add ${chalk.cyan('@vocoder/unplugin')} to your build config`);\n p.log.info(` 2. Wrap translatable strings with ${chalk.green('<T>')}...${chalk.green('</T>')}`);\n p.log.info(' 3. Push to trigger extraction + translation');\n}\n\nexport async function init(options: InitOptions = {}): Promise<number> {\n const apiUrl = options.apiUrl || process.env.VOCODER_API_URL || 'https://vocoder.app';\n\n p.intro('Vocoder Setup');\n\n const spinner = p.spinner();\n\n try {\n // ── Detect git context ─────────────────────────────────────────\n const gitContext = resolveGitContext();\n const identity = gitContext.identity;\n\n if (gitContext.warnings.length > 0) {\n for (const warning of gitContext.warnings) {\n p.log.warn(warning);\n }\n }\n\n // ── Try fast lookup: does a project already exist for this repo?\n if (identity) {\n spinner.start('Checking for existing project...');\n\n const api = new VocoderAPI({ apiUrl, apiKey: '' });\n const existing = await api.lookupProjectByRepo({\n repoCanonical: identity.repoCanonical,\n scopePath: identity.repoScopePath,\n });\n\n if (existing) {\n spinner.stop('Found existing project!');\n p.outro('Vocoder is already set up for this repository.');\n printNextSteps(existing.projectName, existing.organizationName);\n return 0;\n }\n\n spinner.stop('No existing project found for this repo.');\n }\n\n // ── Browser setup flow (new project needed) ────────────────────\n spinner.start('Creating setup session');\n\n const api = new VocoderAPI({ apiUrl, apiKey: '' });\n\n const start = await api.startInitSession({\n projectName: options.projectName,\n sourceLocale: options.sourceLocale,\n targetLocales: parseTargetLocales(options.targetLocales),\n ...(identity?.repoCanonical ? { repoCanonical: identity.repoCanonical } : {}),\n ...(identity ? { repoScopePath: identity.repoScopePath } : {}),\n });\n\n spinner.stop('Setup session created');\n\n const verificationUrlString = start.verificationUrl;\n\n p.log.info('Create a project in your browser to continue.');\n p.note(verificationUrlString, 'Setup URL');\n\n // ── Browser open ───────────────────────────────────────────────\n if (process.stdin.isTTY && process.stdout.isTTY && process.env.CI !== 'true') {\n const shouldOpen = options.yes\n ? true\n : await p.confirm({ message: 'Open this URL in your browser?' });\n\n if (p.isCancel(shouldOpen)) {\n p.cancel('Setup cancelled.');\n return 1;\n }\n\n if (shouldOpen) {\n const opened = await tryOpenBrowser(verificationUrlString);\n if (opened) {\n p.log.info('Opened your browser.');\n } else {\n p.log.info('Could not open a browser automatically. Use the URL above.');\n }\n }\n }\n\n // ── Polling ────────────────────────────────────────────────────\n const expiresAt = new Date(start.expiresAt).getTime();\n spinner.start('Waiting for setup to complete...');\n\n while (Date.now() < expiresAt) {\n const status = await api.getInitSessionStatus({\n sessionId: start.sessionId,\n pollToken: start.poll.token,\n });\n\n if (status.status === 'pending') {\n const pendingMessage = status.message?.trim();\n if (pendingMessage) {\n spinner.message(`Waiting for setup to complete... (${pendingMessage})`);\n }\n await sleep((status.pollIntervalSeconds || start.poll.intervalSeconds) * 1000);\n continue;\n }\n\n if (status.status === 'failed') {\n spinner.stop('Setup failed');\n if (isPlanLimitFailure(status.message)) {\n printPlanLimitMessage(apiUrl, status.message);\n } else {\n p.log.error(status.message);\n }\n p.cancel('Setup could not be completed.');\n return 1;\n }\n\n if (status.status === 'completed') {\n spinner.stop('Setup complete!');\n\n const { credentials } = status;\n\n p.outro('Vocoder initialized successfully!');\n printNextSteps(credentials.projectName, credentials.organizationName);\n\n return 0;\n }\n }\n\n // ── Timeout ──────────────────────────────────────────────────\n spinner.stop('Setup timed out');\n p.log.error('Setup timed out. Run `vocoder init` again.');\n p.cancel('Setup could not be completed.');\n return 1;\n } catch (error) {\n spinner.stop();\n if (error instanceof Error) {\n if (isPlanLimitFailure(error.message)) {\n printPlanLimitMessage(apiUrl, error.message);\n return 1;\n }\n p.log.error(`Error: ${error.message}`);\n } else {\n p.log.error('Unknown setup error');\n }\n\n return 1;\n }\n}\n","import type {\n APIProjectConfig,\n InitStartResponse,\n InitStatusResponse,\n\tLimitErrorResponse,\n\tLocalConfig,\n\tRequestedSyncMode,\n\tRepoIdentityPayload,\n\tSyncPolicyErrorResponse,\n\tTranslationBatchResponse,\n\tTranslationSnapshotResponse,\n\tTranslationStringEntry,\n\tTranslationStatusResponse,\n} from '../types.js';\n\nfunction isLimitErrorResponse(value: unknown): value is LimitErrorResponse {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const candidate = value as Partial<LimitErrorResponse>;\n return (\n typeof candidate.errorCode === 'string' &&\n typeof candidate.limitType === 'string' &&\n typeof candidate.planId === 'string' &&\n typeof candidate.current === 'number' &&\n typeof candidate.required === 'number' &&\n typeof candidate.upgradeUrl === 'string' &&\n typeof candidate.message === 'string'\n );\n}\n\nfunction isSyncPolicyErrorResponse(value: unknown): value is SyncPolicyErrorResponse {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const candidate = value as Partial<SyncPolicyErrorResponse>;\n return (\n (candidate.errorCode === 'BRANCH_NOT_ALLOWED' ||\n candidate.errorCode === 'PROJECT_REPOSITORY_MISMATCH') &&\n typeof candidate.message === 'string'\n );\n}\n\nfunction extractErrorMessage(payload: unknown, fallback: string): string {\n if (!payload || typeof payload !== 'object') {\n return fallback;\n }\n\n const candidate = payload as Record<string, unknown>;\n if (typeof candidate.message === 'string') {\n return candidate.message;\n }\n\n if (typeof candidate.error === 'string') {\n return candidate.error;\n }\n\n return fallback;\n}\n\nfunction parsePayload(raw: string): unknown {\n if (raw.length === 0) {\n return null;\n }\n\n try {\n return JSON.parse(raw);\n } catch {\n return { message: raw };\n }\n}\n\nasync function readPayload(response: {\n text?: () => Promise<string>;\n json?: () => Promise<unknown>;\n}): Promise<unknown> {\n if (typeof response.text === 'function') {\n const raw = await response.text();\n return parsePayload(raw);\n }\n\n if (typeof response.json === 'function') {\n return response.json();\n }\n\n return null;\n}\n\nexport class VocoderAPIError extends Error {\n readonly status: number;\n readonly payload: unknown;\n readonly limitError: LimitErrorResponse | null;\n readonly syncPolicyError: SyncPolicyErrorResponse | null;\n\n constructor(params: {\n message: string;\n status: number;\n payload: unknown;\n limitError?: LimitErrorResponse | null;\n syncPolicyError?: SyncPolicyErrorResponse | null;\n }) {\n super(params.message);\n this.name = 'VocoderAPIError';\n this.status = params.status;\n this.payload = params.payload;\n this.limitError = params.limitError ?? null;\n this.syncPolicyError = params.syncPolicyError ?? null;\n }\n}\n\nexport class VocoderAPI {\n private apiUrl: string;\n private apiKey: string;\n\n constructor(config: LocalConfig) {\n this.apiUrl = config.apiUrl;\n this.apiKey = config.apiKey;\n }\n\n private async request<T>(\n path: string,\n init: RequestInit = {},\n errorPrefix?: string,\n ): Promise<T> {\n const response = await fetch(`${this.apiUrl}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n ...(init.headers ?? {}),\n },\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n const limitError = isLimitErrorResponse(payload) ? payload : null;\n const syncPolicyError = isSyncPolicyErrorResponse(payload) ? payload : null;\n const baseMessage = extractErrorMessage(payload, `Request failed with status ${response.status}`);\n throw new VocoderAPIError({\n message: errorPrefix ? `${errorPrefix}: ${baseMessage}` : baseMessage,\n status: response.status,\n payload,\n limitError,\n syncPolicyError,\n });\n }\n\n return payload as T;\n }\n\n /**\n * Fetch project configuration from API\n * Project is determined from the API key\n */\n\tasync getProjectConfig(): Promise<APIProjectConfig> {\n\t\tconst data = await this.request<{\n\t\t\tprojectName: string;\n\t\t\torganizationName: string;\n\t\t\tsourceLocale: string;\n\t\t\ttargetLocales: string[];\n\t\t\ttargetBranches: string[];\n\t\t\tsyncPolicy?: {\n\t\t\t\tblockingBranches?: string[];\n\t\t\t\tblockingMode?: \"required\" | \"best-effort\";\n\t\t\t\tnonBlockingMode?: \"required\" | \"best-effort\";\n\t\t\t\tdefaultMaxWaitMs?: number;\n\t\t\t};\n\t\t}>('/api/cli/config', {}, 'Failed to fetch project config');\n\n\t\treturn {\n\t\t\tprojectName: data.projectName,\n\t\t\torganizationName: data.organizationName,\n\t\t\tsourceLocale: data.sourceLocale,\n\t\t\ttargetLocales: data.targetLocales,\n\t\t\ttargetBranches: data.targetBranches,\n\t\t\tsyncPolicy: {\n\t\t\t\tblockingBranches: data.syncPolicy?.blockingBranches ?? [\"main\", \"master\"],\n\t\t\t\tblockingMode: data.syncPolicy?.blockingMode ?? \"required\",\n\t\t\t\tnonBlockingMode: data.syncPolicy?.nonBlockingMode ?? \"best-effort\",\n\t\t\t\tdefaultMaxWaitMs: data.syncPolicy?.defaultMaxWaitMs ?? 60_000,\n\t\t\t},\n\t\t};\n\t}\n\n /**\n * Submit strings for translation\n * Project is determined from the API key\n */\n private stableTextKey(text: string): string {\n // FNV-1a 32-bit hash for deterministic fallback IDs\n let hash = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n hash ^= text.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return `SK_TEXT_${(hash >>> 0).toString(16).toUpperCase().padStart(8, '0')}`;\n }\n\n private normalizeStringEntries(\n entries: string[] | TranslationStringEntry[],\n ): TranslationStringEntry[] {\n if (entries.length === 0) {\n return [];\n }\n\n const first = entries[0];\n if (typeof first === 'string') {\n return (entries as string[]).map((text) => ({\n key: this.stableTextKey(text),\n text,\n }));\n }\n\n return (entries as TranslationStringEntry[]).map((entry, index) => ({\n key: entry.key || this.stableTextKey(`${entry.text}:${index}`),\n text: entry.text,\n ...(entry.context ? { context: entry.context } : {}),\n ...(entry.formality ? { formality: entry.formality } : {}),\n }));\n }\n\n\tasync submitTranslation(\n\t\tbranch: string,\n\t\tentries: string[] | TranslationStringEntry[],\n\t\ttargetLocales: string[],\n\t\toptions?: {\n\t\t\trequestedMode?: RequestedSyncMode;\n\t\t\trequestedMaxWaitMs?: number;\n\t\t\tclientRunId?: string;\n\t\t},\n\t\trepoIdentity?: RepoIdentityPayload,\n\t): Promise<TranslationBatchResponse> {\n const stringEntries = this.normalizeStringEntries(entries);\n const strings = stringEntries.map((entry) => entry.text);\n\n // Compute hash of sorted strings for fast comparison\n const crypto = await import('crypto');\n const sortedStrings = [...strings].sort();\n const stringsHash = crypto\n .createHash('sha256')\n .update(JSON.stringify(sortedStrings))\n .digest('hex');\n\n return this.request<TranslationBatchResponse>('/api/cli/sync', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n\t body: JSON.stringify({\n\t branch,\n\t stringEntries,\n\t targetLocales,\n\t stringsHash,\n\t ...(options?.requestedMode ? { requestedMode: options.requestedMode } : {}),\n\t ...(typeof options?.requestedMaxWaitMs === 'number'\n\t ? { requestedMaxWaitMs: options.requestedMaxWaitMs }\n\t : {}),\n\t ...(options?.clientRunId ? { clientRunId: options.clientRunId } : {}),\n\t ...(repoIdentity?.repoCanonical ? { repoCanonical: repoIdentity.repoCanonical } : {}),\n\t ...(repoIdentity?.repoScopePath !== undefined\n\t ? { repoScopePath: repoIdentity.repoScopePath }\n : {}),\n }),\n }, 'Translation submission failed');\n }\n\n /**\n * Check translation status\n */\n\tasync getTranslationStatus(\n\t\tbatchId: string,\n\t): Promise<TranslationStatusResponse> {\n\t\treturn this.request<TranslationStatusResponse>(\n\t\t\t`/api/cli/sync/status/${batchId}`,\n\t\t\t{},\n\t\t\t'Failed to check translation status',\n\t\t);\n\t}\n\n\tasync getTranslationSnapshot(params: {\n\t\tbranch: string;\n\t\ttargetLocales: string[];\n\t}): Promise<TranslationSnapshotResponse> {\n\t\tconst search = new URLSearchParams();\n\t\tsearch.set('branch', params.branch);\n\t\tfor (const locale of params.targetLocales) {\n\t\t\tsearch.append('targetLocale', locale);\n\t\t}\n\n\t\treturn this.request<TranslationSnapshotResponse>(\n\t\t\t`/api/cli/sync/snapshot?${search.toString()}`,\n\t\t\t{},\n\t\t\t'Failed to fetch translation snapshot',\n\t\t);\n\t}\n\n /**\n * Wait for translation to complete with polling\n */\n async waitForCompletion(\n batchId: string,\n timeout: number = 60000,\n onProgress?: (progress: number) => void,\n ): Promise<{\n translations: Record<string, Record<string, string>>;\n localeMetadata?: Record<string, { nativeName: string; dir?: 'rtl' }>;\n }> {\n const startTime = Date.now();\n const pollInterval = 1000; // Poll every second\n\n while (Date.now() - startTime < timeout) {\n const status = await this.getTranslationStatus(batchId);\n\n // Call progress callback\n if (onProgress) {\n onProgress(status.progress);\n }\n\n if (status.status === 'COMPLETED') {\n if (!status.translations) {\n throw new Error('Translation completed but no translations returned');\n }\n return {\n translations: status.translations,\n localeMetadata: status.localeMetadata,\n };\n }\n\n if (status.status === 'FAILED') {\n throw new Error(\n `Translation failed: ${status.errorMessage || 'Unknown error'}`,\n );\n }\n\n // Wait before polling again\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(`Translation timeout after ${timeout}ms`);\n }\n\n async startInitSession(input: {\n projectName?: string;\n sourceLocale?: string;\n targetLocales?: string[];\n repoCanonical?: string;\n repoScopePath?: string;\n }): Promise<InitStartResponse> {\n const response = await fetch(`${this.apiUrl}/api/cli/init/start`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to start init session (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as InitStartResponse;\n }\n\n async getInitSessionStatus(params: {\n sessionId: string;\n pollToken: string;\n }): Promise<InitStatusResponse> {\n const response = await fetch(\n `${this.apiUrl}/api/cli/init/status/${params.sessionId}`,\n {\n headers: {\n Authorization: `Bearer ${params.pollToken}`,\n },\n },\n );\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to get init status (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as InitStatusResponse;\n }\n\n /**\n * Look up whether a project already exists for a given repo + scope.\n * Returns { projectId, projectName, organizationName } or null if not found.\n */\n async lookupProjectByRepo(params: {\n repoCanonical: string;\n scopePath: string;\n }): Promise<{ projectId: string; projectName: string; organizationName: string } | null> {\n try {\n const response = await fetch(`${this.apiUrl}/api/cli/init/lookup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n repo: params.repoCanonical,\n scopePath: params.scopePath,\n }),\n });\n\n if (response.status === 404) return null;\n if (!response.ok) return null;\n\n return (await response.json()) as {\n projectId: string;\n projectName: string;\n organizationName: string;\n };\n } catch {\n return null;\n }\n }\n}\n","import { execSync } from 'child_process';\nimport { relative, resolve } from 'path';\n\nexport type GitRepositoryIdentity = {\n repoCanonical: string;\n repoScopePath: string;\n};\n\nexport type GitContext = {\n identity: GitRepositoryIdentity | null;\n warnings: string[];\n};\n\nfunction safeExec(command: string): string | null {\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n }).trim();\n return output.length > 0 ? output : null;\n } catch {\n return null;\n }\n}\n\nfunction normalizePath(pathname: string): string | null {\n const cleaned = pathname\n .replace(/^\\/+/, '')\n .replace(/\\.git$/i, '')\n .trim();\n\n if (!cleaned || !cleaned.includes('/')) {\n return null;\n }\n\n return cleaned;\n}\n\nfunction parseRemoteUrl(remoteUrl: string): {\n host: string;\n ownerRepoPath: string;\n} | null {\n const trimmed = remoteUrl.trim();\n if (!trimmed) {\n return null;\n }\n\n // SCP-like syntax: git@github.com:owner/repo.git\n if (!trimmed.includes('://')) {\n const scpMatch = trimmed.match(/^(?:.+@)?([^:]+):(.+)$/);\n if (scpMatch) {\n const host = (scpMatch[1] || '').toLowerCase();\n const ownerRepoPath = normalizePath(scpMatch[2] || '');\n if (!host || !ownerRepoPath) {\n return null;\n }\n return { host, ownerRepoPath };\n }\n return null;\n }\n\n try {\n const parsed = new URL(trimmed);\n const host = parsed.hostname.toLowerCase();\n const ownerRepoPath = normalizePath(decodeURIComponent(parsed.pathname));\n if (!host || !ownerRepoPath) {\n return null;\n }\n return { host, ownerRepoPath };\n } catch {\n return null;\n }\n}\n\nfunction toCanonical(host: string, ownerRepoPath: string): string {\n if (host.includes('github.com')) {\n return `github:${ownerRepoPath.toLowerCase()}`;\n }\n if (host.includes('gitlab.com')) {\n return `gitlab:${ownerRepoPath.toLowerCase()}`;\n }\n if (host.includes('bitbucket.org')) {\n return `bitbucket:${ownerRepoPath.toLowerCase()}`;\n }\n return `git:${host}/${ownerRepoPath.toLowerCase()}`;\n}\n\nexport function resolveGitRepositoryIdentity(): GitRepositoryIdentity | null {\n const remoteUrl = safeExec('git config --get remote.origin.url');\n if (!remoteUrl) {\n return null;\n }\n\n const parsed = parseRemoteUrl(remoteUrl);\n if (!parsed) {\n return null;\n }\n\n const repositoryRoot = safeExec('git rev-parse --show-toplevel');\n const currentDirectory = process.cwd();\n let repoScopePath = '';\n if (repositoryRoot) {\n const relativePath = relative(resolve(repositoryRoot), resolve(currentDirectory))\n .replace(/\\\\/g, '/')\n .trim();\n\n if (relativePath && relativePath !== '.' && !relativePath.startsWith('..')) {\n repoScopePath = relativePath;\n }\n }\n\n return {\n repoCanonical: toCanonical(parsed.host, parsed.ownerRepoPath),\n repoScopePath,\n };\n}\n\nexport function resolveGitContext(): GitContext {\n const warnings: string[] = [];\n const identity = resolveGitRepositoryIdentity();\n\n if (!identity) {\n warnings.push(\n 'Could not detect git remote origin. Repo binding will be skipped until sync can detect it.',\n );\n }\n\n return { identity, warnings };\n}\n","import * as p from '@clack/prompts';\n\nimport type {\n EffectiveSyncMode,\n ExtractedString,\n LimitErrorResponse,\n ProjectConfig,\n RequestedSyncMode,\n SyncPolicyConfig,\n TranslateOptions,\n TranslationStringEntry,\n} from '../types.js';\nimport { VocoderAPI, VocoderAPIError } from '../utils/api.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport { detectBranch, isTargetBranch } from '../utils/branch.js';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { getMergedConfig, validateLocalConfig } from '../utils/config.js';\n\nimport { StringExtractor } from '../utils/extract.js';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { resolveGitRepositoryIdentity } from '../utils/git-identity.js';\n\ntype LocaleMetadataMap = Record<string, { nativeName: string; dir?: 'rtl' }>;\ntype TranslationMap = Record<string, Record<string, string>>;\ntype TranslationArtifactSource = 'fresh' | 'local-cache' | 'api-snapshot';\n\ntype TranslationArtifacts = {\n source: TranslationArtifactSource;\n translations: TranslationMap;\n localeMetadata?: LocaleMetadataMap;\n snapshotBatchId?: string;\n completedAt?: string | null;\n cacheBranch?: string;\n};\n\ntype LocalSnapshotCache = {\n version: 1;\n branch: string;\n sourceLocale: string;\n targetLocales: string[];\n savedAt: string;\n snapshotBatchId?: string;\n completedAt?: string | null;\n localeMetadata?: LocaleMetadataMap;\n translations: TranslationMap;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseLocaleMetadata(value: unknown): LocaleMetadataMap | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n\n const metadata: LocaleMetadataMap = {};\n for (const [locale, rawValue] of Object.entries(value)) {\n if (!isRecord(rawValue)) {\n continue;\n }\n\n const nativeName = rawValue.nativeName;\n if (typeof nativeName !== 'string' || nativeName.trim().length === 0) {\n continue;\n }\n\n const entry: { nativeName: string; dir?: 'rtl' } = { nativeName };\n if (rawValue.dir === 'rtl') {\n entry.dir = 'rtl';\n }\n\n metadata[locale] = entry;\n }\n\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nfunction parseTranslations(value: unknown): TranslationMap | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const translations: TranslationMap = {};\n\n for (const [locale, localeValue] of Object.entries(value)) {\n if (!isRecord(localeValue)) {\n continue;\n }\n\n const localeTranslations: Record<string, string> = {};\n for (const [source, translated] of Object.entries(localeValue)) {\n if (typeof translated === 'string') {\n localeTranslations[source] = translated;\n }\n }\n\n translations[locale] = localeTranslations;\n }\n\n return Object.keys(translations).length > 0 ? translations : null;\n}\n\nfunction getCacheFilePath(projectRoot: string, branch: string): string {\n const slug = branch\n .replace(/[^a-zA-Z0-9._-]+/g, '_')\n .replace(/^_+|_+$/g, '')\n .slice(0, 40);\n const branchHash = createHash('sha1').update(branch).digest('hex').slice(0, 12);\n const filename = `${slug || 'branch'}-${branchHash}.json`;\n return join(projectRoot, '.vocoder', 'cache', 'sync', filename);\n}\n\nfunction readLocalSnapshotCache(params: {\n projectRoot: string;\n branch: string;\n}): TranslationArtifacts | null {\n const candidateBranches = params.branch === 'main'\n ? ['main']\n : [params.branch, 'main'];\n\n for (const candidateBranch of candidateBranches) {\n const cacheFilePath = getCacheFilePath(params.projectRoot, candidateBranch);\n\n if (!existsSync(cacheFilePath)) {\n continue;\n }\n\n try {\n const raw = readFileSync(cacheFilePath, 'utf-8');\n const parsed = JSON.parse(raw) as unknown;\n if (!isRecord(parsed)) {\n continue;\n }\n\n const translations = parseTranslations(parsed.translations);\n if (!translations) {\n continue;\n }\n\n const localeMetadata = parseLocaleMetadata(parsed.localeMetadata);\n\n return {\n source: 'local-cache',\n translations,\n localeMetadata,\n snapshotBatchId:\n typeof parsed.snapshotBatchId === 'string'\n ? parsed.snapshotBatchId\n : undefined,\n completedAt:\n typeof parsed.completedAt === 'string' ? parsed.completedAt : null,\n cacheBranch: candidateBranch,\n };\n } catch {\n continue;\n }\n }\n\n return null;\n}\n\nfunction writeLocalSnapshotCache(params: {\n projectRoot: string;\n branch: string;\n sourceLocale: string;\n targetLocales: string[];\n translations: TranslationMap;\n localeMetadata?: LocaleMetadataMap;\n snapshotBatchId?: string;\n completedAt?: string | null;\n}): string {\n const cacheFilePath = getCacheFilePath(params.projectRoot, params.branch);\n mkdirSync(join(params.projectRoot, '.vocoder', 'cache', 'sync'), {\n recursive: true,\n });\n\n const payload: LocalSnapshotCache = {\n version: 1,\n branch: params.branch,\n sourceLocale: params.sourceLocale,\n targetLocales: params.targetLocales,\n savedAt: new Date().toISOString(),\n ...(params.snapshotBatchId ? { snapshotBatchId: params.snapshotBatchId } : {}),\n ...(params.completedAt ? { completedAt: params.completedAt } : {}),\n ...(params.localeMetadata ? { localeMetadata: params.localeMetadata } : {}),\n translations: params.translations,\n };\n\n writeFileSync(cacheFilePath, JSON.stringify(payload, null, 2), 'utf-8');\n return cacheFilePath;\n}\n\nfunction resolveEffectiveModeFromPolicy(params: {\n branch: string;\n requestedMode: RequestedSyncMode;\n policy: SyncPolicyConfig;\n}): EffectiveSyncMode {\n const { requestedMode, policy, branch } = params;\n\n let mode: EffectiveSyncMode;\n if (requestedMode === 'auto') {\n const isBlockingBranch = isTargetBranch(branch, policy.blockingBranches);\n mode = isBlockingBranch ? policy.blockingMode : policy.nonBlockingMode;\n } else {\n mode = requestedMode;\n }\n\n return mode;\n}\n\nfunction resolveWaitTimeoutMs(params: {\n requestedMaxWaitMs?: number;\n policyDefaultMaxWaitMs?: number;\n fallbackTimeoutMs: number;\n}): number {\n if (\n typeof params.requestedMaxWaitMs === 'number' &&\n Number.isFinite(params.requestedMaxWaitMs) &&\n params.requestedMaxWaitMs > 0\n ) {\n return Math.floor(params.requestedMaxWaitMs);\n }\n\n if (\n typeof params.policyDefaultMaxWaitMs === 'number' &&\n Number.isFinite(params.policyDefaultMaxWaitMs) &&\n params.policyDefaultMaxWaitMs > 0\n ) {\n return Math.floor(params.policyDefaultMaxWaitMs);\n }\n\n return params.fallbackTimeoutMs;\n}\n\nfunction normalizeTranslations(params: {\n sourceLocale: string;\n targetLocales: string[];\n sourceStrings: string[];\n translations: TranslationMap;\n}): TranslationMap {\n const merged: TranslationMap = {};\n\n for (const [locale, values] of Object.entries(params.translations)) {\n merged[locale] = { ...values };\n }\n\n const expectedLocales = [\n params.sourceLocale,\n ...params.targetLocales.filter((locale) => locale !== params.sourceLocale),\n ];\n\n for (const locale of expectedLocales) {\n if (!merged[locale]) {\n merged[locale] = {};\n }\n }\n\n if (!merged[params.sourceLocale]) {\n merged[params.sourceLocale] = {};\n }\n\n for (const sourceText of params.sourceStrings) {\n if (!(sourceText in merged[params.sourceLocale]!)) {\n merged[params.sourceLocale]![sourceText] = sourceText;\n }\n }\n\n return merged;\n}\n\nexport function getLimitErrorGuidance(limitError: LimitErrorResponse): string[] {\n if (limitError.limitType === 'providers') {\n return [\n 'Provider setup required.',\n 'Add a DeepL API key in Dashboard -> Workspace Settings -> Providers.',\n `Open settings: ${limitError.upgradeUrl}`,\n ];\n }\n\n if (limitError.limitType === 'translation_chars') {\n return [\n 'Monthly translation character limit reached.',\n `Used this month: ${limitError.current.toLocaleString()} chars`,\n `Requested after sync: ${limitError.required.toLocaleString()} chars`,\n `Upgrade plan: ${limitError.upgradeUrl}`,\n ];\n }\n\n if (limitError.limitType === 'source_strings') {\n return [\n 'Active source string limit reached.',\n `Current active strings: ${limitError.current.toLocaleString()}`,\n `Required for this sync: ${limitError.required.toLocaleString()}`,\n `Upgrade plan: ${limitError.upgradeUrl}`,\n ];\n }\n\n return [\n `Plan: ${limitError.planId}`,\n `Current: ${limitError.current}`,\n `Required: ${limitError.required}`,\n `Upgrade: ${limitError.upgradeUrl}`,\n ];\n}\n\nfunction getSyncPolicyErrorGuidance(\n error: NonNullable<VocoderAPIError['syncPolicyError']>,\n): string[] {\n if (error.errorCode === 'BRANCH_NOT_ALLOWED') {\n const lines = ['This branch is not allowed for this project.'];\n if (error.branch) {\n lines.push(`Current branch: ${error.branch}`);\n }\n if (error.targetBranches && error.targetBranches.length > 0) {\n lines.push(`Allowed branches: ${error.targetBranches.join(', ')}`);\n }\n lines.push('Update your project target branches in the dashboard if needed.');\n return lines;\n }\n\n const lines = ['This project is bound to a different repository.'];\n if (error.boundRepoLabel) {\n lines.push(`Bound repository: ${error.boundRepoLabel}`);\n }\n if (error.boundScopePath) {\n lines.push(`Bound scope: ${error.boundScopePath}`);\n }\n lines.push(\n 'Run `vocoder init` from the correct repository or create a separate project.',\n );\n return lines;\n}\n\nfunction mergeContext(\n current: string | undefined,\n incoming: string | undefined,\n): string | undefined {\n if (!incoming) return current;\n if (!current) return incoming;\n if (current === incoming) return current;\n\n const merged = new Set(\n [...current.split(' | '), ...incoming.split(' | ')]\n .map((part) => part.trim())\n .filter(Boolean),\n );\n return Array.from(merged).join(' | ');\n}\n\nfunction buildStringEntries(\n extractedStrings: ExtractedString[],\n): TranslationStringEntry[] {\n const byText = new Map<string, TranslationStringEntry>();\n\n for (const str of extractedStrings) {\n const existing = byText.get(str.text);\n if (!existing) {\n byText.set(str.text, {\n key: str.key,\n text: str.text,\n ...(str.context ? { context: str.context } : {}),\n ...(str.formality ? { formality: str.formality } : {}),\n });\n continue;\n }\n\n existing.context = mergeContext(existing.context, str.context);\n\n if (!existing.formality && str.formality) {\n existing.formality = str.formality;\n } else if (\n existing.formality &&\n str.formality &&\n existing.formality !== str.formality\n ) {\n existing.formality = 'auto';\n }\n\n if (str.key < existing.key) {\n existing.key = str.key;\n }\n }\n\n return Array.from(byText.values());\n}\n\nasync function fetchApiSnapshot(api: VocoderAPI, params: {\n branch: string;\n targetLocales: string[];\n}): Promise<TranslationArtifacts | null> {\n const snapshot = await api.getTranslationSnapshot({\n branch: params.branch,\n targetLocales: params.targetLocales,\n });\n\n if (snapshot.status !== 'FOUND' || !snapshot.translations) {\n return null;\n }\n\n return {\n source: 'api-snapshot',\n translations: snapshot.translations,\n localeMetadata: snapshot.localeMetadata,\n snapshotBatchId: snapshot.snapshotBatchId,\n completedAt: snapshot.completedAt,\n };\n}\n\n/**\n * Main sync command\n */\nexport async function sync(options: TranslateOptions = {}): Promise<number> {\n const startTime = Date.now();\n const projectRoot = process.cwd();\n\n p.intro('Vocoder Sync');\n\n const spinner = p.spinner();\n\n try {\n spinner.start('Detecting branch');\n const branch = detectBranch(options.branch);\n spinner.stop(`Branch: ${chalk.cyan(branch)}`);\n\n spinner.start('Loading project configuration');\n\n const mergedConfig = await getMergedConfig(options, options.verbose);\n const localConfig = {\n apiKey: mergedConfig.apiKey || '',\n apiUrl: mergedConfig.apiUrl || 'https://vocoder.app',\n };\n validateLocalConfig(localConfig);\n\n const api = new VocoderAPI(localConfig);\n const apiConfig = await api.getProjectConfig();\n\n const requestedMode = mergedConfig.mode;\n const waitTimeoutMs = resolveWaitTimeoutMs({\n requestedMaxWaitMs: mergedConfig.maxWaitMs,\n policyDefaultMaxWaitMs: apiConfig.syncPolicy.defaultMaxWaitMs,\n fallbackTimeoutMs: 60_000,\n });\n\n const config: ProjectConfig = {\n ...localConfig,\n ...apiConfig,\n extractionPattern: mergedConfig.extractionPattern,\n excludePattern: mergedConfig.excludePattern,\n timeout: waitTimeoutMs,\n };\n\n spinner.stop('Project configuration loaded');\n\n if (!options.force && !isTargetBranch(branch, config.targetBranches)) {\n p.log.warn(\n `Skipping translations (${chalk.cyan(branch)} is not a target branch)`,\n );\n p.log.info(`Target branches: ${config.targetBranches.join(', ')}`);\n p.log.info('Use --force to translate anyway');\n p.outro('');\n return 0;\n }\n\n const patternsDisplay = Array.isArray(config.extractionPattern)\n ? config.extractionPattern.join(', ')\n : config.extractionPattern;\n\n spinner.start(`Extracting strings from ${patternsDisplay}`);\n const extractor = new StringExtractor();\n const extractedStrings = await extractor.extractFromProject(\n config.extractionPattern,\n projectRoot,\n config.excludePattern,\n );\n\n if (extractedStrings.length === 0) {\n spinner.stop('No translatable strings found');\n p.log.warn('Make sure you are using <T> components from @vocoder/react');\n p.outro('');\n return 0;\n }\n\n spinner.stop(\n `Extracted ${chalk.cyan(extractedStrings.length)} strings from ${chalk.cyan(patternsDisplay)}`,\n );\n\n if (options.verbose) {\n const sampleLines = extractedStrings\n .slice(0, 5)\n .map((s: ExtractedString) => ` \"${s.text}\" (${s.file}:${s.line})`);\n if (extractedStrings.length > 5) {\n sampleLines.push(` ... and ${extractedStrings.length - 5} more`);\n }\n p.note(sampleLines.join('\\n'), 'Sample strings');\n }\n\n if (options.dryRun) {\n p.note(\n [\n `Strings: ${extractedStrings.length}`,\n `Branch: ${branch}`,\n `Target locales: ${config.targetLocales.join(', ')}`,\n `Requested mode: ${requestedMode}`,\n `Max wait: ${waitTimeoutMs}ms`,\n `No fallback: ${mergedConfig.noFallback ? 'yes' : 'no'}`,\n ].join('\\n'),\n 'Dry run - would translate',\n );\n p.outro('No API calls made.');\n return 0;\n }\n\n const repoIdentity = resolveGitRepositoryIdentity();\n if (!repoIdentity && options.verbose) {\n p.log.warn(\n 'Could not detect git remote origin. Sync will continue without repo metadata.',\n );\n }\n\n const stringEntries = buildStringEntries(extractedStrings);\n const sourceStrings = stringEntries.map((entry) => entry.text);\n\n if (options.verbose && stringEntries.length !== extractedStrings.length) {\n p.log.info(\n `Deduped ${extractedStrings.length} extracted entries into ${stringEntries.length} unique source strings`,\n );\n }\n\n spinner.start('Submitting strings to Vocoder API');\n\n const batchResponse = await api.submitTranslation(\n branch,\n stringEntries,\n config.targetLocales,\n {\n requestedMode,\n requestedMaxWaitMs: waitTimeoutMs,\n clientRunId: randomUUID(),\n },\n repoIdentity ?? undefined,\n );\n\n spinner.stop(`Submitted to API - Batch ${chalk.cyan(batchResponse.batchId)}`);\n\n const effectiveMode = batchResponse.effectiveMode ??\n resolveEffectiveModeFromPolicy({\n branch,\n requestedMode,\n policy: config.syncPolicy,\n });\n\n if (options.verbose) {\n p.log.info(`Requested mode: ${requestedMode}`);\n p.log.info(`Effective mode: ${effectiveMode}`);\n p.log.info(`Wait timeout: ${waitTimeoutMs}ms`);\n if (batchResponse.queueStatus) {\n p.log.info(`Queue status: ${batchResponse.queueStatus}`);\n }\n }\n\n if (batchResponse.status === 'UP_TO_DATE' && batchResponse.noChanges) {\n p.log.success('No changes detected - strings are up to date');\n }\n\n p.log.info(`New strings: ${chalk.cyan(batchResponse.newStrings)}`);\n\n if (batchResponse.deletedStrings && batchResponse.deletedStrings > 0) {\n p.log.info(\n `Deleted strings: ${chalk.yellow(batchResponse.deletedStrings)} (archived)`,\n );\n }\n\n p.log.info(`Total strings: ${chalk.cyan(batchResponse.totalStrings)}`);\n\n if (batchResponse.newStrings === 0) {\n p.log.success('No new strings - using existing translations');\n } else {\n p.log.info(\n `Syncing to ${config.targetLocales.length} locales (${config.targetLocales.join(', ')})`,\n );\n\n if (batchResponse.estimatedTime) {\n p.log.info(`Estimated time: ~${batchResponse.estimatedTime}s`);\n }\n }\n\n let artifacts: TranslationArtifacts | null = null;\n if (batchResponse.translations) {\n artifacts = {\n source: 'fresh',\n translations: batchResponse.translations,\n };\n }\n\n let waitError: Error | null = null;\n if (!artifacts && (effectiveMode === 'required' || effectiveMode === 'best-effort')) {\n spinner.start(`Waiting for translations (max ${waitTimeoutMs}ms)`);\n\n let lastProgress = 0;\n try {\n const completion = await api.waitForCompletion(\n batchResponse.batchId,\n waitTimeoutMs,\n (progress) => {\n const percent = Math.round(progress * 100);\n if (percent > lastProgress) {\n spinner.message(`Translating... ${percent}%`);\n lastProgress = percent;\n }\n },\n );\n\n artifacts = {\n source: 'fresh',\n translations: completion.translations,\n localeMetadata: completion.localeMetadata,\n };\n spinner.stop('Translations complete');\n } catch (error) {\n spinner.stop('Translation wait incomplete');\n waitError = error instanceof Error ? error : new Error(String(error));\n\n if (effectiveMode === 'required') {\n throw waitError;\n }\n\n p.log.warn(`Best-effort wait ended early: ${waitError.message}`);\n }\n }\n\n if (!artifacts) {\n if (mergedConfig.noFallback) {\n throw new Error(\n 'Fresh translations are not available and fallback is disabled (--no-fallback).',\n );\n }\n\n spinner.start('Loading fallback translations');\n\n const localFallback = readLocalSnapshotCache({\n projectRoot,\n branch,\n });\n\n if (localFallback) {\n artifacts = localFallback;\n const cacheBranchLabel =\n localFallback.cacheBranch && localFallback.cacheBranch !== branch\n ? `${localFallback.cacheBranch} fallback`\n : localFallback.cacheBranch || branch;\n spinner.stop(`Using local cached snapshot (${cacheBranchLabel})`);\n } else {\n try {\n const apiSnapshot = await fetchApiSnapshot(api, {\n branch,\n targetLocales: config.targetLocales,\n });\n\n if (apiSnapshot) {\n artifacts = apiSnapshot;\n spinner.stop('Using latest completed API snapshot');\n } else {\n spinner.stop('No completed API snapshot available');\n }\n } catch (error) {\n spinner.stop('Failed to fetch API snapshot');\n if (options.verbose) {\n const message =\n error instanceof Error ? error.message : 'Unknown snapshot fetch error';\n p.log.warn(`Snapshot fetch error: ${message}`);\n }\n }\n }\n\n if (!artifacts) {\n if (waitError) {\n throw new Error(\n `No fallback snapshot available after wait failure: ${waitError.message}`,\n );\n }\n\n throw new Error(\n 'No fallback snapshot available. Try again shortly or run with --mode required.',\n );\n }\n }\n\n const finalTranslations = normalizeTranslations({\n sourceLocale: config.sourceLocale,\n targetLocales: config.targetLocales,\n sourceStrings,\n translations: artifacts.translations,\n });\n\n try {\n const cachePath = writeLocalSnapshotCache({\n projectRoot,\n branch,\n sourceLocale: config.sourceLocale,\n targetLocales: config.targetLocales,\n translations: finalTranslations,\n localeMetadata: artifacts.localeMetadata,\n snapshotBatchId:\n artifacts.snapshotBatchId ??\n (artifacts.source === 'fresh'\n ? batchResponse.batchId\n : batchResponse.latestCompletedBatchId),\n completedAt:\n artifacts.completedAt ??\n (artifacts.source === 'fresh' ? new Date().toISOString() : null),\n });\n\n if (options.verbose) {\n p.log.info(`Cached snapshot: ${cachePath}`);\n }\n } catch (error) {\n if (options.verbose) {\n const message =\n error instanceof Error ? error.message : 'Unknown cache write error';\n p.log.warn(`Failed to write local snapshot cache: ${message}`);\n }\n }\n\n if (artifacts.source !== 'fresh') {\n const sourceLabel =\n artifacts.source === 'local-cache'\n ? 'local cached snapshot'\n : 'completed API snapshot';\n p.log.warn(\n `Using ${sourceLabel}. New strings may appear after the background sync completes.`,\n );\n }\n\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n p.outro(`Sync complete! (${duration}s)`);\n\n p.log.info('Translations will be injected at build time by @vocoder/unplugin.');\n p.log.info('Just use <VocoderProvider> and <T> — no manual imports needed.');\n return 0;\n } catch (error) {\n spinner.stop();\n\n if (error instanceof VocoderAPIError && error.syncPolicyError) {\n p.log.error(error.syncPolicyError.message);\n const guidance = getSyncPolicyErrorGuidance(error.syncPolicyError);\n for (const line of guidance) {\n p.log.info(line);\n }\n return 1;\n }\n\n if (error instanceof VocoderAPIError && error.limitError) {\n const { limitError } = error;\n p.log.error(limitError.message);\n const guidance = getLimitErrorGuidance(limitError);\n for (const line of guidance) {\n p.log.info(line);\n }\n return 1;\n }\n\n if (error instanceof Error) {\n p.log.error(error.message);\n\n if (error.message.includes('VOCODER_API_KEY')) {\n p.log.warn('VOCODER_API_KEY is only needed for `vocoder sync` (CLI push).');\n p.log.info(' Create one at: https://vocoder.app/dashboard');\n p.log.info(' Then: export VOCODER_API_KEY=\"vc_...\" or add it to .env');\n p.log.info('');\n p.log.info(' Note: If you use @vocoder/unplugin, `vocoder sync` is optional.');\n p.log.info(' Translations are fetched automatically at build time.');\n } else if (error.message.includes('git branch')) {\n p.log.warn('Run from a git repository, or use:');\n p.log.info(' vocoder sync --branch main');\n }\n\n if (options.verbose) {\n p.log.info(`Full error: ${error.stack ?? error}`);\n }\n }\n\n return 1;\n }\n}\n","import { execSync } from 'child_process';\n\nconst REGEX_SPECIAL_CHARS = /[.+?^${}()|[\\]\\\\]/g;\n\nfunction escapeRegexChar(value: string): string {\n return value.replace(REGEX_SPECIAL_CHARS, '\\\\$&');\n}\n\n/**\n * Detects the current git branch from multiple sources in priority order:\n * 1. Explicit --branch flag (passed as parameter)\n * 2. CI environment variables (GitHub Actions, Vercel, Netlify, etc.)\n * 3. Git command (local development)\n *\n * @param override - Optional branch name to override detection\n * @returns The current branch name\n */\nexport function detectBranch(override?: string): string {\n // 1. Explicit override (from --branch flag)\n if (override) {\n return override;\n }\n\n // 2. CI environment variables\n const envBranch =\n process.env.GITHUB_HEAD_REF || // GitHub Actions (PR source branch)\n process.env.GITHUB_REF_NAME || // GitHub Actions (push)\n process.env.VERCEL_GIT_COMMIT_REF || // Vercel\n process.env.BRANCH || // Netlify\n process.env.CF_PAGES_BRANCH || // Cloudflare Pages\n process.env.CI_COMMIT_REF_NAME || // GitLab CI\n process.env.BITBUCKET_BRANCH || // Bitbucket Pipelines\n process.env.CIRCLE_BRANCH || // CircleCI\n process.env.RENDER_GIT_BRANCH; // Render\n\n if (envBranch) {\n return envBranch;\n }\n\n // 3. Git command (local development)\n try {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n }).trim();\n\n return branch;\n } catch (error) {\n throw new Error(\n 'Failed to detect git branch. Make sure you are in a git repository or set the --branch flag.',\n );\n }\n}\n\n/**\n * Checks if the current branch is a target branch that should trigger translations\n *\n * @param currentBranch - The current branch name\n * @param targetBranches - List of branches that should trigger translations\n * @returns True if the branch should trigger translations\n */\nexport function isTargetBranch(\n currentBranch: string,\n targetBranches: string[],\n): boolean {\n return targetBranches.some((pattern) =>\n matchBranchPattern(currentBranch, pattern),\n );\n}\n\nexport function matchBranchPattern(branch: string, pattern: string): boolean {\n const trimmedPattern = pattern.trim();\n if (!trimmedPattern) {\n return false;\n }\n\n let regexSource = '^';\n for (let i = 0; i < trimmedPattern.length; i += 1) {\n const char = trimmedPattern[i];\n if (!char) {\n continue;\n }\n\n if (char === '*') {\n const next = trimmedPattern[i + 1];\n if (next === '*') {\n regexSource += '.*';\n i += 1;\n } else {\n regexSource += '[^/]*';\n }\n continue;\n }\n\n regexSource += escapeRegexChar(char);\n }\n regexSource += '$';\n\n return new RegExp(regexSource).test(branch);\n}\n","import type { LocalConfig, RequestedSyncMode, TranslateOptions } from '../types.js';\n\nimport chalk from 'chalk';\nimport { config as loadEnv } from 'dotenv';\n\n// Load .env file if present\nloadEnv();\n\n/**\n * Validates the local configuration\n */\nexport function validateLocalConfig(config: LocalConfig): void {\n if (!config.apiKey || config.apiKey.length === 0) {\n throw new Error('VOCODER_API_KEY is required. Set it in your .env file.');\n }\n\n if (!config.apiKey.startsWith('vc_')) {\n throw new Error('Invalid API key format. Expected format: vc_...');\n }\n\n if (!config.apiUrl || !config.apiUrl.startsWith('http')) {\n throw new Error('Invalid API URL');\n }\n}\n\n/**\n * Merge configuration from all sources with priority:\n * 1. CLI flags (highest priority)\n * 2. Environment variables\n * 3. Defaults (lowest priority)\n *\n * @param cliOptions - Options from CLI flags\n * @param verbose - Whether to log config sources\n * @returns Merged configuration with source information\n */\nexport async function getMergedConfig(\n cliOptions: TranslateOptions,\n verbose: boolean = false,\n _startDir?: string\n): Promise<{\n extractionPattern: string[];\n excludePattern: string[];\n apiKey?: string;\n apiUrl?: string;\n mode: RequestedSyncMode;\n maxWaitMs?: number;\n noFallback: boolean;\n configSources: {\n extractionPattern: string;\n excludePattern: string;\n apiKey: string;\n apiUrl: string;\n mode: string;\n maxWaitMs: string;\n noFallback: string;\n };\n}> {\n const configSources = {\n extractionPattern: 'default',\n excludePattern: 'default',\n apiKey: 'environment',\n apiUrl: 'default',\n mode: 'default',\n maxWaitMs: 'default',\n noFallback: 'default',\n };\n\n // 1. Defaults\n const defaults = {\n extractionPattern: ['src/**/*.{tsx,jsx,ts,js}'],\n excludePattern: [] as string[],\n apiUrl: 'https://vocoder.app',\n };\n\n // 2. Environment variables\n const envExtractionPattern = process.env.VOCODER_EXTRACTION_PATTERN;\n const envApiUrl = process.env.VOCODER_API_URL;\n const envSyncMode = process.env.VOCODER_SYNC_MODE;\n const envSyncMaxWaitMs = process.env.VOCODER_SYNC_MAX_WAIT_MS;\n const envSyncNoFallback = process.env.VOCODER_SYNC_NO_FALLBACK;\n\n // 3. Merge with priority: CLI > env > defaults\n\n // Extract patterns (include)\n let extractionPattern: string[];\n if (cliOptions.include && cliOptions.include.length > 0) {\n extractionPattern = cliOptions.include;\n configSources.extractionPattern = 'CLI flag';\n } else if (envExtractionPattern) {\n extractionPattern = [envExtractionPattern];\n configSources.extractionPattern = 'environment';\n } else {\n extractionPattern = defaults.extractionPattern;\n }\n\n // Exclude patterns\n let excludePattern: string[];\n if (cliOptions.exclude && cliOptions.exclude.length > 0) {\n excludePattern = cliOptions.exclude;\n configSources.excludePattern = 'CLI flag';\n } else {\n excludePattern = defaults.excludePattern;\n }\n\n // API key (from env)\n let apiKey: string | undefined;\n if (process.env.VOCODER_API_KEY) {\n apiKey = process.env.VOCODER_API_KEY;\n configSources.apiKey = 'environment';\n }\n\n // API URL\n let apiUrl: string;\n if (envApiUrl) {\n apiUrl = envApiUrl;\n configSources.apiUrl = 'environment';\n } else {\n apiUrl = defaults.apiUrl;\n }\n\n const modeCandidates = ['auto', 'required', 'best-effort'] as const;\n let mode: RequestedSyncMode = 'auto';\n if (cliOptions.mode && modeCandidates.includes(cliOptions.mode)) {\n mode = cliOptions.mode;\n configSources.mode = 'CLI flag';\n } else if (envSyncMode && modeCandidates.includes(envSyncMode as RequestedSyncMode)) {\n mode = envSyncMode as RequestedSyncMode;\n configSources.mode = 'environment';\n }\n\n let maxWaitMs: number | undefined;\n if (typeof cliOptions.maxWaitMs === 'number' && Number.isFinite(cliOptions.maxWaitMs) && cliOptions.maxWaitMs > 0) {\n maxWaitMs = Math.floor(cliOptions.maxWaitMs);\n configSources.maxWaitMs = 'CLI flag';\n } else if (envSyncMaxWaitMs) {\n const parsed = Number.parseInt(envSyncMaxWaitMs, 10);\n if (Number.isFinite(parsed) && parsed > 0) {\n maxWaitMs = parsed;\n configSources.maxWaitMs = 'environment';\n }\n }\n\n let noFallback = false;\n if (typeof cliOptions.noFallback === 'boolean') {\n noFallback = cliOptions.noFallback;\n configSources.noFallback = 'CLI flag';\n } else if (envSyncNoFallback) {\n noFallback = ['1', 'true', 'yes', 'on'].includes(envSyncNoFallback.toLowerCase());\n configSources.noFallback = 'environment';\n }\n\n // Log config sources in verbose mode\n if (verbose) {\n console.log(chalk.dim('\\n Configuration sources:'));\n console.log(chalk.dim(` Include patterns: ${configSources.extractionPattern}`));\n if (excludePattern.length > 0) {\n console.log(chalk.dim(` Exclude patterns: ${configSources.excludePattern}`));\n }\n console.log(chalk.dim(` API key: ${configSources.apiKey}`));\n console.log(chalk.dim(` API URL: ${configSources.apiUrl}\\n`));\n console.log(chalk.dim(` Sync mode: ${configSources.mode}`));\n if (maxWaitMs) {\n console.log(chalk.dim(` Max wait: ${configSources.maxWaitMs}`));\n }\n console.log(chalk.dim(` No fallback: ${configSources.noFallback}\\n`));\n }\n\n return {\n extractionPattern,\n excludePattern,\n apiKey,\n apiUrl,\n mode,\n maxWaitMs,\n noFallback,\n configSources,\n };\n}\n","import { createHash } from 'crypto';\nimport { readFileSync } from 'fs';\nimport { parse } from '@babel/parser';\nimport babelTraverse from '@babel/traverse';\nimport { glob } from 'glob';\nimport { relative as pathRelative } from 'path';\nimport type { ExtractedString } from '../types.js';\n\n// Handle default export difference between ESM and CommonJS\nconst traverse = (babelTraverse as any).default || babelTraverse;\n\n/**\n * Extract translatable strings from source files\n *\n * NOTE: This is a simplified version for the CLI MVP.\n * Eventually this logic should be moved to a shared @vocoder/extraction package\n * that can be used by both the CLI and the backend.\n */\nexport class StringExtractor {\n /**\n * Extract strings from all files matching the pattern(s)\n *\n * @param pattern - Glob pattern(s) to include\n * @param projectRoot - Project root directory\n * @param excludePattern - Glob pattern(s) to exclude (optional)\n */\n async extractFromProject(\n pattern: string | string[],\n projectRoot: string = process.cwd(),\n excludePattern?: string | string[],\n ): Promise<ExtractedString[]> {\n // Normalize patterns to arrays\n const includePatterns = Array.isArray(pattern) ? pattern : [pattern];\n\n // Default ignore patterns (always excluded)\n const defaultIgnore = ['**/node_modules/**', '**/.next/**', '**/dist/**', '**/build/**'];\n\n // Merge user exclude patterns with defaults\n const ignorePatterns = excludePattern\n ? [...defaultIgnore, ...(Array.isArray(excludePattern) ? excludePattern : [excludePattern])]\n : defaultIgnore;\n\n // Find all files matching any of the include patterns (OR behavior)\n const allFiles = new Set<string>();\n\n for (const includePattern of includePatterns) {\n const files = await glob(includePattern, {\n cwd: projectRoot,\n absolute: true,\n ignore: ignorePatterns,\n });\n\n files.forEach((file: string) => allFiles.add(file));\n }\n\n const allStrings: ExtractedString[] = [];\n\n // Extract from each file\n const sortedFiles = Array.from(allFiles).sort();\n\n for (const file of sortedFiles) {\n try {\n const strings = await this.extractFromFile(file, projectRoot);\n allStrings.push(...strings);\n } catch (error) {\n console.warn(`Warning: Failed to extract from ${file}:`, error);\n }\n }\n\n // Deduplicate strings (same text = one entry)\n const unique = this.deduplicateStrings(allStrings);\n\n return unique;\n }\n\n /**\n * Extract strings from a single file\n */\n private async extractFromFile(\n filePath: string,\n projectRoot: string,\n ): Promise<ExtractedString[]> {\n const code = readFileSync(filePath, 'utf-8');\n const strings: ExtractedString[] = [];\n const relativeFilePath = pathRelative(projectRoot, filePath).split('\\\\').join('/');\n\n try {\n // Parse the code\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n // Track imports from @vocoder/react\n const vocoderImports = new Map<string, string>();\n const tFunctionNames = new Set<string>(); // Track 't' function names\n\n // Traverse the AST\n traverse(ast, {\n // Track imports of <T> component and t function\n ImportDeclaration: (path: any) => {\n const source = path.node.source.value;\n\n if (source === '@vocoder/react') {\n path.node.specifiers.forEach((spec: any) => {\n if (spec.type === 'ImportSpecifier') {\n const imported =\n spec.imported.type === 'Identifier'\n ? spec.imported.name\n : null;\n const local = spec.local.name;\n\n if (imported === 'T') {\n vocoderImports.set(local, 'T');\n }\n // Track direct import of 't' function\n if (imported === 't') {\n tFunctionNames.add(local);\n }\n // Track useVocoder hook (which provides 't')\n if (imported === 'useVocoder') {\n // We'll track destructured 't' in VariableDeclarator\n }\n }\n });\n }\n },\n\n // Track destructured 't' from useVocoder hook\n VariableDeclarator: (path: any) => {\n const init = path.node.init;\n\n // Check if this is: const { t } = useVocoder()\n if (\n init &&\n init.type === 'CallExpression' &&\n init.callee.type === 'Identifier' &&\n init.callee.name === 'useVocoder' &&\n path.node.id.type === 'ObjectPattern'\n ) {\n path.node.id.properties.forEach((prop: any) => {\n if (\n prop.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === 't'\n ) {\n const localName =\n prop.value.type === 'Identifier' ? prop.value.name : 't';\n tFunctionNames.add(localName);\n }\n });\n }\n },\n\n // Extract from t() function calls\n CallExpression: (path: any) => {\n const callee = path.node.callee;\n\n // Check if this is a call to 't' function\n const isTFunction =\n callee.type === 'Identifier' && tFunctionNames.has(callee.name);\n\n if (!isTFunction) return;\n\n // Get the first argument (the string to translate)\n const firstArg = path.node.arguments[0];\n if (!firstArg) return;\n\n let text: string | null = null;\n\n // Handle string literal: t('Hello')\n if (firstArg.type === 'StringLiteral') {\n text = firstArg.value;\n }\n // Handle template literal: t(`Hello ${name}`)\n else if (firstArg.type === 'TemplateLiteral') {\n text = this.extractTemplateText(firstArg);\n }\n\n if (!text || text.trim().length === 0) return;\n\n // Get options from second argument\n const secondArg = path.node.arguments[1];\n let context: string | undefined;\n let formality: 'formal' | 'informal' | 'neutral' | 'auto' | undefined;\n let explicitKey: string | undefined;\n\n if (secondArg && secondArg.type === 'ObjectExpression') {\n secondArg.properties.forEach((prop: any) => {\n if (prop.type === 'ObjectProperty' && prop.key.type === 'Identifier') {\n if (prop.key.name === 'context' && prop.value.type === 'StringLiteral') {\n context = prop.value.value;\n }\n if (prop.key.name === 'formality' && prop.value.type === 'StringLiteral') {\n formality = prop.value.value as 'formal' | 'informal' | 'neutral' | 'auto';\n }\n if (prop.key.name === 'id' && prop.value.type === 'StringLiteral') {\n explicitKey = prop.value.value.trim();\n }\n }\n });\n }\n\n const line = path.node.loc?.start.line || 0;\n const column = path.node.loc?.start.column || 0;\n const key = explicitKey && explicitKey.length > 0\n ? explicitKey\n : this.generateStableKey({\n filePath: relativeFilePath,\n kind: 't-call',\n line,\n column,\n });\n\n strings.push({\n key,\n text: text.trim(),\n file: filePath,\n line,\n context,\n formality,\n });\n },\n\n // Extract from JSX elements\n JSXElement: (path: any) => {\n const opening = path.node.openingElement;\n const tagName =\n opening.name.type === 'JSXIdentifier'\n ? opening.name.name\n : null;\n\n if (!tagName) return;\n\n // Check if this is a <T> component (or aliased import)\n const isTranslationComponent = vocoderImports.has(tagName);\n\n if (!isTranslationComponent) return;\n\n // Check for msg attribute first (preferred for ICU messages)\n const msgAttribute = this.getStringAttribute(opening.attributes, 'msg');\n\n // Extract text - prefer msg attribute over children\n const text = msgAttribute || this.extractTextContent(path.node.children);\n\n if (!text || text.trim().length === 0) return;\n\n // Extract context and formality from props\n const id = this.getStringAttribute(opening.attributes, 'id');\n const context = this.getStringAttribute(opening.attributes, 'context');\n const formality = this.getStringAttribute(\n opening.attributes,\n 'formality',\n ) as 'formal' | 'informal' | 'neutral' | 'auto' | undefined;\n const line = path.node.loc?.start.line || 0;\n const column = path.node.loc?.start.column || 0;\n const key = id && id.trim().length > 0\n ? id.trim()\n : this.generateStableKey({\n filePath: relativeFilePath,\n kind: 'jsx',\n line,\n column,\n });\n\n strings.push({\n key,\n text: text.trim(),\n file: filePath,\n line,\n context,\n formality,\n });\n },\n });\n } catch (error) {\n throw new Error(\n `Failed to parse ${filePath}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n\n return strings;\n }\n\n /**\n * Extract text from template literal\n * Converts template literals like `Hello ${name}` to `Hello {name}`\n */\n private extractTemplateText(node: any): string {\n let text = '';\n\n for (let i = 0; i < node.quasis.length; i++) {\n const quasi = node.quasis[i];\n text += quasi.value.raw;\n\n // Add placeholder for expressions\n if (i < node.expressions.length) {\n const expr = node.expressions[i];\n if (expr.type === 'Identifier') {\n text += `{${expr.name}}`;\n } else {\n // For complex expressions, use generic placeholder\n text += '{value}';\n }\n }\n }\n\n return text;\n }\n\n /**\n * Extract text content from JSX children\n */\n private extractTextContent(children: any[]): string {\n let text = '';\n\n for (const child of children) {\n if (child.type === 'JSXText') {\n text += child.value;\n } else if (child.type === 'JSXExpressionContainer') {\n const expr = child.expression;\n\n // Handle {variableName} - actual identifier\n if (expr.type === 'Identifier') {\n text += `{${expr.name}}`;\n }\n // Handle {\"{variableName}\"} - string literal placeholder\n else if (expr.type === 'StringLiteral') {\n text += expr.value;\n }\n // Handle {`${variableName}`} - template literal\n // Convert template literal syntax to ICU MessageFormat: `$${price}` → ${price}\n else if (expr.type === 'TemplateLiteral') {\n text += this.extractTemplateText(expr);\n }\n }\n }\n\n return text;\n }\n\n /**\n * Get string value from JSX attribute\n * Handles both string literals and template literals\n */\n private getStringAttribute(\n attributes: any[],\n name: string,\n ): string | undefined {\n const attr = attributes.find(\n (a) => a.type === 'JSXAttribute' && a.name.name === name,\n );\n\n if (!attr || !attr.value) return undefined;\n\n // Handle string literal: msg=\"Hello\"\n if (attr.value.type === 'StringLiteral') {\n return attr.value.value;\n }\n\n // Handle JSX expression container: msg={...}\n if (attr.value.type === 'JSXExpressionContainer') {\n const expr = attr.value.expression;\n\n // Handle template literal: msg={`Hello ${name}`}\n if (expr.type === 'TemplateLiteral') {\n return this.extractTemplateText(expr);\n }\n\n // Handle string literal in expression: msg={'Hello'}\n if (expr.type === 'StringLiteral') {\n return expr.value;\n }\n }\n\n return undefined;\n }\n\n /**\n * Deduplicate strings (keep first occurrence)\n */\n private deduplicateStrings(strings: ExtractedString[]): ExtractedString[] {\n const seen = new Map<string, number>();\n const unique: ExtractedString[] = [];\n\n for (const str of strings) {\n // Create a key based on text + context + formality\n const dedupeKey = `${str.text}|${str.context || ''}|${str.formality || ''}`;\n\n const existingIndex = seen.get(dedupeKey);\n if (existingIndex === undefined) {\n seen.set(dedupeKey, unique.length);\n unique.push(str);\n continue;\n }\n\n // Keep the lexicographically smallest key for deterministic stability\n const existing = unique[existingIndex];\n if (existing && str.key < existing.key) {\n existing.key = str.key;\n }\n }\n\n return unique;\n }\n\n private generateStableKey(params: {\n filePath: string;\n kind: 'jsx' | 't-call';\n line: number;\n column: number;\n }): string {\n const payload = `${params.filePath}|${params.kind}|${params.line}:${params.column}`;\n const digest = createHash('sha1').update(payload).digest('hex');\n return `SK_${digest.slice(0, 24).toUpperCase()}`;\n }\n}\n","import { readFileSync, writeFileSync } from 'fs';\nimport { relative } from 'path';\nimport * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport { StringAnalyzer } from '../utils/wrap/analyzer.js';\nimport { StringTransformer } from '../utils/wrap/transformer.js';\nimport { reactAdapter } from '../utils/wrap/adapters/react.js';\nimport type { WrapOptions, WrapCandidate, ConfidenceLevel } from '../utils/wrap/types.js';\n\nconst CONFIDENCE_ORDER: ConfidenceLevel[] = ['high', 'medium', 'low'];\n\nfunction meetsConfidenceThreshold(\n candidate: ConfidenceLevel,\n threshold: ConfidenceLevel,\n): boolean {\n return CONFIDENCE_ORDER.indexOf(candidate) <= CONFIDENCE_ORDER.indexOf(threshold);\n}\n\n/**\n * Main wrap command\n *\n * Workflow:\n * 1. Scan files for unwrapped strings\n * 2. Classify each string with heuristics\n * 3. Filter by confidence threshold\n * 4. Optionally preview (dry-run) or confirm (interactive)\n * 5. Transform files with <T> and t() wrappers\n * 6. Write transformed files\n */\nexport async function wrap(options: WrapOptions = {}): Promise<number> {\n const startTime = Date.now();\n const projectRoot = process.cwd();\n const confidenceThreshold = options.confidence || 'high';\n\n p.intro('Vocoder Wrap');\n\n const spinner = p.spinner();\n\n try {\n // 1. Scan files\n spinner.start('Scanning files for unwrapped strings');\n\n const analyzer = new StringAnalyzer(reactAdapter);\n const allCandidates = await analyzer.analyzeProject(options, projectRoot);\n\n if (allCandidates.length === 0) {\n spinner.stop('No unwrapped strings found');\n p.log.info('All user-facing strings appear to be wrapped already.');\n p.outro('');\n return 0;\n }\n\n spinner.stop(\n `Found ${chalk.cyan(allCandidates.length)} candidate strings`,\n );\n\n // 2. Filter by confidence\n const filtered = allCandidates.filter((c: WrapCandidate) =>\n meetsConfidenceThreshold(c.confidence, confidenceThreshold),\n );\n\n if (filtered.length === 0) {\n p.log.warn(\n `No strings meet the ${chalk.bold(confidenceThreshold)} confidence threshold.`,\n );\n p.log.info('Try --confidence medium or --confidence low to see more candidates.');\n p.outro('');\n return 0;\n }\n\n p.log.info(\n `${filtered.length} strings meet ${chalk.bold(confidenceThreshold)} confidence threshold`,\n );\n\n // Group candidates by file\n const byFile = new Map<string, WrapCandidate[]>();\n for (const c of filtered) {\n const existing = byFile.get(c.file) || [];\n existing.push(c);\n byFile.set(c.file, existing);\n }\n\n // 3. Dry-run mode\n if (options.dryRun) {\n const lines: string[] = [];\n for (const [file, candidates] of byFile) {\n const relPath = relative(projectRoot, file);\n lines.push(chalk.bold(relPath));\n\n for (const c of candidates) {\n const confidenceColor =\n c.confidence === 'high' ? chalk.green :\n c.confidence === 'medium' ? chalk.yellow :\n chalk.red;\n\n const strategyLabel = c.strategy === 'T-component' ? '<T>' : 't()';\n lines.push(\n ` ${chalk.dim(`L${c.line}`)} ${confidenceColor(`[${c.confidence}]`)} ` +\n `${chalk.cyan(strategyLabel)} \"${truncate(c.text, 50)}\"`,\n );\n\n if (options.verbose) {\n lines.push(chalk.dim(` ${c.reason}`));\n }\n }\n lines.push('');\n }\n\n lines.push(summarizeCandidates(filtered));\n p.note(lines.join('\\n'), 'Dry run — would wrap');\n p.outro('Run without --dry-run to apply changes.');\n return 0;\n }\n\n // 4. Interactive mode\n let accepted: WrapCandidate[];\n\n if (options.interactive) {\n accepted = await interactiveConfirm(byFile, projectRoot);\n if (accepted.length === 0) {\n p.log.warn('No strings selected for wrapping.');\n p.outro('');\n return 0;\n }\n } else {\n accepted = filtered;\n }\n\n // 5. Transform files\n spinner.start('Wrapping strings');\n\n const transformer = new StringTransformer(reactAdapter);\n let totalWrapped = 0;\n let filesModified = 0;\n\n // Group accepted candidates by file\n const acceptedByFile = new Map<string, WrapCandidate[]>();\n for (const c of accepted) {\n const existing = acceptedByFile.get(c.file) || [];\n existing.push(c);\n acceptedByFile.set(c.file, existing);\n }\n\n for (const [file, candidates] of acceptedByFile) {\n const code = readFileSync(file, 'utf-8');\n const result = transformer.transform(code, candidates, file);\n\n if (result.wrappedCount > 0) {\n writeFileSync(file, result.output, 'utf-8');\n totalWrapped += result.wrappedCount;\n filesModified++;\n }\n\n if (options.verbose && result.skipped.length > 0) {\n const relPath = relative(projectRoot, file);\n p.log.info(`Skipped ${result.skipped.length} strings in ${relPath}`);\n }\n }\n\n spinner.stop(\n `Wrapped ${chalk.cyan(totalWrapped)} strings across ${chalk.cyan(filesModified)} files`,\n );\n\n // 6. Summary\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n p.outro(`Done! (${duration}s)`);\n\n p.log.info('Next steps:');\n p.log.info(' 1. Review the changes (git diff)');\n p.log.info(' 2. Run your tests to verify nothing broke');\n p.log.info(' 3. Run \"vocoder sync\" to extract and translate');\n return 0;\n\n } catch (error: unknown) {\n spinner.stop();\n if (error instanceof Error) {\n p.log.error(error.message);\n if (options.verbose) {\n p.log.info(`Full error: ${error.stack ?? error}`);\n }\n }\n return 1;\n }\n}\n\n/**\n * Interactive confirmation mode.\n * Prompts user for each candidate using clack select.\n */\nasync function interactiveConfirm(\n byFile: Map<string, WrapCandidate[]>,\n projectRoot: string,\n): Promise<WrapCandidate[]> {\n const accepted: WrapCandidate[] = [];\n\n p.log.info('Interactive mode — confirm each string:');\n\n for (const [file, candidates] of byFile) {\n const relPath = relative(projectRoot, file);\n p.log.step(chalk.bold(relPath));\n\n let skipFile = false;\n\n for (const c of candidates) {\n if (skipFile) break;\n\n const strategyLabel = c.strategy === 'T-component' ? '<T>' : 't()';\n const label = `L${c.line} ${strategyLabel} \"${truncate(c.text, 50)}\"`;\n\n const action = await p.select({\n message: label,\n options: [\n { value: 'yes', label: 'Yes, wrap this string' },\n { value: 'no', label: 'No, skip' },\n { value: 'all', label: 'Accept all remaining' },\n { value: 'skip', label: 'Skip this file' },\n { value: 'quit', label: 'Quit' },\n ],\n });\n\n if (p.isCancel(action) || action === 'quit') {\n return accepted;\n }\n\n if (action === 'yes') {\n accepted.push(c);\n } else if (action === 'all') {\n accepted.push(c);\n // Accept all remaining in this file\n const remaining = candidates.slice(candidates.indexOf(c) + 1);\n accepted.push(...remaining);\n // Accept all remaining files\n for (const [, moreCandidates] of byFile) {\n if (moreCandidates !== candidates) {\n accepted.push(...moreCandidates);\n }\n }\n return accepted;\n } else if (action === 'skip') {\n skipFile = true;\n }\n // 'no' — just continue\n }\n }\n\n return accepted;\n}\n\nfunction truncate(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return text.slice(0, maxLen - 3) + '...';\n}\n\nfunction summarizeCandidates(candidates: WrapCandidate[]): string {\n let high = 0;\n let medium = 0;\n let low = 0;\n let tComponent = 0;\n let tFunction = 0;\n\n for (const c of candidates) {\n if (c.confidence === 'high') high++;\n else if (c.confidence === 'medium') medium++;\n else low++;\n\n if (c.strategy === 'T-component') tComponent++;\n else tFunction++;\n }\n\n const parts: string[] = [];\n if (high > 0) parts.push(chalk.green(`${high} high`));\n if (medium > 0) parts.push(chalk.yellow(`${medium} medium`));\n if (low > 0) parts.push(chalk.red(`${low} low`));\n\n return `${candidates.length} total (${parts.join(', ')}) | ${tComponent} <T>, ${tFunction} t()`;\n}\n","/**\n * AST analyzer that traverses source files to find\n * strings that should be wrapped for translation.\n */\n\nimport { readFileSync } from 'fs';\nimport { parse } from '@babel/parser';\nimport babelTraverse from '@babel/traverse';\nimport type { Node } from '@babel/types';\nimport { glob } from 'glob';\nimport { classifyString, isTranslatableVarName } from './heuristics.js';\nimport type { FrameworkAdapter, WrapCandidate, WrapOptions, StringContext } from './types.js';\n\n// Handle default export difference between ESM and CommonJS\nconst traverse = (babelTraverse as any).default || babelTraverse;\n\nexport class StringAnalyzer {\n private adapter: FrameworkAdapter;\n\n constructor(adapter: FrameworkAdapter) {\n this.adapter = adapter;\n }\n\n /**\n * Analyze all files matching the given patterns and return wrap candidates.\n */\n async analyzeProject(\n options: WrapOptions,\n projectRoot: string = process.cwd(),\n ): Promise<WrapCandidate[]> {\n const includePatterns = options.include?.length\n ? options.include\n : ['src/**/*.{tsx,jsx,ts,js}'];\n\n const defaultIgnore = [\n '**/node_modules/**',\n '**/.next/**',\n '**/dist/**',\n '**/build/**',\n '**/*.test.*',\n '**/*.spec.*',\n '**/*.stories.*',\n '**/__tests__/**',\n ];\n\n const ignorePatterns = options.exclude\n ? [...defaultIgnore, ...options.exclude]\n : defaultIgnore;\n\n const allFiles = new Set<string>();\n\n for (const pattern of includePatterns) {\n const files = await glob(pattern, {\n cwd: projectRoot,\n absolute: true,\n ignore: ignorePatterns,\n });\n files.forEach((file: string) => allFiles.add(file));\n }\n\n const allCandidates: WrapCandidate[] = [];\n\n for (const file of allFiles) {\n try {\n const candidates = this.analyzeFile(file);\n allCandidates.push(...candidates);\n } catch (error: unknown) {\n if (options.verbose) {\n const msg = error instanceof Error ? error.message : 'Unknown error';\n console.warn(`Warning: Failed to analyze ${file}: ${msg}`);\n }\n }\n }\n\n return allCandidates;\n }\n\n /**\n * Analyze a single file and return wrap candidates.\n */\n analyzeFile(filePath: string): WrapCandidate[] {\n const code = readFileSync(filePath, 'utf-8');\n return this.analyzeCode(code, filePath);\n }\n\n /**\n * Analyze source code and return wrap candidates.\n */\n analyzeCode(code: string, filePath: string = '<input>'): WrapCandidate[] {\n const candidates: WrapCandidate[] = [];\n\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n // Track existing vocoder imports\n const vocoderImports = new Map<string, string>();\n const tFunctionNames = new Set<string>();\n\n traverse(ast, {\n // Track imports from @vocoder/react\n ImportDeclaration: (path: any) => {\n const source = path.node.source.value as string;\n if (source === this.adapter.importSource) {\n path.node.specifiers.forEach((spec: any) => {\n if (spec.type === 'ImportSpecifier') {\n const imported =\n spec.imported.type === 'Identifier' ? spec.imported.name : null;\n const local = spec.local.name as string;\n\n if (imported === this.adapter.componentName) {\n vocoderImports.set(local, this.adapter.componentName);\n }\n if (imported === this.adapter.functionName) {\n tFunctionNames.add(local);\n }\n if (imported === this.adapter.hookName) {\n vocoderImports.set(local, this.adapter.hookName);\n }\n }\n });\n }\n },\n\n // Track destructured t from useVocoder()\n VariableDeclarator: (path: any) => {\n const init = path.node.init;\n if (\n init &&\n init.type === 'CallExpression' &&\n init.callee.type === 'Identifier' &&\n init.callee.name === this.adapter.hookName &&\n path.node.id.type === 'ObjectPattern'\n ) {\n path.node.id.properties.forEach((prop: any) => {\n if (\n prop.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === this.adapter.functionName\n ) {\n const localName =\n prop.value.type === 'Identifier' ? prop.value.name : this.adapter.functionName;\n tFunctionNames.add(localName as string);\n }\n });\n }\n },\n\n // Find bare JSX text\n JSXText: (path: any) => {\n const text = path.node.value as string;\n const trimmed = text.trim();\n if (!trimmed) return;\n\n // Check if already inside <T>\n const ancestors = path.getAncestry().map((a: any) => a.node);\n if (this.adapter.isAlreadyWrapped(ancestors, vocoderImports)) return;\n\n const classification = classifyString(trimmed, 'jsx-text', {\n isInsideComponent: true,\n });\n\n if (classification.translatable) {\n candidates.push({\n file: filePath,\n line: path.node.loc?.start.line || 0,\n column: path.node.loc?.start.column || 0,\n text: trimmed,\n confidence: classification.confidence,\n strategy: 'T-component',\n context: 'jsx-text',\n reason: classification.reason,\n });\n }\n },\n\n // Find translatable JSX attributes\n JSXAttribute: (path: any) => {\n const attrName = path.node.name?.name as string | undefined;\n if (!attrName) return;\n\n const value = path.node.value;\n if (!value) return;\n\n let text: string | null = null;\n let context: StringContext = 'jsx-attribute';\n\n if (value.type === 'StringLiteral') {\n text = value.value as string;\n } else if (\n value.type === 'JSXExpressionContainer' &&\n value.expression.type === 'StringLiteral'\n ) {\n text = value.expression.value as string;\n }\n\n if (!text || !text.trim()) return;\n\n // Check if already wrapped in t()\n if (\n value.type === 'JSXExpressionContainer' &&\n value.expression.type === 'CallExpression'\n ) {\n if (this.adapter.isAlreadyWrappedCall(value.expression, tFunctionNames)) return;\n }\n\n const classification = classifyString(text.trim(), context, {\n attributeName: attrName,\n isInsideComponent: true,\n });\n\n if (classification.translatable) {\n candidates.push({\n file: filePath,\n line: path.node.loc?.start.line || 0,\n column: path.node.loc?.start.column || 0,\n text: text.trim(),\n confidence: classification.confidence,\n strategy: 't-function',\n context,\n reason: classification.reason,\n });\n }\n },\n\n // Find string literals in non-JSX contexts\n StringLiteral: (path: any) => {\n // Skip if this is part of an import/require\n if (path.parent.type === 'ImportDeclaration') return;\n if (path.parent.type === 'ExportDeclaration') return;\n\n // Skip if inside JSX attribute (handled by JSXAttribute visitor)\n if (path.parent.type === 'JSXAttribute') return;\n if (\n path.parent.type === 'JSXExpressionContainer' &&\n path.parentPath?.parent?.type === 'JSXAttribute'\n ) return;\n\n // Skip if inside JSX element (handled by JSXText visitor)\n if (path.parent.type === 'JSXExpressionContainer') return;\n\n // Skip if this is a key in an object\n if (path.parent.type === 'ObjectProperty' && path.parent.key === path.node) return;\n\n // Skip TypeScript type annotations\n if (path.parent.type === 'TSLiteralType') return;\n\n // Skip if already inside t()\n if (isInsideTCall(path, tFunctionNames)) return;\n\n const text = path.node.value as string;\n if (!text.trim()) return;\n\n // Determine parent context\n const callExpr = getEnclosingCallExpression(path);\n const parentType = path.parent.type as string;\n\n const classification = classifyString(text.trim(), 'string-literal', {\n parentType,\n isInsideCallExpression: callExpr,\n isInsideComponent: false,\n });\n\n // Boost confidence if variable name suggests translatable content\n let { confidence } = classification;\n if (\n parentType === 'VariableDeclarator' &&\n path.parent.id?.type === 'Identifier'\n ) {\n const varName = path.parent.id.name as string;\n if (isTranslatableVarName(varName) && classification.translatable) {\n confidence = 'high';\n }\n }\n\n if (classification.translatable) {\n candidates.push({\n file: filePath,\n line: path.node.loc?.start.line || 0,\n column: path.node.loc?.start.column || 0,\n text: text.trim(),\n confidence,\n strategy: 't-function',\n context: 'string-literal',\n reason: classification.reason,\n });\n }\n },\n\n // Find template literals\n TemplateLiteral: (path: any) => {\n // Skip if inside import/require\n if (path.parent.type === 'ImportDeclaration') return;\n\n // Skip tagged templates (e.g. css`...`, html`...`)\n if (path.parent.type === 'TaggedTemplateExpression') return;\n\n // Skip if already inside t()\n if (isInsideTCall(path, tFunctionNames)) return;\n\n // Skip templates with no static parts (pure expressions)\n const quasis = path.node.quasis as any[];\n if (quasis.length === 0) return;\n\n // Build the text representation\n const parts: string[] = [];\n for (let i = 0; i < quasis.length; i++) {\n const quasi = quasis[i];\n parts.push(quasi.value.raw as string);\n if (i < path.node.expressions.length) {\n const expr = path.node.expressions[i];\n if (expr.type === 'Identifier') {\n parts.push(`{${expr.name}}`);\n } else {\n parts.push('{value}');\n }\n }\n }\n const text = parts.join('').trim();\n if (!text) return;\n\n const callExpr = getEnclosingCallExpression(path);\n const parentType = path.parent.type as string;\n\n const classification = classifyString(text, 'template-literal', {\n parentType,\n isInsideCallExpression: callExpr,\n isInsideComponent: false,\n });\n\n if (classification.translatable) {\n candidates.push({\n file: filePath,\n line: path.node.loc?.start.line || 0,\n column: path.node.loc?.start.column || 0,\n text,\n confidence: classification.confidence,\n strategy: 't-function',\n context: 'template-literal',\n reason: classification.reason,\n });\n }\n },\n });\n\n return candidates;\n }\n}\n\n/**\n * Check if the current path is inside a t() call.\n */\nfunction isInsideTCall(path: any, tNames: Set<string>): boolean {\n let current = path.parentPath;\n while (current) {\n if (current.node.type === 'CallExpression') {\n const callee = current.node.callee;\n if (callee.type === 'Identifier' && tNames.has(callee.name as string)) {\n return true;\n }\n }\n current = current.parentPath;\n }\n return false;\n}\n\n/**\n * Get the name of the enclosing call expression, if any.\n * Returns names like \"console.log\", \"Error\", \"require\", etc.\n */\nfunction getEnclosingCallExpression(path: any): string | undefined {\n let current = path.parentPath;\n while (current) {\n if (current.node.type === 'CallExpression') {\n const callee = current.node.callee;\n if (callee.type === 'Identifier') {\n return callee.name as string;\n }\n if (\n callee.type === 'MemberExpression' &&\n callee.object.type === 'Identifier' &&\n callee.property.type === 'Identifier'\n ) {\n return `${callee.object.name}.${callee.property.name}`;\n }\n }\n // Also detect: throw new Error(...)\n if (current.node.type === 'NewExpression') {\n const callee = current.node.callee;\n if (callee.type === 'Identifier') {\n return callee.name as string;\n }\n }\n current = current.parentPath;\n }\n return undefined;\n}\n","/**\n * Heuristic classification engine for determining\n * whether a string is user-facing and translatable.\n */\n\nimport type {\n ClassificationResult,\n ClassificationMetadata,\n StringContext,\n} from './types.js';\n\n// Patterns that indicate a string should NEVER be translated\nconst URL_REGEX = /^(https?:\\/\\/|\\/\\/|mailto:|tel:|ftp:\\/\\/)/i;\nconst EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst FILE_PATH_REGEX = /^(\\.{0,2}\\/|[a-zA-Z]:\\\\)/;\nconst COLOR_HEX_REGEX = /^#([0-9a-fA-F]{3,8})$/;\nconst COLOR_FUNC_REGEX = /^(rgb|rgba|hsl|hsla)\\s*\\(/i;\nconst CAMEL_CASE_REGEX = /^[a-z][a-zA-Z0-9]*$/;\nconst PASCAL_CASE_REGEX = /^[A-Z][a-zA-Z0-9]*$/;\nconst SCREAMING_SNAKE_REGEX = /^[A-Z][A-Z0-9_]+$/;\nconst KEBAB_CASE_REGEX = /^[a-z][a-z0-9-]+$/;\nconst MIME_TYPE_REGEX = /^(application|text|image|audio|video|font|multipart)\\//;\nconst DATE_FORMAT_REGEX = /^[YMDHhmsaAZz\\-\\/\\.\\s:,]+$/;\nconst CSS_UNIT_REGEX = /^\\d+(\\.\\d+)?(px|em|rem|vh|vw|%|ch|ex|pt|pc|in|cm|mm)$/;\n\n// Tailwind-like CSS class patterns\nconst TAILWIND_REGEX =\n /^[a-z][\\w-]*(\\s+[a-z][\\w-]*)*$/;\nconst TAILWIND_PREFIXES = [\n 'flex', 'grid', 'block', 'inline', 'hidden', 'absolute', 'relative', 'fixed', 'sticky',\n 'top', 'bottom', 'left', 'right', 'inset',\n 'w-', 'h-', 'min-', 'max-', 'p-', 'px-', 'py-', 'pt-', 'pb-', 'pl-', 'pr-',\n 'm-', 'mx-', 'my-', 'mt-', 'mb-', 'ml-', 'mr-',\n 'text-', 'font-', 'leading-', 'tracking-', 'bg-', 'border-', 'rounded-',\n 'shadow-', 'opacity-', 'z-', 'gap-', 'space-',\n 'items-', 'justify-', 'self-', 'place-',\n 'overflow-', 'cursor-', 'transition-', 'duration-', 'ease-',\n 'sm:', 'md:', 'lg:', 'xl:', '2xl:', 'dark:', 'hover:', 'focus:', 'active:',\n 'group-', 'peer-',\n];\n\n// Non-translatable JSX attributes\nconst NON_TRANSLATABLE_ATTRIBUTES = new Set([\n 'className', 'class', 'href', 'src', 'id', 'key', 'ref', 'style',\n 'data-testid', 'data-cy', 'data-test',\n 'type', 'name', 'value', 'action', 'method', 'encType', 'target',\n 'rel', 'role', 'tabIndex', 'htmlFor', 'for',\n 'width', 'height', 'viewBox', 'xmlns', 'fill', 'stroke',\n 'onClick', 'onChange', 'onSubmit', 'onBlur', 'onFocus', 'onKeyDown',\n 'onKeyUp', 'onKeyPress', 'onMouseEnter', 'onMouseLeave',\n]);\n\n// Translatable JSX attributes\nconst TRANSLATABLE_ATTRIBUTES = new Set([\n 'title', 'placeholder', 'alt', 'aria-label', 'aria-description',\n 'aria-placeholder', 'aria-roledescription', 'aria-valuetext',\n 'label', 'description', 'message', 'heading', 'caption',\n 'helperText', 'errorMessage', 'successMessage', 'tooltip',\n]);\n\n// Non-translatable call expression contexts\nconst NON_TRANSLATABLE_CALLS = new Set([\n 'console.log', 'console.warn', 'console.error', 'console.info', 'console.debug',\n 'require', 'import',\n 'addEventListener', 'removeEventListener',\n 'querySelector', 'querySelectorAll', 'getElementById',\n 'getAttribute', 'setAttribute', 'createElement',\n 'JSON.parse', 'JSON.stringify',\n 'parseInt', 'parseFloat',\n 'encodeURIComponent', 'decodeURIComponent', 'encodeURI', 'decodeURI',\n 'RegExp',\n]);\n\n// Variable names that suggest translatable content\nconst TRANSLATABLE_VAR_NAMES = new Set([\n 'label', 'message', 'title', 'description', 'heading',\n 'text', 'caption', 'subtitle', 'tooltip',\n 'errorMessage', 'successMessage', 'warningMessage', 'infoMessage',\n 'placeholder', 'helperText', 'hint',\n 'buttonText', 'linkText', 'headerText', 'footerText',\n 'confirmText', 'cancelText', 'submitText',\n 'greeting', 'welcome', 'instructions',\n]);\n\n/**\n * Determine if a string is translatable and with what confidence.\n */\nexport function classifyString(\n text: string,\n context: StringContext,\n metadata: ClassificationMetadata = {},\n): ClassificationResult {\n const trimmed = text.trim();\n\n // --- SKIP RULES (never translate) ---\n\n // Empty or whitespace-only\n if (trimmed.length === 0) {\n return { translatable: false, confidence: 'high', reason: 'Empty or whitespace-only' };\n }\n\n // Single character\n if (trimmed.length === 1) {\n return { translatable: false, confidence: 'high', reason: 'Single character' };\n }\n\n // Punctuation-only (no letters)\n if (!/[a-zA-Z]/.test(trimmed)) {\n return { translatable: false, confidence: 'high', reason: 'No alphabetic characters' };\n }\n\n // URLs\n if (URL_REGEX.test(trimmed)) {\n return { translatable: false, confidence: 'high', reason: 'URL' };\n }\n\n // Email addresses\n if (EMAIL_REGEX.test(trimmed)) {\n return { translatable: false, confidence: 'high', reason: 'Email address' };\n }\n\n // File paths\n if (FILE_PATH_REGEX.test(trimmed) && !trimmed.includes(' ')) {\n return { translatable: false, confidence: 'high', reason: 'File path' };\n }\n\n // Color codes\n if (COLOR_HEX_REGEX.test(trimmed) || COLOR_FUNC_REGEX.test(trimmed)) {\n return { translatable: false, confidence: 'high', reason: 'Color code' };\n }\n\n // CSS units\n if (CSS_UNIT_REGEX.test(trimmed)) {\n return { translatable: false, confidence: 'high', reason: 'CSS unit value' };\n }\n\n // MIME types\n if (MIME_TYPE_REGEX.test(trimmed)) {\n return { translatable: false, confidence: 'high', reason: 'MIME type' };\n }\n\n // Date format strings (only non-word chars + format tokens)\n if (DATE_FORMAT_REGEX.test(trimmed) && trimmed.length > 1) {\n return { translatable: false, confidence: 'high', reason: 'Date format string' };\n }\n\n // --- ATTRIBUTE CHECKS (run before identifier checks) ---\n\n // Non-translatable attributes\n if (context === 'jsx-attribute' && metadata.attributeName) {\n if (NON_TRANSLATABLE_ATTRIBUTES.has(metadata.attributeName)) {\n return { translatable: false, confidence: 'high', reason: `Non-translatable attribute: ${metadata.attributeName}` };\n }\n\n // data-* attributes (except data-label, data-title, etc.)\n if (\n metadata.attributeName.startsWith('data-') &&\n !TRANSLATABLE_ATTRIBUTES.has(metadata.attributeName)\n ) {\n return { translatable: false, confidence: 'high', reason: 'data-* attribute' };\n }\n\n // Event handler attributes\n if (metadata.attributeName.startsWith('on') && metadata.attributeName.length > 2) {\n const thirdChar = metadata.attributeName[2];\n if (thirdChar && thirdChar === thirdChar.toUpperCase()) {\n return { translatable: false, confidence: 'high', reason: 'Event handler attribute' };\n }\n }\n\n // Translatable attributes — return early as high confidence\n if (TRANSLATABLE_ATTRIBUTES.has(metadata.attributeName)) {\n return { translatable: true, confidence: 'high', reason: `Translatable attribute: ${metadata.attributeName}` };\n }\n }\n\n // JSX text with words — return early as high confidence\n if (context === 'jsx-text') {\n const hasWords = /[a-zA-Z]{2,}/.test(trimmed);\n if (hasWords) {\n return { translatable: true, confidence: 'high', reason: 'JSX text with words' };\n }\n }\n\n // Identifiers: camelCase, PascalCase, SCREAMING_SNAKE (no spaces = code identifier)\n if (\n !trimmed.includes(' ') &&\n (CAMEL_CASE_REGEX.test(trimmed) ||\n PASCAL_CASE_REGEX.test(trimmed) ||\n SCREAMING_SNAKE_REGEX.test(trimmed) ||\n KEBAB_CASE_REGEX.test(trimmed))\n ) {\n return { translatable: false, confidence: 'high', reason: 'Code identifier' };\n }\n\n // Tailwind / CSS class strings\n if (isTailwindClasses(trimmed)) {\n return { translatable: false, confidence: 'high', reason: 'CSS/Tailwind classes' };\n }\n\n // Inside non-translatable call expressions\n if (metadata.isInsideCallExpression) {\n if (NON_TRANSLATABLE_CALLS.has(metadata.isInsideCallExpression)) {\n return { translatable: false, confidence: 'high', reason: `Inside ${metadata.isInsideCallExpression}()` };\n }\n }\n\n // throw new Error(...)\n if (metadata.parentType === 'ThrowStatement' || metadata.isInsideCallExpression === 'Error') {\n return { translatable: false, confidence: 'high', reason: 'Error message' };\n }\n\n // --- MEDIUM CONFIDENCE ---\n\n // Variables with translatable names\n if (\n (context === 'string-literal' || context === 'template-literal') &&\n metadata.parentType === 'VariableDeclarator'\n ) {\n // Check if there's a naming hint (not directly available, but we can check)\n return { translatable: true, confidence: 'medium', reason: 'String in variable declaration' };\n }\n\n // Multi-word strings (phrases)\n const wordCount = trimmed.split(/\\s+/).length;\n if (wordCount >= 3) {\n return { translatable: true, confidence: 'medium', reason: `Multi-word string (${wordCount} words)` };\n }\n\n // Two-word strings\n if (wordCount === 2 && /[a-zA-Z]{2,}/.test(trimmed)) {\n return { translatable: true, confidence: 'low', reason: 'Short phrase (2 words)' };\n }\n\n // Single word with spaces or that looks like UI text\n if (/^[A-Z][a-z]/.test(trimmed) && context !== 'string-literal') {\n return { translatable: true, confidence: 'low', reason: 'Capitalized word, possibly UI text' };\n }\n\n // Default: not translatable for single words in ambiguous contexts\n return { translatable: false, confidence: 'low', reason: 'Ambiguous single-word string' };\n}\n\n/**\n * Check if a variable name suggests translatable content.\n */\nexport function isTranslatableVarName(name: string): boolean {\n const lower = name.toLowerCase();\n for (const varName of TRANSLATABLE_VAR_NAMES) {\n if (lower === varName.toLowerCase() || lower.endsWith(varName.toLowerCase())) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Detect if a string looks like Tailwind / CSS utility classes.\n */\nfunction isTailwindClasses(text: string): boolean {\n // Must match the general pattern (lowercase words separated by spaces)\n if (!TAILWIND_REGEX.test(text)) return false;\n\n const parts = text.split(/\\s+/);\n\n // If most parts look like Tailwind classes, it's CSS\n let tailwindCount = 0;\n for (const part of parts) {\n if (TAILWIND_PREFIXES.some((prefix: string) => part.startsWith(prefix))) {\n tailwindCount++;\n }\n }\n\n // If more than half the parts look like Tailwind, classify as CSS\n return tailwindCount > parts.length / 2;\n}\n\nexport { TRANSLATABLE_ATTRIBUTES, NON_TRANSLATABLE_ATTRIBUTES };\n","/**\n * AST transformer that applies wrapping transformations\n * to source files using recast for format-preserving output.\n */\n\nimport * as recast from 'recast';\nimport { parse as babelParse } from '@babel/parser';\nimport type { WrapCandidate, TransformResult, FrameworkAdapter, WrapStrategy } from './types.js';\n\n// Recast-compatible Babel parser\nconst babelParser = {\n parse(source: string) {\n return babelParse(source, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n tokens: true,\n });\n },\n};\n\nexport class StringTransformer {\n private adapter: FrameworkAdapter;\n\n constructor(adapter: FrameworkAdapter) {\n this.adapter = adapter;\n }\n\n /**\n * Transform a file by wrapping the given candidates.\n * Returns the transformed source code.\n */\n transform(\n code: string,\n candidates: WrapCandidate[],\n filePath: string = '<input>',\n ): TransformResult {\n const ast = recast.parse(code, { parser: babelParser });\n const b = recast.types.builders;\n\n const wrapped: WrapCandidate[] = [];\n const skipped: WrapCandidate[] = [];\n const usedStrategies = new Set<WrapStrategy>();\n\n // Track which components need useVocoder hook injection\n const componentsNeedingHook = new Set<any>();\n\n // Build a lookup of candidates by line+column for matching\n const candidatesByLocation = new Map<string, WrapCandidate>();\n for (const c of candidates) {\n candidatesByLocation.set(`${c.line}:${c.column}`, c);\n }\n\n // Track existing vocoder imports\n let existingImportDecl: any = null;\n const existingSpecifiers = new Set<string>();\n\n // Capture adapter for use in visitors (recast's `this` is visitor context)\n const adapter = this.adapter;\n\n recast.visit(ast, {\n visitImportDeclaration(path) {\n const source = path.node.source.value;\n if (source === adapter.importSource) {\n existingImportDecl = path;\n for (const spec of path.node.specifiers || []) {\n if (spec.type === 'ImportSpecifier' && spec.imported.type === 'Identifier') {\n existingSpecifiers.add(spec.imported.name);\n }\n }\n }\n this.traverse(path);\n },\n\n visitJSXText(path) {\n const loc = path.node.loc;\n if (!loc) { this.traverse(path); return; }\n\n const key = `${loc.start.line}:${loc.start.column}`;\n const candidate = candidatesByLocation.get(key);\n if (!candidate || candidate.strategy !== 'T-component') {\n this.traverse(path);\n return;\n }\n\n const tOpen = b.jsxOpeningElement(\n b.jsxIdentifier(adapter.componentName),\n [],\n );\n const tClose = b.jsxClosingElement(\n b.jsxIdentifier(adapter.componentName),\n );\n const tElement = b.jsxElement(\n tOpen,\n tClose,\n [b.jsxText(candidate.text)],\n );\n\n path.replace(tElement);\n\n wrapped.push(candidate);\n usedStrategies.add('T-component');\n candidatesByLocation.delete(key);\n\n return false;\n },\n\n visitJSXAttribute(path) {\n const loc = path.node.loc;\n if (!loc) { this.traverse(path); return; }\n\n const key = `${loc.start.line}:${loc.start.column}`;\n const candidate = candidatesByLocation.get(key);\n if (!candidate || candidate.strategy !== 't-function') {\n this.traverse(path);\n return;\n }\n\n const value = path.node.value;\n if (!value) { this.traverse(path); return; }\n\n const tCall = b.callExpression(\n b.identifier(adapter.functionName),\n [b.stringLiteral(candidate.text)],\n );\n const exprContainer = b.jsxExpressionContainer(tCall);\n\n path.node.value = exprContainer;\n\n const componentFunc = findEnclosingComponent(path);\n if (componentFunc) {\n componentsNeedingHook.add(componentFunc);\n }\n\n wrapped.push(candidate);\n usedStrategies.add('t-function');\n candidatesByLocation.delete(key);\n\n this.traverse(path);\n },\n\n visitStringLiteral(path) {\n const loc = path.node.loc;\n if (!loc) { this.traverse(path); return; }\n\n const key = `${loc.start.line}:${loc.start.column}`;\n const candidate = candidatesByLocation.get(key);\n if (!candidate || candidate.strategy !== 't-function') {\n this.traverse(path);\n return;\n }\n\n if (path.parent.node.type === 'JSXAttribute') {\n this.traverse(path);\n return;\n }\n\n const tCall = b.callExpression(\n b.identifier(adapter.functionName),\n [b.stringLiteral(candidate.text)],\n );\n\n path.replace(tCall);\n\n const componentFunc = findEnclosingComponent(path);\n if (componentFunc) {\n componentsNeedingHook.add(componentFunc);\n }\n\n wrapped.push(candidate);\n usedStrategies.add('t-function');\n candidatesByLocation.delete(key);\n\n return false;\n },\n });\n\n // Any remaining candidates were not found in AST traversal\n for (const candidate of candidatesByLocation.values()) {\n skipped.push(candidate);\n }\n\n // Inject useVocoder hook into components that need it\n if (componentsNeedingHook.size > 0) {\n this.injectUseVocoderHooks(ast, componentsNeedingHook, b);\n }\n\n // Manage imports\n this.manageImports(ast, usedStrategies, existingImportDecl, existingSpecifiers, componentsNeedingHook.size > 0, b);\n\n const output = recast.print(ast).code;\n\n return {\n file: filePath,\n output,\n wrappedCount: wrapped.length,\n wrapped,\n skipped,\n };\n }\n\n /**\n * Inject `const { t } = useVocoder();` at the top of component functions.\n */\n private injectUseVocoderHooks(\n ast: any,\n componentFuncs: Set<any>,\n b: typeof recast.types.builders,\n ): void {\n const adapterFunctionName = this.adapter.functionName;\n const adapterHookName = this.adapter.hookName;\n\n const buildHookDecl = () => b.variableDeclaration('const', [\n b.variableDeclarator(\n b.objectPattern([\n b.property.from({\n kind: 'init',\n key: b.identifier(adapterFunctionName),\n value: b.identifier(adapterFunctionName),\n shorthand: true,\n }),\n ]),\n b.callExpression(b.identifier(adapterHookName), []),\n ),\n ]);\n\n recast.visit(ast, {\n visitFunction(path) {\n if (componentFuncs.has(path.node)) {\n const body = path.node.body;\n if (body.type === 'BlockStatement') {\n const alreadyHasHook = body.body.some((stmt: any) => {\n if (stmt.type !== 'VariableDeclaration') return false;\n return stmt.declarations.some((decl: any) =>\n decl.init?.type === 'CallExpression' &&\n decl.init.callee?.type === 'Identifier' &&\n decl.init.callee.name === 'useVocoder',\n );\n });\n\n if (!alreadyHasHook) {\n body.body.unshift(buildHookDecl());\n }\n }\n }\n this.traverse(path);\n },\n\n visitArrowFunctionExpression(path) {\n if (componentFuncs.has(path.node)) {\n const body = path.node.body;\n if (body.type === 'BlockStatement') {\n const alreadyHasHook = body.body.some((stmt: any) => {\n if (stmt.type !== 'VariableDeclaration') return false;\n return stmt.declarations.some((decl: any) =>\n decl.init?.type === 'CallExpression' &&\n decl.init.callee?.type === 'Identifier' &&\n decl.init.callee.name === 'useVocoder',\n );\n });\n\n if (!alreadyHasHook) {\n body.body.unshift(buildHookDecl());\n }\n }\n }\n this.traverse(path);\n },\n });\n }\n\n /**\n * Add or update @vocoder/react imports.\n */\n private manageImports(\n ast: any,\n usedStrategies: Set<WrapStrategy>,\n existingImportPath: any,\n existingSpecifiers: Set<string>,\n needsHook: boolean,\n b: typeof recast.types.builders,\n ): void {\n if (usedStrategies.size === 0) return;\n\n const neededSpecifiers = new Set<string>();\n\n if (usedStrategies.has('T-component')) {\n neededSpecifiers.add(this.adapter.componentName);\n }\n\n if (usedStrategies.has('t-function') && needsHook) {\n neededSpecifiers.add(this.adapter.hookName);\n }\n\n const missingSpecifiers: string[] = [];\n for (const spec of neededSpecifiers) {\n if (!existingSpecifiers.has(spec)) {\n missingSpecifiers.push(spec);\n }\n }\n\n if (missingSpecifiers.length === 0) return;\n\n if (existingImportPath) {\n for (const name of missingSpecifiers) {\n const specifier = b.importSpecifier(b.identifier(name), b.identifier(name));\n existingImportPath.node.specifiers.push(specifier);\n }\n } else {\n const specifiers = missingSpecifiers.map((name: string) =>\n b.importSpecifier(b.identifier(name), b.identifier(name)),\n );\n const importDecl = b.importDeclaration(\n specifiers,\n b.stringLiteral(this.adapter.importSource),\n );\n\n const body = ast.program.body;\n let lastImportIndex = -1;\n for (let i = 0; i < body.length; i++) {\n if (body[i].type === 'ImportDeclaration') {\n lastImportIndex = i;\n }\n }\n\n if (lastImportIndex >= 0) {\n body.splice(lastImportIndex + 1, 0, importDecl);\n } else {\n body.unshift(importDecl);\n }\n }\n }\n}\n\n/**\n * Walk up the AST to find the enclosing function component.\n * Returns the function node if found (used to inject useVocoder hook).\n */\nfunction findEnclosingComponent(path: any): any | null {\n let current = path.parent;\n while (current) {\n const node = current.node;\n\n if (node.type === 'FunctionDeclaration' && node.id?.name) {\n const name = node.id.name as string;\n if (/^[A-Z]/.test(name)) return node;\n }\n\n if (node.type === 'ArrowFunctionExpression') {\n const parent = current.parent?.node;\n if (\n parent?.type === 'VariableDeclarator' &&\n parent.id?.type === 'Identifier'\n ) {\n const name = parent.id.name as string;\n if (/^[A-Z]/.test(name)) return node;\n }\n }\n\n if (node.type === 'FunctionExpression') {\n const parent = current.parent?.node;\n if (\n parent?.type === 'VariableDeclarator' &&\n parent.id?.type === 'Identifier'\n ) {\n const name = parent.id.name as string;\n if (/^[A-Z]/.test(name)) return node;\n }\n }\n\n current = current.parent;\n }\n return null;\n}\n","/**\n * React framework adapter for the wrap command.\n * Implements FrameworkAdapter for React/JSX/TSX files.\n */\n\nimport type { FrameworkAdapter, WrapStrategy } from '../types.js';\n\nexport const reactAdapter: FrameworkAdapter = {\n name: 'react',\n extensions: ['.tsx', '.jsx', '.ts', '.js'],\n importSource: '@vocoder/react',\n componentName: 'T',\n functionName: 't',\n hookName: 'useVocoder',\n\n translatableAttributes: [\n 'title', 'placeholder', 'alt',\n 'aria-label', 'aria-description', 'aria-placeholder',\n 'aria-roledescription', 'aria-valuetext',\n 'label', 'description', 'message', 'heading', 'caption',\n 'helperText', 'errorMessage', 'successMessage', 'tooltip',\n ],\n\n nonTranslatableAttributes: [\n 'className', 'class', 'href', 'src', 'id', 'key', 'ref', 'style',\n 'data-testid', 'data-cy', 'data-test',\n 'type', 'name', 'value', 'action', 'method', 'encType', 'target',\n 'rel', 'role', 'tabIndex', 'htmlFor', 'for',\n 'width', 'height', 'viewBox', 'xmlns', 'fill', 'stroke',\n ],\n\n isAlreadyWrapped(ancestors: any[], imports: Map<string, string>): boolean {\n // Walk ancestor nodes to check if we're inside a <T> element\n for (const ancestor of ancestors) {\n if (ancestor.type === 'JSXElement') {\n const opening = ancestor.openingElement;\n if (opening && opening.name && opening.name.type === 'JSXIdentifier') {\n const tagName = opening.name.name as string;\n if (imports.has(tagName) && imports.get(tagName) === 'T') {\n return true;\n }\n }\n }\n }\n return false;\n },\n\n isAlreadyWrappedCall(node: any, tNames: Set<string>): boolean {\n // Check if this node is already inside a t() call expression\n if (node.type === 'CallExpression') {\n const callee = node.callee;\n if (callee.type === 'Identifier' && tNames.has(callee.name as string)) {\n return true;\n }\n }\n return false;\n },\n\n getRequiredImports(strategies: Set<WrapStrategy>): {\n specifiers: string[];\n source: string;\n } {\n const specifiers: string[] = [];\n\n if (strategies.has('T-component')) {\n specifiers.push('T');\n }\n\n if (strategies.has('t-function')) {\n // Inside components we use useVocoder hook; at module level we use t directly\n // The transformer decides which one to add based on context\n specifiers.push('useVocoder');\n }\n\n return { specifiers, source: '@vocoder/react' };\n },\n};\n"],"mappings":";;;AAEA,SAAS,eAAe;;;ACFxB,YAAY,OAAO;AACnB,OAAO,WAAW;;;ACclB,SAAS,qBAAqB,OAA6C;AACzE,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAClB,SACE,OAAO,UAAU,cAAc,YAC/B,OAAO,UAAU,cAAc,YAC/B,OAAO,UAAU,WAAW,YAC5B,OAAO,UAAU,YAAY,YAC7B,OAAO,UAAU,aAAa,YAC9B,OAAO,UAAU,eAAe,YAChC,OAAO,UAAU,YAAY;AAEjC;AAEA,SAAS,0BAA0B,OAAkD;AACnF,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAClB,UACG,UAAU,cAAc,wBACvB,UAAU,cAAc,kCAC1B,OAAO,UAAU,YAAY;AAEjC;AAEA,SAAS,oBAAoB,SAAkB,UAA0B;AACvE,MAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAClB,MAAI,OAAO,UAAU,YAAY,UAAU;AACzC,WAAO,UAAU;AAAA,EACnB;AAEA,MAAI,OAAO,UAAU,UAAU,UAAU;AACvC,WAAO,UAAU;AAAA,EACnB;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,KAAsB;AAC1C,MAAI,IAAI,WAAW,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO,EAAE,SAAS,IAAI;AAAA,EACxB;AACF;AAEA,eAAe,YAAY,UAGN;AACnB,MAAI,OAAO,SAAS,SAAS,YAAY;AACvC,UAAM,MAAM,MAAM,SAAS,KAAK;AAChC,WAAO,aAAa,GAAG;AAAA,EACzB;AAEA,MAAI,OAAO,SAAS,SAAS,YAAY;AACvC,WAAO,SAAS,KAAK;AAAA,EACvB;AAEA,SAAO;AACT;AAEO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAMzC,YAAY,QAMT;AACD,UAAM,OAAO,OAAO;AACpB,SAAK,OAAO;AACZ,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO;AACtB,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,kBAAkB,OAAO,mBAAmB;AAAA,EACnD;AACF;AAEO,IAAM,aAAN,MAAiB;AAAA,EAItB,YAAY,QAAqB;AAC/B,SAAK,SAAS,OAAO;AACrB,SAAK,SAAS,OAAO;AAAA,EACvB;AAAA,EAEA,MAAc,QACZ,MACAA,QAAoB,CAAC,GACrB,aACY;AACZ,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,IAAI;AAAA,MACpD,GAAGA;AAAA,MACH,SAAS;AAAA,QACP,eAAe,UAAU,KAAK,MAAM;AAAA,QACpC,GAAIA,MAAK,WAAW,CAAC;AAAA,MACvB;AAAA,IACF,CAAC;AAED,UAAM,UAAU,MAAM,YAAY,QAAQ;AAE1C,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,aAAa,qBAAqB,OAAO,IAAI,UAAU;AAC7D,YAAM,kBAAkB,0BAA0B,OAAO,IAAI,UAAU;AACvE,YAAM,cAAc,oBAAoB,SAAS,8BAA8B,SAAS,MAAM,EAAE;AAChG,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,cAAc,GAAG,WAAW,KAAK,WAAW,KAAK;AAAA,QAC1D,QAAQ,SAAS;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,MAAM,mBAA8C;AACnD,UAAM,OAAO,MAAM,KAAK,QAYrB,mBAAmB,CAAC,GAAG,gCAAgC;AAE1D,WAAO;AAAA,MACN,aAAa,KAAK;AAAA,MAClB,kBAAkB,KAAK;AAAA,MACvB,cAAc,KAAK;AAAA,MACnB,eAAe,KAAK;AAAA,MACpB,gBAAgB,KAAK;AAAA,MACrB,YAAY;AAAA,QACX,kBAAkB,KAAK,YAAY,oBAAoB,CAAC,QAAQ,QAAQ;AAAA,QACxE,cAAc,KAAK,YAAY,gBAAgB;AAAA,QAC/C,iBAAiB,KAAK,YAAY,mBAAmB;AAAA,QACrD,kBAAkB,KAAK,YAAY,oBAAoB;AAAA,MACxD;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMS,cAAc,MAAsB;AAE1C,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAQ,KAAK,WAAW,CAAC;AACzB,aAAO,KAAK,KAAK,MAAM,QAAU;AAAA,IACnC;AACA,WAAO,YAAY,SAAS,GAAG,SAAS,EAAE,EAAE,YAAY,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EAC5E;AAAA,EAEQ,uBACN,SAC0B;AAC1B,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,QAAQ,QAAQ,CAAC;AACvB,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAQ,QAAqB,IAAI,CAAC,UAAU;AAAA,QAC1C,KAAK,KAAK,cAAc,IAAI;AAAA,QAC5B;AAAA,MACF,EAAE;AAAA,IACJ;AAEA,WAAQ,QAAqC,IAAI,CAAC,OAAO,WAAW;AAAA,MAClE,KAAK,MAAM,OAAO,KAAK,cAAc,GAAG,MAAM,IAAI,IAAI,KAAK,EAAE;AAAA,MAC7D,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,MAClD,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,IAC1D,EAAE;AAAA,EACJ;AAAA,EAED,MAAM,kBACL,QACA,SACA,eACA,SAKA,cACoC;AAClC,UAAM,gBAAgB,KAAK,uBAAuB,OAAO;AACzD,UAAM,UAAU,cAAc,IAAI,CAAC,UAAU,MAAM,IAAI;AAGvD,UAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,UAAM,gBAAgB,CAAC,GAAG,OAAO,EAAE,KAAK;AACxC,UAAM,cAAc,OACjB,WAAW,QAAQ,EACnB,OAAO,KAAK,UAAU,aAAa,CAAC,EACpC,OAAO,KAAK;AAEf,WAAO,KAAK,QAAkC,iBAAiB;AAAA,MAC7D,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACC,MAAM,KAAK,UAAU;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAI,SAAS,gBAAgB,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,QACzE,GAAI,OAAO,SAAS,uBAAuB,WACvC,EAAE,oBAAoB,QAAQ,mBAAmB,IACjD,CAAC;AAAA,QACL,GAAI,SAAS,cAAc,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,QACnE,GAAI,cAAc,gBAAgB,EAAE,eAAe,aAAa,cAAc,IAAI,CAAC;AAAA,QACnF,GAAI,cAAc,kBAAkB,SAChC,EAAE,eAAe,aAAa,cAAc,IAC7C,CAAC;AAAA,MACP,CAAC;AAAA,IACH,GAAG,+BAA+B;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKD,MAAM,qBACL,SACqC;AACrC,WAAO,KAAK;AAAA,MACX,wBAAwB,OAAO;AAAA,MAC/B,CAAC;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAM,uBAAuB,QAGY;AACxC,UAAM,SAAS,IAAI,gBAAgB;AACnC,WAAO,IAAI,UAAU,OAAO,MAAM;AAClC,eAAW,UAAU,OAAO,eAAe;AAC1C,aAAO,OAAO,gBAAgB,MAAM;AAAA,IACrC;AAEA,WAAO,KAAK;AAAA,MACX,0BAA0B,OAAO,SAAS,CAAC;AAAA,MAC3C,CAAC;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKC,MAAM,kBACJ,SACA,UAAkB,KAClB,YAIC;AACD,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,eAAe;AAErB,WAAO,KAAK,IAAI,IAAI,YAAY,SAAS;AACvC,YAAM,SAAS,MAAM,KAAK,qBAAqB,OAAO;AAGtD,UAAI,YAAY;AACd,mBAAW,OAAO,QAAQ;AAAA,MAC5B;AAEA,UAAI,OAAO,WAAW,aAAa;AACjC,YAAI,CAAC,OAAO,cAAc;AACxB,gBAAM,IAAI,MAAM,oDAAoD;AAAA,QACtE;AACA,eAAO;AAAA,UACL,cAAc,OAAO;AAAA,UACrB,gBAAgB,OAAO;AAAA,QACzB;AAAA,MACF;AAEA,UAAI,OAAO,WAAW,UAAU;AAC9B,cAAM,IAAI;AAAA,UACR,uBAAuB,OAAO,gBAAgB,eAAe;AAAA,QAC/D;AAAA,MACF;AAGA,YAAM,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,YAAY,CAAC;AAAA,IAClE;AAEA,UAAM,IAAI,MAAM,6BAA6B,OAAO,IAAI;AAAA,EAC1D;AAAA,EAEA,MAAM,iBAAiB,OAMQ;AAC7B,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,MAAM,uBAAuB;AAAA,MAChE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,KAAK;AAAA,IAC5B,CAAC;AAED,UAAM,UAAU,MAAM,YAAY,QAAQ;AAE1C,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,oBAAoB,SAAS,iCAAiC,SAAS,MAAM,GAAG;AAAA,QACzF,QAAQ,SAAS;AAAA,QACjB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,qBAAqB,QAGK;AAC9B,UAAM,WAAW,MAAM;AAAA,MACrB,GAAG,KAAK,MAAM,wBAAwB,OAAO,SAAS;AAAA,MACtD;AAAA,QACE,SAAS;AAAA,UACP,eAAe,UAAU,OAAO,SAAS;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,YAAY,QAAQ;AAE1C,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,oBAAoB,SAAS,8BAA8B,SAAS,MAAM,GAAG;AAAA,QACtF,QAAQ,SAAS;AAAA,QACjB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAoB,QAG+D;AACvF,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,MAAM,wBAAwB;AAAA,QACjE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU;AAAA,UACnB,MAAM,OAAO;AAAA,UACb,WAAW,OAAO;AAAA,QACpB,CAAC;AAAA,MACH,CAAC;AAED,UAAI,SAAS,WAAW,IAAK,QAAO;AACpC,UAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,aAAQ,MAAM,SAAS,KAAK;AAAA,IAK9B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC3aA,SAAS,gBAAgB;AACzB,SAAS,UAAU,eAAe;AAYlC,SAAS,SAAS,SAAgC;AAChD,MAAI;AACF,UAAM,SAAS,SAAS,SAAS;AAAA,MAC/B,UAAU;AAAA,MACV,OAAO,CAAC,QAAQ,QAAQ,QAAQ;AAAA,IAClC,CAAC,EAAE,KAAK;AACR,WAAO,OAAO,SAAS,IAAI,SAAS;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAAc,UAAiC;AACtD,QAAM,UAAU,SACb,QAAQ,QAAQ,EAAE,EAClB,QAAQ,WAAW,EAAE,EACrB,KAAK;AAER,MAAI,CAAC,WAAW,CAAC,QAAQ,SAAS,GAAG,GAAG;AACtC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,WAGf;AACP,QAAM,UAAU,UAAU,KAAK;AAC/B,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,QAAQ,SAAS,KAAK,GAAG;AAC5B,UAAM,WAAW,QAAQ,MAAM,wBAAwB;AACvD,QAAI,UAAU;AACZ,YAAM,QAAQ,SAAS,CAAC,KAAK,IAAI,YAAY;AAC7C,YAAM,gBAAgB,cAAc,SAAS,CAAC,KAAK,EAAE;AACrD,UAAI,CAAC,QAAQ,CAAC,eAAe;AAC3B,eAAO;AAAA,MACT;AACA,aAAO,EAAE,MAAM,cAAc;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,OAAO;AAC9B,UAAM,OAAO,OAAO,SAAS,YAAY;AACzC,UAAM,gBAAgB,cAAc,mBAAmB,OAAO,QAAQ,CAAC;AACvE,QAAI,CAAC,QAAQ,CAAC,eAAe;AAC3B,aAAO;AAAA,IACT;AACA,WAAO,EAAE,MAAM,cAAc;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,MAAc,eAA+B;AAChE,MAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,WAAO,UAAU,cAAc,YAAY,CAAC;AAAA,EAC9C;AACA,MAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,WAAO,UAAU,cAAc,YAAY,CAAC;AAAA,EAC9C;AACA,MAAI,KAAK,SAAS,eAAe,GAAG;AAClC,WAAO,aAAa,cAAc,YAAY,CAAC;AAAA,EACjD;AACA,SAAO,OAAO,IAAI,IAAI,cAAc,YAAY,CAAC;AACnD;AAEO,SAAS,+BAA6D;AAC3E,QAAM,YAAY,SAAS,oCAAoC;AAC/D,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,eAAe,SAAS;AACvC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,SAAS,+BAA+B;AAC/D,QAAM,mBAAmB,QAAQ,IAAI;AACrC,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAClB,UAAM,eAAe,SAAS,QAAQ,cAAc,GAAG,QAAQ,gBAAgB,CAAC,EAC7E,QAAQ,OAAO,GAAG,EAClB,KAAK;AAER,QAAI,gBAAgB,iBAAiB,OAAO,CAAC,aAAa,WAAW,IAAI,GAAG;AAC1E,sBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,eAAe,YAAY,OAAO,MAAM,OAAO,aAAa;AAAA,IAC5D;AAAA,EACF;AACF;AAEO,SAAS,oBAAgC;AAC9C,QAAM,WAAqB,CAAC;AAC5B,QAAM,WAAW,6BAA6B;AAE9C,MAAI,CAAC,UAAU;AACb,aAAS;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,SAAS;AAC9B;;;AFzHA,SAAS,aAAa;AAEtB,IAAM,6BAA6B;AAEnC,SAAS,mBAAmB,OAAsC;AAChE,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,UAAU,MACb,MAAM,GAAG,EACT,IAAI,CAAC,WAAmB,OAAO,KAAK,CAAC,EACrC,OAAO,OAAO;AAEjB,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,eAAe,MAAM,IAA2B;AAC9C,QAAM,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,EAAE,CAAC;AACxD;AAEA,eAAe,eAAe,KAA+B;AAC3D,MAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,OAAO,QAAQ;AACtD,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AAEJ,MAAI,QAAQ,aAAa,UAAU;AACjC,cAAU;AACV,WAAO,CAAC,GAAG;AAAA,EACb,WAAW,QAAQ,aAAa,SAAS;AACvC,cAAU;AACV,WAAO,CAAC,+BAA+B,GAAG;AAAA,EAC5C,OAAO;AACL,cAAU;AACV,WAAO,CAAC,GAAG;AAAA,EACb;AAEA,SAAO,MAAM,IAAI,QAAiB,CAACA,aAAY;AAC7C,QAAI;AACF,YAAM,QAAQ,MAAM,SAAS,MAAM;AAAA,QACjC,UAAU;AAAA,QACV,OAAO;AAAA,QACP,aAAa;AAAA,MACf,CAAC;AAED,UAAI,UAAU;AACd,YAAM,KAAK,SAAS,MAAM;AACxB,YAAI,QAAS;AACb,kBAAU;AACV,cAAM,MAAM;AACZ,QAAAA,SAAQ,IAAI;AAAA,MACd,CAAC;AACD,YAAM,KAAK,SAAS,MAAM;AACxB,YAAI,QAAS;AACb,kBAAU;AACV,QAAAA,SAAQ,KAAK;AAAA,MACf,CAAC;AACD,iBAAW,MAAM;AACf,YAAI,QAAS;AACb,kBAAU;AACV,QAAAA,SAAQ,KAAK;AAAA,MACf,GAAG,GAAG;AAAA,IACR,QAAQ;AACN,MAAAA,SAAQ,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAEA,SAAS,mBAAmB,SAA2B;AACrD,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,iBAAiB,KAAK,OAAO;AACtC;AAEA,SAAS,2BAA2B,QAAwB;AAC1D,SAAO,IAAI,IAAI,4BAA4B,MAAM,EAAE,SAAS;AAC9D;AAEA,SAAS,sBAAsB,QAAgB,SAAuB;AACpE,EAAE,MAAI,MAAM;AAAA,KAAsC,OAAO,EAAE;AAC3D,EAAE,MAAI,KAAK,wBAAwB,2BAA2B,MAAM,CAAC,EAAE;AACzE;AAEA,SAAS,eAAe,aAAqB,kBAAgC;AAC3E,EAAE,MAAI,KAAK,cAAc,MAAM,KAAK,WAAW,CAAC,EAAE;AAClD,EAAE,MAAI,KAAK,cAAc,MAAM,KAAK,gBAAgB,CAAC,EAAE;AACvD,EAAE,MAAI,KAAK,EAAE;AACb,EAAE,MAAI,KAAK,aAAa;AACxB,EAAE,MAAI,KAAK,YAAY,MAAM,KAAK,mBAAmB,CAAC,uBAAuB;AAC7E,EAAE,MAAI,KAAK,uCAAuC,MAAM,MAAM,KAAK,CAAC,MAAM,MAAM,MAAM,MAAM,CAAC,EAAE;AAC/F,EAAE,MAAI,KAAK,+CAA+C;AAC5D;AAEA,eAAsB,KAAK,UAAuB,CAAC,GAAoB;AACrE,QAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI,mBAAmB;AAEhE,EAAE,QAAM,eAAe;AAEvB,QAAMC,WAAY,UAAQ;AAE1B,MAAI;AAEF,UAAM,aAAa,kBAAkB;AACrC,UAAM,WAAW,WAAW;AAE5B,QAAI,WAAW,SAAS,SAAS,GAAG;AAClC,iBAAW,WAAW,WAAW,UAAU;AACzC,QAAE,MAAI,KAAK,OAAO;AAAA,MACpB;AAAA,IACF;AAGA,QAAI,UAAU;AACZ,MAAAA,SAAQ,MAAM,kCAAkC;AAEhD,YAAMC,OAAM,IAAI,WAAW,EAAE,QAAQ,QAAQ,GAAG,CAAC;AACjD,YAAM,WAAW,MAAMA,KAAI,oBAAoB;AAAA,QAC7C,eAAe,SAAS;AAAA,QACxB,WAAW,SAAS;AAAA,MACtB,CAAC;AAED,UAAI,UAAU;AACZ,QAAAD,SAAQ,KAAK,yBAAyB;AACtC,QAAE,QAAM,gDAAgD;AACxD,uBAAe,SAAS,aAAa,SAAS,gBAAgB;AAC9D,eAAO;AAAA,MACT;AAEA,MAAAA,SAAQ,KAAK,0CAA0C;AAAA,IACzD;AAGA,IAAAA,SAAQ,MAAM,wBAAwB;AAEtC,UAAM,MAAM,IAAI,WAAW,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAEjD,UAAM,QAAQ,MAAM,IAAI,iBAAiB;AAAA,MACvC,aAAa,QAAQ;AAAA,MACrB,cAAc,QAAQ;AAAA,MACtB,eAAe,mBAAmB,QAAQ,aAAa;AAAA,MACvD,GAAI,UAAU,gBAAgB,EAAE,eAAe,SAAS,cAAc,IAAI,CAAC;AAAA,MAC3E,GAAI,WAAW,EAAE,eAAe,SAAS,cAAc,IAAI,CAAC;AAAA,IAC9D,CAAC;AAED,IAAAA,SAAQ,KAAK,uBAAuB;AAEpC,UAAM,wBAAwB,MAAM;AAEpC,IAAE,MAAI,KAAK,+CAA+C;AAC1D,IAAE,OAAK,uBAAuB,WAAW;AAGzC,QAAI,QAAQ,MAAM,SAAS,QAAQ,OAAO,SAAS,QAAQ,IAAI,OAAO,QAAQ;AAC5E,YAAM,aAAa,QAAQ,MACvB,OACA,MAAQ,UAAQ,EAAE,SAAS,iCAAiC,CAAC;AAEjE,UAAM,WAAS,UAAU,GAAG;AAC1B,QAAE,SAAO,kBAAkB;AAC3B,eAAO;AAAA,MACT;AAEA,UAAI,YAAY;AACd,cAAM,SAAS,MAAM,eAAe,qBAAqB;AACzD,YAAI,QAAQ;AACV,UAAE,MAAI,KAAK,sBAAsB;AAAA,QACnC,OAAO;AACL,UAAE,MAAI,KAAK,4DAA4D;AAAA,QACzE;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,IAAI,KAAK,MAAM,SAAS,EAAE,QAAQ;AACpD,IAAAA,SAAQ,MAAM,kCAAkC;AAEhD,WAAO,KAAK,IAAI,IAAI,WAAW;AAC7B,YAAM,SAAS,MAAM,IAAI,qBAAqB;AAAA,QAC5C,WAAW,MAAM;AAAA,QACjB,WAAW,MAAM,KAAK;AAAA,MACxB,CAAC;AAED,UAAI,OAAO,WAAW,WAAW;AAC/B,cAAM,iBAAiB,OAAO,SAAS,KAAK;AAC5C,YAAI,gBAAgB;AAClB,UAAAA,SAAQ,QAAQ,qCAAqC,cAAc,GAAG;AAAA,QACxE;AACA,cAAM,OAAO,OAAO,uBAAuB,MAAM,KAAK,mBAAmB,GAAI;AAC7E;AAAA,MACF;AAEA,UAAI,OAAO,WAAW,UAAU;AAC9B,QAAAA,SAAQ,KAAK,cAAc;AAC3B,YAAI,mBAAmB,OAAO,OAAO,GAAG;AACtC,gCAAsB,QAAQ,OAAO,OAAO;AAAA,QAC9C,OAAO;AACL,UAAE,MAAI,MAAM,OAAO,OAAO;AAAA,QAC5B;AACA,QAAE,SAAO,+BAA+B;AACxC,eAAO;AAAA,MACT;AAEA,UAAI,OAAO,WAAW,aAAa;AACjC,QAAAA,SAAQ,KAAK,iBAAiB;AAE9B,cAAM,EAAE,YAAY,IAAI;AAExB,QAAE,QAAM,mCAAmC;AAC3C,uBAAe,YAAY,aAAa,YAAY,gBAAgB;AAEpE,eAAO;AAAA,MACT;AAAA,IACF;AAGA,IAAAA,SAAQ,KAAK,iBAAiB;AAC9B,IAAE,MAAI,MAAM,4CAA4C;AACxD,IAAE,SAAO,+BAA+B;AACxC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,IAAAA,SAAQ,KAAK;AACb,QAAI,iBAAiB,OAAO;AAC1B,UAAI,mBAAmB,MAAM,OAAO,GAAG;AACrC,8BAAsB,QAAQ,MAAM,OAAO;AAC3C,eAAO;AAAA,MACT;AACA,MAAE,MAAI,MAAM,UAAU,MAAM,OAAO,EAAE;AAAA,IACvC,OAAO;AACL,MAAE,MAAI,MAAM,qBAAqB;AAAA,IACnC;AAEA,WAAO;AAAA,EACT;AACF;;;AGhPA,YAAYE,QAAO;AAanB,SAAS,cAAAC,aAAY,kBAAkB;;;ACbvC,SAAS,YAAAC,iBAAgB;AAEzB,IAAM,sBAAsB;AAE5B,SAAS,gBAAgB,OAAuB;AAC9C,SAAO,MAAM,QAAQ,qBAAqB,MAAM;AAClD;AAWO,SAAS,aAAa,UAA2B;AAEtD,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AAGA,QAAM,YACJ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAAA,EACZ,QAAQ,IAAI;AAEd,MAAI,WAAW;AACb,WAAO;AAAA,EACT;AAGA,MAAI;AACF,UAAM,SAASA,UAAS,mCAAmC;AAAA,MACzD,UAAU;AAAA,MACV,OAAO,CAAC,QAAQ,QAAQ,QAAQ;AAAA,IAClC,CAAC,EAAE,KAAK;AAER,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AASO,SAAS,eACd,eACA,gBACS;AACT,SAAO,eAAe;AAAA,IAAK,CAAC,YAC1B,mBAAmB,eAAe,OAAO;AAAA,EAC3C;AACF;AAEO,SAAS,mBAAmB,QAAgB,SAA0B;AAC3E,QAAM,iBAAiB,QAAQ,KAAK;AACpC,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAEA,MAAI,cAAc;AAClB,WAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK,GAAG;AACjD,UAAM,OAAO,eAAe,CAAC;AAC7B,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AAEA,QAAI,SAAS,KAAK;AAChB,YAAM,OAAO,eAAe,IAAI,CAAC;AACjC,UAAI,SAAS,KAAK;AAChB,uBAAe;AACf,aAAK;AAAA,MACP,OAAO;AACL,uBAAe;AAAA,MACjB;AACA;AAAA,IACF;AAEA,mBAAe,gBAAgB,IAAI;AAAA,EACrC;AACA,iBAAe;AAEf,SAAO,IAAI,OAAO,WAAW,EAAE,KAAK,MAAM;AAC5C;;;ADpFA,SAAS,YAAY,WAAW,gBAAAC,eAAc,qBAAqB;;;AEbnE,OAAOC,YAAW;AAClB,SAAS,UAAU,eAAe;AAGlC,QAAQ;AAKD,SAAS,oBAAoB,QAA2B;AAC7D,MAAI,CAAC,OAAO,UAAU,OAAO,OAAO,WAAW,GAAG;AAChD,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AAEA,MAAI,CAAC,OAAO,OAAO,WAAW,KAAK,GAAG;AACpC,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,MAAI,CAAC,OAAO,UAAU,CAAC,OAAO,OAAO,WAAW,MAAM,GAAG;AACvD,UAAM,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACF;AAYA,eAAsB,gBACpB,YACA,UAAmB,OACnB,WAkBC;AACD,QAAM,gBAAgB;AAAA,IACpB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAGA,QAAM,WAAW;AAAA,IACf,mBAAmB,CAAC,0BAA0B;AAAA,IAC9C,gBAAgB,CAAC;AAAA,IACjB,QAAQ;AAAA,EACV;AAGA,QAAM,uBAAuB,QAAQ,IAAI;AACzC,QAAM,YAAY,QAAQ,IAAI;AAC9B,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,mBAAmB,QAAQ,IAAI;AACrC,QAAM,oBAAoB,QAAQ,IAAI;AAKtC,MAAI;AACJ,MAAI,WAAW,WAAW,WAAW,QAAQ,SAAS,GAAG;AACvD,wBAAoB,WAAW;AAC/B,kBAAc,oBAAoB;AAAA,EACpC,WAAW,sBAAsB;AAC/B,wBAAoB,CAAC,oBAAoB;AACzC,kBAAc,oBAAoB;AAAA,EACpC,OAAO;AACL,wBAAoB,SAAS;AAAA,EAC/B;AAGA,MAAI;AACJ,MAAI,WAAW,WAAW,WAAW,QAAQ,SAAS,GAAG;AACvD,qBAAiB,WAAW;AAC5B,kBAAc,iBAAiB;AAAA,EACjC,OAAO;AACL,qBAAiB,SAAS;AAAA,EAC5B;AAGA,MAAI;AACJ,MAAI,QAAQ,IAAI,iBAAiB;AAC/B,aAAS,QAAQ,IAAI;AACrB,kBAAc,SAAS;AAAA,EACzB;AAGA,MAAI;AACJ,MAAI,WAAW;AACb,aAAS;AACT,kBAAc,SAAS;AAAA,EACzB,OAAO;AACL,aAAS,SAAS;AAAA,EACpB;AAEA,QAAM,iBAAiB,CAAC,QAAQ,YAAY,aAAa;AACzD,MAAI,OAA0B;AAC9B,MAAI,WAAW,QAAQ,eAAe,SAAS,WAAW,IAAI,GAAG;AAC/D,WAAO,WAAW;AAClB,kBAAc,OAAO;AAAA,EACvB,WAAW,eAAe,eAAe,SAAS,WAAgC,GAAG;AACnF,WAAO;AACP,kBAAc,OAAO;AAAA,EACvB;AAEA,MAAI;AACJ,MAAI,OAAO,WAAW,cAAc,YAAY,OAAO,SAAS,WAAW,SAAS,KAAK,WAAW,YAAY,GAAG;AACjH,gBAAY,KAAK,MAAM,WAAW,SAAS;AAC3C,kBAAc,YAAY;AAAA,EAC5B,WAAW,kBAAkB;AAC3B,UAAM,SAAS,OAAO,SAAS,kBAAkB,EAAE;AACnD,QAAI,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AACzC,kBAAY;AACZ,oBAAc,YAAY;AAAA,IAC5B;AAAA,EACF;AAEA,MAAI,aAAa;AACjB,MAAI,OAAO,WAAW,eAAe,WAAW;AAC9C,iBAAa,WAAW;AACxB,kBAAc,aAAa;AAAA,EAC7B,WAAW,mBAAmB;AAC5B,iBAAa,CAAC,KAAK,QAAQ,OAAO,IAAI,EAAE,SAAS,kBAAkB,YAAY,CAAC;AAChF,kBAAc,aAAa;AAAA,EAC7B;AAGA,MAAI,SAAS;AACX,YAAQ,IAAIA,OAAM,IAAI,6BAA6B,CAAC;AACpD,YAAQ,IAAIA,OAAM,IAAI,0BAA0B,cAAc,iBAAiB,EAAE,CAAC;AAClF,QAAI,eAAe,SAAS,GAAG;AAC7B,cAAQ,IAAIA,OAAM,IAAI,0BAA0B,cAAc,cAAc,EAAE,CAAC;AAAA,IACjF;AACA,YAAQ,IAAIA,OAAM,IAAI,iBAAiB,cAAc,MAAM,EAAE,CAAC;AAC9D,YAAQ,IAAIA,OAAM,IAAI,iBAAiB,cAAc,MAAM;AAAA,CAAI,CAAC;AAChE,YAAQ,IAAIA,OAAM,IAAI,mBAAmB,cAAc,IAAI,EAAE,CAAC;AAC9D,QAAI,WAAW;AACb,cAAQ,IAAIA,OAAM,IAAI,kBAAkB,cAAc,SAAS,EAAE,CAAC;AAAA,IACpE;AACA,YAAQ,IAAIA,OAAM,IAAI,qBAAqB,cAAc,UAAU;AAAA,CAAI,CAAC;AAAA,EAC1E;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACjLA,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,aAAa;AACtB,OAAO,mBAAmB;AAC1B,SAAS,YAAY;AACrB,SAAS,YAAY,oBAAoB;AAIzC,IAAM,WAAY,cAAsB,WAAW;AAS5C,IAAM,kBAAN,MAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3B,MAAM,mBACJ,SACA,cAAsB,QAAQ,IAAI,GAClC,gBAC4B;AAE5B,UAAM,kBAAkB,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO;AAGnE,UAAM,gBAAgB,CAAC,sBAAsB,eAAe,cAAc,aAAa;AAGvF,UAAM,iBAAiB,iBACnB,CAAC,GAAG,eAAe,GAAI,MAAM,QAAQ,cAAc,IAAI,iBAAiB,CAAC,cAAc,CAAE,IACzF;AAGJ,UAAM,WAAW,oBAAI,IAAY;AAEjC,eAAW,kBAAkB,iBAAiB;AAC5C,YAAM,QAAQ,MAAM,KAAK,gBAAgB;AAAA,QACvC,KAAK;AAAA,QACL,UAAU;AAAA,QACV,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,QAAQ,CAAC,SAAiB,SAAS,IAAI,IAAI,CAAC;AAAA,IACpD;AAEA,UAAM,aAAgC,CAAC;AAGvC,UAAM,cAAc,MAAM,KAAK,QAAQ,EAAE,KAAK;AAE9C,eAAW,QAAQ,aAAa;AAC9B,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,gBAAgB,MAAM,WAAW;AAC5D,mBAAW,KAAK,GAAG,OAAO;AAAA,MAC5B,SAAS,OAAO;AACd,gBAAQ,KAAK,mCAAmC,IAAI,KAAK,KAAK;AAAA,MAChE;AAAA,IACF;AAGA,UAAM,SAAS,KAAK,mBAAmB,UAAU;AAEjD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBACZ,UACA,aAC4B;AAC5B,UAAM,OAAO,aAAa,UAAU,OAAO;AAC3C,UAAM,UAA6B,CAAC;AACpC,UAAM,mBAAmB,aAAa,aAAa,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,GAAG;AAEjF,QAAI;AAEF,YAAM,MAAM,MAAM,MAAM;AAAA,QACtB,YAAY;AAAA,QACZ,SAAS,CAAC,OAAO,YAAY;AAAA,MAC/B,CAAC;AAGD,YAAM,iBAAiB,oBAAI,IAAoB;AAC/C,YAAM,iBAAiB,oBAAI,IAAY;AAGvC,eAAS,KAAK;AAAA;AAAA,QAEZ,mBAAmB,CAAC,SAAc;AAChC,gBAAM,SAAS,KAAK,KAAK,OAAO;AAEhC,cAAI,WAAW,kBAAkB;AAC/B,iBAAK,KAAK,WAAW,QAAQ,CAAC,SAAc;AAC1C,kBAAI,KAAK,SAAS,mBAAmB;AACnC,sBAAM,WACJ,KAAK,SAAS,SAAS,eACnB,KAAK,SAAS,OACd;AACN,sBAAM,QAAQ,KAAK,MAAM;AAEzB,oBAAI,aAAa,KAAK;AACpB,iCAAe,IAAI,OAAO,GAAG;AAAA,gBAC/B;AAEA,oBAAI,aAAa,KAAK;AACpB,iCAAe,IAAI,KAAK;AAAA,gBAC1B;AAEA,oBAAI,aAAa,cAAc;AAAA,gBAE/B;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA;AAAA,QAGA,oBAAoB,CAAC,SAAc;AACjC,gBAAMC,QAAO,KAAK,KAAK;AAGvB,cACEA,SACAA,MAAK,SAAS,oBACdA,MAAK,OAAO,SAAS,gBACrBA,MAAK,OAAO,SAAS,gBACrB,KAAK,KAAK,GAAG,SAAS,iBACtB;AACA,iBAAK,KAAK,GAAG,WAAW,QAAQ,CAAC,SAAc;AAC7C,kBACE,KAAK,SAAS,oBACd,KAAK,IAAI,SAAS,gBAClB,KAAK,IAAI,SAAS,KAClB;AACA,sBAAM,YACJ,KAAK,MAAM,SAAS,eAAe,KAAK,MAAM,OAAO;AACvD,+BAAe,IAAI,SAAS;AAAA,cAC9B;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA;AAAA,QAGA,gBAAgB,CAAC,SAAc;AAC7B,gBAAM,SAAS,KAAK,KAAK;AAGzB,gBAAM,cACJ,OAAO,SAAS,gBAAgB,eAAe,IAAI,OAAO,IAAI;AAEhE,cAAI,CAAC,YAAa;AAGlB,gBAAM,WAAW,KAAK,KAAK,UAAU,CAAC;AACtC,cAAI,CAAC,SAAU;AAEf,cAAI,OAAsB;AAG1B,cAAI,SAAS,SAAS,iBAAiB;AACrC,mBAAO,SAAS;AAAA,UAClB,WAES,SAAS,SAAS,mBAAmB;AAC5C,mBAAO,KAAK,oBAAoB,QAAQ;AAAA,UAC1C;AAEA,cAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,WAAW,EAAG;AAGvC,gBAAM,YAAY,KAAK,KAAK,UAAU,CAAC;AACvC,cAAI;AACJ,cAAI;AACJ,cAAI;AAEJ,cAAI,aAAa,UAAU,SAAS,oBAAoB;AACtD,sBAAU,WAAW,QAAQ,CAAC,SAAc;AAC1C,kBAAI,KAAK,SAAS,oBAAoB,KAAK,IAAI,SAAS,cAAc;AACpE,oBAAI,KAAK,IAAI,SAAS,aAAa,KAAK,MAAM,SAAS,iBAAiB;AACtE,4BAAU,KAAK,MAAM;AAAA,gBACvB;AACA,oBAAI,KAAK,IAAI,SAAS,eAAe,KAAK,MAAM,SAAS,iBAAiB;AACxE,8BAAY,KAAK,MAAM;AAAA,gBACzB;AACA,oBAAI,KAAK,IAAI,SAAS,QAAQ,KAAK,MAAM,SAAS,iBAAiB;AACjE,gCAAc,KAAK,MAAM,MAAM,KAAK;AAAA,gBACtC;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAEA,gBAAM,OAAO,KAAK,KAAK,KAAK,MAAM,QAAQ;AAC1C,gBAAM,SAAS,KAAK,KAAK,KAAK,MAAM,UAAU;AAC9C,gBAAM,MAAM,eAAe,YAAY,SAAS,IAC5C,cACA,KAAK,kBAAkB;AAAA,YACrB,UAAU;AAAA,YACV,MAAM;AAAA,YACN;AAAA,YACA;AAAA,UACF,CAAC;AAEL,kBAAQ,KAAK;AAAA,YACX;AAAA,YACA,MAAM,KAAK,KAAK;AAAA,YAChB,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA;AAAA,QAGA,YAAY,CAAC,SAAc;AACzB,gBAAM,UAAU,KAAK,KAAK;AAC1B,gBAAM,UACJ,QAAQ,KAAK,SAAS,kBAClB,QAAQ,KAAK,OACb;AAEN,cAAI,CAAC,QAAS;AAGd,gBAAM,yBAAyB,eAAe,IAAI,OAAO;AAEzD,cAAI,CAAC,uBAAwB;AAG7B,gBAAM,eAAe,KAAK,mBAAmB,QAAQ,YAAY,KAAK;AAGtE,gBAAM,OAAO,gBAAgB,KAAK,mBAAmB,KAAK,KAAK,QAAQ;AAEvE,cAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,WAAW,EAAG;AAGvC,gBAAM,KAAK,KAAK,mBAAmB,QAAQ,YAAY,IAAI;AAC3D,gBAAM,UAAU,KAAK,mBAAmB,QAAQ,YAAY,SAAS;AACrE,gBAAM,YAAY,KAAK;AAAA,YACrB,QAAQ;AAAA,YACR;AAAA,UACF;AACA,gBAAM,OAAO,KAAK,KAAK,KAAK,MAAM,QAAQ;AAC1C,gBAAM,SAAS,KAAK,KAAK,KAAK,MAAM,UAAU;AAC9C,gBAAM,MAAM,MAAM,GAAG,KAAK,EAAE,SAAS,IACjC,GAAG,KAAK,IACR,KAAK,kBAAkB;AAAA,YACrB,UAAU;AAAA,YACV,MAAM;AAAA,YACN;AAAA,YACA;AAAA,UACF,CAAC;AAEL,kBAAQ,KAAK;AAAA,YACX;AAAA,YACA,MAAM,KAAK,KAAK;AAAA,YAChB,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,mBAAmB,QAAQ,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MAC1F;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,oBAAoB,MAAmB;AAC7C,QAAI,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AAC3C,YAAM,QAAQ,KAAK,OAAO,CAAC;AAC3B,cAAQ,MAAM,MAAM;AAGpB,UAAI,IAAI,KAAK,YAAY,QAAQ;AAC/B,cAAM,OAAO,KAAK,YAAY,CAAC;AAC/B,YAAI,KAAK,SAAS,cAAc;AAC9B,kBAAQ,IAAI,KAAK,IAAI;AAAA,QACvB,OAAO;AAEL,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,UAAyB;AAClD,QAAI,OAAO;AAEX,eAAW,SAAS,UAAU;AAC5B,UAAI,MAAM,SAAS,WAAW;AAC5B,gBAAQ,MAAM;AAAA,MAChB,WAAW,MAAM,SAAS,0BAA0B;AAClD,cAAM,OAAO,MAAM;AAGnB,YAAI,KAAK,SAAS,cAAc;AAC9B,kBAAQ,IAAI,KAAK,IAAI;AAAA,QACvB,WAES,KAAK,SAAS,iBAAiB;AACtC,kBAAQ,KAAK;AAAA,QACf,WAGS,KAAK,SAAS,mBAAmB;AACxC,kBAAQ,KAAK,oBAAoB,IAAI;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBACN,YACA,MACoB;AACpB,UAAM,OAAO,WAAW;AAAA,MACtB,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,KAAK,SAAS;AAAA,IACtD;AAEA,QAAI,CAAC,QAAQ,CAAC,KAAK,MAAO,QAAO;AAGjC,QAAI,KAAK,MAAM,SAAS,iBAAiB;AACvC,aAAO,KAAK,MAAM;AAAA,IACpB;AAGA,QAAI,KAAK,MAAM,SAAS,0BAA0B;AAChD,YAAM,OAAO,KAAK,MAAM;AAGxB,UAAI,KAAK,SAAS,mBAAmB;AACnC,eAAO,KAAK,oBAAoB,IAAI;AAAA,MACtC;AAGA,UAAI,KAAK,SAAS,iBAAiB;AACjC,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,SAA+C;AACxE,UAAM,OAAO,oBAAI,IAAoB;AACrC,UAAM,SAA4B,CAAC;AAEnC,eAAW,OAAO,SAAS;AAEzB,YAAM,YAAY,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE,IAAI,IAAI,aAAa,EAAE;AAEzE,YAAM,gBAAgB,KAAK,IAAI,SAAS;AACxC,UAAI,kBAAkB,QAAW;AAC/B,aAAK,IAAI,WAAW,OAAO,MAAM;AACjC,eAAO,KAAK,GAAG;AACf;AAAA,MACF;AAGA,YAAM,WAAW,OAAO,aAAa;AACrC,UAAI,YAAY,IAAI,MAAM,SAAS,KAAK;AACtC,iBAAS,MAAM,IAAI;AAAA,MACrB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,QAKf;AACT,UAAM,UAAU,GAAG,OAAO,QAAQ,IAAI,OAAO,IAAI,IAAI,OAAO,IAAI,IAAI,OAAO,MAAM;AACjF,UAAM,SAAS,WAAW,MAAM,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AAC9D,WAAO,MAAM,OAAO,MAAM,GAAG,EAAE,EAAE,YAAY,CAAC;AAAA,EAChD;AACF;;;AH7YA,OAAOC,YAAW;AAClB,SAAS,YAAY;AA4BrB,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,oBAAoB,OAA+C;AAC1E,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,WAA8B,CAAC;AACrC,aAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,QAAQ,KAAK,GAAG;AACtD,QAAI,CAAC,SAAS,QAAQ,GAAG;AACvB;AAAA,IACF;AAEA,UAAM,aAAa,SAAS;AAC5B,QAAI,OAAO,eAAe,YAAY,WAAW,KAAK,EAAE,WAAW,GAAG;AACpE;AAAA,IACF;AAEA,UAAM,QAA6C,EAAE,WAAW;AAChE,QAAI,SAAS,QAAQ,OAAO;AAC1B,YAAM,MAAM;AAAA,IACd;AAEA,aAAS,MAAM,IAAI;AAAA,EACrB;AAEA,SAAO,OAAO,KAAK,QAAQ,EAAE,SAAS,IAAI,WAAW;AACvD;AAEA,SAAS,kBAAkB,OAAuC;AAChE,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,eAA+B,CAAC;AAEtC,aAAW,CAAC,QAAQ,WAAW,KAAK,OAAO,QAAQ,KAAK,GAAG;AACzD,QAAI,CAAC,SAAS,WAAW,GAAG;AAC1B;AAAA,IACF;AAEA,UAAM,qBAA6C,CAAC;AACpD,eAAW,CAAC,QAAQ,UAAU,KAAK,OAAO,QAAQ,WAAW,GAAG;AAC9D,UAAI,OAAO,eAAe,UAAU;AAClC,2BAAmB,MAAM,IAAI;AAAA,MAC/B;AAAA,IACF;AAEA,iBAAa,MAAM,IAAI;AAAA,EACzB;AAEA,SAAO,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAC/D;AAEA,SAAS,iBAAiB,aAAqB,QAAwB;AACrE,QAAM,OAAO,OACV,QAAQ,qBAAqB,GAAG,EAChC,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE;AACd,QAAM,aAAaC,YAAW,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC9E,QAAM,WAAW,GAAG,QAAQ,QAAQ,IAAI,UAAU;AAClD,SAAO,KAAK,aAAa,YAAY,SAAS,QAAQ,QAAQ;AAChE;AAEA,SAAS,uBAAuB,QAGA;AAC9B,QAAM,oBAAoB,OAAO,WAAW,SACxC,CAAC,MAAM,IACP,CAAC,OAAO,QAAQ,MAAM;AAE1B,aAAW,mBAAmB,mBAAmB;AAC/C,UAAM,gBAAgB,iBAAiB,OAAO,aAAa,eAAe;AAE1E,QAAI,CAAC,WAAW,aAAa,GAAG;AAC9B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,MAAMC,cAAa,eAAe,OAAO;AAC/C,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,CAAC,SAAS,MAAM,GAAG;AACrB;AAAA,MACF;AAEA,YAAM,eAAe,kBAAkB,OAAO,YAAY;AAC1D,UAAI,CAAC,cAAc;AACjB;AAAA,MACF;AAEA,YAAM,iBAAiB,oBAAoB,OAAO,cAAc;AAEhE,aAAO;AAAA,QACL,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,iBACE,OAAO,OAAO,oBAAoB,WAC9B,OAAO,kBACP;AAAA,QACN,aACE,OAAO,OAAO,gBAAgB,WAAW,OAAO,cAAc;AAAA,QAChE,aAAa;AAAA,MACf;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,QAStB;AACT,QAAM,gBAAgB,iBAAiB,OAAO,aAAa,OAAO,MAAM;AACxE,YAAU,KAAK,OAAO,aAAa,YAAY,SAAS,MAAM,GAAG;AAAA,IAC/D,WAAW;AAAA,EACb,CAAC;AAED,QAAM,UAA8B;AAAA,IAClC,SAAS;AAAA,IACT,QAAQ,OAAO;AAAA,IACf,cAAc,OAAO;AAAA,IACrB,eAAe,OAAO;AAAA,IACtB,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,IAChC,GAAI,OAAO,kBAAkB,EAAE,iBAAiB,OAAO,gBAAgB,IAAI,CAAC;AAAA,IAC5E,GAAI,OAAO,cAAc,EAAE,aAAa,OAAO,YAAY,IAAI,CAAC;AAAA,IAChE,GAAI,OAAO,iBAAiB,EAAE,gBAAgB,OAAO,eAAe,IAAI,CAAC;AAAA,IACzE,cAAc,OAAO;AAAA,EACvB;AAEA,gBAAc,eAAe,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,OAAO;AACtE,SAAO;AACT;AAEA,SAAS,+BAA+B,QAIlB;AACpB,QAAM,EAAE,eAAe,QAAQ,OAAO,IAAI;AAE1C,MAAI;AACJ,MAAI,kBAAkB,QAAQ;AAC5B,UAAM,mBAAmB,eAAe,QAAQ,OAAO,gBAAgB;AACvE,WAAO,mBAAmB,OAAO,eAAe,OAAO;AAAA,EACzD,OAAO;AACL,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,qBAAqB,QAInB;AACT,MACE,OAAO,OAAO,uBAAuB,YACrC,OAAO,SAAS,OAAO,kBAAkB,KACzC,OAAO,qBAAqB,GAC5B;AACA,WAAO,KAAK,MAAM,OAAO,kBAAkB;AAAA,EAC7C;AAEA,MACE,OAAO,OAAO,2BAA2B,YACzC,OAAO,SAAS,OAAO,sBAAsB,KAC7C,OAAO,yBAAyB,GAChC;AACA,WAAO,KAAK,MAAM,OAAO,sBAAsB;AAAA,EACjD;AAEA,SAAO,OAAO;AAChB;AAEA,SAAS,sBAAsB,QAKZ;AACjB,QAAM,SAAyB,CAAC;AAEhC,aAAW,CAAC,QAAQ,MAAM,KAAK,OAAO,QAAQ,OAAO,YAAY,GAAG;AAClE,WAAO,MAAM,IAAI,EAAE,GAAG,OAAO;AAAA,EAC/B;AAEA,QAAM,kBAAkB;AAAA,IACtB,OAAO;AAAA,IACP,GAAG,OAAO,cAAc,OAAO,CAAC,WAAW,WAAW,OAAO,YAAY;AAAA,EAC3E;AAEA,aAAW,UAAU,iBAAiB;AACpC,QAAI,CAAC,OAAO,MAAM,GAAG;AACnB,aAAO,MAAM,IAAI,CAAC;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,OAAO,YAAY,GAAG;AAChC,WAAO,OAAO,YAAY,IAAI,CAAC;AAAA,EACjC;AAEA,aAAW,cAAc,OAAO,eAAe;AAC7C,QAAI,EAAE,cAAc,OAAO,OAAO,YAAY,IAAK;AACjD,aAAO,OAAO,YAAY,EAAG,UAAU,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,sBAAsB,YAA0C;AAC9E,MAAI,WAAW,cAAc,aAAa;AACxC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,kBAAkB,WAAW,UAAU;AAAA,IACzC;AAAA,EACF;AAEA,MAAI,WAAW,cAAc,qBAAqB;AAChD,WAAO;AAAA,MACL;AAAA,MACA,oBAAoB,WAAW,QAAQ,eAAe,CAAC;AAAA,MACvD,yBAAyB,WAAW,SAAS,eAAe,CAAC;AAAA,MAC7D,iBAAiB,WAAW,UAAU;AAAA,IACxC;AAAA,EACF;AAEA,MAAI,WAAW,cAAc,kBAAkB;AAC7C,WAAO;AAAA,MACL;AAAA,MACA,2BAA2B,WAAW,QAAQ,eAAe,CAAC;AAAA,MAC9D,2BAA2B,WAAW,SAAS,eAAe,CAAC;AAAA,MAC/D,iBAAiB,WAAW,UAAU;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,WAAW,MAAM;AAAA,IAC1B,YAAY,WAAW,OAAO;AAAA,IAC9B,aAAa,WAAW,QAAQ;AAAA,IAChC,YAAY,WAAW,UAAU;AAAA,EACnC;AACF;AAEA,SAAS,2BACP,OACU;AACV,MAAI,MAAM,cAAc,sBAAsB;AAC5C,UAAMC,SAAQ,CAAC,8CAA8C;AAC7D,QAAI,MAAM,QAAQ;AAChB,MAAAA,OAAM,KAAK,mBAAmB,MAAM,MAAM,EAAE;AAAA,IAC9C;AACA,QAAI,MAAM,kBAAkB,MAAM,eAAe,SAAS,GAAG;AAC3D,MAAAA,OAAM,KAAK,qBAAqB,MAAM,eAAe,KAAK,IAAI,CAAC,EAAE;AAAA,IACnE;AACA,IAAAA,OAAM,KAAK,iEAAiE;AAC5E,WAAOA;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,kDAAkD;AACjE,MAAI,MAAM,gBAAgB;AACxB,UAAM,KAAK,qBAAqB,MAAM,cAAc,EAAE;AAAA,EACxD;AACA,MAAI,MAAM,gBAAgB;AACxB,UAAM,KAAK,gBAAgB,MAAM,cAAc,EAAE;AAAA,EACnD;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aACP,SACA,UACoB;AACpB,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,YAAY,SAAU,QAAO;AAEjC,QAAM,SAAS,IAAI;AAAA,IACjB,CAAC,GAAG,QAAQ,MAAM,KAAK,GAAG,GAAG,SAAS,MAAM,KAAK,CAAC,EAC/C,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO;AAAA,EACnB;AACA,SAAO,MAAM,KAAK,MAAM,EAAE,KAAK,KAAK;AACtC;AAEA,SAAS,mBACP,kBAC0B;AAC1B,QAAM,SAAS,oBAAI,IAAoC;AAEvD,aAAW,OAAO,kBAAkB;AAClC,UAAM,WAAW,OAAO,IAAI,IAAI,IAAI;AACpC,QAAI,CAAC,UAAU;AACb,aAAO,IAAI,IAAI,MAAM;AAAA,QACnB,KAAK,IAAI;AAAA,QACT,MAAM,IAAI;AAAA,QACV,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,QAC9C,GAAI,IAAI,YAAY,EAAE,WAAW,IAAI,UAAU,IAAI,CAAC;AAAA,MACtD,CAAC;AACD;AAAA,IACF;AAEA,aAAS,UAAU,aAAa,SAAS,SAAS,IAAI,OAAO;AAE7D,QAAI,CAAC,SAAS,aAAa,IAAI,WAAW;AACxC,eAAS,YAAY,IAAI;AAAA,IAC3B,WACE,SAAS,aACT,IAAI,aACJ,SAAS,cAAc,IAAI,WAC3B;AACA,eAAS,YAAY;AAAA,IACvB;AAEA,QAAI,IAAI,MAAM,SAAS,KAAK;AAC1B,eAAS,MAAM,IAAI;AAAA,IACrB;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,OAAO,OAAO,CAAC;AACnC;AAEA,eAAe,iBAAiB,KAAiB,QAGR;AACvC,QAAM,WAAW,MAAM,IAAI,uBAAuB;AAAA,IAChD,QAAQ,OAAO;AAAA,IACf,eAAe,OAAO;AAAA,EACxB,CAAC;AAED,MAAI,SAAS,WAAW,WAAW,CAAC,SAAS,cAAc;AACzD,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,cAAc,SAAS;AAAA,IACvB,gBAAgB,SAAS;AAAA,IACzB,iBAAiB,SAAS;AAAA,IAC1B,aAAa,SAAS;AAAA,EACxB;AACF;AAKA,eAAsB,KAAK,UAA4B,CAAC,GAAoB;AAC1E,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,cAAc,QAAQ,IAAI;AAEhC,EAAE,SAAM,cAAc;AAEtB,QAAMC,WAAY,WAAQ;AAE1B,MAAI;AACF,IAAAA,SAAQ,MAAM,kBAAkB;AAChC,UAAM,SAAS,aAAa,QAAQ,MAAM;AAC1C,IAAAA,SAAQ,KAAK,WAAWC,OAAM,KAAK,MAAM,CAAC,EAAE;AAE5C,IAAAD,SAAQ,MAAM,+BAA+B;AAE7C,UAAM,eAAe,MAAM,gBAAgB,SAAS,QAAQ,OAAO;AACnE,UAAM,cAAc;AAAA,MAClB,QAAQ,aAAa,UAAU;AAAA,MAC/B,QAAQ,aAAa,UAAU;AAAA,IACjC;AACA,wBAAoB,WAAW;AAE/B,UAAM,MAAM,IAAI,WAAW,WAAW;AACtC,UAAM,YAAY,MAAM,IAAI,iBAAiB;AAE7C,UAAM,gBAAgB,aAAa;AACnC,UAAM,gBAAgB,qBAAqB;AAAA,MACzC,oBAAoB,aAAa;AAAA,MACjC,wBAAwB,UAAU,WAAW;AAAA,MAC7C,mBAAmB;AAAA,IACrB,CAAC;AAED,UAAM,SAAwB;AAAA,MAC5B,GAAG;AAAA,MACH,GAAG;AAAA,MACH,mBAAmB,aAAa;AAAA,MAChC,gBAAgB,aAAa;AAAA,MAC7B,SAAS;AAAA,IACX;AAEA,IAAAA,SAAQ,KAAK,8BAA8B;AAE3C,QAAI,CAAC,QAAQ,SAAS,CAAC,eAAe,QAAQ,OAAO,cAAc,GAAG;AACpE,MAAE,OAAI;AAAA,QACJ,0BAA0BC,OAAM,KAAK,MAAM,CAAC;AAAA,MAC9C;AACA,MAAE,OAAI,KAAK,oBAAoB,OAAO,eAAe,KAAK,IAAI,CAAC,EAAE;AACjE,MAAE,OAAI,KAAK,iCAAiC;AAC5C,MAAE,SAAM,EAAE;AACV,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,MAAM,QAAQ,OAAO,iBAAiB,IAC1D,OAAO,kBAAkB,KAAK,IAAI,IAClC,OAAO;AAEX,IAAAD,SAAQ,MAAM,2BAA2B,eAAe,EAAE;AAC1D,UAAM,YAAY,IAAI,gBAAgB;AACtC,UAAM,mBAAmB,MAAM,UAAU;AAAA,MACvC,OAAO;AAAA,MACP;AAAA,MACA,OAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,WAAW,GAAG;AACjC,MAAAA,SAAQ,KAAK,+BAA+B;AAC5C,MAAE,OAAI,KAAK,4DAA4D;AACvE,MAAE,SAAM,EAAE;AACV,aAAO;AAAA,IACT;AAEA,IAAAA,SAAQ;AAAA,MACN,aAAaC,OAAM,KAAK,iBAAiB,MAAM,CAAC,iBAAiBA,OAAM,KAAK,eAAe,CAAC;AAAA,IAC9F;AAEA,QAAI,QAAQ,SAAS;AACnB,YAAM,cAAc,iBACjB,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAuB,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,IAAI,EAAE,IAAI,GAAG;AACpE,UAAI,iBAAiB,SAAS,GAAG;AAC/B,oBAAY,KAAK,aAAa,iBAAiB,SAAS,CAAC,OAAO;AAAA,MAClE;AACA,MAAE,QAAK,YAAY,KAAK,IAAI,GAAG,gBAAgB;AAAA,IACjD;AAEA,QAAI,QAAQ,QAAQ;AAClB,MAAE;AAAA,QACA;AAAA,UACE,YAAY,iBAAiB,MAAM;AAAA,UACnC,WAAW,MAAM;AAAA,UACjB,mBAAmB,OAAO,cAAc,KAAK,IAAI,CAAC;AAAA,UAClD,mBAAmB,aAAa;AAAA,UAChC,aAAa,aAAa;AAAA,UAC1B,gBAAgB,aAAa,aAAa,QAAQ,IAAI;AAAA,QACxD,EAAE,KAAK,IAAI;AAAA,QACX;AAAA,MACF;AACA,MAAE,SAAM,oBAAoB;AAC5B,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,6BAA6B;AAClD,QAAI,CAAC,gBAAgB,QAAQ,SAAS;AACpC,MAAE,OAAI;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgB,mBAAmB,gBAAgB;AACzD,UAAM,gBAAgB,cAAc,IAAI,CAAC,UAAU,MAAM,IAAI;AAE7D,QAAI,QAAQ,WAAW,cAAc,WAAW,iBAAiB,QAAQ;AACvE,MAAE,OAAI;AAAA,QACJ,WAAW,iBAAiB,MAAM,2BAA2B,cAAc,MAAM;AAAA,MACnF;AAAA,IACF;AAEA,IAAAD,SAAQ,MAAM,mCAAmC;AAEjD,UAAM,gBAAgB,MAAM,IAAI;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,QACE;AAAA,QACA,oBAAoB;AAAA,QACpB,aAAa,WAAW;AAAA,MAC1B;AAAA,MACA,gBAAgB;AAAA,IAClB;AAEA,IAAAA,SAAQ,KAAK,4BAA4BC,OAAM,KAAK,cAAc,OAAO,CAAC,EAAE;AAE5E,UAAM,gBAAgB,cAAc,iBAClC,+BAA+B;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IACjB,CAAC;AAEH,QAAI,QAAQ,SAAS;AACnB,MAAE,OAAI,KAAK,mBAAmB,aAAa,EAAE;AAC7C,MAAE,OAAI,KAAK,mBAAmB,aAAa,EAAE;AAC7C,MAAE,OAAI,KAAK,iBAAiB,aAAa,IAAI;AAC7C,UAAI,cAAc,aAAa;AAC7B,QAAE,OAAI,KAAK,iBAAiB,cAAc,WAAW,EAAE;AAAA,MACzD;AAAA,IACF;AAEA,QAAI,cAAc,WAAW,gBAAgB,cAAc,WAAW;AACpE,MAAE,OAAI,QAAQ,8CAA8C;AAAA,IAC9D;AAEA,IAAE,OAAI,KAAK,gBAAgBA,OAAM,KAAK,cAAc,UAAU,CAAC,EAAE;AAEjE,QAAI,cAAc,kBAAkB,cAAc,iBAAiB,GAAG;AACpE,MAAE,OAAI;AAAA,QACJ,oBAAoBA,OAAM,OAAO,cAAc,cAAc,CAAC;AAAA,MAChE;AAAA,IACF;AAEA,IAAE,OAAI,KAAK,kBAAkBA,OAAM,KAAK,cAAc,YAAY,CAAC,EAAE;AAErE,QAAI,cAAc,eAAe,GAAG;AAClC,MAAE,OAAI,QAAQ,8CAA8C;AAAA,IAC9D,OAAO;AACL,MAAE,OAAI;AAAA,QACJ,cAAc,OAAO,cAAc,MAAM,aAAa,OAAO,cAAc,KAAK,IAAI,CAAC;AAAA,MACvF;AAEA,UAAI,cAAc,eAAe;AAC/B,QAAE,OAAI,KAAK,oBAAoB,cAAc,aAAa,GAAG;AAAA,MAC/D;AAAA,IACF;AAEA,QAAI,YAAyC;AAC7C,QAAI,cAAc,cAAc;AAC9B,kBAAY;AAAA,QACV,QAAQ;AAAA,QACR,cAAc,cAAc;AAAA,MAC9B;AAAA,IACF;AAEA,QAAI,YAA0B;AAC9B,QAAI,CAAC,cAAc,kBAAkB,cAAc,kBAAkB,gBAAgB;AACnF,MAAAD,SAAQ,MAAM,iCAAiC,aAAa,KAAK;AAEjE,UAAI,eAAe;AACnB,UAAI;AACF,cAAM,aAAa,MAAM,IAAI;AAAA,UAC3B,cAAc;AAAA,UACd;AAAA,UACA,CAAC,aAAa;AACZ,kBAAM,UAAU,KAAK,MAAM,WAAW,GAAG;AACzC,gBAAI,UAAU,cAAc;AAC1B,cAAAA,SAAQ,QAAQ,kBAAkB,OAAO,GAAG;AAC5C,6BAAe;AAAA,YACjB;AAAA,UACF;AAAA,QACF;AAEA,oBAAY;AAAA,UACV,QAAQ;AAAA,UACR,cAAc,WAAW;AAAA,UACzB,gBAAgB,WAAW;AAAA,QAC7B;AACA,QAAAA,SAAQ,KAAK,uBAAuB;AAAA,MACtC,SAAS,OAAO;AACd,QAAAA,SAAQ,KAAK,6BAA6B;AAC1C,oBAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAEpE,YAAI,kBAAkB,YAAY;AAChC,gBAAM;AAAA,QACR;AAEA,QAAE,OAAI,KAAK,iCAAiC,UAAU,OAAO,EAAE;AAAA,MACjE;AAAA,IACF;AAEA,QAAI,CAAC,WAAW;AACd,UAAI,aAAa,YAAY;AAC3B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,MAAAA,SAAQ,MAAM,+BAA+B;AAE7C,YAAM,gBAAgB,uBAAuB;AAAA,QAC3C;AAAA,QACA;AAAA,MACF,CAAC;AAED,UAAI,eAAe;AACjB,oBAAY;AACZ,cAAM,mBACJ,cAAc,eAAe,cAAc,gBAAgB,SACvD,GAAG,cAAc,WAAW,cAC5B,cAAc,eAAe;AACnC,QAAAA,SAAQ,KAAK,gCAAgC,gBAAgB,GAAG;AAAA,MAClE,OAAO;AACL,YAAI;AACF,gBAAM,cAAc,MAAM,iBAAiB,KAAK;AAAA,YAC9C;AAAA,YACA,eAAe,OAAO;AAAA,UACxB,CAAC;AAED,cAAI,aAAa;AACf,wBAAY;AACZ,YAAAA,SAAQ,KAAK,qCAAqC;AAAA,UACpD,OAAO;AACL,YAAAA,SAAQ,KAAK,qCAAqC;AAAA,UACpD;AAAA,QACF,SAAS,OAAO;AACd,UAAAA,SAAQ,KAAK,8BAA8B;AAC3C,cAAI,QAAQ,SAAS;AACnB,kBAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,YAAE,OAAI,KAAK,yBAAyB,OAAO,EAAE;AAAA,UAC/C;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,WAAW;AACd,YAAI,WAAW;AACb,gBAAM,IAAI;AAAA,YACR,sDAAsD,UAAU,OAAO;AAAA,UACzE;AAAA,QACF;AAEA,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,oBAAoB,sBAAsB;AAAA,MAC9C,cAAc,OAAO;AAAA,MACrB,eAAe,OAAO;AAAA,MACtB;AAAA,MACA,cAAc,UAAU;AAAA,IAC1B,CAAC;AAED,QAAI;AACF,YAAM,YAAY,wBAAwB;AAAA,QACxC;AAAA,QACA;AAAA,QACA,cAAc,OAAO;AAAA,QACrB,eAAe,OAAO;AAAA,QACtB,cAAc;AAAA,QACd,gBAAgB,UAAU;AAAA,QAC1B,iBACE,UAAU,oBACT,UAAU,WAAW,UAClB,cAAc,UACd,cAAc;AAAA,QACpB,aACE,UAAU,gBACT,UAAU,WAAW,WAAU,oBAAI,KAAK,GAAE,YAAY,IAAI;AAAA,MAC/D,CAAC;AAED,UAAI,QAAQ,SAAS;AACnB,QAAE,OAAI,KAAK,oBAAoB,SAAS,EAAE;AAAA,MAC5C;AAAA,IACF,SAAS,OAAO;AACd,UAAI,QAAQ,SAAS;AACnB,cAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,QAAE,OAAI,KAAK,yCAAyC,OAAO,EAAE;AAAA,MAC/D;AAAA,IACF;AAEA,QAAI,UAAU,WAAW,SAAS;AAChC,YAAM,cACJ,UAAU,WAAW,gBACjB,0BACA;AACN,MAAE,OAAI;AAAA,QACJ,SAAS,WAAW;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,aAAa,KAAK,IAAI,IAAI,aAAa,KAAM,QAAQ,CAAC;AAC5D,IAAE,SAAM,mBAAmB,QAAQ,IAAI;AAEvC,IAAE,OAAI,KAAK,mEAAmE;AAC9E,IAAE,OAAI,KAAK,qEAAgE;AAC3E,WAAO;AAAA,EACT,SAAS,OAAO;AACd,IAAAA,SAAQ,KAAK;AAEb,QAAI,iBAAiB,mBAAmB,MAAM,iBAAiB;AAC7D,MAAE,OAAI,MAAM,MAAM,gBAAgB,OAAO;AACzC,YAAM,WAAW,2BAA2B,MAAM,eAAe;AACjE,iBAAW,QAAQ,UAAU;AAC3B,QAAE,OAAI,KAAK,IAAI;AAAA,MACjB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,mBAAmB,MAAM,YAAY;AACxD,YAAM,EAAE,WAAW,IAAI;AACvB,MAAE,OAAI,MAAM,WAAW,OAAO;AAC9B,YAAM,WAAW,sBAAsB,UAAU;AACjD,iBAAW,QAAQ,UAAU;AAC3B,QAAE,OAAI,KAAK,IAAI;AAAA,MACjB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,OAAO;AAC1B,MAAE,OAAI,MAAM,MAAM,OAAO;AAEzB,UAAI,MAAM,QAAQ,SAAS,iBAAiB,GAAG;AAC7C,QAAE,OAAI,KAAK,+DAA+D;AAC1E,QAAE,OAAI,KAAK,gDAAgD;AAC3D,QAAE,OAAI,KAAK,2DAA2D;AACtE,QAAE,OAAI,KAAK,EAAE;AACb,QAAE,OAAI,KAAK,mEAAmE;AAC9E,QAAE,OAAI,KAAK,yDAAyD;AAAA,MACtE,WAAW,MAAM,QAAQ,SAAS,YAAY,GAAG;AAC/C,QAAE,OAAI,KAAK,oCAAoC;AAC/C,QAAE,OAAI,KAAK,8BAA8B;AAAA,MAC3C;AAEA,UAAI,QAAQ,SAAS;AACnB,QAAE,OAAI,KAAK,eAAe,MAAM,SAAS,KAAK,EAAE;AAAA,MAClD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AIjxBA,SAAS,gBAAAE,eAAc,iBAAAC,sBAAqB;AAC5C,SAAS,YAAAC,iBAAgB;AACzB,YAAYC,QAAO;AACnB,OAAOC,YAAW;;;ACElB,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,SAAAC,cAAa;AACtB,OAAOC,oBAAmB;AAE1B,SAAS,QAAAC,aAAY;;;ACGrB,IAAM,YAAY;AAClB,IAAM,cAAc;AACpB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,iBAAiB;AAGvB,IAAM,iBACJ;AACF,IAAM,oBAAoB;AAAA,EACxB;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EAAY;AAAA,EAAY;AAAA,EAAS;AAAA,EAC9E;AAAA,EAAO;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAS;AAAA,EAClC;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACrE;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACzC;AAAA,EAAS;AAAA,EAAS;AAAA,EAAY;AAAA,EAAa;AAAA,EAAO;AAAA,EAAW;AAAA,EAC7D;AAAA,EAAW;AAAA,EAAY;AAAA,EAAM;AAAA,EAAQ;AAAA,EACrC;AAAA,EAAU;AAAA,EAAY;AAAA,EAAS;AAAA,EAC/B;AAAA,EAAa;AAAA,EAAW;AAAA,EAAe;AAAA,EAAa;AAAA,EACpD;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EACjE;AAAA,EAAU;AACZ;AAGA,IAAM,8BAA8B,oBAAI,IAAI;AAAA,EAC1C;AAAA,EAAa;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EACzD;AAAA,EAAe;AAAA,EAAW;AAAA,EAC1B;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EAAW;AAAA,EACxD;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAW;AAAA,EACtC;AAAA,EAAS;AAAA,EAAU;AAAA,EAAW;AAAA,EAAS;AAAA,EAAQ;AAAA,EAC/C;AAAA,EAAW;AAAA,EAAY;AAAA,EAAY;AAAA,EAAU;AAAA,EAAW;AAAA,EACxD;AAAA,EAAW;AAAA,EAAc;AAAA,EAAgB;AAC3C,CAAC;AAGD,IAAM,0BAA0B,oBAAI,IAAI;AAAA,EACtC;AAAA,EAAS;AAAA,EAAe;AAAA,EAAO;AAAA,EAAc;AAAA,EAC7C;AAAA,EAAoB;AAAA,EAAwB;AAAA,EAC5C;AAAA,EAAS;AAAA,EAAe;AAAA,EAAW;AAAA,EAAW;AAAA,EAC9C;AAAA,EAAc;AAAA,EAAgB;AAAA,EAAkB;AAClD,CAAC;AAGD,IAAM,yBAAyB,oBAAI,IAAI;AAAA,EACrC;AAAA,EAAe;AAAA,EAAgB;AAAA,EAAiB;AAAA,EAAgB;AAAA,EAChE;AAAA,EAAW;AAAA,EACX;AAAA,EAAoB;AAAA,EACpB;AAAA,EAAiB;AAAA,EAAoB;AAAA,EACrC;AAAA,EAAgB;AAAA,EAAgB;AAAA,EAChC;AAAA,EAAc;AAAA,EACd;AAAA,EAAY;AAAA,EACZ;AAAA,EAAsB;AAAA,EAAsB;AAAA,EAAa;AAAA,EACzD;AACF,CAAC;AAGD,IAAM,yBAAyB,oBAAI,IAAI;AAAA,EACrC;AAAA,EAAS;AAAA,EAAW;AAAA,EAAS;AAAA,EAAe;AAAA,EAC5C;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAY;AAAA,EAC/B;AAAA,EAAgB;AAAA,EAAkB;AAAA,EAAkB;AAAA,EACpD;AAAA,EAAe;AAAA,EAAc;AAAA,EAC7B;AAAA,EAAc;AAAA,EAAY;AAAA,EAAc;AAAA,EACxC;AAAA,EAAe;AAAA,EAAc;AAAA,EAC7B;AAAA,EAAY;AAAA,EAAW;AACzB,CAAC;AAKM,SAAS,eACd,MACA,SACA,WAAmC,CAAC,GACd;AACtB,QAAM,UAAU,KAAK,KAAK;AAK1B,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,2BAA2B;AAAA,EACvF;AAGA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,mBAAmB;AAAA,EAC/E;AAGA,MAAI,CAAC,WAAW,KAAK,OAAO,GAAG;AAC7B,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,2BAA2B;AAAA,EACvF;AAGA,MAAI,UAAU,KAAK,OAAO,GAAG;AAC3B,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,MAAM;AAAA,EAClE;AAGA,MAAI,YAAY,KAAK,OAAO,GAAG;AAC7B,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,gBAAgB;AAAA,EAC5E;AAGA,MAAI,gBAAgB,KAAK,OAAO,KAAK,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC3D,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,YAAY;AAAA,EACxE;AAGA,MAAI,gBAAgB,KAAK,OAAO,KAAK,iBAAiB,KAAK,OAAO,GAAG;AACnE,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,aAAa;AAAA,EACzE;AAGA,MAAI,eAAe,KAAK,OAAO,GAAG;AAChC,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,iBAAiB;AAAA,EAC7E;AAGA,MAAI,gBAAgB,KAAK,OAAO,GAAG;AACjC,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,YAAY;AAAA,EACxE;AAGA,MAAI,kBAAkB,KAAK,OAAO,KAAK,QAAQ,SAAS,GAAG;AACzD,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,qBAAqB;AAAA,EACjF;AAKA,MAAI,YAAY,mBAAmB,SAAS,eAAe;AACzD,QAAI,4BAA4B,IAAI,SAAS,aAAa,GAAG;AAC3D,aAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,+BAA+B,SAAS,aAAa,GAAG;AAAA,IACpH;AAGA,QACE,SAAS,cAAc,WAAW,OAAO,KACzC,CAAC,wBAAwB,IAAI,SAAS,aAAa,GACnD;AACA,aAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,mBAAmB;AAAA,IAC/E;AAGA,QAAI,SAAS,cAAc,WAAW,IAAI,KAAK,SAAS,cAAc,SAAS,GAAG;AAChF,YAAM,YAAY,SAAS,cAAc,CAAC;AAC1C,UAAI,aAAa,cAAc,UAAU,YAAY,GAAG;AACtD,eAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,0BAA0B;AAAA,MACtF;AAAA,IACF;AAGA,QAAI,wBAAwB,IAAI,SAAS,aAAa,GAAG;AACvD,aAAO,EAAE,cAAc,MAAM,YAAY,QAAQ,QAAQ,2BAA2B,SAAS,aAAa,GAAG;AAAA,IAC/G;AAAA,EACF;AAGA,MAAI,YAAY,YAAY;AAC1B,UAAM,WAAW,eAAe,KAAK,OAAO;AAC5C,QAAI,UAAU;AACZ,aAAO,EAAE,cAAc,MAAM,YAAY,QAAQ,QAAQ,sBAAsB;AAAA,IACjF;AAAA,EACF;AAGA,MACE,CAAC,QAAQ,SAAS,GAAG,MACpB,iBAAiB,KAAK,OAAO,KAC5B,kBAAkB,KAAK,OAAO,KAC9B,sBAAsB,KAAK,OAAO,KAClC,iBAAiB,KAAK,OAAO,IAC/B;AACA,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,kBAAkB;AAAA,EAC9E;AAGA,MAAI,kBAAkB,OAAO,GAAG;AAC9B,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,uBAAuB;AAAA,EACnF;AAGA,MAAI,SAAS,wBAAwB;AACnC,QAAI,uBAAuB,IAAI,SAAS,sBAAsB,GAAG;AAC/D,aAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,UAAU,SAAS,sBAAsB,KAAK;AAAA,IAC1G;AAAA,EACF;AAGA,MAAI,SAAS,eAAe,oBAAoB,SAAS,2BAA2B,SAAS;AAC3F,WAAO,EAAE,cAAc,OAAO,YAAY,QAAQ,QAAQ,gBAAgB;AAAA,EAC5E;AAKA,OACG,YAAY,oBAAoB,YAAY,uBAC7C,SAAS,eAAe,sBACxB;AAEA,WAAO,EAAE,cAAc,MAAM,YAAY,UAAU,QAAQ,iCAAiC;AAAA,EAC9F;AAGA,QAAM,YAAY,QAAQ,MAAM,KAAK,EAAE;AACvC,MAAI,aAAa,GAAG;AAClB,WAAO,EAAE,cAAc,MAAM,YAAY,UAAU,QAAQ,sBAAsB,SAAS,UAAU;AAAA,EACtG;AAGA,MAAI,cAAc,KAAK,eAAe,KAAK,OAAO,GAAG;AACnD,WAAO,EAAE,cAAc,MAAM,YAAY,OAAO,QAAQ,yBAAyB;AAAA,EACnF;AAGA,MAAI,cAAc,KAAK,OAAO,KAAK,YAAY,kBAAkB;AAC/D,WAAO,EAAE,cAAc,MAAM,YAAY,OAAO,QAAQ,qCAAqC;AAAA,EAC/F;AAGA,SAAO,EAAE,cAAc,OAAO,YAAY,OAAO,QAAQ,+BAA+B;AAC1F;AAKO,SAAS,sBAAsB,MAAuB;AAC3D,QAAM,QAAQ,KAAK,YAAY;AAC/B,aAAW,WAAW,wBAAwB;AAC5C,QAAI,UAAU,QAAQ,YAAY,KAAK,MAAM,SAAS,QAAQ,YAAY,CAAC,GAAG;AAC5E,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,kBAAkB,MAAuB;AAEhD,MAAI,CAAC,eAAe,KAAK,IAAI,EAAG,QAAO;AAEvC,QAAM,QAAQ,KAAK,MAAM,KAAK;AAG9B,MAAI,gBAAgB;AACpB,aAAW,QAAQ,OAAO;AACxB,QAAI,kBAAkB,KAAK,CAAC,WAAmB,KAAK,WAAW,MAAM,CAAC,GAAG;AACvE;AAAA,IACF;AAAA,EACF;AAGA,SAAO,gBAAgB,MAAM,SAAS;AACxC;;;ADrQA,IAAMC,YAAYC,eAAsB,WAAWA;AAE5C,IAAM,iBAAN,MAAqB;AAAA,EAG1B,YAAY,SAA2B;AACrC,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eACJ,SACA,cAAsB,QAAQ,IAAI,GACR;AAC1B,UAAM,kBAAkB,QAAQ,SAAS,SACrC,QAAQ,UACR,CAAC,0BAA0B;AAE/B,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,iBAAiB,QAAQ,UAC3B,CAAC,GAAG,eAAe,GAAG,QAAQ,OAAO,IACrC;AAEJ,UAAM,WAAW,oBAAI,IAAY;AAEjC,eAAW,WAAW,iBAAiB;AACrC,YAAM,QAAQ,MAAMC,MAAK,SAAS;AAAA,QAChC,KAAK;AAAA,QACL,UAAU;AAAA,QACV,QAAQ;AAAA,MACV,CAAC;AACD,YAAM,QAAQ,CAAC,SAAiB,SAAS,IAAI,IAAI,CAAC;AAAA,IACpD;AAEA,UAAM,gBAAiC,CAAC;AAExC,eAAW,QAAQ,UAAU;AAC3B,UAAI;AACF,cAAM,aAAa,KAAK,YAAY,IAAI;AACxC,sBAAc,KAAK,GAAG,UAAU;AAAA,MAClC,SAAS,OAAgB;AACvB,YAAI,QAAQ,SAAS;AACnB,gBAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,kBAAQ,KAAK,8BAA8B,IAAI,KAAK,GAAG,EAAE;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAAmC;AAC7C,UAAM,OAAOC,cAAa,UAAU,OAAO;AAC3C,WAAO,KAAK,YAAY,MAAM,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,MAAc,WAAmB,WAA4B;AACvE,UAAM,aAA8B,CAAC;AAErC,UAAM,MAAMC,OAAM,MAAM;AAAA,MACtB,YAAY;AAAA,MACZ,SAAS,CAAC,OAAO,YAAY;AAAA,IAC/B,CAAC;AAGD,UAAM,iBAAiB,oBAAI,IAAoB;AAC/C,UAAM,iBAAiB,oBAAI,IAAY;AAEvC,IAAAJ,UAAS,KAAK;AAAA;AAAA,MAEZ,mBAAmB,CAAC,SAAc;AAChC,cAAM,SAAS,KAAK,KAAK,OAAO;AAChC,YAAI,WAAW,KAAK,QAAQ,cAAc;AACxC,eAAK,KAAK,WAAW,QAAQ,CAAC,SAAc;AAC1C,gBAAI,KAAK,SAAS,mBAAmB;AACnC,oBAAM,WACJ,KAAK,SAAS,SAAS,eAAe,KAAK,SAAS,OAAO;AAC7D,oBAAM,QAAQ,KAAK,MAAM;AAEzB,kBAAI,aAAa,KAAK,QAAQ,eAAe;AAC3C,+BAAe,IAAI,OAAO,KAAK,QAAQ,aAAa;AAAA,cACtD;AACA,kBAAI,aAAa,KAAK,QAAQ,cAAc;AAC1C,+BAAe,IAAI,KAAK;AAAA,cAC1B;AACA,kBAAI,aAAa,KAAK,QAAQ,UAAU;AACtC,+BAAe,IAAI,OAAO,KAAK,QAAQ,QAAQ;AAAA,cACjD;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA,MAGA,oBAAoB,CAAC,SAAc;AACjC,cAAMK,QAAO,KAAK,KAAK;AACvB,YACEA,SACAA,MAAK,SAAS,oBACdA,MAAK,OAAO,SAAS,gBACrBA,MAAK,OAAO,SAAS,KAAK,QAAQ,YAClC,KAAK,KAAK,GAAG,SAAS,iBACtB;AACA,eAAK,KAAK,GAAG,WAAW,QAAQ,CAAC,SAAc;AAC7C,gBACE,KAAK,SAAS,oBACd,KAAK,IAAI,SAAS,gBAClB,KAAK,IAAI,SAAS,KAAK,QAAQ,cAC/B;AACA,oBAAM,YACJ,KAAK,MAAM,SAAS,eAAe,KAAK,MAAM,OAAO,KAAK,QAAQ;AACpE,6BAAe,IAAI,SAAmB;AAAA,YACxC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA,MAGA,SAAS,CAAC,SAAc;AACtB,cAAM,OAAO,KAAK,KAAK;AACvB,cAAM,UAAU,KAAK,KAAK;AAC1B,YAAI,CAAC,QAAS;AAGd,cAAM,YAAY,KAAK,YAAY,EAAE,IAAI,CAAC,MAAW,EAAE,IAAI;AAC3D,YAAI,KAAK,QAAQ,iBAAiB,WAAW,cAAc,EAAG;AAE9D,cAAM,iBAAiB,eAAe,SAAS,YAAY;AAAA,UACzD,mBAAmB;AAAA,QACrB,CAAC;AAED,YAAI,eAAe,cAAc;AAC/B,qBAAW,KAAK;AAAA,YACd,MAAM;AAAA,YACN,MAAM,KAAK,KAAK,KAAK,MAAM,QAAQ;AAAA,YACnC,QAAQ,KAAK,KAAK,KAAK,MAAM,UAAU;AAAA,YACvC,MAAM;AAAA,YACN,YAAY,eAAe;AAAA,YAC3B,UAAU;AAAA,YACV,SAAS;AAAA,YACT,QAAQ,eAAe;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA,MAGA,cAAc,CAAC,SAAc;AAC3B,cAAM,WAAW,KAAK,KAAK,MAAM;AACjC,YAAI,CAAC,SAAU;AAEf,cAAM,QAAQ,KAAK,KAAK;AACxB,YAAI,CAAC,MAAO;AAEZ,YAAI,OAAsB;AAC1B,YAAI,UAAyB;AAE7B,YAAI,MAAM,SAAS,iBAAiB;AAClC,iBAAO,MAAM;AAAA,QACf,WACE,MAAM,SAAS,4BACf,MAAM,WAAW,SAAS,iBAC1B;AACA,iBAAO,MAAM,WAAW;AAAA,QAC1B;AAEA,YAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,EAAG;AAG3B,YACE,MAAM,SAAS,4BACf,MAAM,WAAW,SAAS,kBAC1B;AACA,cAAI,KAAK,QAAQ,qBAAqB,MAAM,YAAY,cAAc,EAAG;AAAA,QAC3E;AAEA,cAAM,iBAAiB,eAAe,KAAK,KAAK,GAAG,SAAS;AAAA,UAC1D,eAAe;AAAA,UACf,mBAAmB;AAAA,QACrB,CAAC;AAED,YAAI,eAAe,cAAc;AAC/B,qBAAW,KAAK;AAAA,YACd,MAAM;AAAA,YACN,MAAM,KAAK,KAAK,KAAK,MAAM,QAAQ;AAAA,YACnC,QAAQ,KAAK,KAAK,KAAK,MAAM,UAAU;AAAA,YACvC,MAAM,KAAK,KAAK;AAAA,YAChB,YAAY,eAAe;AAAA,YAC3B,UAAU;AAAA,YACV;AAAA,YACA,QAAQ,eAAe;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA,MAGA,eAAe,CAAC,SAAc;AAE5B,YAAI,KAAK,OAAO,SAAS,oBAAqB;AAC9C,YAAI,KAAK,OAAO,SAAS,oBAAqB;AAG9C,YAAI,KAAK,OAAO,SAAS,eAAgB;AACzC,YACE,KAAK,OAAO,SAAS,4BACrB,KAAK,YAAY,QAAQ,SAAS,eAClC;AAGF,YAAI,KAAK,OAAO,SAAS,yBAA0B;AAGnD,YAAI,KAAK,OAAO,SAAS,oBAAoB,KAAK,OAAO,QAAQ,KAAK,KAAM;AAG5E,YAAI,KAAK,OAAO,SAAS,gBAAiB;AAG1C,YAAI,cAAc,MAAM,cAAc,EAAG;AAEzC,cAAM,OAAO,KAAK,KAAK;AACvB,YAAI,CAAC,KAAK,KAAK,EAAG;AAGlB,cAAM,WAAW,2BAA2B,IAAI;AAChD,cAAM,aAAa,KAAK,OAAO;AAE/B,cAAM,iBAAiB,eAAe,KAAK,KAAK,GAAG,kBAAkB;AAAA,UACnE;AAAA,UACA,wBAAwB;AAAA,UACxB,mBAAmB;AAAA,QACrB,CAAC;AAGD,YAAI,EAAE,WAAW,IAAI;AACrB,YACE,eAAe,wBACf,KAAK,OAAO,IAAI,SAAS,cACzB;AACA,gBAAM,UAAU,KAAK,OAAO,GAAG;AAC/B,cAAI,sBAAsB,OAAO,KAAK,eAAe,cAAc;AACjE,yBAAa;AAAA,UACf;AAAA,QACF;AAEA,YAAI,eAAe,cAAc;AAC/B,qBAAW,KAAK;AAAA,YACd,MAAM;AAAA,YACN,MAAM,KAAK,KAAK,KAAK,MAAM,QAAQ;AAAA,YACnC,QAAQ,KAAK,KAAK,KAAK,MAAM,UAAU;AAAA,YACvC,MAAM,KAAK,KAAK;AAAA,YAChB;AAAA,YACA,UAAU;AAAA,YACV,SAAS;AAAA,YACT,QAAQ,eAAe;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA,MAGA,iBAAiB,CAAC,SAAc;AAE9B,YAAI,KAAK,OAAO,SAAS,oBAAqB;AAG9C,YAAI,KAAK,OAAO,SAAS,2BAA4B;AAGrD,YAAI,cAAc,MAAM,cAAc,EAAG;AAGzC,cAAM,SAAS,KAAK,KAAK;AACzB,YAAI,OAAO,WAAW,EAAG;AAGzB,cAAM,QAAkB,CAAC;AACzB,iBAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,gBAAM,QAAQ,OAAO,CAAC;AACtB,gBAAM,KAAK,MAAM,MAAM,GAAa;AACpC,cAAI,IAAI,KAAK,KAAK,YAAY,QAAQ;AACpC,kBAAM,OAAO,KAAK,KAAK,YAAY,CAAC;AACpC,gBAAI,KAAK,SAAS,cAAc;AAC9B,oBAAM,KAAK,IAAI,KAAK,IAAI,GAAG;AAAA,YAC7B,OAAO;AACL,oBAAM,KAAK,SAAS;AAAA,YACtB;AAAA,UACF;AAAA,QACF;AACA,cAAM,OAAO,MAAM,KAAK,EAAE,EAAE,KAAK;AACjC,YAAI,CAAC,KAAM;AAEX,cAAM,WAAW,2BAA2B,IAAI;AAChD,cAAM,aAAa,KAAK,OAAO;AAE/B,cAAM,iBAAiB,eAAe,MAAM,oBAAoB;AAAA,UAC9D;AAAA,UACA,wBAAwB;AAAA,UACxB,mBAAmB;AAAA,QACrB,CAAC;AAED,YAAI,eAAe,cAAc;AAC/B,qBAAW,KAAK;AAAA,YACd,MAAM;AAAA,YACN,MAAM,KAAK,KAAK,KAAK,MAAM,QAAQ;AAAA,YACnC,QAAQ,KAAK,KAAK,KAAK,MAAM,UAAU;AAAA,YACvC;AAAA,YACA,YAAY,eAAe;AAAA,YAC3B,UAAU;AAAA,YACV,SAAS;AAAA,YACT,QAAQ,eAAe;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AACF;AAKA,SAAS,cAAc,MAAW,QAA8B;AAC9D,MAAI,UAAU,KAAK;AACnB,SAAO,SAAS;AACd,QAAI,QAAQ,KAAK,SAAS,kBAAkB;AAC1C,YAAM,SAAS,QAAQ,KAAK;AAC5B,UAAI,OAAO,SAAS,gBAAgB,OAAO,IAAI,OAAO,IAAc,GAAG;AACrE,eAAO;AAAA,MACT;AAAA,IACF;AACA,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;AAMA,SAAS,2BAA2B,MAA+B;AACjE,MAAI,UAAU,KAAK;AACnB,SAAO,SAAS;AACd,QAAI,QAAQ,KAAK,SAAS,kBAAkB;AAC1C,YAAM,SAAS,QAAQ,KAAK;AAC5B,UAAI,OAAO,SAAS,cAAc;AAChC,eAAO,OAAO;AAAA,MAChB;AACA,UACE,OAAO,SAAS,sBAChB,OAAO,OAAO,SAAS,gBACvB,OAAO,SAAS,SAAS,cACzB;AACA,eAAO,GAAG,OAAO,OAAO,IAAI,IAAI,OAAO,SAAS,IAAI;AAAA,MACtD;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,SAAS,iBAAiB;AACzC,YAAM,SAAS,QAAQ,KAAK;AAC5B,UAAI,OAAO,SAAS,cAAc;AAChC,eAAO,OAAO;AAAA,MAChB;AAAA,IACF;AACA,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;;;AExYA,YAAY,YAAY;AACxB,SAAS,SAAS,kBAAkB;AAIpC,IAAM,cAAc;AAAA,EAClB,MAAM,QAAgB;AACpB,WAAO,WAAW,QAAQ;AAAA,MACxB,YAAY;AAAA,MACZ,SAAS,CAAC,OAAO,YAAY;AAAA,MAC7B,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAG7B,YAAY,SAA2B;AACrC,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UACE,MACA,YACA,WAAmB,WACF;AACjB,UAAM,MAAa,aAAM,MAAM,EAAE,QAAQ,YAAY,CAAC;AACtD,UAAM,IAAW,aAAM;AAEvB,UAAM,UAA2B,CAAC;AAClC,UAAM,UAA2B,CAAC;AAClC,UAAM,iBAAiB,oBAAI,IAAkB;AAG7C,UAAM,wBAAwB,oBAAI,IAAS;AAG3C,UAAM,uBAAuB,oBAAI,IAA2B;AAC5D,eAAW,KAAK,YAAY;AAC1B,2BAAqB,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE,MAAM,IAAI,CAAC;AAAA,IACrD;AAGA,QAAI,qBAA0B;AAC9B,UAAM,qBAAqB,oBAAI,IAAY;AAG3C,UAAM,UAAU,KAAK;AAErB,IAAO,aAAM,KAAK;AAAA,MAChB,uBAAuB,MAAM;AAC3B,cAAM,SAAS,KAAK,KAAK,OAAO;AAChC,YAAI,WAAW,QAAQ,cAAc;AACnC,+BAAqB;AACrB,qBAAW,QAAQ,KAAK,KAAK,cAAc,CAAC,GAAG;AAC7C,gBAAI,KAAK,SAAS,qBAAqB,KAAK,SAAS,SAAS,cAAc;AAC1E,iCAAmB,IAAI,KAAK,SAAS,IAAI;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AACA,aAAK,SAAS,IAAI;AAAA,MACpB;AAAA,MAEA,aAAa,MAAM;AACjB,cAAM,MAAM,KAAK,KAAK;AACtB,YAAI,CAAC,KAAK;AAAE,eAAK,SAAS,IAAI;AAAG;AAAA,QAAQ;AAEzC,cAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,MAAM;AACjD,cAAM,YAAY,qBAAqB,IAAI,GAAG;AAC9C,YAAI,CAAC,aAAa,UAAU,aAAa,eAAe;AACtD,eAAK,SAAS,IAAI;AAClB;AAAA,QACF;AAEA,cAAM,QAAQ,EAAE;AAAA,UACd,EAAE,cAAc,QAAQ,aAAa;AAAA,UACrC,CAAC;AAAA,QACH;AACA,cAAM,SAAS,EAAE;AAAA,UACf,EAAE,cAAc,QAAQ,aAAa;AAAA,QACvC;AACA,cAAM,WAAW,EAAE;AAAA,UACjB;AAAA,UACA;AAAA,UACA,CAAC,EAAE,QAAQ,UAAU,IAAI,CAAC;AAAA,QAC5B;AAEA,aAAK,QAAQ,QAAQ;AAErB,gBAAQ,KAAK,SAAS;AACtB,uBAAe,IAAI,aAAa;AAChC,6BAAqB,OAAO,GAAG;AAE/B,eAAO;AAAA,MACT;AAAA,MAEA,kBAAkB,MAAM;AACtB,cAAM,MAAM,KAAK,KAAK;AACtB,YAAI,CAAC,KAAK;AAAE,eAAK,SAAS,IAAI;AAAG;AAAA,QAAQ;AAEzC,cAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,MAAM;AACjD,cAAM,YAAY,qBAAqB,IAAI,GAAG;AAC9C,YAAI,CAAC,aAAa,UAAU,aAAa,cAAc;AACrD,eAAK,SAAS,IAAI;AAClB;AAAA,QACF;AAEA,cAAM,QAAQ,KAAK,KAAK;AACxB,YAAI,CAAC,OAAO;AAAE,eAAK,SAAS,IAAI;AAAG;AAAA,QAAQ;AAE3C,cAAM,QAAQ,EAAE;AAAA,UACd,EAAE,WAAW,QAAQ,YAAY;AAAA,UACjC,CAAC,EAAE,cAAc,UAAU,IAAI,CAAC;AAAA,QAClC;AACA,cAAM,gBAAgB,EAAE,uBAAuB,KAAK;AAEpD,aAAK,KAAK,QAAQ;AAElB,cAAM,gBAAgB,uBAAuB,IAAI;AACjD,YAAI,eAAe;AACjB,gCAAsB,IAAI,aAAa;AAAA,QACzC;AAEA,gBAAQ,KAAK,SAAS;AACtB,uBAAe,IAAI,YAAY;AAC/B,6BAAqB,OAAO,GAAG;AAE/B,aAAK,SAAS,IAAI;AAAA,MACpB;AAAA,MAEA,mBAAmB,MAAM;AACvB,cAAM,MAAM,KAAK,KAAK;AACtB,YAAI,CAAC,KAAK;AAAE,eAAK,SAAS,IAAI;AAAG;AAAA,QAAQ;AAEzC,cAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,MAAM;AACjD,cAAM,YAAY,qBAAqB,IAAI,GAAG;AAC9C,YAAI,CAAC,aAAa,UAAU,aAAa,cAAc;AACrD,eAAK,SAAS,IAAI;AAClB;AAAA,QACF;AAEA,YAAI,KAAK,OAAO,KAAK,SAAS,gBAAgB;AAC5C,eAAK,SAAS,IAAI;AAClB;AAAA,QACF;AAEA,cAAM,QAAQ,EAAE;AAAA,UACd,EAAE,WAAW,QAAQ,YAAY;AAAA,UACjC,CAAC,EAAE,cAAc,UAAU,IAAI,CAAC;AAAA,QAClC;AAEA,aAAK,QAAQ,KAAK;AAElB,cAAM,gBAAgB,uBAAuB,IAAI;AACjD,YAAI,eAAe;AACjB,gCAAsB,IAAI,aAAa;AAAA,QACzC;AAEA,gBAAQ,KAAK,SAAS;AACtB,uBAAe,IAAI,YAAY;AAC/B,6BAAqB,OAAO,GAAG;AAE/B,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAGD,eAAW,aAAa,qBAAqB,OAAO,GAAG;AACrD,cAAQ,KAAK,SAAS;AAAA,IACxB;AAGA,QAAI,sBAAsB,OAAO,GAAG;AAClC,WAAK,sBAAsB,KAAK,uBAAuB,CAAC;AAAA,IAC1D;AAGA,SAAK,cAAc,KAAK,gBAAgB,oBAAoB,oBAAoB,sBAAsB,OAAO,GAAG,CAAC;AAEjH,UAAM,SAAgB,aAAM,GAAG,EAAE;AAEjC,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,cAAc,QAAQ;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBACN,KACA,gBACA,GACM;AACN,UAAM,sBAAsB,KAAK,QAAQ;AACzC,UAAM,kBAAkB,KAAK,QAAQ;AAErC,UAAM,gBAAgB,MAAM,EAAE,oBAAoB,SAAS;AAAA,MACzD,EAAE;AAAA,QACA,EAAE,cAAc;AAAA,UACd,EAAE,SAAS,KAAK;AAAA,YACd,MAAM;AAAA,YACN,KAAK,EAAE,WAAW,mBAAmB;AAAA,YACrC,OAAO,EAAE,WAAW,mBAAmB;AAAA,YACvC,WAAW;AAAA,UACb,CAAC;AAAA,QACH,CAAC;AAAA,QACD,EAAE,eAAe,EAAE,WAAW,eAAe,GAAG,CAAC,CAAC;AAAA,MACpD;AAAA,IACF,CAAC;AAED,IAAO,aAAM,KAAK;AAAA,MAChB,cAAc,MAAM;AAClB,YAAI,eAAe,IAAI,KAAK,IAAI,GAAG;AACjC,gBAAM,OAAO,KAAK,KAAK;AACvB,cAAI,KAAK,SAAS,kBAAkB;AAClC,kBAAM,iBAAiB,KAAK,KAAK,KAAK,CAAC,SAAc;AACnD,kBAAI,KAAK,SAAS,sBAAuB,QAAO;AAChD,qBAAO,KAAK,aAAa;AAAA,gBAAK,CAAC,SAC7B,KAAK,MAAM,SAAS,oBACpB,KAAK,KAAK,QAAQ,SAAS,gBAC3B,KAAK,KAAK,OAAO,SAAS;AAAA,cAC5B;AAAA,YACF,CAAC;AAED,gBAAI,CAAC,gBAAgB;AACnB,mBAAK,KAAK,QAAQ,cAAc,CAAC;AAAA,YACnC;AAAA,UACF;AAAA,QACF;AACA,aAAK,SAAS,IAAI;AAAA,MACpB;AAAA,MAEA,6BAA6B,MAAM;AACjC,YAAI,eAAe,IAAI,KAAK,IAAI,GAAG;AACjC,gBAAM,OAAO,KAAK,KAAK;AACvB,cAAI,KAAK,SAAS,kBAAkB;AAClC,kBAAM,iBAAiB,KAAK,KAAK,KAAK,CAAC,SAAc;AACnD,kBAAI,KAAK,SAAS,sBAAuB,QAAO;AAChD,qBAAO,KAAK,aAAa;AAAA,gBAAK,CAAC,SAC7B,KAAK,MAAM,SAAS,oBACpB,KAAK,KAAK,QAAQ,SAAS,gBAC3B,KAAK,KAAK,OAAO,SAAS;AAAA,cAC5B;AAAA,YACF,CAAC;AAED,gBAAI,CAAC,gBAAgB;AACnB,mBAAK,KAAK,QAAQ,cAAc,CAAC;AAAA,YACnC;AAAA,UACF;AAAA,QACF;AACA,aAAK,SAAS,IAAI;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,cACN,KACA,gBACA,oBACA,oBACA,WACA,GACM;AACN,QAAI,eAAe,SAAS,EAAG;AAE/B,UAAM,mBAAmB,oBAAI,IAAY;AAEzC,QAAI,eAAe,IAAI,aAAa,GAAG;AACrC,uBAAiB,IAAI,KAAK,QAAQ,aAAa;AAAA,IACjD;AAEA,QAAI,eAAe,IAAI,YAAY,KAAK,WAAW;AACjD,uBAAiB,IAAI,KAAK,QAAQ,QAAQ;AAAA,IAC5C;AAEA,UAAM,oBAA8B,CAAC;AACrC,eAAW,QAAQ,kBAAkB;AACnC,UAAI,CAAC,mBAAmB,IAAI,IAAI,GAAG;AACjC,0BAAkB,KAAK,IAAI;AAAA,MAC7B;AAAA,IACF;AAEA,QAAI,kBAAkB,WAAW,EAAG;AAEpC,QAAI,oBAAoB;AACtB,iBAAW,QAAQ,mBAAmB;AACpC,cAAM,YAAY,EAAE,gBAAgB,EAAE,WAAW,IAAI,GAAG,EAAE,WAAW,IAAI,CAAC;AAC1E,2BAAmB,KAAK,WAAW,KAAK,SAAS;AAAA,MACnD;AAAA,IACF,OAAO;AACL,YAAM,aAAa,kBAAkB;AAAA,QAAI,CAAC,SACxC,EAAE,gBAAgB,EAAE,WAAW,IAAI,GAAG,EAAE,WAAW,IAAI,CAAC;AAAA,MAC1D;AACA,YAAM,aAAa,EAAE;AAAA,QACnB;AAAA,QACA,EAAE,cAAc,KAAK,QAAQ,YAAY;AAAA,MAC3C;AAEA,YAAM,OAAO,IAAI,QAAQ;AACzB,UAAI,kBAAkB;AACtB,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAI,KAAK,CAAC,EAAE,SAAS,qBAAqB;AACxC,4BAAkB;AAAA,QACpB;AAAA,MACF;AAEA,UAAI,mBAAmB,GAAG;AACxB,aAAK,OAAO,kBAAkB,GAAG,GAAG,UAAU;AAAA,MAChD,OAAO;AACL,aAAK,QAAQ,UAAU;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,uBAAuB,MAAuB;AACrD,MAAI,UAAU,KAAK;AACnB,SAAO,SAAS;AACd,UAAM,OAAO,QAAQ;AAErB,QAAI,KAAK,SAAS,yBAAyB,KAAK,IAAI,MAAM;AACxD,YAAM,OAAO,KAAK,GAAG;AACrB,UAAI,SAAS,KAAK,IAAI,EAAG,QAAO;AAAA,IAClC;AAEA,QAAI,KAAK,SAAS,2BAA2B;AAC3C,YAAM,SAAS,QAAQ,QAAQ;AAC/B,UACE,QAAQ,SAAS,wBACjB,OAAO,IAAI,SAAS,cACpB;AACA,cAAM,OAAO,OAAO,GAAG;AACvB,YAAI,SAAS,KAAK,IAAI,EAAG,QAAO;AAAA,MAClC;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,sBAAsB;AACtC,YAAM,SAAS,QAAQ,QAAQ;AAC/B,UACE,QAAQ,SAAS,wBACjB,OAAO,IAAI,SAAS,cACpB;AACA,cAAM,OAAO,OAAO,GAAG;AACvB,YAAI,SAAS,KAAK,IAAI,EAAG,QAAO;AAAA,MAClC;AAAA,IACF;AAEA,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;;;AC7WO,IAAM,eAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,OAAO,KAAK;AAAA,EACzC,cAAc;AAAA,EACd,eAAe;AAAA,EACf,cAAc;AAAA,EACd,UAAU;AAAA,EAEV,wBAAwB;AAAA,IACtB;AAAA,IAAS;AAAA,IAAe;AAAA,IACxB;AAAA,IAAc;AAAA,IAAoB;AAAA,IAClC;AAAA,IAAwB;AAAA,IACxB;AAAA,IAAS;AAAA,IAAe;AAAA,IAAW;AAAA,IAAW;AAAA,IAC9C;AAAA,IAAc;AAAA,IAAgB;AAAA,IAAkB;AAAA,EAClD;AAAA,EAEA,2BAA2B;AAAA,IACzB;AAAA,IAAa;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAM;AAAA,IAAO;AAAA,IAAO;AAAA,IACzD;AAAA,IAAe;AAAA,IAAW;AAAA,IAC1B;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAU;AAAA,IAAU;AAAA,IAAW;AAAA,IACxD;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAY;AAAA,IAAW;AAAA,IACtC;AAAA,IAAS;AAAA,IAAU;AAAA,IAAW;AAAA,IAAS;AAAA,IAAQ;AAAA,EACjD;AAAA,EAEA,iBAAiB,WAAkB,SAAuC;AAExE,eAAW,YAAY,WAAW;AAChC,UAAI,SAAS,SAAS,cAAc;AAClC,cAAM,UAAU,SAAS;AACzB,YAAI,WAAW,QAAQ,QAAQ,QAAQ,KAAK,SAAS,iBAAiB;AACpE,gBAAM,UAAU,QAAQ,KAAK;AAC7B,cAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK;AACxD,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,qBAAqB,MAAW,QAA8B;AAE5D,QAAI,KAAK,SAAS,kBAAkB;AAClC,YAAM,SAAS,KAAK;AACpB,UAAI,OAAO,SAAS,gBAAgB,OAAO,IAAI,OAAO,IAAc,GAAG;AACrE,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,YAGjB;AACA,UAAM,aAAuB,CAAC;AAE9B,QAAI,WAAW,IAAI,aAAa,GAAG;AACjC,iBAAW,KAAK,GAAG;AAAA,IACrB;AAEA,QAAI,WAAW,IAAI,YAAY,GAAG;AAGhC,iBAAW,KAAK,YAAY;AAAA,IAC9B;AAEA,WAAO,EAAE,YAAY,QAAQ,iBAAiB;AAAA,EAChD;AACF;;;AJnEA,IAAM,mBAAsC,CAAC,QAAQ,UAAU,KAAK;AAEpE,SAAS,yBACP,WACA,WACS;AACT,SAAO,iBAAiB,QAAQ,SAAS,KAAK,iBAAiB,QAAQ,SAAS;AAClF;AAaA,eAAsB,KAAK,UAAuB,CAAC,GAAoB;AACrE,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,sBAAsB,QAAQ,cAAc;AAElD,EAAE,SAAM,cAAc;AAEtB,QAAMC,WAAY,WAAQ;AAE1B,MAAI;AAEF,IAAAA,SAAQ,MAAM,sCAAsC;AAEpD,UAAM,WAAW,IAAI,eAAe,YAAY;AAChD,UAAM,gBAAgB,MAAM,SAAS,eAAe,SAAS,WAAW;AAExE,QAAI,cAAc,WAAW,GAAG;AAC9B,MAAAA,SAAQ,KAAK,4BAA4B;AACzC,MAAE,OAAI,KAAK,uDAAuD;AAClE,MAAE,SAAM,EAAE;AACV,aAAO;AAAA,IACT;AAEA,IAAAA,SAAQ;AAAA,MACN,SAASC,OAAM,KAAK,cAAc,MAAM,CAAC;AAAA,IAC3C;AAGA,UAAM,WAAW,cAAc;AAAA,MAAO,CAAC,MACrC,yBAAyB,EAAE,YAAY,mBAAmB;AAAA,IAC5D;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,MAAE,OAAI;AAAA,QACJ,uBAAuBA,OAAM,KAAK,mBAAmB,CAAC;AAAA,MACxD;AACA,MAAE,OAAI,KAAK,qEAAqE;AAChF,MAAE,SAAM,EAAE;AACV,aAAO;AAAA,IACT;AAEA,IAAE,OAAI;AAAA,MACJ,GAAG,SAAS,MAAM,iBAAiBA,OAAM,KAAK,mBAAmB,CAAC;AAAA,IACpE;AAGA,UAAM,SAAS,oBAAI,IAA6B;AAChD,eAAW,KAAK,UAAU;AACxB,YAAM,WAAW,OAAO,IAAI,EAAE,IAAI,KAAK,CAAC;AACxC,eAAS,KAAK,CAAC;AACf,aAAO,IAAI,EAAE,MAAM,QAAQ;AAAA,IAC7B;AAGA,QAAI,QAAQ,QAAQ;AAClB,YAAM,QAAkB,CAAC;AACzB,iBAAW,CAAC,MAAM,UAAU,KAAK,QAAQ;AACvC,cAAM,UAAUC,UAAS,aAAa,IAAI;AAC1C,cAAM,KAAKD,OAAM,KAAK,OAAO,CAAC;AAE9B,mBAAW,KAAK,YAAY;AAC1B,gBAAM,kBACJ,EAAE,eAAe,SAASA,OAAM,QAChC,EAAE,eAAe,WAAWA,OAAM,SAClCA,OAAM;AAER,gBAAM,gBAAgB,EAAE,aAAa,gBAAgB,QAAQ;AAC7D,gBAAM;AAAA,YACJ,KAAKA,OAAM,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,gBAAgB,IAAI,EAAE,UAAU,GAAG,CAAC,IACjEA,OAAM,KAAK,aAAa,CAAC,KAAK,SAAS,EAAE,MAAM,EAAE,CAAC;AAAA,UACvD;AAEA,cAAI,QAAQ,SAAS;AACnB,kBAAM,KAAKA,OAAM,IAAI,WAAW,EAAE,MAAM,EAAE,CAAC;AAAA,UAC7C;AAAA,QACF;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,YAAM,KAAK,oBAAoB,QAAQ,CAAC;AACxC,MAAE,QAAK,MAAM,KAAK,IAAI,GAAG,2BAAsB;AAC/C,MAAE,SAAM,yCAAyC;AACjD,aAAO;AAAA,IACT;AAGA,QAAI;AAEJ,QAAI,QAAQ,aAAa;AACvB,iBAAW,MAAM,mBAAmB,QAAQ,WAAW;AACvD,UAAI,SAAS,WAAW,GAAG;AACzB,QAAE,OAAI,KAAK,mCAAmC;AAC9C,QAAE,SAAM,EAAE;AACV,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,iBAAW;AAAA,IACb;AAGA,IAAAD,SAAQ,MAAM,kBAAkB;AAEhC,UAAM,cAAc,IAAI,kBAAkB,YAAY;AACtD,QAAI,eAAe;AACnB,QAAI,gBAAgB;AAGpB,UAAM,iBAAiB,oBAAI,IAA6B;AACxD,eAAW,KAAK,UAAU;AACxB,YAAM,WAAW,eAAe,IAAI,EAAE,IAAI,KAAK,CAAC;AAChD,eAAS,KAAK,CAAC;AACf,qBAAe,IAAI,EAAE,MAAM,QAAQ;AAAA,IACrC;AAEA,eAAW,CAAC,MAAM,UAAU,KAAK,gBAAgB;AAC/C,YAAM,OAAOG,cAAa,MAAM,OAAO;AACvC,YAAM,SAAS,YAAY,UAAU,MAAM,YAAY,IAAI;AAE3D,UAAI,OAAO,eAAe,GAAG;AAC3B,QAAAC,eAAc,MAAM,OAAO,QAAQ,OAAO;AAC1C,wBAAgB,OAAO;AACvB;AAAA,MACF;AAEA,UAAI,QAAQ,WAAW,OAAO,QAAQ,SAAS,GAAG;AAChD,cAAM,UAAUF,UAAS,aAAa,IAAI;AAC1C,QAAE,OAAI,KAAK,WAAW,OAAO,QAAQ,MAAM,eAAe,OAAO,EAAE;AAAA,MACrE;AAAA,IACF;AAEA,IAAAF,SAAQ;AAAA,MACN,WAAWC,OAAM,KAAK,YAAY,CAAC,mBAAmBA,OAAM,KAAK,aAAa,CAAC;AAAA,IACjF;AAGA,UAAM,aAAa,KAAK,IAAI,IAAI,aAAa,KAAM,QAAQ,CAAC;AAC5D,IAAE,SAAM,UAAU,QAAQ,IAAI;AAE9B,IAAE,OAAI,KAAK,aAAa;AACxB,IAAE,OAAI,KAAK,oCAAoC;AAC/C,IAAE,OAAI,KAAK,6CAA6C;AACxD,IAAE,OAAI,KAAK,kDAAkD;AAC7D,WAAO;AAAA,EAET,SAAS,OAAgB;AACvB,IAAAD,SAAQ,KAAK;AACb,QAAI,iBAAiB,OAAO;AAC1B,MAAE,OAAI,MAAM,MAAM,OAAO;AACzB,UAAI,QAAQ,SAAS;AACnB,QAAE,OAAI,KAAK,eAAe,MAAM,SAAS,KAAK,EAAE;AAAA,MAClD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAMA,eAAe,mBACb,QACA,aAC0B;AAC1B,QAAM,WAA4B,CAAC;AAEnC,EAAE,OAAI,KAAK,8CAAyC;AAEpD,aAAW,CAAC,MAAM,UAAU,KAAK,QAAQ;AACvC,UAAM,UAAUE,UAAS,aAAa,IAAI;AAC1C,IAAE,OAAI,KAAKD,OAAM,KAAK,OAAO,CAAC;AAE9B,QAAI,WAAW;AAEf,eAAW,KAAK,YAAY;AAC1B,UAAI,SAAU;AAEd,YAAM,gBAAgB,EAAE,aAAa,gBAAgB,QAAQ;AAC7D,YAAM,QAAQ,IAAI,EAAE,IAAI,IAAI,aAAa,KAAK,SAAS,EAAE,MAAM,EAAE,CAAC;AAElE,YAAM,SAAS,MAAQ,UAAO;AAAA,QAC5B,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,OAAO,OAAO,OAAO,wBAAwB;AAAA,UAC/C,EAAE,OAAO,MAAM,OAAO,WAAW;AAAA,UACjC,EAAE,OAAO,OAAO,OAAO,uBAAuB;AAAA,UAC9C,EAAE,OAAO,QAAQ,OAAO,iBAAiB;AAAA,UACzC,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,QACjC;AAAA,MACF,CAAC;AAED,UAAM,YAAS,MAAM,KAAK,WAAW,QAAQ;AAC3C,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,OAAO;AACpB,iBAAS,KAAK,CAAC;AAAA,MACjB,WAAW,WAAW,OAAO;AAC3B,iBAAS,KAAK,CAAC;AAEf,cAAM,YAAY,WAAW,MAAM,WAAW,QAAQ,CAAC,IAAI,CAAC;AAC5D,iBAAS,KAAK,GAAG,SAAS;AAE1B,mBAAW,CAAC,EAAE,cAAc,KAAK,QAAQ;AACvC,cAAI,mBAAmB,YAAY;AACjC,qBAAS,KAAK,GAAG,cAAc;AAAA,UACjC;AAAA,QACF;AACA,eAAO;AAAA,MACT,WAAW,WAAW,QAAQ;AAC5B,mBAAW;AAAA,MACb;AAAA,IAEF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,SAAS,MAAc,QAAwB;AACtD,MAAI,KAAK,UAAU,OAAQ,QAAO;AAClC,SAAO,KAAK,MAAM,GAAG,SAAS,CAAC,IAAI;AACrC;AAEA,SAAS,oBAAoB,YAAqC;AAChE,MAAI,OAAO;AACX,MAAI,SAAS;AACb,MAAI,MAAM;AACV,MAAI,aAAa;AACjB,MAAI,YAAY;AAEhB,aAAW,KAAK,YAAY;AAC1B,QAAI,EAAE,eAAe,OAAQ;AAAA,aACpB,EAAE,eAAe,SAAU;AAAA,QAC/B;AAEL,QAAI,EAAE,aAAa,cAAe;AAAA,QAC7B;AAAA,EACP;AAEA,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,EAAG,OAAM,KAAKA,OAAM,MAAM,GAAG,IAAI,OAAO,CAAC;AACpD,MAAI,SAAS,EAAG,OAAM,KAAKA,OAAM,OAAO,GAAG,MAAM,SAAS,CAAC;AAC3D,MAAI,MAAM,EAAG,OAAM,KAAKA,OAAM,IAAI,GAAG,GAAG,MAAM,CAAC;AAE/C,SAAO,GAAG,WAAW,MAAM,WAAW,MAAM,KAAK,IAAI,CAAC,OAAO,UAAU,SAAS,SAAS;AAC3F;;;ARxQA,SAAS,QAAQ,OAAe,WAAqB,CAAC,GAAa;AACjE,SAAO,SAAS,OAAO,CAAC,KAAK,CAAC;AAChC;AAEA,eAAe,WAAW,SAA4C,SAA6B;AACjG,QAAM,WAAW,MAAM,QAAQ,OAAO;AACtC,UAAQ,WAAW;AACrB;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,SAAS,EACd,YAAY,sDAAsD,EAClE,QAAQ,OAAO;AAElB,QACG,QAAQ,MAAM,EACd,YAAY,uCAAuC,EACnD,OAAO,uBAAuB,2DAA2D,SAAS,CAAC,CAAC,EACpG,OAAO,uBAAuB,2DAA2D,SAAS,CAAC,CAAC,EACpG,OAAO,mBAAmB,2BAA2B,EACrD,OAAO,WAAW,kCAAkC,EACpD,OAAO,iBAAiB,sCAAsC,EAC9D,OAAO,sBAAsB,sCAAsC,CAAC,UAAU,OAAO,SAAS,OAAO,EAAE,CAAC,EACxG,OAAO,iBAAiB,0CAA0C,EAClE,OAAO,aAAa,4CAA4C,EAChE,OAAO,aAAa,wBAAwB,EAC5C,OAAO,CAAC,YAAY,WAAW,MAAM;AAAA,EACpC,GAAG;AAAA,EACH,YAAY,QAAQ,aAAa,OAAO;AAC1C,CAAC,CAAC;AAEJ,QACG,QAAQ,MAAM,EACd,YAAY,oDAAoD,EAChE,OAAO,uBAAuB,2DAA2D,SAAS,CAAC,CAAC,EACpG,OAAO,uBAAuB,2DAA2D,SAAS,CAAC,CAAC,EACpG,OAAO,aAAa,yCAAyC,EAC7D,OAAO,iBAAiB,mCAAmC,EAC3D,OAAO,wBAAwB,yCAAyC,MAAM,EAC9E,OAAO,aAAa,iBAAiB,EACrC,OAAO,CAAC,YAAY,WAAW,MAAM,OAAO,CAAC;AAEhD,QACG,QAAQ,MAAM,EACd,YAAY,qDAAqD,EACjE,OAAO,mBAAmB,0BAA0B,EACpD,OAAO,SAAS,gDAAgD,EAChE,OAAO,yBAAyB,gCAAgC,EAChE,OAAO,4BAA4B,uCAAuC,EAC1E,OAAO,2BAA2B,gDAAgD,EAClF,OAAO,CAAC,YAAY,WAAW,MAAM,OAAO,CAAC;AAEhD,QAAQ,MAAM,QAAQ,IAAI;","names":["init","resolve","resolve","spinner","api","p","createHash","execSync","readFileSync","chalk","init","chalk","createHash","readFileSync","lines","spinner","chalk","readFileSync","writeFileSync","relative","p","chalk","readFileSync","parse","babelTraverse","glob","traverse","babelTraverse","glob","readFileSync","parse","init","spinner","chalk","relative","readFileSync","writeFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts","../src/commands/init.ts","../src/utils/auth-store.ts","../src/utils/github-connect.ts","../src/utils/local-server.ts","../src/utils/api.ts","../src/utils/git-identity.ts","../src/utils/project-create.ts","../src/utils/locale-search.ts","../src/utils/branch-select.ts","../src/utils/workspace.ts","../src/commands/logout.ts","../src/commands/sync.ts","../src/utils/branch.ts","../src/utils/config.ts","../src/commands/whoami.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { init } from './commands/init.js';\nimport { logout } from './commands/logout.js';\nimport { sync } from './commands/sync.js';\nimport { whoami } from './commands/whoami.js';\n\n\n/**\n * Collector function for repeated CLI options\n * Allows multiple --include or --exclude flags\n */\nfunction collect(value: string, previous: string[] = []): string[] {\n return previous.concat([value]);\n}\n\nasync function runCommand(command: (options: any) => Promise<number>, options: any): Promise<void> {\n const exitCode = await command(options);\n // Force exit so open stdin handles from readline/clack don't stall the process.\n process.exit(exitCode);\n}\n\nconst program = new Command();\n\nprogram\n .name('vocoder')\n .description('Vocoder CLI - Project setup and string extraction')\n .version('0.1.5');\n\nprogram\n .command('init')\n .description('Authenticate and provision Vocoder for this project')\n .option('--api-url <url>', 'Override Vocoder API URL')\n .option('--yes', 'Allow overwriting existing local config values')\n .option('--ci', 'Non-interactive mode: print auth URL to stdout, skip browser open')\n .option('--project-name <name>', 'Starter project name to create')\n .option('--source-locale <locale>', 'Source locale for the starter project')\n .option('--target-locales <list>', 'Comma-separated target locales (e.g. es,fr,de)')\n .action((options) => runCommand(init, options));\n\nprogram\n .command('sync')\n .description('Extract strings and sync translations')\n .option('--branch <branch>', 'Override detected branch')\n .option('--mode <mode>', 'Sync mode: auto, required, best-effort', 'auto')\n .option('--max-wait <ms>', 'Max wait for translations (ms)')\n .option('--force', 'Force re-extraction even if no changes')\n .option('--dry-run', 'Preview without syncing')\n .option('--no-fallback', 'Disable fallback to cached translations')\n .option('--include <pattern>', 'Include glob pattern', collect, [])\n .option('--exclude <pattern>', 'Exclude glob pattern', collect, [])\n .option('--verbose', 'Detailed output')\n .action((options) => {\n const translated: Record<string, unknown> = { ...options };\n if (options.maxWait) translated.maxWaitMs = Number(options.maxWait);\n if (options.fallback === false) translated.noFallback = true;\n return runCommand(sync, translated);\n });\n\nprogram\n .command('logout')\n .description('Log out and remove stored credentials')\n .option('--api-url <url>', 'Override Vocoder API URL')\n .action((options) => runCommand(logout, options));\n\nprogram\n .command('whoami')\n .description('Show the currently authenticated user')\n .option('--api-url <url>', 'Override Vocoder API URL')\n .action((options) => runCommand(whoami, options));\n\nprogram.parse(process.argv);\n","import * as p from '@clack/prompts';\n\nimport {\n buildInstallCommand,\n detectLocalEcosystem,\n getPackagesToInstall,\n} from '../utils/detect-local.js';\nimport { clearAuthData, readAuthData, writeAuthData } from '../utils/auth-store.js';\nimport { runGitHubDiscoveryFlow, runGitHubInstallFlow, selectGitHubInstallation } from '../utils/github-connect.js';\n\nimport type { InitOptions } from '../types.js';\nimport { VocoderAPI } from '../utils/api.js';\nimport chalk from 'chalk';\nimport { execSync } from 'node:child_process';\nimport { getSetupSnippets } from '../utils/setup-snippets.js';\nimport { config as loadEnv } from 'dotenv';\nimport { resolveGitContext } from '../utils/git-identity.js';\nimport { runProjectCreate } from '../utils/project-create.js';\nimport { selectWorkspace } from '../utils/workspace.js';\nimport { spawn } from 'node:child_process';\nimport { startCallbackServer } from '../utils/local-server.js';\n\nloadEnv();\n\nconst SUBSCRIPTION_SETTINGS_PATH = '/dashboard/workspace/settings?tab=subscription';\n\nasync function sleep(ms: number): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function tryOpenBrowser(url: string): Promise<boolean> {\n if (!process.stdout.isTTY || process.env.CI === 'true') {\n return false;\n }\n\n let command: string;\n let args: string[];\n\n if (process.platform === 'darwin') {\n command = 'open';\n args = [url];\n } else if (process.platform === 'win32') {\n command = 'rundll32';\n args = ['url.dll,FileProtocolHandler', url];\n } else {\n command = 'xdg-open';\n args = [url];\n }\n\n return await new Promise<boolean>((resolve) => {\n try {\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n windowsHide: true,\n });\n\n let settled = false;\n child.once('spawn', () => {\n if (settled) return;\n settled = true;\n child.unref();\n resolve(true);\n });\n child.once('error', () => {\n if (settled) return;\n settled = true;\n resolve(false);\n });\n setTimeout(() => {\n if (settled) return;\n settled = true;\n resolve(false);\n }, 300);\n } catch {\n resolve(false);\n }\n });\n}\n\nfunction isPlanLimitFailure(message?: string): boolean {\n if (!message) return false;\n return /limit|upgrade/i.test(message);\n}\n\nfunction getSubscriptionSettingsUrl(apiUrl: string): string {\n return new URL(SUBSCRIPTION_SETTINGS_PATH, apiUrl).toString();\n}\n\nfunction printPlanLimitMessage(apiUrl: string, message: string): void {\n p.log.error(`You are over your plan limits.\\n ${message}`);\n p.log.info(`Manage subscription: ${getSubscriptionSettingsUrl(apiUrl)}`);\n}\n\ninterface ScaffoldParams {\n projectName: string;\n organizationName: string;\n sourceLocale: string;\n translationTriggers: string[];\n}\n\nfunction runScaffold(params: ScaffoldParams): void {\n const { projectName, organizationName, sourceLocale, translationTriggers } = params;\n\n p.log.info(`Project: ${chalk.bold(projectName)}`);\n p.log.info(`Workspace: ${chalk.bold(organizationName)}`);\n\n const detection = detectLocalEcosystem();\n\n if (detection.ecosystem) {\n const frameworkLabel = detection.framework ?? detection.ecosystem;\n const pmLabel = detection.packageManager;\n p.log.info(`Detected: ${chalk.bold(frameworkLabel)} (${pmLabel})`);\n }\n\n const packagesToInstall = getPackagesToInstall(detection);\n if (packagesToInstall.length > 0) {\n const installCmd = buildInstallCommand(detection.packageManager, packagesToInstall);\n p.log.info('');\n const installSpinner = p.spinner();\n installSpinner.start(`Installing ${packagesToInstall.join(', ')}...`);\n\n try {\n execSync(installCmd, { stdio: 'pipe', cwd: process.cwd() });\n installSpinner.stop(`Installed ${packagesToInstall.join(', ')}`);\n } catch {\n installSpinner.stop('Package installation failed');\n p.log.warn(`Run manually: ${chalk.cyan(installCmd)}`);\n }\n } else if (detection.ecosystem) {\n p.log.info(`Packages: ${chalk.green('already installed')}`);\n }\n\n const snippets = getSetupSnippets({\n framework: detection.framework,\n ecosystem: detection.ecosystem,\n sourceLocale,\n translationTriggers,\n });\n\n let stepNum = 1;\n\n if (snippets.pluginStep) {\n p.log.message('');\n p.log.step(`${chalk.bold(`Step ${stepNum}:`)} Add the plugin to ${chalk.cyan(snippets.pluginStep.file)}`);\n printCodeBlock(snippets.pluginStep.code);\n stepNum++;\n }\n\n if (snippets.providerStep) {\n p.log.step(`${chalk.bold(`Step ${stepNum}:`)} Add the provider to ${chalk.cyan(snippets.providerStep.file)}`);\n printCodeBlock(snippets.providerStep.code);\n stepNum++;\n }\n\n p.log.step(`${chalk.bold(`Step ${stepNum}:`)} Wrap translatable strings`);\n printCodeBlock(snippets.wrapStep.code);\n\n p.log.message('');\n for (const line of snippets.whatsNext.split('\\n')) {\n p.log.success(line);\n }\n}\n\nfunction printMcpSetup(apiKey: string): void {\n const addCommand = `claude mcp add --scope project --transport stdio \\\\\\n --env VOCODER_API_KEY=${apiKey} \\\\\\n vocoder -- npx -y @vocoder/mcp`;\n\n const teamConfig = JSON.stringify(\n {\n mcpServers: {\n vocoder: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@vocoder/mcp'],\n env: { VOCODER_API_KEY: '${env:VOCODER_API_KEY}' },\n },\n },\n },\n null,\n 2,\n );\n\n p.log.message('');\n p.log.message(chalk.bold('Use Vocoder with Claude Code'));\n p.log.message('Run this to add the MCP server to your project:');\n p.log.message('');\n printCodeBlock(addCommand);\n p.log.message('');\n p.log.message('To share with your team, commit ' + chalk.cyan('.mcp.json') + ' with an env var reference');\n p.log.message('so each developer supplies their own key:');\n p.log.message('');\n printCodeBlock(teamConfig);\n p.log.message('');\n p.log.message(chalk.gray('Setup instructions: https://vocoder.app/docs/mcp'));\n}\n\nfunction printCodeBlock(code: string): void {\n const lines = code.split('\\n');\n const maxLen = lines.reduce((max: number, line: string) => Math.max(max, line.length), 0);\n const bar = chalk.gray('│');\n const pad = (s: string) => s + ' '.repeat(maxLen - s.length);\n\n process.stdout.write(`${chalk.gray('│')}\\n`);\n process.stdout.write(`${chalk.gray('│')} ${chalk.gray('┌' + '─'.repeat(maxLen + 2) + '┐')}\\n`);\n for (const line of lines) {\n process.stdout.write(`${chalk.gray('│')} ${bar} ${pad(line)} ${bar}\\n`);\n }\n process.stdout.write(`${chalk.gray('│')} ${chalk.gray('└' + '─'.repeat(maxLen + 2) + '┘')}\\n`);\n}\n\n// ── Auth helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Verify a stored auth token against the API.\n * Returns user info on success, null if the token is invalid/expired.\n * On 401, clears the stored token.\n */\nasync function verifyStoredToken(\n api: VocoderAPI,\n token: string,\n): Promise<{ userId: string; email: string; name: string | null } | null> {\n try {\n return await api.getCliUserInfo(token);\n } catch {\n clearAuthData();\n return null;\n }\n}\n\n/**\n * Run the browser authentication flow.\n * Returns `{ token, userInfo, organizationId? }` on success, or null if cancelled.\n * When `organizationId` is set, the GitHub App was installed in the same browser\n * trip — the caller should skip workspace selection and GitHub connect.\n *\n * @param reauth - When true, the user has an expired token and already has a workspace.\n * Use verificationUrl (auth/cli page) instead of installUrl so we don't create a\n * duplicate workspace. The direct-to-GitHub install URL is only for first-time setup.\n */\nasync function runAuthFlow(\n api: VocoderAPI,\n options: InitOptions,\n reauth = false,\n repoCanonical?: string,\n): Promise<{ token: string; userId: string; email: string; name: string | null; organizationId?: string; discoveryReady?: boolean } | null> {\n // Try to start a local callback server for instant token delivery.\n // In --ci mode the browser step is handled externally, so skip the callback\n // server and go straight to polling — simpler and testable.\n let server: Awaited<ReturnType<typeof startCallbackServer>> | null = null;\n if (!options.ci) {\n try {\n server = await startCallbackServer();\n } catch {\n // Port conflict or other issue — fall back to polling\n }\n }\n\n const session = await api.startCliAuthSession(server?.port, repoCanonical);\n // Re-auth: user already has a workspace — use verificationUrl (auth/cli page)\n // so we don't trigger a new GitHub App install and create a duplicate workspace.\n // First-time: use installUrl to combine Vocoder auth + App install in one trip.\n const browserUrl = reauth\n ? session.verificationUrl\n : (session.installUrl ?? session.verificationUrl);\n const expiresAt = new Date(session.expiresAt).getTime();\n\n if (options.ci) {\n // Machine-readable output for automated test harnesses.\n // Parsed by e2e/helpers/cli.ts: /^VOCODER_AUTH_URL: (.+)$/m\n process.stdout.write(`VOCODER_AUTH_URL: ${browserUrl}\\n`);\n // Also emit the session ID separately so tests can expire/complete sessions\n process.stdout.write(`VOCODER_SESSION_ID: ${session.sessionId}\\n`);\n } else if (process.stdin.isTTY && process.stdout.isTTY && process.env.CI !== 'true') {\n if (reauth) {\n // Re-auth: token expired, just sign in — no install choice needed\n if (!options.yes) {\n const shouldOpen = await p.confirm({ message: 'Open your browser to sign in again?' });\n if (p.isCancel(shouldOpen)) {\n server?.close();\n p.cancel('Setup cancelled.');\n return null;\n }\n if (!shouldOpen) {\n p.log.info('Open the URL above manually in your browser to continue.');\n } else {\n const opened = await tryOpenBrowser(browserUrl);\n if (!opened) {\n p.note(browserUrl, 'Sign In');\n p.log.info('Open the URL above manually to continue.');\n }\n }\n } else {\n await tryOpenBrowser(browserUrl);\n }\n } else {\n // First-time setup: let user choose install vs link existing\n let isLinkFlow = false;\n if (!options.yes) {\n const connectChoice = await p.select<string>({\n message: 'Vocoder needs to be installed on your GitHub account to get started',\n options: [\n { value: 'install', label: 'Install GitHub App', hint: 'recommended' },\n { value: 'link', label: 'Already installed? Link your account' },\n ],\n });\n\n if (p.isCancel(connectChoice)) {\n server?.close();\n p.cancel('Setup cancelled.');\n return null;\n }\n\n isLinkFlow = connectChoice === 'link';\n }\n\n // For \"link\": get the OAuth-only URL from the server (no install page shown)\n let urlToOpen = browserUrl;\n if (isLinkFlow) {\n try {\n const linkSession = await api.startCliGitHubLinkSession(\n session.sessionId,\n server?.port,\n );\n urlToOpen = linkSession.oauthUrl;\n } catch {\n // Fall back to install URL if link-start fails\n urlToOpen = browserUrl;\n }\n }\n\n // Open browser immediately — no separate confirm needed\n const opened = await tryOpenBrowser(urlToOpen);\n if (!opened) {\n // Only show URL as a fallback if auto-open fails\n p.log.warn('Could not open your browser automatically.');\n p.note(urlToOpen, 'GitHub');\n p.log.info('Open the URL above to continue.');\n }\n }\n }\n\n const authSpinner = p.spinner();\n authSpinner.start('Waiting for GitHub authorization...');\n\n let rawToken: string | null = null;\n let callbackOrganizationId: string | undefined;\n let callbackDiscoveryReady = false;\n\n if (server) {\n // Fast path: wait for the localhost callback\n try {\n const deadline = Math.min(expiresAt, Date.now() + 10 * 60 * 1000);\n const timeoutMs = deadline - Date.now();\n const params = await Promise.race([\n server.waitForCallback(),\n new Promise<null>((resolve) => setTimeout(() => resolve(null), timeoutMs)),\n ]);\n\n if (params && typeof params.token === 'string') {\n rawToken = params.token;\n if (typeof params.organizationId === 'string' && params.organizationId) {\n callbackOrganizationId = params.organizationId;\n }\n // Link flow: callback signals discovery results are cached\n if (params.discovery_ready === '1') {\n callbackDiscoveryReady = true;\n }\n }\n } catch {\n // Fall through to polling\n } finally {\n server.close();\n }\n }\n\n if (!rawToken) {\n // Polling fallback\n while (Date.now() < expiresAt) {\n const result = await api.pollCliAuthSession(session.sessionId);\n\n if (result.status === 'complete') {\n rawToken = result.token;\n if (result.organizationId) {\n callbackOrganizationId = result.organizationId;\n }\n break;\n }\n\n if (result.status === 'failed') {\n authSpinner.stop();\n p.log.error(result.reason);\n return null;\n }\n\n // Still pending — wait 2s before next poll\n await sleep(2000);\n }\n }\n\n if (!rawToken) {\n authSpinner.stop();\n p.log.error('The authentication link expired. Run `vocoder init` again.');\n return null;\n }\n\n // Validate the token and get user info\n const userInfo = await api.getCliUserInfo(rawToken);\n authSpinner.stop();\n p.log.success(`Authenticated as ${chalk.bold(userInfo.email)}`);\n\n return { token: rawToken, ...userInfo, organizationId: callbackOrganizationId, discoveryReady: callbackDiscoveryReady };\n}\n\n// ── Main command ─────────────────────────────────────────────────────────────\n\nexport async function init(options: InitOptions = {}): Promise<number> {\n const apiUrl = options.apiUrl || process.env.VOCODER_API_URL || 'https://vocoder.app';\n\n p.intro('Vocoder Setup');\n\n try {\n // ── Detect git context ──────────────────────────────────────────────────\n const gitContext = resolveGitContext();\n const identity = gitContext.identity;\n\n if (gitContext.warnings.length > 0) {\n for (const warning of gitContext.warnings) {\n p.log.warn(warning);\n }\n }\n\n // ── Fast lookup: does a project already exist for this repo? ────────────\n // No spinner — this is a fast DB read and we don't want an empty ◇ on miss.\n if (identity) {\n const anonApi = new VocoderAPI({ apiUrl, apiKey: '' });\n const existing = await anonApi.lookupProjectByRepo({\n repoCanonical: identity.repoCanonical,\n scopePath: identity.repoScopePath,\n });\n\n if (existing) {\n runScaffold({\n projectName: existing.projectName,\n organizationName: existing.organizationName,\n sourceLocale: existing.sourceLocale ?? 'en',\n translationTriggers: existing.translationTriggers ?? ['push'],\n });\n\n p.outro(\"Vocoder is already set up for this repository.\");\n return 0;\n }\n }\n\n // ── Auth: check stored token, prompt if missing ─────────────────────────\n const api = new VocoderAPI({ apiUrl, apiKey: '' });\n let userToken: string;\n let userEmail: string;\n let userName: string | null;\n\n // organizationId is set when auth+GitHub install completed in one browser trip\n let authOrganizationId: string | undefined;\n // discoveryReady is set when auth completed via link-start OAuth (no install)\n let authDiscoveryReady = false;\n\n const stored = readAuthData();\n if (stored && stored.apiUrl === apiUrl) {\n const verified = await verifyStoredToken(api, stored.token);\n\n if (verified) {\n p.log.success(`Authenticated as ${chalk.bold(verified.email)}`);\n userToken = stored.token;\n userEmail = verified.email;\n userName = verified.name;\n } else {\n p.log.warn('Stored credentials expired — signing in again');\n const authResult = await runAuthFlow(api, options, /* reauth */ true);\n if (!authResult) return 1;\n userToken = authResult.token;\n userEmail = authResult.email;\n userName = authResult.name;\n authOrganizationId = authResult.organizationId;\n authDiscoveryReady = authResult.discoveryReady ?? false;\n\n writeAuthData({\n token: userToken,\n apiUrl,\n userId: authResult.userId,\n email: userEmail,\n name: userName,\n createdAt: new Date().toISOString(),\n });\n }\n } else {\n const authResult = await runAuthFlow(api, options, false, identity?.repoCanonical);\n if (!authResult) return 1;\n userToken = authResult.token;\n userEmail = authResult.email;\n userName = authResult.name;\n authOrganizationId = authResult.organizationId;\n\n writeAuthData({\n token: userToken,\n apiUrl,\n userId: authResult.userId,\n email: userEmail,\n name: userName,\n createdAt: new Date().toISOString(),\n });\n }\n\n // ── Workspace selection ─────────────────────────────────────────────────────\n let selectedWorkspaceId: string;\n let selectedWorkspaceName: string;\n\n if (authOrganizationId) {\n // Install path: auth+install completed in one browser trip, workspace already created.\n const workspaceData = await api.listWorkspaces(userToken);\n const ws = workspaceData.workspaces.find((w) => w.id === authOrganizationId);\n selectedWorkspaceId = authOrganizationId;\n selectedWorkspaceName = ws?.name ?? userEmail;\n p.log.success(`Connected as ${chalk.bold(userEmail)} — workspace: ${chalk.bold(selectedWorkspaceName)}`);\n } else {\n // Always check for cached discovery results first. The cache expires in\n // 5 minutes so returning users (no recent link flow) fall through cleanly.\n const discoveryResult = await api.getCliGitHubDiscovery(userToken).catch(() => null);\n const cachedInstallations = discoveryResult?.installations ?? [];\n\n if (cachedInstallations.length > 0) {\n // Warn if none of the discovered installations belong to the org that\n // owns the current repo — the binding won't be created even if setup succeeds.\n if (identity?.repoCanonical) {\n const repoOwner = identity.repoCanonical.split(':')[1]?.split('/')[0]?.toLowerCase();\n if (repoOwner) {\n const hasMatchingAccount = cachedInstallations.some(\n (i) => i.accountLogin.toLowerCase() === repoOwner,\n );\n if (!hasMatchingAccount) {\n p.log.warn(\n `None of your GitHub App installations belong to \"${repoOwner}\", ` +\n `the account that owns this repository.\\n` +\n ` The project will be created but translations won't trigger automatically.\\n` +\n ` To fix: install the Vocoder GitHub App on \"${repoOwner}\" instead.`,\n );\n }\n }\n }\n\n // Auto-select when there's exactly one valid (non-suspended, unclaimed) installation\n const validInstallations = cachedInstallations.filter(\n (i) => !i.isSuspended && !i.conflictLabel,\n );\n\n let selectedInstallationId: number | string | null = null;\n\n if (validInstallations.length === 1 && cachedInstallations.length === 1) {\n // Single installation — claim silently, no prompt needed\n selectedInstallationId = validInstallations[0]!.installationId;\n } else {\n selectedInstallationId = await selectGitHubInstallation(\n cachedInstallations.map((inst) => ({\n installationId: inst.installationId,\n accountLogin: inst.accountLogin,\n accountType: inst.accountType,\n isSuspended: inst.isSuspended,\n conflictLabel: inst.conflictLabel,\n })),\n false,\n );\n }\n\n if (selectedInstallationId === null || selectedInstallationId === 'install_new') {\n p.cancel('Setup cancelled. Re-run `vocoder init` and choose Install GitHub App.');\n return 1;\n }\n\n const claimResult = await api.claimCliGitHubInstallation(userToken, {\n installationId: String(selectedInstallationId),\n organizationId: null,\n });\n selectedWorkspaceId = claimResult.organizationId;\n selectedWorkspaceName = claimResult.organizationName;\n p.log.success(`Workspace: ${chalk.bold(selectedWorkspaceName)}`);\n } else {\n const workspaceData = await api.listWorkspaces(userToken);\n\n // Auto-select when there's exactly one workspace and the plan doesn't\n // allow creating more — no point showing a single-item select with no\n // \"Create new\" option.\n if (workspaceData.workspaces.length === 1 && !workspaceData.canCreateWorkspace) {\n const ws = workspaceData.workspaces[0]!;\n selectedWorkspaceId = ws.id;\n selectedWorkspaceName = ws.name;\n p.log.success(`Workspace: ${chalk.bold(selectedWorkspaceName)}`);\n } else {\n\n const workspaceResult = await selectWorkspace(workspaceData);\n\n if (workspaceResult.action === 'cancelled') {\n p.cancel('Setup cancelled.');\n return 1;\n }\n\n if (workspaceResult.action === 'use') {\n selectedWorkspaceId = workspaceResult.workspace.id;\n selectedWorkspaceName = workspaceResult.workspace.name;\n p.log.success(`Workspace: ${chalk.bold(selectedWorkspaceName)}`);\n } else {\n // ── New workspace: GitHub connect flow ──────────────────────────────────\n const connectChoice = await p.select<string>({\n message: 'Connect your new workspace to GitHub',\n options: [\n { value: 'install', label: 'Install the Vocoder GitHub App' },\n { value: 'link', label: 'Link an existing installation' },\n ],\n });\n\n if (p.isCancel(connectChoice)) {\n p.cancel('Setup cancelled.');\n return 1;\n }\n\n if (connectChoice === 'install') {\n // Full GitHub App install flow\n const connectResult = await runGitHubInstallFlow({\n api,\n userToken,\n yes: options.yes,\n });\n\n if (!connectResult) {\n p.log.error('GitHub App installation did not complete. Run `vocoder init` again.');\n return 1;\n }\n\n selectedWorkspaceId = connectResult.organizationId;\n selectedWorkspaceName = connectResult.organizationName;\n p.log.success(`Workspace: ${chalk.bold(selectedWorkspaceName)}`);\n } else {\n // OAuth discovery → select installation → claim\n const installations = await runGitHubDiscoveryFlow({\n api,\n userToken,\n yes: options.yes,\n });\n\n if (!installations) return 1;\n\n if (installations.length === 0) {\n p.log.warn('No GitHub installations found. Install the Vocoder GitHub App first.');\n const installNow = await p.confirm({ message: 'Open GitHub to install the App?' });\n if (p.isCancel(installNow) || !installNow) return 1;\n\n const connectResult = await runGitHubInstallFlow({\n api,\n userToken,\n yes: options.yes,\n });\n\n if (!connectResult) return 1;\n\n selectedWorkspaceId = connectResult.organizationId;\n selectedWorkspaceName = connectResult.organizationName;\n } else {\n const selectedInstallationId = await selectGitHubInstallation(\n installations.map((inst) => ({\n installationId: inst.installationId,\n accountLogin: inst.accountLogin,\n accountType: inst.accountType,\n isSuspended: inst.isSuspended,\n conflictLabel: inst.conflictLabel,\n })),\n true,\n );\n\n if (selectedInstallationId === null) {\n p.cancel('Setup cancelled.');\n return 1;\n }\n\n if (selectedInstallationId === 'install_new') {\n const connectResult = await runGitHubInstallFlow({\n api,\n userToken,\n yes: options.yes,\n });\n\n if (!connectResult) return 1;\n\n selectedWorkspaceId = connectResult.organizationId;\n selectedWorkspaceName = connectResult.organizationName;\n } else {\n const claimResult = await api.claimCliGitHubInstallation(userToken, {\n installationId: String(selectedInstallationId),\n organizationId: null,\n });\n\n selectedWorkspaceId = claimResult.organizationId;\n selectedWorkspaceName = claimResult.organizationName;\n }\n }\n\n p.log.success(`Workspace: ${chalk.bold(selectedWorkspaceName)}`);\n }\n } // closes if (workspaceResult.action === 'use') else\n } // closes cachedInstallations.length === 0 else\n } // closes auto-select else\n } // closes if (authOrganizationId) else\n\n // ── Project configuration ────────────────────────────────────────────────────\n const projectResult = await runProjectCreate({\n api,\n userToken,\n organizationId: selectedWorkspaceId,\n defaultName: identity?.repoCanonical\n ? identity.repoCanonical.split('/').pop()\n : undefined,\n defaultSourceLocale: 'en',\n repoCanonical: identity?.repoCanonical,\n defaultBranches: ['main'],\n });\n\n if (!projectResult) {\n p.log.error('Project creation failed. Run `vocoder init` again.');\n return 1;\n }\n\n // Warn if the current repo isn't accessible to the GitHub App installation.\n // This means translations won't trigger on push until the App is granted access.\n if (!projectResult.repositoryBound && identity?.repoCanonical) {\n p.log.warn(\n `This repository isn't accessible to your GitHub App installation.\\n` +\n `Translations won't run automatically until you grant access.\\n\\n` +\n ` To fix: go to your GitHub App installation settings and add this\\n` +\n ` repository to the allowed list, or switch to \"All repositories\".\\n` +\n (projectResult.configureUrl\n ? `\\n ${chalk.dim(projectResult.configureUrl)}\\n`\n : ''),\n );\n }\n\n // ── Scaffold + MCP setup ─────────────────────────────────────────────────────\n runScaffold({\n projectName: projectResult.projectName,\n organizationName: selectedWorkspaceName,\n sourceLocale: projectResult.sourceLocale,\n translationTriggers: projectResult.translationTriggers,\n });\n\n printMcpSetup(projectResult.apiKey);\n\n p.outro(\"You're all set.\");\n return 0;\n } catch (error) {\n if (error instanceof Error) {\n if (isPlanLimitFailure(error.message)) {\n printPlanLimitMessage(apiUrl, error.message);\n return 1;\n }\n p.log.error(`Error: ${error.message}`);\n } else {\n p.log.error('Unknown setup error');\n }\n\n return 1;\n }\n}\n","import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nexport interface AuthData {\n token: string;\n apiUrl: string;\n userId: string;\n email: string;\n name: string | null;\n createdAt: string;\n}\n\nfunction getAuthFilePath(): string {\n return join(homedir(), '.config', 'vocoder', 'auth.json');\n}\n\nexport function readAuthData(): AuthData | null {\n const filePath = getAuthFilePath();\n try {\n const raw = readFileSync(filePath, 'utf8');\n const parsed: unknown = JSON.parse(raw);\n if (!parsed || typeof parsed !== 'object') return null;\n const data = parsed as Partial<AuthData>;\n if (\n typeof data.token !== 'string' ||\n typeof data.apiUrl !== 'string' ||\n typeof data.userId !== 'string' ||\n typeof data.email !== 'string' ||\n typeof data.createdAt !== 'string'\n ) {\n return null;\n }\n return {\n token: data.token,\n apiUrl: data.apiUrl,\n userId: data.userId,\n email: data.email,\n name: typeof data.name === 'string' ? data.name : null,\n createdAt: data.createdAt,\n };\n } catch {\n return null;\n }\n}\n\nexport function writeAuthData(data: AuthData): void {\n const filePath = getAuthFilePath();\n const dir = dirname(filePath);\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n writeFileSync(filePath, JSON.stringify(data, null, 2), { mode: 0o600 });\n}\n\nexport function clearAuthData(): void {\n const filePath = getAuthFilePath();\n try {\n unlinkSync(filePath);\n } catch {\n // Already gone — that's fine\n }\n}\n","import * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport { spawn } from 'node:child_process';\nimport type { VocoderAPI } from './api.js';\nimport { startCallbackServer } from './local-server.js';\n\nasync function tryOpenBrowser(url: string): Promise<boolean> {\n if (!process.stdout.isTTY || process.env.CI === 'true') {\n return false;\n }\n\n const platform = process.platform;\n let command: string;\n let args: string[];\n\n if (platform === 'darwin') {\n command = 'open';\n args = [url];\n } else if (platform === 'win32') {\n command = 'rundll32';\n args = ['url.dll,FileProtocolHandler', url];\n } else {\n command = 'xdg-open';\n args = [url];\n }\n\n return new Promise<boolean>((resolve) => {\n try {\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n windowsHide: true,\n });\n\n let settled = false;\n child.once('spawn', () => {\n if (settled) return;\n settled = true;\n child.unref();\n resolve(true);\n });\n child.once('error', () => {\n if (settled) return;\n settled = true;\n resolve(false);\n });\n setTimeout(() => {\n if (settled) return;\n settled = true;\n resolve(false);\n }, 300);\n } catch {\n resolve(false);\n }\n });\n}\n\nexport interface GitHubConnectResult {\n organizationId: string;\n organizationName: string;\n connectionLabel: string;\n}\n\n/**\n * Run the full GitHub App install flow for a new workspace.\n * Opens the browser to the GitHub App install page and waits for completion.\n *\n * Returns `null` if the user cancelled or an error occurred.\n */\nexport async function runGitHubInstallFlow(params: {\n api: VocoderAPI;\n userToken: string;\n organizationId?: string;\n yes?: boolean;\n}): Promise<GitHubConnectResult | null> {\n // Try to start a local callback server for instant notification\n let server: Awaited<ReturnType<typeof startCallbackServer>> | null = null;\n try {\n server = await startCallbackServer();\n } catch {\n // Fall through — the user can re-run if something goes wrong\n }\n\n const { installUrl } = await params.api.startCliGitHubInstall(params.userToken, {\n organizationId: params.organizationId,\n callbackPort: server?.port,\n });\n\n p.log.info('Opening GitHub to install the Vocoder App...');\n p.note(installUrl, 'Install URL');\n\n if (process.stdin.isTTY && process.stdout.isTTY && process.env.CI !== 'true') {\n const shouldOpen = params.yes\n ? true\n : await p.confirm({ message: 'Open in your browser?' });\n\n if (p.isCancel(shouldOpen)) {\n server?.close();\n return null;\n }\n\n if (shouldOpen) {\n const opened = await tryOpenBrowser(installUrl);\n if (!opened) {\n p.log.info('Could not open a browser automatically. Use the URL above.');\n }\n }\n }\n\n const connectSpinner = p.spinner();\n connectSpinner.start('Waiting for GitHub App installation...');\n\n if (server) {\n try {\n const params_timeout = 15 * 60 * 1000; // 15 minutes\n const callbackParams = await Promise.race([\n server.waitForCallback(),\n new Promise<null>((resolve) => setTimeout(() => resolve(null), params_timeout)),\n ]);\n\n server.close();\n\n if (!callbackParams) {\n connectSpinner.stop('GitHub App installation timed out');\n p.log.error('The installation flow timed out. Run `vocoder init` again.');\n return null;\n }\n\n if (callbackParams.error) {\n connectSpinner.stop('GitHub App installation failed');\n p.log.error(callbackParams.error);\n return null;\n }\n\n const { organizationId, connectionLabel, workspace_created } = callbackParams;\n\n if (!organizationId || !connectionLabel) {\n connectSpinner.stop('GitHub App installation incomplete');\n p.log.error('Missing organization or connection data from callback.');\n return null;\n }\n\n connectSpinner.stop(`Connected to GitHub as ${chalk.bold(connectionLabel)}`);\n\n // Fetch the org name\n const orgName = workspace_created ? connectionLabel : organizationId;\n return {\n organizationId,\n organizationName: orgName,\n connectionLabel,\n };\n } catch {\n server.close();\n connectSpinner.stop('GitHub App installation failed');\n return null;\n }\n }\n\n // No local server — there's no polling fallback for install; just wait\n connectSpinner.stop('Could not detect GitHub App installation automatically');\n p.log.warn('Complete the installation in your browser, then run `vocoder init` again.');\n return null;\n}\n\n/**\n * Run the GitHub OAuth discovery flow to find existing installations.\n * Returns the list of installations with conflict labels, or null on cancellation/error.\n */\nexport async function runGitHubDiscoveryFlow(params: {\n api: VocoderAPI;\n userToken: string;\n organizationId?: string;\n yes?: boolean;\n}): Promise<Array<{\n installationId: number;\n accountLogin: string;\n accountType: string;\n isSuspended: boolean;\n conflictLabel: string | null;\n}> | null> {\n // Try local callback server\n let server: Awaited<ReturnType<typeof startCallbackServer>> | null = null;\n try {\n server = await startCallbackServer();\n } catch {\n // Fall through\n }\n\n const { oauthUrl } = await params.api.startCliGitHubOAuth(params.userToken, {\n organizationId: params.organizationId,\n callbackPort: server?.port,\n });\n\n p.log.info('Opening GitHub to authorize your account...');\n p.note('Complete authorization in your browser.');\n\n if (process.stdin.isTTY && process.stdout.isTTY && process.env.CI !== 'true') {\n const shouldOpen = params.yes\n ? true\n : await p.confirm({ message: 'Open in your browser?' });\n\n if (p.isCancel(shouldOpen)) {\n server?.close();\n return null;\n }\n\n if (shouldOpen) {\n const opened = await tryOpenBrowser(oauthUrl);\n if (!opened) {\n p.log.info(`Could not open browser automatically. Visit: ${oauthUrl}`);\n }\n }\n }\n\n const oauthSpinner = p.spinner();\n oauthSpinner.start('Waiting for GitHub authorization...');\n\n if (server) {\n try {\n const timeoutMs = 10 * 60 * 1000;\n const callbackParams = await Promise.race([\n server.waitForCallback(),\n new Promise<null>((resolve) => setTimeout(() => resolve(null), timeoutMs)),\n ]);\n\n server.close();\n\n if (!callbackParams) {\n oauthSpinner.stop('GitHub authorization timed out');\n return null;\n }\n\n if (callbackParams.error) {\n oauthSpinner.stop('GitHub authorization failed');\n p.log.error(callbackParams.error);\n return null;\n }\n } catch {\n server.close();\n oauthSpinner.stop('GitHub authorization failed');\n return null;\n }\n }\n\n oauthSpinner.stop('GitHub account authorized');\n\n // Fetch discovery results\n const discoveryResult = await params.api.getCliGitHubDiscovery(params.userToken);\n return discoveryResult.installations;\n}\n\ntype DiscoveredInstallation = {\n installationId: number;\n accountLogin: string;\n accountType: string;\n isSuspended: boolean;\n conflictLabel: string | null;\n};\n\n/**\n * Prompt the user to select a GitHub installation from discovery results.\n * Returns the selected installation ID, 'install_new' to trigger install flow,\n * or null on cancellation.\n */\nexport async function selectGitHubInstallation(\n installations: DiscoveredInstallation[],\n canInstallNew: boolean,\n): Promise<number | 'install_new' | null> {\n type SelectValue = string;\n\n const options: Array<{ value: SelectValue; label: string; hint?: string }> =\n installations.map((inst) => ({\n value: String(inst.installationId),\n label: inst.accountLogin,\n hint: [\n inst.accountType === 'Organization' ? 'organization' : 'personal',\n inst.conflictLabel ? `connected to ${inst.conflictLabel}` : '',\n inst.isSuspended ? 'suspended' : '',\n ]\n .filter(Boolean)\n .join(' · ') || undefined,\n }));\n\n if (canInstallNew) {\n options.push({ value: 'install_new', label: 'Install on a new account' });\n }\n\n const selected = await p.select<SelectValue>({\n message: 'Select a GitHub installation',\n options,\n });\n\n if (p.isCancel(selected)) return null;\n if (selected === 'install_new') return 'install_new';\n\n return Number(selected);\n}\n","import { createServer } from 'node:http';\nimport { AddressInfo } from 'node:net';\nimport { URL } from 'node:url';\n\nexport interface LocalServerHandle {\n port: number;\n waitForCallback: () => Promise<Record<string, string>>;\n close: () => void;\n}\n\n/**\n * Starts a local HTTP server on a random available port.\n * Returns the port and a promise that resolves when the browser\n * redirects to /callback with query parameters.\n *\n * Used for the browser→CLI token handoff pattern:\n * 1. CLI passes `port` to the auth session start request\n * 2. After browser auth, vocoder.app redirects to localhost:<port>/callback?token=...\n * 3. `waitForCallback()` resolves with the query params\n */\nexport function startCallbackServer(): Promise<LocalServerHandle> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let callbackResolve: ((params: Record<string, string>) => void) | null = null;\n let callbackReject: ((err: Error) => void) | null = null;\n\n const callbackPromise = new Promise<Record<string, string>>((res, rej) => {\n callbackResolve = res;\n callbackReject = rej;\n });\n\n const server = createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400);\n res.end();\n return;\n }\n\n let pathname: string;\n let params: Record<string, string>;\n\n try {\n const parsed = new URL(req.url, 'http://localhost');\n pathname = parsed.pathname;\n params = Object.fromEntries(parsed.searchParams.entries());\n } catch {\n res.writeHead(400);\n res.end('Bad request');\n return;\n }\n\n if (pathname !== '/callback') {\n res.writeHead(404);\n res.end('Not found');\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(\n '<!DOCTYPE html><html><head><title>Authenticated</title></head>' +\n '<body style=\"font-family:sans-serif;text-align:center;padding:3rem;\">' +\n '<h2>Authenticated</h2>' +\n '<p>Return to your terminal to continue. You can close this tab.</p>' +\n '</body></html>',\n );\n\n if (callbackResolve) {\n callbackResolve(params);\n callbackResolve = null;\n }\n\n setImmediate(() => server.close());\n });\n\n server.on('error', (err) => {\n if (!settled) {\n settled = true;\n if (callbackReject) callbackReject(err);\n reject(err);\n }\n });\n\n // Bind to a random port on localhost only\n server.listen(0, '127.0.0.1', () => {\n if (settled) return;\n settled = true;\n\n const port = (server.address() as AddressInfo).port;\n\n resolve({\n port,\n waitForCallback: () => callbackPromise,\n close: () => server.close(),\n });\n });\n });\n}\n","import type {\n APIProjectConfig,\n InitStartResponse,\n InitStatusResponse,\n\tLimitErrorResponse,\n\tLocalConfig,\n\tRequestedSyncMode,\n\tRepoIdentityPayload,\n\tSyncPolicyErrorResponse,\n\tTranslationBatchResponse,\n\tTranslationSnapshotResponse,\n\tTranslationStringEntry,\n\tTranslationStatusResponse,\n} from '../types.js';\n\nfunction isLimitErrorResponse(value: unknown): value is LimitErrorResponse {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const candidate = value as Partial<LimitErrorResponse>;\n return (\n typeof candidate.errorCode === 'string' &&\n typeof candidate.limitType === 'string' &&\n typeof candidate.planId === 'string' &&\n typeof candidate.current === 'number' &&\n typeof candidate.required === 'number' &&\n typeof candidate.upgradeUrl === 'string' &&\n typeof candidate.message === 'string'\n );\n}\n\nfunction isSyncPolicyErrorResponse(value: unknown): value is SyncPolicyErrorResponse {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const candidate = value as Partial<SyncPolicyErrorResponse>;\n return (\n (candidate.errorCode === 'BRANCH_NOT_ALLOWED' ||\n candidate.errorCode === 'PROJECT_REPOSITORY_MISMATCH') &&\n typeof candidate.message === 'string'\n );\n}\n\nfunction extractErrorMessage(payload: unknown, fallback: string): string {\n if (!payload || typeof payload !== 'object') {\n return fallback;\n }\n\n const candidate = payload as Record<string, unknown>;\n if (typeof candidate.message === 'string') {\n return candidate.message;\n }\n\n if (typeof candidate.error === 'string') {\n return candidate.error;\n }\n\n return fallback;\n}\n\nfunction parsePayload(raw: string): unknown {\n if (raw.length === 0) {\n return null;\n }\n\n try {\n return JSON.parse(raw);\n } catch {\n return { message: raw };\n }\n}\n\nasync function readPayload(response: {\n text?: () => Promise<string>;\n json?: () => Promise<unknown>;\n}): Promise<unknown> {\n if (typeof response.text === 'function') {\n const raw = await response.text();\n return parsePayload(raw);\n }\n\n if (typeof response.json === 'function') {\n return response.json();\n }\n\n return null;\n}\n\nexport class VocoderAPIError extends Error {\n readonly status: number;\n readonly payload: unknown;\n readonly limitError: LimitErrorResponse | null;\n readonly syncPolicyError: SyncPolicyErrorResponse | null;\n\n constructor(params: {\n message: string;\n status: number;\n payload: unknown;\n limitError?: LimitErrorResponse | null;\n syncPolicyError?: SyncPolicyErrorResponse | null;\n }) {\n super(params.message);\n this.name = 'VocoderAPIError';\n this.status = params.status;\n this.payload = params.payload;\n this.limitError = params.limitError ?? null;\n this.syncPolicyError = params.syncPolicyError ?? null;\n }\n}\n\nexport class VocoderAPI {\n private apiUrl: string;\n private apiKey: string;\n\n constructor(config: LocalConfig) {\n this.apiUrl = config.apiUrl;\n this.apiKey = config.apiKey;\n }\n\n private async request<T>(\n path: string,\n init: RequestInit = {},\n errorPrefix?: string,\n ): Promise<T> {\n const response = await fetch(`${this.apiUrl}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n ...(init.headers ?? {}),\n },\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n const limitError = isLimitErrorResponse(payload) ? payload : null;\n const syncPolicyError = isSyncPolicyErrorResponse(payload) ? payload : null;\n const baseMessage = extractErrorMessage(payload, `Request failed with status ${response.status}`);\n throw new VocoderAPIError({\n message: errorPrefix ? `${errorPrefix}: ${baseMessage}` : baseMessage,\n status: response.status,\n payload,\n limitError,\n syncPolicyError,\n });\n }\n\n return payload as T;\n }\n\n /**\n * Fetch project configuration from API\n * Project is determined from the API key\n */\n\tasync getProjectConfig(): Promise<APIProjectConfig> {\n\t\tconst data = await this.request<{\n\t\t\tprojectName: string;\n\t\t\torganizationName: string;\n\t\t\tsourceLocale: string;\n\t\t\ttargetLocales: string[];\n\t\t\ttargetBranches: string[];\n\t\t\tsyncPolicy?: {\n\t\t\t\tblockingBranches?: string[];\n\t\t\t\tblockingMode?: \"required\" | \"best-effort\";\n\t\t\t\tnonBlockingMode?: \"required\" | \"best-effort\";\n\t\t\t\tdefaultMaxWaitMs?: number;\n\t\t\t};\n\t\t}>('/api/cli/config', {}, 'Failed to fetch project config');\n\n\t\treturn {\n\t\t\tprojectName: data.projectName,\n\t\t\torganizationName: data.organizationName,\n\t\t\tsourceLocale: data.sourceLocale,\n\t\t\ttargetLocales: data.targetLocales,\n\t\t\ttargetBranches: data.targetBranches,\n\t\t\tsyncPolicy: {\n\t\t\t\tblockingBranches: data.syncPolicy?.blockingBranches ?? [\"main\", \"master\"],\n\t\t\t\tblockingMode: data.syncPolicy?.blockingMode ?? \"required\",\n\t\t\t\tnonBlockingMode: data.syncPolicy?.nonBlockingMode ?? \"best-effort\",\n\t\t\t\tdefaultMaxWaitMs: data.syncPolicy?.defaultMaxWaitMs ?? 60_000,\n\t\t\t},\n\t\t};\n\t}\n\n /**\n * Submit strings for translation\n * Project is determined from the API key\n */\n private stableTextKey(text: string): string {\n // FNV-1a 32-bit hash for deterministic fallback IDs\n let hash = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n hash ^= text.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return `SK_TEXT_${(hash >>> 0).toString(16).toUpperCase().padStart(8, '0')}`;\n }\n\n private normalizeStringEntries(\n entries: string[] | TranslationStringEntry[],\n ): TranslationStringEntry[] {\n if (entries.length === 0) {\n return [];\n }\n\n const first = entries[0];\n if (typeof first === 'string') {\n return (entries as string[]).map((text) => ({\n key: this.stableTextKey(text),\n text,\n }));\n }\n\n return (entries as TranslationStringEntry[]).map((entry, index) => ({\n key: entry.key || this.stableTextKey(`${entry.text}:${index}`),\n text: entry.text,\n ...(entry.context ? { context: entry.context } : {}),\n ...(entry.formality ? { formality: entry.formality } : {}),\n }));\n }\n\n\tasync submitTranslation(\n\t\tbranch: string,\n\t\tentries: string[] | TranslationStringEntry[],\n\t\ttargetLocales: string[],\n\t\toptions?: {\n\t\t\trequestedMode?: RequestedSyncMode;\n\t\t\trequestedMaxWaitMs?: number;\n\t\t\tclientRunId?: string;\n\t\t},\n\t\trepoIdentity?: RepoIdentityPayload,\n\t): Promise<TranslationBatchResponse> {\n const stringEntries = this.normalizeStringEntries(entries);\n const strings = stringEntries.map((entry) => entry.text);\n\n // Compute hash of sorted strings for fast comparison\n const crypto = await import('crypto');\n const sortedStrings = [...strings].sort();\n const stringsHash = crypto\n .createHash('sha256')\n .update(JSON.stringify(sortedStrings))\n .digest('hex');\n\n return this.request<TranslationBatchResponse>('/api/cli/sync', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n\t body: JSON.stringify({\n\t branch,\n\t stringEntries,\n\t targetLocales,\n\t stringsHash,\n\t ...(options?.requestedMode ? { requestedMode: options.requestedMode } : {}),\n\t ...(typeof options?.requestedMaxWaitMs === 'number'\n\t ? { requestedMaxWaitMs: options.requestedMaxWaitMs }\n\t : {}),\n\t ...(options?.clientRunId ? { clientRunId: options.clientRunId } : {}),\n\t ...(repoIdentity?.repoCanonical ? { repoCanonical: repoIdentity.repoCanonical } : {}),\n\t ...(repoIdentity?.repoScopePath !== undefined\n\t ? { repoScopePath: repoIdentity.repoScopePath }\n : {}),\n }),\n }, 'Translation submission failed');\n }\n\n /**\n * Check translation status\n */\n\tasync getTranslationStatus(\n\t\tbatchId: string,\n\t): Promise<TranslationStatusResponse> {\n\t\treturn this.request<TranslationStatusResponse>(\n\t\t\t`/api/cli/sync/status/${batchId}`,\n\t\t\t{},\n\t\t\t'Failed to check translation status',\n\t\t);\n\t}\n\n\tasync getTranslationSnapshot(params: {\n\t\tbranch: string;\n\t\ttargetLocales: string[];\n\t}): Promise<TranslationSnapshotResponse> {\n\t\tconst search = new URLSearchParams();\n\t\tsearch.set('branch', params.branch);\n\t\tfor (const locale of params.targetLocales) {\n\t\t\tsearch.append('targetLocale', locale);\n\t\t}\n\n\t\treturn this.request<TranslationSnapshotResponse>(\n\t\t\t`/api/cli/sync/snapshot?${search.toString()}`,\n\t\t\t{},\n\t\t\t'Failed to fetch translation snapshot',\n\t\t);\n\t}\n\n /**\n * Wait for translation to complete with polling\n */\n async waitForCompletion(\n batchId: string,\n timeout: number = 60000,\n onProgress?: (progress: number) => void,\n ): Promise<{\n translations: Record<string, Record<string, string>>;\n localeMetadata?: Record<string, { nativeName: string; dir?: 'rtl' }>;\n }> {\n const startTime = Date.now();\n const pollInterval = 1000; // Poll every second\n\n while (Date.now() - startTime < timeout) {\n const status = await this.getTranslationStatus(batchId);\n\n // Call progress callback\n if (onProgress) {\n onProgress(status.progress);\n }\n\n if (status.status === 'COMPLETED') {\n if (!status.translations) {\n throw new Error('Translation completed but no translations returned');\n }\n return {\n translations: status.translations,\n localeMetadata: status.localeMetadata,\n };\n }\n\n if (status.status === 'FAILED') {\n throw new Error(\n `Translation failed: ${status.errorMessage || 'Unknown error'}`,\n );\n }\n\n // Wait before polling again\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(`Translation timeout after ${timeout}ms`);\n }\n\n async startInitSession(input: {\n projectName?: string;\n sourceLocale?: string;\n targetLocales?: string[];\n repoCanonical?: string;\n repoScopePath?: string;\n }): Promise<InitStartResponse> {\n const response = await fetch(`${this.apiUrl}/api/cli/init/start`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to start init session (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as InitStartResponse;\n }\n\n async getInitSessionStatus(params: {\n sessionId: string;\n pollToken: string;\n }): Promise<InitStatusResponse> {\n const response = await fetch(\n `${this.apiUrl}/api/cli/init/status/${params.sessionId}`,\n {\n headers: {\n Authorization: `Bearer ${params.pollToken}`,\n },\n },\n );\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to get init status (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as InitStatusResponse;\n }\n\n // ── CLI Auth endpoints (no project API key needed) ──────────────────────────\n\n /**\n * Start a CLI auth session. Returns `{ sessionId, verificationUrl, expiresAt }`.\n * `sessionId` is the raw poll token — keep it secret, used for polling.\n */\n async startCliAuthSession(callbackPort?: number, repoCanonical?: string): Promise<{\n sessionId: string;\n verificationUrl: string;\n installUrl?: string;\n expiresAt: string;\n }> {\n const response = await fetch(`${this.apiUrl}/api/cli/auth/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n ...(callbackPort != null ? { callbackPort } : {}),\n ...(repoCanonical ? { repoCanonical } : {}),\n }),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to start auth session (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as { sessionId: string; verificationUrl: string; installUrl?: string; expiresAt: string };\n }\n\n /**\n * Poll for CLI auth session completion.\n * Returns `{ token }` on success, throws on failure/expiry.\n * The server returns HTTP 202 while still pending.\n */\n async pollCliAuthSession(pollToken: string): Promise<\n | { status: 'pending' }\n | { status: 'complete'; token: string; organizationId?: string }\n | { status: 'failed'; reason: string }\n > {\n const response = await fetch(\n `${this.apiUrl}/api/cli/auth/session?session=${encodeURIComponent(pollToken)}`,\n );\n\n const payload = await readPayload(response);\n\n if (response.status === 202) {\n return { status: 'pending' };\n }\n\n if (response.status === 410) {\n return {\n status: 'failed',\n reason: extractErrorMessage(payload, 'Auth session expired or failed'),\n };\n }\n\n if (!response.ok) {\n return {\n status: 'failed',\n reason: extractErrorMessage(payload, `Auth session error (${response.status})`),\n };\n }\n\n const result = payload as { token?: string; organizationId?: string };\n if (!result.token) {\n return { status: 'failed', reason: 'No token in response' };\n }\n\n return {\n status: 'complete',\n token: result.token,\n ...(result.organizationId ? { organizationId: result.organizationId } : {}),\n };\n }\n\n /**\n * Validate a CLI user token and return the authenticated user's info.\n * Used by the CLI to verify stored credentials on startup.\n */\n async getCliUserInfo(userToken: string): Promise<{\n userId: string;\n email: string;\n name: string | null;\n }> {\n const response = await fetch(`${this.apiUrl}/api/cli/auth/me`, {\n headers: { Authorization: `Bearer ${userToken}` },\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Token validation failed (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as { userId: string; email: string; name: string | null };\n }\n\n /**\n * Revoke the given CLI user token server-side.\n */\n async revokeCliToken(userToken: string): Promise<void> {\n const response = await fetch(`${this.apiUrl}/api/cli/auth/token`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${userToken}` },\n });\n\n if (!response.ok) {\n const payload = await readPayload(response);\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Token revocation failed (${response.status})`),\n status: response.status,\n payload,\n });\n }\n }\n\n // ── Workspaces ────────────────────────────────────────────────────────────────\n\n async listWorkspaces(userToken: string): Promise<{\n workspaces: Array<{\n id: string;\n name: string;\n planId: string;\n projectCount: number;\n hasGitHubConnection: boolean;\n connectionLabel: string | null;\n }>;\n canCreateWorkspace: boolean;\n }> {\n const response = await fetch(`${this.apiUrl}/api/cli/workspaces`, {\n headers: { Authorization: `Bearer ${userToken}` },\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to list workspaces (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as {\n workspaces: Array<{\n id: string;\n name: string;\n planId: string;\n projectCount: number;\n hasGitHubConnection: boolean;\n connectionLabel: string | null;\n }>;\n canCreateWorkspace: boolean;\n };\n }\n\n // ── CLI GitHub endpoints ──────────────────────────────────────────────────────\n\n async startCliGitHubInstall(\n userToken: string,\n params: { organizationId?: string; callbackPort?: number },\n ): Promise<{ installUrl: string }> {\n const response = await fetch(`${this.apiUrl}/api/cli/github/install/start`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${userToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to start GitHub install (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as { installUrl: string };\n }\n\n /**\n * Start the \"link existing installation\" discovery flow.\n * Unlike startCliGitHubOAuth, this requires no bearer token — the Vocoder\n * account is created from the OAuth code in the callback.\n */\n async startCliGitHubLinkSession(\n sessionId: string,\n callbackPort?: number,\n ): Promise<{ oauthUrl: string }> {\n const response = await fetch(`${this.apiUrl}/api/cli/github/oauth/link-start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, ...(callbackPort != null ? { callbackPort } : {}) }),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to start GitHub link session (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as { oauthUrl: string };\n }\n\n async startCliGitHubOAuth(\n userToken: string,\n params: { organizationId?: string; callbackPort?: number },\n ): Promise<{ oauthUrl: string }> {\n const response = await fetch(`${this.apiUrl}/api/cli/github/oauth/start`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${userToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to start GitHub OAuth (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as { oauthUrl: string };\n }\n\n async getCliGitHubDiscovery(userToken: string): Promise<{\n installations: Array<{\n installationId: number;\n accountLogin: string;\n accountType: string;\n isSuspended: boolean;\n conflictLabel: string | null;\n }>;\n }> {\n const response = await fetch(`${this.apiUrl}/api/cli/github/discovery`, {\n headers: { Authorization: `Bearer ${userToken}` },\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to fetch GitHub discovery (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as {\n installations: Array<{\n installationId: number;\n accountLogin: string;\n accountType: string;\n isSuspended: boolean;\n conflictLabel: string | null;\n }>;\n };\n }\n\n async claimCliGitHubInstallation(\n userToken: string,\n params: { installationId: string; organizationId: string | null },\n ): Promise<{\n organizationId: string;\n organizationName: string;\n connectionLabel: string;\n repoCount: number;\n }> {\n const response = await fetch(`${this.apiUrl}/api/cli/github/claim`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${userToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to claim GitHub installation (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as {\n organizationId: string;\n organizationName: string;\n connectionLabel: string;\n repoCount: number;\n };\n }\n\n // ── Locales ───────────────────────────────────────────────────────────────────\n\n async listLocales(userToken: string): Promise<Array<{ code: string; name: string; nativeName?: string }>> {\n const response = await fetch(`${this.apiUrl}/api/cli/locales`, {\n headers: { Authorization: `Bearer ${userToken}` },\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to list locales (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n const result = payload as { locales: Array<{ code: string; name: string; nativeName?: string }> };\n return result.locales;\n }\n\n // ── Project creation ──────────────────────────────────────────────────────────\n\n async createProject(\n userToken: string,\n params: {\n organizationId: string;\n name: string;\n sourceLocale: string;\n targetLocales: string[];\n targetBranches: string[];\n translationTriggers: string[];\n scopePaths: string[];\n repoCanonical?: string;\n },\n ): Promise<{\n projectId: string;\n projectName: string;\n apiKey: string;\n sourceLocale: string;\n targetLocales: string[];\n translationTriggers: string[];\n repositoryBound: boolean;\n configureUrl?: string;\n }> {\n const response = await fetch(`${this.apiUrl}/api/cli/projects`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${userToken}`,\n },\n body: JSON.stringify(params),\n });\n\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw new VocoderAPIError({\n message: extractErrorMessage(payload, `Failed to create project (${response.status})`),\n status: response.status,\n payload,\n });\n }\n\n return payload as {\n projectId: string;\n projectName: string;\n apiKey: string;\n sourceLocale: string;\n targetLocales: string[];\n translationTriggers: string[];\n repositoryBound: boolean;\n configureUrl?: string;\n };\n }\n\n // ── Project lookup ────────────────────────────────────────────────────────────\n\n /**\n * Look up whether a project already exists for a given repo + scope.\n * Returns { projectId, projectName, organizationName } or null if not found.\n */\n async lookupProjectByRepo(params: {\n repoCanonical: string;\n scopePath: string;\n }): Promise<{\n projectId: string;\n projectName: string;\n organizationName: string;\n sourceLocale?: string;\n translationTriggers?: string[];\n } | null> {\n try {\n const response = await fetch(`${this.apiUrl}/api/cli/init/lookup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n repo: params.repoCanonical,\n scopePath: params.scopePath,\n }),\n });\n\n if (response.status === 404) return null;\n if (!response.ok) return null;\n\n return (await response.json()) as {\n projectId: string;\n projectName: string;\n organizationName: string;\n sourceLocale?: string;\n translationTriggers?: string[];\n };\n } catch {\n return null;\n }\n }\n}\n","import { execSync } from 'child_process';\nimport { relative, resolve } from 'path';\n\nexport type GitRepositoryIdentity = {\n repoCanonical: string;\n repoScopePath: string;\n};\n\nexport type GitContext = {\n identity: GitRepositoryIdentity | null;\n warnings: string[];\n};\n\nfunction safeExec(command: string): string | null {\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n }).trim();\n return output.length > 0 ? output : null;\n } catch {\n return null;\n }\n}\n\nfunction normalizePath(pathname: string): string | null {\n const cleaned = pathname\n .replace(/^\\/+/, '')\n .replace(/\\.git$/i, '')\n .trim();\n\n if (!cleaned || !cleaned.includes('/')) {\n return null;\n }\n\n return cleaned;\n}\n\nfunction parseRemoteUrl(remoteUrl: string): {\n host: string;\n ownerRepoPath: string;\n} | null {\n const trimmed = remoteUrl.trim();\n if (!trimmed) {\n return null;\n }\n\n // SCP-like syntax: git@github.com:owner/repo.git\n if (!trimmed.includes('://')) {\n const scpMatch = trimmed.match(/^(?:.+@)?([^:]+):(.+)$/);\n if (scpMatch) {\n const host = (scpMatch[1] || '').toLowerCase();\n const ownerRepoPath = normalizePath(scpMatch[2] || '');\n if (!host || !ownerRepoPath) {\n return null;\n }\n return { host, ownerRepoPath };\n }\n return null;\n }\n\n try {\n const parsed = new URL(trimmed);\n const host = parsed.hostname.toLowerCase();\n const ownerRepoPath = normalizePath(decodeURIComponent(parsed.pathname));\n if (!host || !ownerRepoPath) {\n return null;\n }\n return { host, ownerRepoPath };\n } catch {\n return null;\n }\n}\n\nfunction toCanonical(host: string, ownerRepoPath: string): string {\n if (host.includes('github.com')) {\n return `github:${ownerRepoPath.toLowerCase()}`;\n }\n if (host.includes('gitlab.com')) {\n return `gitlab:${ownerRepoPath.toLowerCase()}`;\n }\n if (host.includes('bitbucket.org')) {\n return `bitbucket:${ownerRepoPath.toLowerCase()}`;\n }\n return `git:${host}/${ownerRepoPath.toLowerCase()}`;\n}\n\nexport function resolveGitRepositoryIdentity(): GitRepositoryIdentity | null {\n const remoteUrl = safeExec('git config --get remote.origin.url');\n if (!remoteUrl) {\n return null;\n }\n\n const parsed = parseRemoteUrl(remoteUrl);\n if (!parsed) {\n return null;\n }\n\n const repositoryRoot = safeExec('git rev-parse --show-toplevel');\n const currentDirectory = process.cwd();\n let repoScopePath = '';\n if (repositoryRoot) {\n const relativePath = relative(resolve(repositoryRoot), resolve(currentDirectory))\n .replace(/\\\\/g, '/')\n .trim();\n\n if (relativePath && relativePath !== '.' && !relativePath.startsWith('..')) {\n repoScopePath = relativePath;\n }\n }\n\n return {\n repoCanonical: toCanonical(parsed.host, parsed.ownerRepoPath),\n repoScopePath,\n };\n}\n\nexport function resolveGitContext(): GitContext {\n const warnings: string[] = [];\n const identity = resolveGitRepositoryIdentity();\n\n if (!identity) {\n warnings.push(\n 'Could not detect git remote origin. Repo binding will be skipped until sync can detect it.',\n );\n }\n\n return { identity, warnings };\n}\n","import * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport type { VocoderAPI } from './api.js';\nimport type { LocaleOption } from './locale-search.js';\nimport { searchMultiSelectLocales, searchSelectLocale } from './locale-search.js';\nimport { detectGitBranches, filterableBranchSelect } from './branch-select.js';\n\nexport interface ProjectCreateParams {\n api: VocoderAPI;\n userToken: string;\n organizationId: string;\n /** Default project name (repo name or directory name) */\n defaultName?: string;\n /** Pre-detected source locale, e.g. \"en\" */\n defaultSourceLocale?: string;\n /** Repo canonical for binding the project, e.g. \"github:owner/repo\" */\n repoCanonical?: string;\n /** Default target branches */\n defaultBranches?: string[];\n}\n\nexport interface ProjectCreateResult {\n projectId: string;\n projectName: string;\n apiKey: string;\n sourceLocale: string;\n targetLocales: string[];\n translationTriggers: string[];\n repositoryBound: boolean;\n configureUrl?: string;\n}\n\n/** All locales — used for target language selection. */\nfunction buildLocaleOptions(\n locales: Array<{ code: string; name: string; nativeName?: string }>,\n): LocaleOption[] {\n return locales.map((l) => ({\n bcp47: l.code,\n label: `${l.name} — ${l.code}`,\n }));\n}\n\n/**\n * Deduplicated language list — used for source language selection.\n * Groups locales by language family (prefix before first hyphen) and keeps one\n * representative per family, preferring the shortest/base code (e.g. \"en\" over\n * \"en-US\"). This prevents showing \"English\", \"English (American)\", \"English\n * (British)\" as three separate choices when the user just means \"English\".\n */\nfunction buildLanguageOptions(\n locales: Array<{ code: string; name: string; nativeName?: string }>,\n): LocaleOption[] {\n const byFamily = new Map<string, LocaleOption>();\n\n for (const l of locales) {\n const family = l.code.split('-')[0]!.toLowerCase();\n const opt: LocaleOption = { bcp47: l.code, label: `${l.name} — ${l.code}` };\n const existing = byFamily.get(family);\n // Prefer base code (shorter, no region suffix) over regional variants\n if (!existing || l.code.length < existing.bcp47.length) {\n byFamily.set(family, opt);\n }\n }\n\n return Array.from(byFamily.values());\n}\n\n/**\n * Run the full project configuration TUI: prompts for name, source locale,\n * target locales, and target branches, then calls POST /api/cli/projects.\n *\n * Returns the created project info (including API key), or null if cancelled.\n */\nexport async function runProjectCreate(\n params: ProjectCreateParams,\n): Promise<ProjectCreateResult | null> {\n const { api, userToken, organizationId, repoCanonical } = params;\n\n // ── Project name ────────────────────────────────────────────────────────────\n // Use the detected repo name automatically — no prompt needed.\n const projectName = (params.defaultName ?? 'my-project').trim();\n p.log.success(`Project: ${chalk.bold(projectName)}`);\n\n // ── Fetch available locales ─────────────────────────────────────────────────\n let rawLocales: Array<{ code: string; name: string; nativeName?: string }>;\n try {\n rawLocales = await api.listLocales(userToken);\n } catch {\n p.log.error('Failed to fetch supported locales. Check your connection and try again.');\n return null;\n }\n\n // Source: deduplicated by language family (e.g. just \"English — en\", not all variants)\n const languageOptions = buildLanguageOptions(rawLocales);\n // Target: all locales (regional variants matter for translation targets)\n const localeOptions = buildLocaleOptions(rawLocales);\n\n // ── Source locale ───────────────────────────────────────────────────────────\n const sourceLocale = await searchSelectLocale(\n languageOptions,\n 'Source language (the language your code is written in)',\n params.defaultSourceLocale ?? 'en',\n );\n\n if (sourceLocale === null) return null;\n\n // ── Target locales ──────────────────────────────────────────────────────────\n // Exclude the exact source locale; regional variants (e.g. en-GB when source=en) remain available\n const targetOptions = localeOptions.filter((opt) => opt.bcp47 !== sourceLocale);\n\n const targetLocales = await searchMultiSelectLocales(\n targetOptions,\n 'Target languages (languages to translate into)',\n );\n\n if (targetLocales === null) return null;\n\n if (targetLocales.length === 0) {\n p.log.warn('No target languages selected — you can add them later from the dashboard.');\n }\n\n // ── Target branches ─────────────────────────────────────────────────────────\n const detected = detectGitBranches();\n const initialBranches = params.defaultBranches?.length\n ? params.defaultBranches\n : [detected.defaultBranch];\n\n let targetBranches: string[] = [];\n {\n let initial = initialBranches;\n while (targetBranches.length === 0) {\n const result = await filterableBranchSelect({\n message: 'Target branches (translations will run when you push to these)',\n branches: detected.branches,\n defaultBranch: detected.defaultBranch,\n initialValues: initial,\n });\n if (result === null) return null;\n if (result.length === 0) {\n p.log.warn('At least one branch is required. Please select at least one.');\n initial = [detected.defaultBranch];\n } else {\n targetBranches = result;\n }\n }\n }\n\n // ── Create project ──────────────────────────────────────────────────────────\n try {\n const result = await api.createProject(userToken, {\n organizationId,\n name: projectName,\n sourceLocale,\n targetLocales,\n targetBranches,\n translationTriggers: ['push'],\n scopePaths: [],\n repoCanonical,\n });\n\n p.log.success(`Project ${chalk.bold(result.projectName)} created!`);\n return result;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n p.log.error(`Failed to create project: ${message}`);\n return null;\n }\n}\n","import { Prompt, isCancel } from '@clack/core';\nimport * as p from '@clack/prompts';\nimport chalk from 'chalk';\n\nexport interface LocaleOption {\n bcp47: string;\n /** Human-readable label, e.g. \"English — en\" */\n label: string;\n}\n\n// ── Symbols (match @clack/prompts style) ──────────────────────────────────────\n\nconst S_BAR = '│';\nconst S_BAR_END = '└';\nconst S_ACTIVE = '◆';\nconst S_SUBMIT = '◆';\nconst S_CANCEL = '■';\nconst S_ERROR = '▲';\n\nconst noColor = process.env.NO_COLOR === '1' || process.env.FORCE_COLOR === '0';\nconst dim = (s: string) => noColor ? s : chalk.gray(s);\nconst cyan = (s: string) => noColor ? s : chalk.cyan(s);\nconst grn = (s: string) => noColor ? s : chalk.green(s);\nconst ylw = (s: string) => noColor ? s : chalk.yellow(s);\nconst red = (s: string) => noColor ? s : chalk.red(s);\nconst bld = (s: string) => noColor ? s : chalk.bold(s);\n\nfunction symbol(state: string): string {\n switch (state) {\n case 'submit': return grn(S_SUBMIT);\n case 'cancel': return red(S_CANCEL);\n case 'error': return ylw(S_ERROR);\n default: return cyan(S_ACTIVE);\n }\n}\n\n// ── Filter ────────────────────────────────────────────────────────────────────\n\nconst MAX_VISIBLE = 12;\n\nfunction filterLocales(options: LocaleOption[], query: string): LocaleOption[] {\n if (!query.trim()) return options;\n const lower = query.toLowerCase();\n return options.filter(\n (o) => o.bcp47.toLowerCase().includes(lower) || o.label.toLowerCase().includes(lower),\n );\n}\n\n// ── List renderer ─────────────────────────────────────────────────────────────\n\nfunction buildList(\n filtered: LocaleOption[],\n cursor: number,\n scrollOffset: number,\n selected: Set<string> | null, // null = single-select\n): string {\n const isMulti = selected !== null;\n const end = Math.min(filtered.length, scrollOffset + MAX_VISIBLE);\n const visibleLines: string[] = [];\n\n for (let i = scrollOffset; i < end; i++) {\n const opt = filtered[i]!;\n const isCursor = i === cursor;\n const isChecked = isMulti && selected!.has(opt.bcp47);\n\n const icon = isMulti\n ? (isChecked ? (isCursor ? grn('◼') : '◼') : (isCursor ? grn('◻') : dim('◻')))\n : (isCursor ? grn('●') : dim('○'));\n\n visibleLines.push(`${cyan(S_BAR)} ${icon} ${isCursor ? bld(opt.label) : opt.label}`);\n }\n\n const hidden = filtered.length - (end - scrollOffset);\n if (hidden > 0) visibleLines.push(dim(`${S_BAR} ${hidden} more — keep typing to narrow`));\n if (filtered.length === 0) visibleLines.push(dim(`${S_BAR} No matches`));\n if (isMulti && selected!.size > 0) {\n visibleLines.push(dim(`${S_BAR} ${selected!.size} selected — Enter to confirm`));\n }\n\n return visibleLines.join('\\n');\n}\n\n// ── Core prompt factory ───────────────────────────────────────────────────────\n\nasync function runFilterablePrompt(opts: {\n message: string;\n options: LocaleOption[];\n multi: boolean;\n initialValue?: string;\n initialValues?: string[];\n}): Promise<string | string[] | null> {\n const { message, options, multi } = opts;\n\n let filter = '';\n let cursor = 0;\n let scrollOffset = 0;\n const selected = new Set<string>(multi ? (opts.initialValues ?? []) : []);\n\n if (!multi && opts.initialValue) {\n const idx = options.findIndex((o) => o.bcp47 === opts.initialValue);\n if (idx >= 0) cursor = idx;\n }\n\n const getFiltered = () => filterLocales(options, filter);\n\n // Keep cursor in bounds and scroll window centred\n const clampCursor = (filtered: LocaleOption[]) => {\n if (cursor >= filtered.length) cursor = Math.max(0, filtered.length - 1);\n if (cursor < scrollOffset) scrollOffset = cursor;\n if (cursor >= scrollOffset + MAX_VISIBLE) scrollOffset = cursor - MAX_VISIBLE + 1;\n if (scrollOffset < 0) scrollOffset = 0;\n };\n\n // @clack/core Prompt: render() returns the ENTIRE frame; clack handles\n // re-rendering (cursor movement + diff) automatically.\n // Using `any` cast to pass `trackValue=false` (2nd constructor arg).\n const prompt = new (Prompt as any)(\n {\n initialValue: !multi ? (options[cursor]?.bcp47 ?? null) : null,\n validate() {\n const f = getFiltered();\n if (multi && selected.size === 0) return 'At least one target language is required.';\n if (!multi && !f[cursor]) return 'Please select a language.';\n return undefined;\n },\n render(this: { state: string; error: string; value: unknown }) {\n const filtered = getFiltered();\n clampCursor(filtered);\n\n const hdr = `${dim(S_BAR)}\\n${symbol(this.state)} ${message}\\n`;\n const hint = filter.length > 0\n ? filter\n : dim('type to filter, ↑↓ navigate' + (multi ? ', space select' : ''));\n\n switch (this.state) {\n case 'submit': {\n const val = multi\n ? Array.from(selected).map((id) => options.find((o) => o.bcp47 === id)?.label ?? id).join(', ')\n : options.find((o) => o.bcp47 === (this.value as string))?.label ?? '';\n return `${hdr}${dim(S_BAR)} ${bld(val || dim('none'))}`;\n }\n case 'cancel':\n return `${hdr}${dim(S_BAR)}`;\n case 'error':\n return [\n hdr.trimEnd(),\n `${ylw(S_BAR)} ${dim('/')} ${hint}`,\n buildList(filtered, cursor, scrollOffset, multi ? selected : null),\n `${ylw(S_BAR_END)} ${ylw(this.error)}`,\n '',\n ].join('\\n');\n default:\n return [\n hdr.trimEnd(),\n `${cyan(S_BAR)} ${dim('/')} ${hint}`,\n buildList(filtered, cursor, scrollOffset, multi ? selected : null),\n `${cyan(S_BAR_END)}`,\n '',\n ].join('\\n');\n }\n },\n },\n false, // trackValue=false — we manage value manually\n ) as InstanceType<typeof Prompt> & { value: unknown; state: string };\n\n // Character input → update filter\n prompt.on('key', (key: string | undefined) => {\n if (!key || key === ' ') return; // space handled by cursor event\n const cp = key.codePointAt(0) ?? 0;\n if (cp === 0x7f || cp === 0x08) { // backspace\n filter = filter.slice(0, -1);\n cursor = 0; scrollOffset = 0;\n } else if (cp >= 32 && cp !== 127) {\n filter += key;\n cursor = 0; scrollOffset = 0;\n }\n });\n\n // Navigation + toggle\n prompt.on('cursor', (action: string | undefined) => {\n const filtered = getFiltered();\n switch (action) {\n case 'up': cursor = Math.max(0, cursor - 1); break;\n case 'down': cursor = Math.min(Math.max(filtered.length - 1, 0), cursor + 1); break;\n case 'space':\n if (multi) {\n const opt = filtered[cursor];\n if (opt) {\n if (selected.has(opt.bcp47)) selected.delete(opt.bcp47);\n else selected.add(opt.bcp47);\n }\n }\n break;\n }\n // Sync prompt.value for single-select so submit gets the right value\n if (!multi) {\n const opt = getFiltered()[cursor];\n (prompt as any).value = opt?.bcp47 ?? null;\n }\n });\n\n // Before submit resolves, set value to the selected items (multi) or current cursor (single)\n prompt.on('finalize', () => {\n if ((prompt as any).state === 'submit') {\n if (multi) {\n (prompt as any).value = Array.from(selected);\n } else {\n const f = getFiltered();\n (prompt as any).value = f[cursor]?.bcp47 ?? null;\n }\n }\n });\n\n const result = await prompt.prompt();\n\n if (isCancel(result)) return null;\n return result as string | string[];\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport async function searchSelectLocale(\n options: LocaleOption[],\n message: string,\n initialValue?: string,\n): Promise<string | null> {\n const result = await runFilterablePrompt({ message, options, multi: false, initialValue });\n return typeof result === 'string' ? result : null;\n}\n\nexport async function searchMultiSelectLocales(\n options: LocaleOption[],\n message: string,\n initialValues?: string[],\n): Promise<string[] | null> {\n const result = await runFilterablePrompt({ message, options, multi: true, initialValues });\n if (result === null) return null;\n const picks = result as string[];\n // Validate already prevents empty on first try; this handles the retry path\n if (picks.length === 0) {\n p.log.warn('At least one target language is required. Please select at least one.');\n return searchMultiSelectLocales(options, message, initialValues);\n }\n return picks;\n}\n","import { Prompt, isCancel } from '@clack/core';\nimport chalk from 'chalk';\nimport { execSync } from 'node:child_process';\n\n// ── Symbols ───────────────────────────────────────────────────────────────────\n\nconst S_BAR = '│';\nconst S_BAR_END = '└';\nconst S_ACTIVE = '◆';\nconst S_SUBMIT = '◆';\nconst S_CANCEL = '■';\nconst S_ERROR = '▲';\n\nconst noColor = process.env.NO_COLOR === '1' || process.env.FORCE_COLOR === '0';\nconst dim = (s: string) => noColor ? s : chalk.gray(s);\nconst cyan = (s: string) => noColor ? s : chalk.cyan(s);\nconst grn = (s: string) => noColor ? s : chalk.green(s);\nconst ylw = (s: string) => noColor ? s : chalk.yellow(s);\nconst red = (s: string) => noColor ? s : chalk.red(s);\nconst bld = (s: string) => noColor ? s : chalk.bold(s);\n\nfunction symbol(state: string): string {\n switch (state) {\n case 'submit': return grn(S_SUBMIT);\n case 'cancel': return red(S_CANCEL);\n case 'error': return ylw(S_ERROR);\n default: return cyan(S_ACTIVE);\n }\n}\n\n// ── Git detection ─────────────────────────────────────────────────────────────\n\nexport interface DetectedBranches {\n branches: string[];\n defaultBranch: string;\n}\n\nexport function detectGitBranches(cwd?: string): DetectedBranches {\n const workDir = cwd ?? process.cwd();\n try {\n // Local branches\n const localOut = execSync('git branch', { cwd: workDir, stdio: 'pipe' }).toString();\n const localBranches = localOut.split('\\n')\n .filter(Boolean)\n .map((b) => b.replace(/^\\*?\\s*/, '').trim())\n .filter(Boolean);\n\n // Remote branches (strip \"origin/\" prefix, skip HEAD pointer)\n let remoteBranches: string[] = [];\n try {\n const remoteOut = execSync('git branch -r', { cwd: workDir, stdio: 'pipe' }).toString();\n remoteBranches = remoteOut.split('\\n')\n .map((b) => b.trim())\n .filter((b) => b && !b.includes('HEAD'))\n .map((b) => b.replace(/^[^/]+\\//, '')); // strip \"origin/\" (or any remote name)\n } catch { /* no remote */ }\n\n const branches = [...new Set([...localBranches, ...remoteBranches])].sort();\n\n // Default branch: ask git for origin's HEAD (local cache, no network call).\n // Falls back to 'main' if the remote HEAD isn't cached.\n let defaultBranch = 'main';\n try {\n const ref = execSync('git symbolic-ref refs/remotes/origin/HEAD', { cwd: workDir, stdio: 'pipe' })\n .toString().trim();\n // ref = \"refs/remotes/origin/main\"\n defaultBranch = ref.split('/').pop() ?? 'main';\n } catch { /* HEAD not cached — run \"git remote set-head origin --auto\" to fix */ }\n\n return {\n branches: branches.length > 0 ? branches : [defaultBranch],\n defaultBranch,\n };\n } catch {\n return { branches: ['main'], defaultBranch: 'main' };\n }\n}\n\n// ── Validation ────────────────────────────────────────────────────────────────\n\nconst INVALID_CHARS = /[\\s?^~:[\\]\\\\]/;\n\nexport function validateBranchPattern(pattern: string): string | null {\n const t = pattern.trim();\n if (!t) return 'Pattern cannot be empty';\n if (INVALID_CHARS.test(t)) return 'Invalid characters — avoid spaces, ?, ^, ~, :, [, ], \\\\';\n if (t.startsWith('/') || t.endsWith('/')) return 'Cannot start or end with /';\n if (t.includes('//')) return 'Cannot contain //';\n return null;\n}\n\n// ── List renderer ─────────────────────────────────────────────────────────────\n\nconst MAX_VISIBLE = 10;\nconst ADD_PATTERN_VALUE = '__add__';\n\ninterface BranchItem {\n value: string;\n label: string;\n isCustom?: boolean;\n}\n\nfunction buildItems(\n branches: string[],\n defaultBranch: string,\n customPatterns: string[],\n): BranchItem[] {\n const items: BranchItem[] = branches.map((b) => ({\n value: b,\n label: b === defaultBranch ? `${b} (default branch)` : b,\n }));\n for (const pt of customPatterns) {\n if (!branches.includes(pt)) {\n items.push({ value: pt, label: pt, isCustom: true });\n }\n }\n return items;\n}\n\nfunction filterItems(items: BranchItem[], query: string): BranchItem[] {\n if (!query.trim()) return items;\n const lower = query.toLowerCase();\n return items.filter((i) => i.value.toLowerCase().includes(lower));\n}\n\nfunction buildList(\n filtered: BranchItem[],\n cursor: number,\n scrollOffset: number,\n selected: Set<string>,\n filter: string,\n customPatterns: string[],\n addCursor: boolean,\n): string {\n const lines: string[] = [];\n const end = Math.min(filtered.length, scrollOffset + MAX_VISIBLE);\n\n for (let i = scrollOffset; i < end; i++) {\n const item = filtered[i]!;\n const isCursor = i === cursor && !addCursor;\n const isChecked = selected.has(item.value);\n\n const icon = isChecked\n ? (isCursor ? grn('◼') : '◼')\n : (isCursor ? grn('◻') : dim('◻'));\n\n let label = item.isCustom ? `${item.label} ${dim('(custom)')}` : item.label;\n if (isCursor) label = bld(label);\n\n lines.push(`${cyan(S_BAR)} ${icon} ${label}`);\n }\n\n // \"Add pattern\" option\n const trimmed = filter.trim();\n const allItems = [...filtered]; // simplified: just check filtered\n const isNewPattern =\n trimmed.length > 0 &&\n !allItems.some((i) => i.value === trimmed) &&\n !customPatterns.includes(trimmed);\n\n if (isNewPattern) {\n const err = validateBranchPattern(trimmed);\n const icon = addCursor ? grn('◻') : dim('◻');\n const label = err\n ? `${ylw('+')} ${dim(`\"${trimmed}\" — ${err}`)}`\n : `${grn('+')} Add \"${trimmed}\" as branch pattern`;\n lines.push(`${cyan(S_BAR)} ${icon} ${label}`);\n } else if (filtered.length === 0 && trimmed.length === 0) {\n lines.push(dim(`${S_BAR} No branches detected`));\n }\n\n const hidden = filtered.length - (end - scrollOffset);\n if (hidden > 0) lines.push(dim(`${S_BAR} ${hidden} more`));\n if (selected.size > 0) lines.push(dim(`${S_BAR} ${selected.size} selected — Enter to confirm`));\n\n return lines.join('\\n');\n}\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\nexport async function filterableBranchSelect(params: {\n message: string;\n branches: string[];\n defaultBranch: string;\n initialValues?: string[];\n}): Promise<string[] | null> {\n const { message, branches, defaultBranch } = params;\n\n let filter = '';\n let cursor = 0;\n let scrollOffset = 0;\n let addCursor = false;\n const customPatterns: string[] = [];\n const selected = new Set<string>(params.initialValues ?? [defaultBranch]);\n\n const getItems = () => buildItems(branches, defaultBranch, customPatterns);\n const getFiltered = () => filterItems(getItems(), filter);\n\n const isNewPattern = () => {\n const t = filter.trim();\n if (!t) return false;\n return !getItems().some((i) => i.value === t) && !customPatterns.includes(t);\n };\n\n const clampCursor = (filtered: BranchItem[]) => {\n const hasAdd = isNewPattern();\n const max = filtered.length - 1 + (hasAdd ? 1 : 0);\n if (cursor > max && !addCursor) cursor = Math.max(0, max);\n if (!addCursor) {\n if (cursor < scrollOffset) scrollOffset = cursor;\n if (cursor >= scrollOffset + MAX_VISIBLE) scrollOffset = cursor - MAX_VISIBLE + 1;\n if (scrollOffset < 0) scrollOffset = 0;\n }\n };\n\n const prompt = new (Prompt as any)(\n {\n validate() {\n if (selected.size === 0) return 'At least one branch is required.';\n return undefined;\n },\n render(this: { state: string; error: string }) {\n const filtered = getFiltered();\n clampCursor(filtered);\n\n const hdr = `${dim(S_BAR)}\\n${symbol(this.state)} ${message}\\n`;\n const hint = filter.length > 0\n ? filter\n : dim('type to filter or add pattern, ↑↓ navigate, space select');\n\n switch (this.state) {\n case 'submit': {\n const summary = selected.size > 0\n ? bld(Array.from(selected).join(', '))\n : dim('none');\n return `${hdr}${dim(S_BAR)} ${summary}`;\n }\n case 'cancel':\n return `${hdr}${dim(S_BAR)}`;\n case 'error':\n return [\n hdr.trimEnd(),\n `${ylw(S_BAR)} ${dim('/')} ${hint}`,\n buildList(filtered, cursor, scrollOffset, selected, filter, customPatterns, addCursor),\n `${ylw(S_BAR_END)} ${ylw(this.error)}`,\n '',\n ].join('\\n');\n default:\n return [\n hdr.trimEnd(),\n `${cyan(S_BAR)} ${dim('/')} ${hint}`,\n buildList(filtered, cursor, scrollOffset, selected, filter, customPatterns, addCursor),\n `${cyan(S_BAR_END)}`,\n '',\n ].join('\\n');\n }\n },\n },\n false,\n ) as InstanceType<typeof Prompt> & { value: unknown; state: string };\n\n prompt.on('key', (key: string | undefined) => {\n if (!key || key === ' ') return;\n const cp = key.codePointAt(0) ?? 0;\n if (cp === 0x7f || cp === 0x08) {\n filter = filter.slice(0, -1);\n cursor = 0; scrollOffset = 0; addCursor = false;\n } else if (cp >= 32 && cp !== 127) {\n filter += key;\n cursor = 0; scrollOffset = 0; addCursor = false;\n }\n });\n\n prompt.on('cursor', (action: string | undefined) => {\n const filtered = getFiltered();\n const hasAdd = isNewPattern();\n\n switch (action) {\n case 'up':\n if (addCursor) { addCursor = false; cursor = Math.max(0, filtered.length - 1); }\n else cursor = Math.max(0, cursor - 1);\n break;\n case 'down':\n if (!addCursor && cursor >= filtered.length - 1 && hasAdd) addCursor = true;\n else if (!addCursor) cursor = Math.min(filtered.length - 1, cursor + 1);\n break;\n case 'space':\n if (addCursor) {\n const t = filter.trim();\n const err = validateBranchPattern(t);\n if (!err) {\n customPatterns.push(t);\n selected.add(t);\n filter = '';\n cursor = 0; scrollOffset = 0; addCursor = false;\n }\n } else {\n const item = filtered[cursor];\n if (item) {\n if (selected.has(item.value)) selected.delete(item.value);\n else selected.add(item.value);\n }\n }\n break;\n }\n });\n\n prompt.on('finalize', () => {\n if ((prompt as any).state === 'submit') {\n (prompt as any).value = Array.from(selected);\n }\n });\n\n const result = await prompt.prompt();\n if (isCancel(result)) return null;\n return result as string[];\n}\n","import * as p from '@clack/prompts';\nimport chalk from 'chalk';\n\nexport interface WorkspaceInfo {\n id: string;\n name: string;\n planId: string;\n projectCount: number;\n hasGitHubConnection: boolean;\n connectionLabel: string | null;\n}\n\nexport interface WorkspaceListResult {\n workspaces: WorkspaceInfo[];\n canCreateWorkspace: boolean;\n}\n\nexport type WorkspaceSelection =\n | { action: 'use'; workspace: WorkspaceInfo }\n | { action: 'create' }\n | { action: 'cancelled' };\n\nfunction workspaceLabel(ws: WorkspaceInfo): string {\n const parts: string[] = [ws.name];\n const meta: string[] = [];\n\n if (ws.projectCount === 1) {\n meta.push('1 project');\n } else if (ws.projectCount > 1) {\n meta.push(`${ws.projectCount} projects`);\n }\n\n if (ws.connectionLabel) {\n meta.push(`GitHub: ${ws.connectionLabel}`);\n }\n\n if (meta.length > 0) {\n parts.push(chalk.dim(`(${meta.join(', ')})`));\n }\n\n return parts.join(' ');\n}\n\n/**\n * Prompt the user to select a workspace or create a new one.\n * Returns a `WorkspaceSelection` describing what the user chose.\n */\nexport async function selectWorkspace(\n result: WorkspaceListResult,\n): Promise<WorkspaceSelection> {\n const { workspaces, canCreateWorkspace } = result;\n\n if (workspaces.length === 0) {\n // No workspaces — must create\n return { action: 'create' };\n }\n\n type SelectValue = string | 'create';\n\n const options: Array<{ value: SelectValue; label: string; hint?: string }> =\n workspaces.map((ws) => ({\n value: ws.id,\n label: ws.name,\n hint:\n [\n ws.projectCount > 0 ? `${ws.projectCount} project${ws.projectCount !== 1 ? 's' : ''}` : '',\n ws.connectionLabel ? `GitHub: ${ws.connectionLabel}` : '',\n ]\n .filter(Boolean)\n .join(' · ') || undefined,\n }));\n\n if (canCreateWorkspace) {\n options.push({ value: 'create', label: 'Create new workspace' });\n }\n\n const selected = await p.select<SelectValue>({\n message: 'Select workspace',\n options,\n });\n\n if (p.isCancel(selected)) {\n return { action: 'cancelled' };\n }\n\n if (selected === 'create') {\n return { action: 'create' };\n }\n\n const workspace = workspaces.find((ws) => ws.id === selected);\n if (!workspace) {\n return { action: 'cancelled' };\n }\n\n return { action: 'use', workspace };\n}\n","import * as p from '@clack/prompts';\nimport { VocoderAPI } from '../utils/api.js';\nimport { clearAuthData, readAuthData } from '../utils/auth-store.js';\n\nexport interface LogoutOptions {\n apiUrl?: string;\n}\n\nexport async function logout(options: LogoutOptions = {}): Promise<number> {\n const stored = readAuthData();\n\n if (!stored) {\n p.log.info('Not currently authenticated.');\n return 0;\n }\n\n const apiUrl = options.apiUrl ?? stored.apiUrl ?? 'https://vocoder.app';\n const api = new VocoderAPI({ apiUrl, apiKey: '' });\n\n try {\n await api.revokeCliToken(stored.token);\n } catch {\n // Ignore errors — we still clear local data even if the server call fails\n }\n\n clearAuthData();\n p.log.success(`Logged out (was ${stored.email})`);\n return 0;\n}\n","import * as p from '@clack/prompts';\n\nimport type {\n EffectiveSyncMode,\n ExtractedString,\n LimitErrorResponse,\n ProjectConfig,\n RequestedSyncMode,\n SyncPolicyConfig,\n TranslateOptions,\n TranslationStringEntry,\n} from '../types.js';\nimport { VocoderAPI, VocoderAPIError } from '../utils/api.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport { detectBranch, isTargetBranch } from '../utils/branch.js';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { getMergedConfig, validateLocalConfig } from '../utils/config.js';\n\nimport { StringExtractor } from '../utils/extract.js';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { resolveGitRepositoryIdentity } from '../utils/git-identity.js';\n\ntype LocaleMetadataMap = Record<string, { nativeName: string; dir?: 'rtl' }>;\ntype TranslationMap = Record<string, Record<string, string>>;\ntype TranslationArtifactSource = 'fresh' | 'local-cache' | 'api-snapshot';\n\ntype TranslationArtifacts = {\n source: TranslationArtifactSource;\n translations: TranslationMap;\n localeMetadata?: LocaleMetadataMap;\n snapshotBatchId?: string;\n completedAt?: string | null;\n cacheBranch?: string;\n};\n\ntype LocalSnapshotCache = {\n version: 1;\n branch: string;\n sourceLocale: string;\n targetLocales: string[];\n savedAt: string;\n snapshotBatchId?: string;\n completedAt?: string | null;\n localeMetadata?: LocaleMetadataMap;\n translations: TranslationMap;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseLocaleMetadata(value: unknown): LocaleMetadataMap | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n\n const metadata: LocaleMetadataMap = {};\n for (const [locale, rawValue] of Object.entries(value)) {\n if (!isRecord(rawValue)) {\n continue;\n }\n\n const nativeName = rawValue.nativeName;\n if (typeof nativeName !== 'string' || nativeName.trim().length === 0) {\n continue;\n }\n\n const entry: { nativeName: string; dir?: 'rtl' } = { nativeName };\n if (rawValue.dir === 'rtl') {\n entry.dir = 'rtl';\n }\n\n metadata[locale] = entry;\n }\n\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nfunction parseTranslations(value: unknown): TranslationMap | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const translations: TranslationMap = {};\n\n for (const [locale, localeValue] of Object.entries(value)) {\n if (!isRecord(localeValue)) {\n continue;\n }\n\n const localeTranslations: Record<string, string> = {};\n for (const [source, translated] of Object.entries(localeValue)) {\n if (typeof translated === 'string') {\n localeTranslations[source] = translated;\n }\n }\n\n translations[locale] = localeTranslations;\n }\n\n return Object.keys(translations).length > 0 ? translations : null;\n}\n\nfunction getCacheFilePath(projectRoot: string, branch: string): string {\n const slug = branch\n .replace(/[^a-zA-Z0-9._-]+/g, '_')\n .replace(/^_+|_+$/g, '')\n .slice(0, 40);\n const branchHash = createHash('sha1').update(branch).digest('hex').slice(0, 12);\n const filename = `${slug || 'branch'}-${branchHash}.json`;\n return join(projectRoot, 'node_modules', '.vocoder', 'cache', 'sync', filename);\n}\n\nfunction readLocalSnapshotCache(params: {\n projectRoot: string;\n branch: string;\n}): TranslationArtifacts | null {\n const candidateBranches = params.branch === 'main'\n ? ['main']\n : [params.branch, 'main'];\n\n for (const candidateBranch of candidateBranches) {\n const cacheFilePath = getCacheFilePath(params.projectRoot, candidateBranch);\n\n if (!existsSync(cacheFilePath)) {\n continue;\n }\n\n try {\n const raw = readFileSync(cacheFilePath, 'utf-8');\n const parsed = JSON.parse(raw) as unknown;\n if (!isRecord(parsed)) {\n continue;\n }\n\n const translations = parseTranslations(parsed.translations);\n if (!translations) {\n continue;\n }\n\n const localeMetadata = parseLocaleMetadata(parsed.localeMetadata);\n\n return {\n source: 'local-cache',\n translations,\n localeMetadata,\n snapshotBatchId:\n typeof parsed.snapshotBatchId === 'string'\n ? parsed.snapshotBatchId\n : undefined,\n completedAt:\n typeof parsed.completedAt === 'string' ? parsed.completedAt : null,\n cacheBranch: candidateBranch,\n };\n } catch {\n continue;\n }\n }\n\n return null;\n}\n\nfunction writeLocalSnapshotCache(params: {\n projectRoot: string;\n branch: string;\n sourceLocale: string;\n targetLocales: string[];\n translations: TranslationMap;\n localeMetadata?: LocaleMetadataMap;\n snapshotBatchId?: string;\n completedAt?: string | null;\n}): string {\n const cacheFilePath = getCacheFilePath(params.projectRoot, params.branch);\n mkdirSync(join(params.projectRoot, 'node_modules', '.vocoder', 'cache', 'sync'), {\n recursive: true,\n });\n\n const payload: LocalSnapshotCache = {\n version: 1,\n branch: params.branch,\n sourceLocale: params.sourceLocale,\n targetLocales: params.targetLocales,\n savedAt: new Date().toISOString(),\n ...(params.snapshotBatchId ? { snapshotBatchId: params.snapshotBatchId } : {}),\n ...(params.completedAt ? { completedAt: params.completedAt } : {}),\n ...(params.localeMetadata ? { localeMetadata: params.localeMetadata } : {}),\n translations: params.translations,\n };\n\n writeFileSync(cacheFilePath, JSON.stringify(payload, null, 2), 'utf-8');\n return cacheFilePath;\n}\n\nfunction resolveEffectiveModeFromPolicy(params: {\n branch: string;\n requestedMode: RequestedSyncMode;\n policy: SyncPolicyConfig;\n}): EffectiveSyncMode {\n const { requestedMode, policy, branch } = params;\n\n let mode: EffectiveSyncMode;\n if (requestedMode === 'auto') {\n const isBlockingBranch = isTargetBranch(branch, policy.blockingBranches);\n mode = isBlockingBranch ? policy.blockingMode : policy.nonBlockingMode;\n } else {\n mode = requestedMode;\n }\n\n return mode;\n}\n\nfunction resolveWaitTimeoutMs(params: {\n requestedMaxWaitMs?: number;\n policyDefaultMaxWaitMs?: number;\n fallbackTimeoutMs: number;\n}): number {\n if (\n typeof params.requestedMaxWaitMs === 'number' &&\n Number.isFinite(params.requestedMaxWaitMs) &&\n params.requestedMaxWaitMs > 0\n ) {\n return Math.floor(params.requestedMaxWaitMs);\n }\n\n if (\n typeof params.policyDefaultMaxWaitMs === 'number' &&\n Number.isFinite(params.policyDefaultMaxWaitMs) &&\n params.policyDefaultMaxWaitMs > 0\n ) {\n return Math.floor(params.policyDefaultMaxWaitMs);\n }\n\n return params.fallbackTimeoutMs;\n}\n\nfunction normalizeTranslations(params: {\n sourceLocale: string;\n targetLocales: string[];\n sourceStrings: string[];\n translations: TranslationMap;\n}): TranslationMap {\n const merged: TranslationMap = {};\n\n for (const [locale, values] of Object.entries(params.translations)) {\n merged[locale] = { ...values };\n }\n\n const expectedLocales = [\n params.sourceLocale,\n ...params.targetLocales.filter((locale) => locale !== params.sourceLocale),\n ];\n\n for (const locale of expectedLocales) {\n if (!merged[locale]) {\n merged[locale] = {};\n }\n }\n\n if (!merged[params.sourceLocale]) {\n merged[params.sourceLocale] = {};\n }\n\n for (const sourceText of params.sourceStrings) {\n if (!(sourceText in merged[params.sourceLocale]!)) {\n merged[params.sourceLocale]![sourceText] = sourceText;\n }\n }\n\n return merged;\n}\n\nexport function getLimitErrorGuidance(limitError: LimitErrorResponse): string[] {\n if (limitError.limitType === 'providers') {\n return [\n 'Provider setup required.',\n 'Add a DeepL API key in Dashboard -> Workspace Settings -> Providers.',\n `Open settings: ${limitError.upgradeUrl}`,\n ];\n }\n\n if (limitError.limitType === 'translation_chars') {\n return [\n 'Monthly translation character limit reached.',\n `Used this month: ${limitError.current.toLocaleString()} chars`,\n `Requested after sync: ${limitError.required.toLocaleString()} chars`,\n `Upgrade plan: ${limitError.upgradeUrl}`,\n ];\n }\n\n if (limitError.limitType === 'source_strings') {\n return [\n 'Active source string limit reached.',\n `Current active strings: ${limitError.current.toLocaleString()}`,\n `Required for this sync: ${limitError.required.toLocaleString()}`,\n `Upgrade plan: ${limitError.upgradeUrl}`,\n ];\n }\n\n return [\n `Plan: ${limitError.planId}`,\n `Current: ${limitError.current}`,\n `Required: ${limitError.required}`,\n `Upgrade: ${limitError.upgradeUrl}`,\n ];\n}\n\nfunction getSyncPolicyErrorGuidance(\n error: NonNullable<VocoderAPIError['syncPolicyError']>,\n): string[] {\n if (error.errorCode === 'BRANCH_NOT_ALLOWED') {\n const lines = ['This branch is not allowed for this project.'];\n if (error.branch) {\n lines.push(`Current branch: ${error.branch}`);\n }\n if (error.targetBranches && error.targetBranches.length > 0) {\n lines.push(`Allowed branches: ${error.targetBranches.join(', ')}`);\n }\n lines.push('Update your project target branches in the dashboard if needed.');\n return lines;\n }\n\n const lines = ['This project is bound to a different repository.'];\n if (error.boundRepoLabel) {\n lines.push(`Bound repository: ${error.boundRepoLabel}`);\n }\n if (error.boundScopePath) {\n lines.push(`Bound scope: ${error.boundScopePath}`);\n }\n lines.push(\n 'Run `vocoder init` from the correct repository or create a separate project.',\n );\n return lines;\n}\n\nfunction mergeContext(\n current: string | undefined,\n incoming: string | undefined,\n): string | undefined {\n if (!incoming) return current;\n if (!current) return incoming;\n if (current === incoming) return current;\n\n const merged = new Set(\n [...current.split(' | '), ...incoming.split(' | ')]\n .map((part) => part.trim())\n .filter(Boolean),\n );\n return Array.from(merged).join(' | ');\n}\n\nfunction buildStringEntries(\n extractedStrings: ExtractedString[],\n): TranslationStringEntry[] {\n const byText = new Map<string, TranslationStringEntry>();\n\n for (const str of extractedStrings) {\n const existing = byText.get(str.text);\n if (!existing) {\n byText.set(str.text, {\n key: str.key,\n text: str.text,\n ...(str.context ? { context: str.context } : {}),\n ...(str.formality ? { formality: str.formality } : {}),\n });\n continue;\n }\n\n existing.context = mergeContext(existing.context, str.context);\n\n if (!existing.formality && str.formality) {\n existing.formality = str.formality;\n } else if (\n existing.formality &&\n str.formality &&\n existing.formality !== str.formality\n ) {\n existing.formality = 'auto';\n }\n\n if (str.key < existing.key) {\n existing.key = str.key;\n }\n }\n\n return Array.from(byText.values());\n}\n\nasync function fetchApiSnapshot(api: VocoderAPI, params: {\n branch: string;\n targetLocales: string[];\n}): Promise<TranslationArtifacts | null> {\n const snapshot = await api.getTranslationSnapshot({\n branch: params.branch,\n targetLocales: params.targetLocales,\n });\n\n if (snapshot.status !== 'FOUND' || !snapshot.translations) {\n return null;\n }\n\n return {\n source: 'api-snapshot',\n translations: snapshot.translations,\n localeMetadata: snapshot.localeMetadata,\n snapshotBatchId: snapshot.snapshotBatchId,\n completedAt: snapshot.completedAt,\n };\n}\n\n/**\n * Main sync command\n */\nexport async function sync(options: TranslateOptions = {}): Promise<number> {\n const startTime = Date.now();\n const projectRoot = process.cwd();\n\n p.intro('Vocoder Sync');\n\n const spinner = p.spinner();\n\n try {\n spinner.start('Detecting branch');\n const branch = detectBranch(options.branch);\n spinner.stop(`Branch: ${chalk.cyan(branch)}`);\n\n spinner.start('Loading project configuration');\n\n const mergedConfig = await getMergedConfig(options, options.verbose);\n const localConfig = {\n apiKey: mergedConfig.apiKey || '',\n apiUrl: mergedConfig.apiUrl || 'https://vocoder.app',\n };\n validateLocalConfig(localConfig);\n\n const api = new VocoderAPI(localConfig);\n const apiConfig = await api.getProjectConfig();\n\n const requestedMode = mergedConfig.mode;\n const waitTimeoutMs = resolveWaitTimeoutMs({\n requestedMaxWaitMs: mergedConfig.maxWaitMs,\n policyDefaultMaxWaitMs: apiConfig.syncPolicy.defaultMaxWaitMs,\n fallbackTimeoutMs: 60_000,\n });\n\n const config: ProjectConfig = {\n ...localConfig,\n ...apiConfig,\n extractionPattern: mergedConfig.extractionPattern,\n excludePattern: mergedConfig.excludePattern,\n timeout: waitTimeoutMs,\n };\n\n spinner.stop('Project configuration loaded');\n\n if (!options.force && !isTargetBranch(branch, config.targetBranches)) {\n p.log.warn(\n `Skipping translations (${chalk.cyan(branch)} is not a target branch)`,\n );\n p.log.info(`Target branches: ${config.targetBranches.join(', ')}`);\n p.log.info('Use --force to translate anyway');\n p.outro('');\n return 0;\n }\n\n const patternsDisplay = Array.isArray(config.extractionPattern)\n ? config.extractionPattern.join(', ')\n : config.extractionPattern;\n\n spinner.start(`Extracting strings from ${patternsDisplay}`);\n const extractor = new StringExtractor();\n const extractedStrings = await extractor.extractFromProject(\n config.extractionPattern,\n projectRoot,\n config.excludePattern,\n );\n\n if (extractedStrings.length === 0) {\n spinner.stop('No translatable strings found');\n p.log.warn('Make sure you are wrapping translatable strings with Vocoder');\n p.outro('');\n return 0;\n }\n\n spinner.stop(\n `Extracted ${chalk.cyan(extractedStrings.length)} strings from ${chalk.cyan(patternsDisplay)}`,\n );\n\n if (options.verbose) {\n const sampleLines = extractedStrings\n .slice(0, 5)\n .map((s: ExtractedString) => ` \"${s.text}\" (${s.file}:${s.line})`);\n if (extractedStrings.length > 5) {\n sampleLines.push(` ... and ${extractedStrings.length - 5} more`);\n }\n p.note(sampleLines.join('\\n'), 'Sample strings');\n }\n\n if (options.dryRun) {\n p.note(\n [\n `Strings: ${extractedStrings.length}`,\n `Branch: ${branch}`,\n `Target locales: ${config.targetLocales.join(', ')}`,\n `Requested mode: ${requestedMode}`,\n `Max wait: ${waitTimeoutMs}ms`,\n `No fallback: ${mergedConfig.noFallback ? 'yes' : 'no'}`,\n ].join('\\n'),\n 'Dry run - would translate',\n );\n p.outro('No API calls made.');\n return 0;\n }\n\n const repoIdentity = resolveGitRepositoryIdentity();\n if (!repoIdentity && options.verbose) {\n p.log.warn(\n 'Could not detect git remote origin. Sync will continue without repo metadata.',\n );\n }\n\n const stringEntries = buildStringEntries(extractedStrings);\n const sourceStrings = stringEntries.map((entry) => entry.text);\n\n if (options.verbose && stringEntries.length !== extractedStrings.length) {\n p.log.info(\n `Deduped ${extractedStrings.length} extracted entries into ${stringEntries.length} unique source strings`,\n );\n }\n\n spinner.start('Submitting strings to Vocoder API');\n\n const batchResponse = await api.submitTranslation(\n branch,\n stringEntries,\n config.targetLocales,\n {\n requestedMode,\n requestedMaxWaitMs: waitTimeoutMs,\n clientRunId: randomUUID(),\n },\n repoIdentity ?? undefined,\n );\n\n spinner.stop(`Submitted to API - Batch ${chalk.cyan(batchResponse.batchId)}`);\n\n const effectiveMode = batchResponse.effectiveMode ??\n resolveEffectiveModeFromPolicy({\n branch,\n requestedMode,\n policy: config.syncPolicy,\n });\n\n if (options.verbose) {\n p.log.info(`Requested mode: ${requestedMode}`);\n p.log.info(`Effective mode: ${effectiveMode}`);\n p.log.info(`Wait timeout: ${waitTimeoutMs}ms`);\n if (batchResponse.queueStatus) {\n p.log.info(`Queue status: ${batchResponse.queueStatus}`);\n }\n }\n\n if (batchResponse.status === 'UP_TO_DATE' && batchResponse.noChanges) {\n p.log.success('No changes detected - strings are up to date');\n }\n\n p.log.info(`New strings: ${chalk.cyan(batchResponse.newStrings)}`);\n\n if (batchResponse.deletedStrings && batchResponse.deletedStrings > 0) {\n p.log.info(\n `Deleted strings: ${chalk.yellow(batchResponse.deletedStrings)} (archived)`,\n );\n }\n\n p.log.info(`Total strings: ${chalk.cyan(batchResponse.totalStrings)}`);\n\n if (batchResponse.newStrings === 0) {\n p.log.success('No new strings - using existing translations');\n } else {\n p.log.info(\n `Syncing to ${config.targetLocales.length} locales (${config.targetLocales.join(', ')})`,\n );\n\n if (batchResponse.estimatedTime) {\n p.log.info(`Estimated time: ~${batchResponse.estimatedTime}s`);\n }\n }\n\n let artifacts: TranslationArtifacts | null = null;\n if (batchResponse.translations) {\n artifacts = {\n source: 'fresh',\n translations: batchResponse.translations,\n };\n }\n\n let waitError: Error | null = null;\n if (!artifacts && (effectiveMode === 'required' || effectiveMode === 'best-effort')) {\n spinner.start(`Waiting for translations (max ${waitTimeoutMs}ms)`);\n\n let lastProgress = 0;\n try {\n const completion = await api.waitForCompletion(\n batchResponse.batchId,\n waitTimeoutMs,\n (progress) => {\n const percent = Math.round(progress * 100);\n if (percent > lastProgress) {\n spinner.message(`Translating... ${percent}%`);\n lastProgress = percent;\n }\n },\n );\n\n artifacts = {\n source: 'fresh',\n translations: completion.translations,\n localeMetadata: completion.localeMetadata,\n };\n spinner.stop('Translations complete');\n } catch (error) {\n spinner.stop('Translation wait incomplete');\n waitError = error instanceof Error ? error : new Error(String(error));\n\n if (effectiveMode === 'required') {\n throw waitError;\n }\n\n p.log.warn(`Best-effort wait ended early: ${waitError.message}`);\n }\n }\n\n if (!artifacts) {\n if (mergedConfig.noFallback) {\n throw new Error(\n 'Fresh translations are not available and fallback is disabled (--no-fallback).',\n );\n }\n\n spinner.start('Loading fallback translations');\n\n const localFallback = readLocalSnapshotCache({\n projectRoot,\n branch,\n });\n\n if (localFallback) {\n artifacts = localFallback;\n const cacheBranchLabel =\n localFallback.cacheBranch && localFallback.cacheBranch !== branch\n ? `${localFallback.cacheBranch} fallback`\n : localFallback.cacheBranch || branch;\n spinner.stop(`Using local cached snapshot (${cacheBranchLabel})`);\n } else {\n try {\n const apiSnapshot = await fetchApiSnapshot(api, {\n branch,\n targetLocales: config.targetLocales,\n });\n\n if (apiSnapshot) {\n artifacts = apiSnapshot;\n spinner.stop('Using latest completed API snapshot');\n } else {\n spinner.stop('No completed API snapshot available');\n }\n } catch (error) {\n spinner.stop('Failed to fetch API snapshot');\n if (options.verbose) {\n const message =\n error instanceof Error ? error.message : 'Unknown snapshot fetch error';\n p.log.warn(`Snapshot fetch error: ${message}`);\n }\n }\n }\n\n if (!artifacts) {\n if (waitError) {\n throw new Error(\n `No fallback snapshot available after wait failure: ${waitError.message}`,\n );\n }\n\n throw new Error(\n 'No fallback snapshot available. Try again shortly or run with --mode required.',\n );\n }\n }\n\n const finalTranslations = normalizeTranslations({\n sourceLocale: config.sourceLocale,\n targetLocales: config.targetLocales,\n sourceStrings,\n translations: artifacts.translations,\n });\n\n try {\n const cachePath = writeLocalSnapshotCache({\n projectRoot,\n branch,\n sourceLocale: config.sourceLocale,\n targetLocales: config.targetLocales,\n translations: finalTranslations,\n localeMetadata: artifacts.localeMetadata,\n snapshotBatchId:\n artifacts.snapshotBatchId ??\n (artifacts.source === 'fresh'\n ? batchResponse.batchId\n : batchResponse.latestCompletedBatchId),\n completedAt:\n artifacts.completedAt ??\n (artifacts.source === 'fresh' ? new Date().toISOString() : null),\n });\n\n if (options.verbose) {\n p.log.info(`Cached snapshot: ${cachePath}`);\n }\n } catch (error) {\n if (options.verbose) {\n const message =\n error instanceof Error ? error.message : 'Unknown cache write error';\n p.log.warn(`Failed to write local snapshot cache: ${message}`);\n }\n }\n\n if (artifacts.source !== 'fresh') {\n const sourceLabel =\n artifacts.source === 'local-cache'\n ? 'local cached snapshot'\n : 'completed API snapshot';\n p.log.warn(\n `Using ${sourceLabel}. New strings may appear after the background sync completes.`,\n );\n }\n\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n p.outro(`Sync complete! (${duration}s)`);\n\n p.log.info('Translations will be injected at build time by @vocoder/unplugin.');\n p.log.info('Just use <VocoderProvider> and <T> — no manual imports needed.');\n return 0;\n } catch (error) {\n spinner.stop();\n\n if (error instanceof VocoderAPIError && error.syncPolicyError) {\n p.log.error(error.syncPolicyError.message);\n const guidance = getSyncPolicyErrorGuidance(error.syncPolicyError);\n for (const line of guidance) {\n p.log.info(line);\n }\n return 1;\n }\n\n if (error instanceof VocoderAPIError && error.limitError) {\n const { limitError } = error;\n p.log.error(limitError.message);\n const guidance = getLimitErrorGuidance(limitError);\n for (const line of guidance) {\n p.log.info(line);\n }\n return 1;\n }\n\n if (error instanceof Error) {\n p.log.error(error.message);\n\n if (error.message.includes('VOCODER_API_KEY')) {\n p.log.warn('VOCODER_API_KEY is only needed for `vocoder sync` (CLI push).');\n p.log.info(' Create one at: https://vocoder.app/dashboard');\n p.log.info(' Then: export VOCODER_API_KEY=\"vc_...\" or add it to .env');\n p.log.info('');\n p.log.info(' Note: If you use @vocoder/unplugin, `vocoder sync` is optional.');\n p.log.info(' Translations are fetched automatically at build time.');\n } else if (error.message.includes('git branch')) {\n p.log.warn('Run from a git repository, or use:');\n p.log.info(' vocoder sync --branch main');\n }\n\n if (options.verbose) {\n p.log.info(`Full error: ${error.stack ?? error}`);\n }\n }\n\n return 1;\n }\n}\n","import { execSync } from 'child_process';\n\nconst REGEX_SPECIAL_CHARS = /[.+?^${}()|[\\]\\\\]/g;\n\nfunction escapeRegexChar(value: string): string {\n return value.replace(REGEX_SPECIAL_CHARS, '\\\\$&');\n}\n\n/**\n * Detects the current git branch from multiple sources in priority order:\n * 1. Explicit --branch flag (passed as parameter)\n * 2. CI environment variables (GitHub Actions, Vercel, Netlify, etc.)\n * 3. Git command (local development)\n *\n * @param override - Optional branch name to override detection\n * @returns The current branch name\n */\nexport function detectBranch(override?: string): string {\n // 1. Explicit override (from --branch flag)\n if (override) {\n return override;\n }\n\n // 2. CI environment variables\n const envBranch =\n process.env.GITHUB_HEAD_REF || // GitHub Actions (PR source branch)\n process.env.GITHUB_REF_NAME || // GitHub Actions (push)\n process.env.VERCEL_GIT_COMMIT_REF || // Vercel\n process.env.BRANCH || // Netlify\n process.env.CF_PAGES_BRANCH || // Cloudflare Pages\n process.env.CI_COMMIT_REF_NAME || // GitLab CI\n process.env.BITBUCKET_BRANCH || // Bitbucket Pipelines\n process.env.CIRCLE_BRANCH || // CircleCI\n process.env.RENDER_GIT_BRANCH; // Render\n\n if (envBranch) {\n return envBranch;\n }\n\n // 3. Git command (local development)\n try {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n }).trim();\n\n return branch;\n } catch (error) {\n throw new Error(\n 'Failed to detect git branch. Make sure you are in a git repository or set the --branch flag.',\n );\n }\n}\n\n/**\n * Checks if the current branch is a target branch that should trigger translations\n *\n * @param currentBranch - The current branch name\n * @param targetBranches - List of branches that should trigger translations\n * @returns True if the branch should trigger translations\n */\nexport function isTargetBranch(\n currentBranch: string,\n targetBranches: string[],\n): boolean {\n return targetBranches.some((pattern) =>\n matchBranchPattern(currentBranch, pattern),\n );\n}\n\nexport function matchBranchPattern(branch: string, pattern: string): boolean {\n const trimmedPattern = pattern.trim();\n if (!trimmedPattern) {\n return false;\n }\n\n let regexSource = '^';\n for (let i = 0; i < trimmedPattern.length; i += 1) {\n const char = trimmedPattern[i];\n if (!char) {\n continue;\n }\n\n if (char === '*') {\n const next = trimmedPattern[i + 1];\n if (next === '*') {\n regexSource += '.*';\n i += 1;\n } else {\n regexSource += '[^/]*';\n }\n continue;\n }\n\n regexSource += escapeRegexChar(char);\n }\n regexSource += '$';\n\n return new RegExp(regexSource).test(branch);\n}\n","import type { LocalConfig, RequestedSyncMode, TranslateOptions } from '../types.js';\n\nimport chalk from 'chalk';\nimport { config as loadEnv } from 'dotenv';\n\n// Load .env file if present\nloadEnv();\n\n/**\n * Validates the local configuration\n */\nexport function validateLocalConfig(config: LocalConfig): void {\n if (!config.apiKey || config.apiKey.length === 0) {\n throw new Error('VOCODER_API_KEY is required. Set it in your .env file.');\n }\n\n if (!config.apiKey.startsWith('vc_')) {\n throw new Error('Invalid API key format. Expected format: vc_...');\n }\n\n if (!config.apiUrl || !config.apiUrl.startsWith('http')) {\n throw new Error('Invalid API URL');\n }\n}\n\n/**\n * Merge configuration from all sources with priority:\n * 1. CLI flags (highest priority)\n * 2. Environment variables\n * 3. Defaults (lowest priority)\n *\n * @param cliOptions - Options from CLI flags\n * @param verbose - Whether to log config sources\n * @returns Merged configuration with source information\n */\nexport async function getMergedConfig(\n cliOptions: TranslateOptions,\n verbose: boolean = false,\n _startDir?: string\n): Promise<{\n extractionPattern: string[];\n excludePattern: string[];\n apiKey?: string;\n apiUrl?: string;\n mode: RequestedSyncMode;\n maxWaitMs?: number;\n noFallback: boolean;\n configSources: {\n extractionPattern: string;\n excludePattern: string;\n apiKey: string;\n apiUrl: string;\n mode: string;\n maxWaitMs: string;\n noFallback: string;\n };\n}> {\n const configSources = {\n extractionPattern: 'default',\n excludePattern: 'default',\n apiKey: 'environment',\n apiUrl: 'default',\n mode: 'default',\n maxWaitMs: 'default',\n noFallback: 'default',\n };\n\n // 1. Defaults\n const defaults = {\n extractionPattern: ['src/**/*.{tsx,jsx,ts,js}'],\n excludePattern: [] as string[],\n apiUrl: 'https://vocoder.app',\n };\n\n // 2. Environment variables\n const envExtractionPattern = process.env.VOCODER_EXTRACTION_PATTERN;\n const envApiUrl = process.env.VOCODER_API_URL;\n const envSyncMode = process.env.VOCODER_SYNC_MODE;\n const envSyncMaxWaitMs = process.env.VOCODER_SYNC_MAX_WAIT_MS;\n const envSyncNoFallback = process.env.VOCODER_SYNC_NO_FALLBACK;\n\n // 3. Merge with priority: CLI > env > defaults\n\n // Extract patterns (include)\n let extractionPattern: string[];\n if (cliOptions.include && cliOptions.include.length > 0) {\n extractionPattern = cliOptions.include;\n configSources.extractionPattern = 'CLI flag';\n } else if (envExtractionPattern) {\n extractionPattern = [envExtractionPattern];\n configSources.extractionPattern = 'environment';\n } else {\n extractionPattern = defaults.extractionPattern;\n }\n\n // Exclude patterns\n let excludePattern: string[];\n if (cliOptions.exclude && cliOptions.exclude.length > 0) {\n excludePattern = cliOptions.exclude;\n configSources.excludePattern = 'CLI flag';\n } else {\n excludePattern = defaults.excludePattern;\n }\n\n // API key (from env)\n let apiKey: string | undefined;\n if (process.env.VOCODER_API_KEY) {\n apiKey = process.env.VOCODER_API_KEY;\n configSources.apiKey = 'environment';\n }\n\n // API URL\n let apiUrl: string;\n if (envApiUrl) {\n apiUrl = envApiUrl;\n configSources.apiUrl = 'environment';\n } else {\n apiUrl = defaults.apiUrl;\n }\n\n const modeCandidates = ['auto', 'required', 'best-effort'] as const;\n let mode: RequestedSyncMode = 'auto';\n if (cliOptions.mode && modeCandidates.includes(cliOptions.mode)) {\n mode = cliOptions.mode;\n configSources.mode = 'CLI flag';\n } else if (envSyncMode && modeCandidates.includes(envSyncMode as RequestedSyncMode)) {\n mode = envSyncMode as RequestedSyncMode;\n configSources.mode = 'environment';\n }\n\n let maxWaitMs: number | undefined;\n if (typeof cliOptions.maxWaitMs === 'number' && Number.isFinite(cliOptions.maxWaitMs) && cliOptions.maxWaitMs > 0) {\n maxWaitMs = Math.floor(cliOptions.maxWaitMs);\n configSources.maxWaitMs = 'CLI flag';\n } else if (envSyncMaxWaitMs) {\n const parsed = Number.parseInt(envSyncMaxWaitMs, 10);\n if (Number.isFinite(parsed) && parsed > 0) {\n maxWaitMs = parsed;\n configSources.maxWaitMs = 'environment';\n }\n }\n\n let noFallback = false;\n if (typeof cliOptions.noFallback === 'boolean') {\n noFallback = cliOptions.noFallback;\n configSources.noFallback = 'CLI flag';\n } else if (envSyncNoFallback) {\n noFallback = ['1', 'true', 'yes', 'on'].includes(envSyncNoFallback.toLowerCase());\n configSources.noFallback = 'environment';\n }\n\n // Log config sources in verbose mode\n if (verbose) {\n console.log(chalk.dim('\\n Configuration sources:'));\n console.log(chalk.dim(` Include patterns: ${configSources.extractionPattern}`));\n if (excludePattern.length > 0) {\n console.log(chalk.dim(` Exclude patterns: ${configSources.excludePattern}`));\n }\n console.log(chalk.dim(` API key: ${configSources.apiKey}`));\n console.log(chalk.dim(` API URL: ${configSources.apiUrl}\\n`));\n console.log(chalk.dim(` Sync mode: ${configSources.mode}`));\n if (maxWaitMs) {\n console.log(chalk.dim(` Max wait: ${configSources.maxWaitMs}`));\n }\n console.log(chalk.dim(` No fallback: ${configSources.noFallback}\\n`));\n }\n\n return {\n extractionPattern,\n excludePattern,\n apiKey,\n apiUrl,\n mode,\n maxWaitMs,\n noFallback,\n configSources,\n };\n}\n","import * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport { VocoderAPI } from '../utils/api.js';\nimport { readAuthData } from '../utils/auth-store.js';\n\nexport interface WhoamiOptions {\n apiUrl?: string;\n}\n\nexport async function whoami(options: WhoamiOptions = {}): Promise<number> {\n const stored = readAuthData();\n\n if (!stored) {\n p.log.info('Not logged in. Run `vocoder init` to authenticate.');\n return 1;\n }\n\n const apiUrl = options.apiUrl ?? stored.apiUrl ?? 'https://vocoder.app';\n const api = new VocoderAPI({ apiUrl, apiKey: '' });\n\n try {\n const info = await api.getCliUserInfo(stored.token);\n p.log.info(`Logged in as ${chalk.bold(info.email)}`);\n if (info.name) {\n p.log.info(`Name: ${info.name}`);\n }\n p.log.info(`API: ${apiUrl}`);\n return 0;\n } catch {\n p.log.error('Stored credentials are invalid or expired. Run `vocoder init` to re-authenticate.');\n return 1;\n }\n}\n"],"mappings":"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","names":["p","URL","resolve","resolve","init","resolve","chalk","execSync","p","chalk","isCancel","p","chalk","Prompt","isCancel","chalk","execSync","S_BAR","S_BAR_END","S_ACTIVE","S_SUBMIT","S_CANCEL","S_ERROR","noColor","dim","cyan","grn","ylw","red","bld","symbol","MAX_VISIBLE","buildList","MAX_VISIBLE","grn","dim","bld","cyan","S_BAR","ylw","Prompt","symbol","S_BAR_END","isCancel","chalk","p","chalk","spawn","resolve","tryOpenBrowser","spawn","chalk","execSync","p","p","execSync","mkdirSync","readFileSync","writeFileSync","chalk","loadEnv","chalk","join","join","readFileSync","mkdirSync","writeFileSync","lines","spinner","chalk","p","chalk","chalk"]}
|