llm-usage-metrics 0.3.5 → 0.3.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 +21 -1
- package/dist/index.js +1050 -112
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/runtime-overrides.ts","../src/update/update-cache-repository.ts","../src/utils/as-record.ts","../src/utils/cache-root-dir.ts","../src/utils/compare-by-code-point.ts","../src/update/version-utils.ts","../src/update/update-install-runner.ts","../src/update/update-notifier.ts","../src/cli/create-cli.ts","../src/sources/codex/codex-source-adapter.ts","../src/domain/normalization.ts","../src/domain/usage-event.ts","../src/utils/discover-files.ts","../src/utils/discover-jsonl-files.ts","../src/utils/fs-helpers.ts","../src/utils/read-jsonl-objects.ts","../src/sources/parsing-utils.ts","../src/sources/droid/droid-source-adapter.ts","../src/sources/parse-diagnostics.ts","../src/sources/gemini/gemini-source-adapter.ts","../src/sources/opencode/opencode-db-path-resolver.ts","../src/sources/opencode/node-sqlite-loader.ts","../src/sources/opencode/sqlite-warning-suppression.ts","../src/sources/opencode/opencode-row-parser.ts","../src/sources/opencode/opencode-sqlite-errors.ts","../src/sources/opencode/opencode-retry-policy.ts","../src/sources/opencode/opencode-sqlite-query.ts","../src/sources/opencode/opencode-source-adapter.ts","../src/sources/pi/pi-source-adapter.ts","../src/sources/create-default-adapters.ts","../src/utils/time-buckets.ts","../src/aggregate/aggregate-usage.ts","../src/efficiency/efficiency-row.ts","../src/efficiency/aggregate-efficiency.ts","../src/efficiency/git-outcome-collector.ts","../src/efficiency/repo-attribution.ts","../src/config/env-var-display.ts","../src/cli/build-usage-data-diagnostics.ts","../src/cli/build-usage-data-inputs.ts","../src/cli/build-usage-data-parsing.ts","../src/cli/normalize-skipped-row-reasons.ts","../src/cli/parse-file-cache.ts","../src/pricing/cost-engine.ts","../src/pricing/litellm-pricing-fetcher.ts","../src/pricing/litellm-model-map.json","../src/cli/build-usage-data-pricing.ts","../src/cli/build-usage-data.ts","../src/cli/build-efficiency-data.ts","../src/utils/logger.ts","../src/cli/emit-diagnostics.ts","../src/cli/emit-env-var-overrides.ts","../src/render/table-text-layout.ts","../src/cli/terminal-overflow-warning.ts","../src/render/render-efficiency-report.ts","../src/render/report-header.ts","../src/render/efficiency-row-cells.ts","../src/render/terminal-table.ts","../src/render/terminal-style-policy.ts","../src/render/row-cells.ts","../src/render/unicode-table.ts","../src/cli/run-efficiency-report.ts","../src/render/markdown-table.ts","../src/render/render-usage-report.ts","../src/cli/run-usage-report.ts","../src/cli/package-metadata.ts","../src/cli/index.ts"],"sourcesContent":["const MINUTE_MS = 60_000;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nconst UPDATE_CACHE_TTL_DEFAULT_MS = HOUR_MS;\nconst UPDATE_FETCH_TIMEOUT_DEFAULT_MS = 1_000;\nconst PRICING_CACHE_TTL_DEFAULT_MS = DAY_MS;\nconst PRICING_FETCH_TIMEOUT_DEFAULT_MS = 4_000;\nconst PARSE_MAX_PARALLEL_DEFAULT = 8;\nconst PARSE_CACHE_ENABLED_DEFAULT = true;\nconst PARSE_CACHE_TTL_DEFAULT_MS = 7 * DAY_MS;\nconst PARSE_CACHE_MAX_ENTRIES_DEFAULT = 2_000;\nconst PARSE_CACHE_MAX_BYTES_DEFAULT = 32 * 1024 * 1024;\n\nfunction resolveBoundedEnvInteger(\n envValue: string | undefined,\n defaults: {\n fallback: number;\n min: number;\n max: number;\n },\n): number {\n if (envValue === undefined) {\n return defaults.fallback;\n }\n\n const trimmedValue = envValue.trim();\n\n if (trimmedValue.length === 0) {\n return defaults.fallback;\n }\n\n if (!/^[+-]?\\d+$/u.test(trimmedValue)) {\n return defaults.fallback;\n }\n\n const parsedValue = Number.parseInt(trimmedValue, 10);\n\n if (parsedValue < defaults.min) {\n return defaults.min;\n }\n\n if (parsedValue > defaults.max) {\n return defaults.max;\n }\n\n return parsedValue;\n}\n\nfunction resolveEnvBoolean(envValue: string | undefined, fallback: boolean): boolean {\n if (envValue === undefined) {\n return fallback;\n }\n\n const normalizedValue = envValue.trim().toLowerCase();\n\n if (normalizedValue.length === 0) {\n return fallback;\n }\n\n if (['1', 'true', 'yes', 'on'].includes(normalizedValue)) {\n return true;\n }\n\n if (['0', 'false', 'no', 'off'].includes(normalizedValue)) {\n return false;\n }\n\n return fallback;\n}\n\nexport type UpdateNotifierRuntimeConfig = {\n cacheTtlMs: number;\n fetchTimeoutMs: number;\n};\n\nexport type PricingFetcherRuntimeConfig = {\n cacheTtlMs: number;\n fetchTimeoutMs: number;\n};\n\nexport type ParsingRuntimeConfig = {\n maxParallelFileParsing: number;\n parseCacheEnabled: boolean;\n parseCacheTtlMs: number;\n parseCacheMaxEntries: number;\n parseCacheMaxBytes: number;\n};\n\nexport function getUpdateNotifierRuntimeConfig(\n env: NodeJS.ProcessEnv = process.env,\n): UpdateNotifierRuntimeConfig {\n return {\n cacheTtlMs: resolveBoundedEnvInteger(env.LLM_USAGE_UPDATE_CACHE_TTL_MS, {\n fallback: UPDATE_CACHE_TTL_DEFAULT_MS,\n min: 0,\n max: 30 * DAY_MS,\n }),\n fetchTimeoutMs: resolveBoundedEnvInteger(env.LLM_USAGE_UPDATE_FETCH_TIMEOUT_MS, {\n fallback: UPDATE_FETCH_TIMEOUT_DEFAULT_MS,\n min: 200,\n max: 30_000,\n }),\n };\n}\n\nexport function getPricingFetcherRuntimeConfig(\n env: NodeJS.ProcessEnv = process.env,\n): PricingFetcherRuntimeConfig {\n return {\n cacheTtlMs: resolveBoundedEnvInteger(env.LLM_USAGE_PRICING_CACHE_TTL_MS, {\n fallback: PRICING_CACHE_TTL_DEFAULT_MS,\n min: MINUTE_MS,\n max: 30 * DAY_MS,\n }),\n fetchTimeoutMs: resolveBoundedEnvInteger(env.LLM_USAGE_PRICING_FETCH_TIMEOUT_MS, {\n fallback: PRICING_FETCH_TIMEOUT_DEFAULT_MS,\n min: 200,\n max: 30_000,\n }),\n };\n}\n\nexport function getParsingRuntimeConfig(\n env: NodeJS.ProcessEnv = process.env,\n): ParsingRuntimeConfig {\n return {\n maxParallelFileParsing: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_MAX_PARALLEL, {\n fallback: PARSE_MAX_PARALLEL_DEFAULT,\n min: 1,\n max: 64,\n }),\n parseCacheEnabled: resolveEnvBoolean(\n env.LLM_USAGE_PARSE_CACHE_ENABLED,\n PARSE_CACHE_ENABLED_DEFAULT,\n ),\n parseCacheTtlMs: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_CACHE_TTL_MS, {\n fallback: PARSE_CACHE_TTL_DEFAULT_MS,\n min: HOUR_MS,\n max: 30 * DAY_MS,\n }),\n parseCacheMaxEntries: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_CACHE_MAX_ENTRIES, {\n fallback: PARSE_CACHE_MAX_ENTRIES_DEFAULT,\n min: 100,\n max: 20_000,\n }),\n parseCacheMaxBytes: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_CACHE_MAX_BYTES, {\n fallback: PARSE_CACHE_MAX_BYTES_DEFAULT,\n min: 1024 * 1024,\n max: 512 * 1024 * 1024,\n }),\n };\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { asRecord } from '../utils/as-record.js';\nimport { getUserCacheRootDir } from '../utils/cache-root-dir.js';\nimport { parseVersion } from './version-utils.js';\n\nconst DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000;\nconst DEFAULT_FETCH_TIMEOUT_MS = 1000;\nconst DEFAULT_FETCH_RETRY_COUNT = 2;\nconst DEFAULT_FETCH_RETRY_DELAY_MS = 200;\n\nexport const UPDATE_CHECK_CACHE_SCOPE_ENV_VAR = 'LLM_USAGE_UPDATE_CACHE_SCOPE';\nexport const UPDATE_CHECK_CACHE_SESSION_KEY_ENV_VAR = 'LLM_USAGE_UPDATE_CACHE_SESSION_KEY';\n\nexport type UpdateCheckCachePayload = {\n checkedAt: number;\n latestVersion: string;\n};\n\nexport type ResolveLatestVersionOptions = {\n packageName: string;\n cacheFilePath?: string;\n cacheTtlMs?: number;\n fetchTimeoutMs?: number;\n fetchRetryCount?: number;\n fetchRetryDelayMs?: number;\n fetchImpl?: typeof fetch;\n now?: () => number;\n sleep?: (delayMs: number) => Promise<void>;\n};\n\nclass RetryableFetchError extends Error {\n public constructor(message: string) {\n super(message);\n this.name = 'RetryableFetchError';\n }\n}\n\nfunction isRetryableHttpStatus(status: number): boolean {\n return [408, 425, 429, 500, 502, 503, 504].includes(status);\n}\n\nfunction isRetryableFetchFailure(error: unknown): boolean {\n if (error instanceof RetryableFetchError) {\n return true;\n }\n\n if (!(error instanceof Error)) {\n return false;\n }\n\n if (error.name === 'AbortError' || error.name === 'TimeoutError') {\n return true;\n }\n\n if (error instanceof TypeError) {\n return true;\n }\n\n return /timeout|timed out|network|econn|enotfound|eai_again/iu.test(error.message);\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n}\n\nexport function getDefaultUpdateCheckCachePath(): string {\n return path.join(getUserCacheRootDir(), 'llm-usage-metrics', 'update-check.json');\n}\n\nfunction sanitizeCachePathFragment(value: string): string {\n return value.replace(/[^A-Za-z0-9._-]/gu, '_');\n}\n\nfunction toCacheSessionKey(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const trimmedValue = value.trim();\n\n if (!trimmedValue) {\n return undefined;\n }\n\n const sanitizedValue = sanitizeCachePathFragment(trimmedValue);\n return sanitizedValue || undefined;\n}\n\nexport function getSessionScopedCachePath(\n baseCacheFilePath: string,\n env: NodeJS.ProcessEnv,\n options: { parentPid?: number } = {},\n): string {\n const cacheScope = env[UPDATE_CHECK_CACHE_SCOPE_ENV_VAR]?.trim().toLowerCase();\n\n if (cacheScope !== 'session') {\n return baseCacheFilePath;\n }\n\n const parentPid = options.parentPid ?? process.ppid;\n const sessionKey =\n toCacheSessionKey(env[UPDATE_CHECK_CACHE_SESSION_KEY_ENV_VAR]) ?? `ppid-${parentPid}`;\n\n const parsedPath = path.parse(baseCacheFilePath);\n return path.join(parsedPath.dir, `${parsedPath.name}.${sessionKey}${parsedPath.ext}`);\n}\n\nfunction toNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value !== 'number') {\n return undefined;\n }\n\n if (!Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return value;\n}\n\nfunction isValidVersion(value: string): boolean {\n return parseVersion(value) !== undefined;\n}\n\nexport function isCacheFresh(\n payload: Pick<UpdateCheckCachePayload, 'checkedAt'>,\n cacheTtlMs: number,\n now: () => number,\n): boolean {\n const nowTimestamp = now();\n\n if (payload.checkedAt > nowTimestamp) {\n return false;\n }\n\n return nowTimestamp - payload.checkedAt <= cacheTtlMs;\n}\n\nexport async function readUpdateCheckCachePayload(\n cacheFilePath: string,\n): Promise<UpdateCheckCachePayload | undefined> {\n let content: string;\n\n try {\n content = await readFile(cacheFilePath, 'utf8');\n } catch {\n return undefined;\n }\n\n let parsedContent: unknown;\n\n try {\n parsedContent = JSON.parse(content);\n } catch {\n return undefined;\n }\n\n const record = asRecord(parsedContent);\n\n if (!record) {\n return undefined;\n }\n\n const checkedAt = toNonNegativeNumber(record.checkedAt);\n const latestVersion = typeof record.latestVersion === 'string' ? record.latestVersion.trim() : '';\n\n if (checkedAt === undefined || !latestVersion || !isValidVersion(latestVersion)) {\n return undefined;\n }\n\n return {\n checkedAt,\n latestVersion,\n };\n}\n\nexport async function writeUpdateCheckCachePayload(\n cacheFilePath: string,\n payload: UpdateCheckCachePayload,\n): Promise<void> {\n await mkdir(path.dirname(cacheFilePath), { recursive: true });\n await writeFile(cacheFilePath, JSON.stringify(payload), 'utf8');\n}\n\nasync function fetchLatestVersion(\n packageName: string,\n fetchImpl: typeof fetch,\n fetchTimeoutMs: number,\n): Promise<string | undefined> {\n const response = await fetchImpl(\n `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`,\n {\n signal: AbortSignal.timeout(fetchTimeoutMs),\n },\n );\n\n if (!response.ok) {\n if (isRetryableHttpStatus(response.status)) {\n throw new RetryableFetchError(\n `Retryable update-check response status: HTTP ${response.status}`,\n );\n }\n\n return undefined;\n }\n\n let payload: unknown;\n\n try {\n payload = (await response.json()) as unknown;\n } catch {\n return undefined;\n }\n\n const payloadRecord = asRecord(payload);\n\n if (!payloadRecord) {\n return undefined;\n }\n\n const version = typeof payloadRecord.version === 'string' ? payloadRecord.version.trim() : '';\n\n if (!version || !isValidVersion(version)) {\n return undefined;\n }\n\n return version;\n}\n\nasync function fetchLatestVersionWithRetry(\n packageName: string,\n fetchImpl: typeof fetch,\n fetchTimeoutMs: number,\n fetchRetryCount: number,\n fetchRetryDelayMs: number,\n sleepFn: (delayMs: number) => Promise<void>,\n): Promise<string | undefined> {\n const safeRetryCount =\n Number.isFinite(fetchRetryCount) && fetchRetryCount >= 0\n ? Math.trunc(fetchRetryCount)\n : DEFAULT_FETCH_RETRY_COUNT;\n const safeRetryDelayMs =\n Number.isFinite(fetchRetryDelayMs) && fetchRetryDelayMs > 0\n ? Math.trunc(fetchRetryDelayMs)\n : DEFAULT_FETCH_RETRY_DELAY_MS;\n const maxAttempts = safeRetryCount + 1;\n\n for (let attemptIndex = 0; attemptIndex < maxAttempts; attemptIndex += 1) {\n try {\n return await fetchLatestVersion(packageName, fetchImpl, fetchTimeoutMs);\n } catch (error) {\n const shouldRetry = isRetryableFetchFailure(error) && attemptIndex < maxAttempts - 1;\n\n if (!shouldRetry) {\n throw error;\n }\n }\n\n const backoffDelay = safeRetryDelayMs * 2 ** attemptIndex;\n await sleepFn(backoffDelay);\n }\n\n return undefined;\n}\n\nexport async function resolveLatestVersion(\n options: ResolveLatestVersionOptions,\n): Promise<string | undefined> {\n const cacheFilePath = options.cacheFilePath ?? getDefaultUpdateCheckCachePath();\n const cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n const fetchTimeoutMs = options.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;\n const fetchRetryCount = options.fetchRetryCount ?? DEFAULT_FETCH_RETRY_COUNT;\n const fetchRetryDelayMs = options.fetchRetryDelayMs ?? DEFAULT_FETCH_RETRY_DELAY_MS;\n const fetchImpl = options.fetchImpl ?? fetch;\n const now = options.now ?? Date.now;\n const sleepFn = options.sleep ?? sleep;\n\n const cachePayload = await readUpdateCheckCachePayload(cacheFilePath);\n\n if (cachePayload && isCacheFresh(cachePayload, cacheTtlMs, now)) {\n return cachePayload.latestVersion;\n }\n\n try {\n const latestVersion = await fetchLatestVersionWithRetry(\n options.packageName,\n fetchImpl,\n fetchTimeoutMs,\n fetchRetryCount,\n fetchRetryDelayMs,\n sleepFn,\n );\n\n if (!latestVersion) {\n return cachePayload?.latestVersion;\n }\n\n try {\n await writeUpdateCheckCachePayload(cacheFilePath, {\n checkedAt: now(),\n latestVersion,\n });\n } catch {\n // Cache writes are best-effort.\n }\n\n return latestVersion;\n } catch {\n return cachePayload?.latestVersion;\n }\n}\n","function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n\n return value;\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nexport function getUserCacheRootDir(\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n homedir: string = os.homedir(),\n): string {\n const xdgCacheDir = env.XDG_CACHE_HOME;\n\n if (xdgCacheDir) {\n return xdgCacheDir;\n }\n\n if (platform === 'win32') {\n const localAppData = env.LOCALAPPDATA;\n\n if (localAppData) {\n return localAppData;\n }\n }\n\n return path.join(homedir, '.cache');\n}\n","export function compareByCodePoint(left: string, right: string): number {\n if (left === right) {\n return 0;\n }\n\n const leftIterator = left[Symbol.iterator]();\n const rightIterator = right[Symbol.iterator]();\n\n for (;;) {\n const leftStep = leftIterator.next();\n const rightStep = rightIterator.next();\n\n if (leftStep.done && rightStep.done) {\n return 0;\n }\n\n if (leftStep.done) {\n return -1;\n }\n\n if (rightStep.done) {\n return 1;\n }\n\n const leftCodePoint = leftStep.value.codePointAt(0) ?? 0;\n const rightCodePoint = rightStep.value.codePointAt(0) ?? 0;\n\n if (leftCodePoint !== rightCodePoint) {\n return leftCodePoint < rightCodePoint ? -1 : 1;\n }\n }\n}\n","import { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\nexport type ParsedVersion = {\n major: number;\n minor: number;\n patch: number;\n prerelease: string[];\n};\n\nexport function parseVersion(value: string): ParsedVersion | undefined {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/u.exec(\n value.trim(),\n );\n\n if (!match) {\n return undefined;\n }\n\n const major = Number(match[1]);\n const minor = Number(match[2]);\n const patch = Number(match[3]);\n\n if (![major, minor, patch].every((part) => Number.isSafeInteger(part))) {\n return undefined;\n }\n\n const prerelease = match[4] ? match[4].split('.') : [];\n\n return {\n major,\n minor,\n patch,\n prerelease,\n };\n}\n\nfunction isNumericIdentifier(value: string): boolean {\n return /^\\d+$/u.test(value);\n}\n\nfunction comparePrereleaseIdentifiers(left: string, right: string): number {\n const leftIsNumeric = isNumericIdentifier(left);\n const rightIsNumeric = isNumericIdentifier(right);\n\n if (leftIsNumeric && rightIsNumeric) {\n return Number(left) - Number(right);\n }\n\n if (leftIsNumeric && !rightIsNumeric) {\n return -1;\n }\n\n if (!leftIsNumeric && rightIsNumeric) {\n return 1;\n }\n\n return compareByCodePoint(left, right);\n}\n\nfunction isPrerelease(version: string): boolean {\n const parsed = parseVersion(version);\n return Boolean(parsed && parsed.prerelease.length > 0);\n}\n\nexport function compareVersions(left: string, right: string): number {\n const parsedLeft = parseVersion(left);\n const parsedRight = parseVersion(right);\n\n if (!parsedLeft || !parsedRight) {\n return 0;\n }\n\n if (parsedLeft.major !== parsedRight.major) {\n return parsedLeft.major - parsedRight.major;\n }\n\n if (parsedLeft.minor !== parsedRight.minor) {\n return parsedLeft.minor - parsedRight.minor;\n }\n\n if (parsedLeft.patch !== parsedRight.patch) {\n return parsedLeft.patch - parsedRight.patch;\n }\n\n const leftPrerelease = parsedLeft.prerelease;\n const rightPrerelease = parsedRight.prerelease;\n\n if (leftPrerelease.length === 0 && rightPrerelease.length === 0) {\n return 0;\n }\n\n if (leftPrerelease.length === 0) {\n return 1;\n }\n\n if (rightPrerelease.length === 0) {\n return -1;\n }\n\n const comparableLength = Math.min(leftPrerelease.length, rightPrerelease.length);\n\n for (let index = 0; index < comparableLength; index += 1) {\n const comparison = comparePrereleaseIdentifiers(leftPrerelease[index], rightPrerelease[index]);\n\n if (comparison !== 0) {\n return comparison;\n }\n }\n\n return leftPrerelease.length - rightPrerelease.length;\n}\n\nexport function shouldOfferUpdate(currentVersion: string, latestVersion: string): boolean {\n if (isPrerelease(latestVersion) && !isPrerelease(currentVersion)) {\n return false;\n }\n\n return compareVersions(latestVersion, currentVersion) > 0;\n}\n","import { spawn } from 'node:child_process';\nimport { createInterface } from 'node:readline/promises';\n\ntype CommandRunnerOptions = {\n env?: NodeJS.ProcessEnv;\n stdio?: 'inherit';\n};\n\nexport type CommandRunner = (\n command: string,\n args: string[],\n options?: CommandRunnerOptions,\n) => Promise<number>;\n\nexport type ConfirmInstall = (prompt: string) => Promise<boolean>;\nexport type Notify = (message: string) => void;\n\nexport type UpdateInstallRestartResult = {\n continueExecution: boolean;\n exitCode?: number;\n};\n\nexport type RunInteractiveInstallAndRestartOptions = {\n packageName: string;\n updateMessage: string;\n env: NodeJS.ProcessEnv;\n argv: string[];\n execPath?: string;\n skipUpdateCheckEnvVar: string;\n confirmInstall?: ConfirmInstall;\n runCommand?: CommandRunner;\n notify?: Notify;\n};\n\nexport function isInteractiveSession(options: {\n env: NodeJS.ProcessEnv;\n stdinIsTTY: boolean;\n stdoutIsTTY: boolean;\n}): boolean {\n const ciValue = options.env.CI;\n const normalizedCiValue = ciValue?.trim().toLowerCase();\n const ciEnabled =\n normalizedCiValue !== undefined &&\n normalizedCiValue.length > 0 &&\n !['0', 'false', 'no', 'off'].includes(normalizedCiValue);\n\n return options.stdinIsTTY && options.stdoutIsTTY && !ciEnabled;\n}\n\nexport async function defaultConfirmInstall(prompt: string): Promise<boolean> {\n const readline = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n try {\n const answer = await readline.question(prompt);\n return ['y', 'yes'].includes(answer.trim().toLowerCase());\n } finally {\n readline.close();\n }\n}\n\nexport async function runCommandWithSpawn(\n command: string,\n args: string[],\n options: CommandRunnerOptions = {},\n): Promise<number> {\n return await new Promise<number>((resolve, reject) => {\n const child = spawn(command, args, {\n env: options.env,\n stdio: options.stdio ?? 'inherit',\n });\n\n child.once('error', (error) => {\n reject(error);\n });\n\n child.once('close', (exitCode) => {\n resolve(exitCode ?? 1);\n });\n });\n}\n\nexport function defaultNotify(message: string): void {\n console.error(message);\n}\n\nexport async function runInteractiveInstallAndRestart(\n options: RunInteractiveInstallAndRestartOptions,\n): Promise<UpdateInstallRestartResult> {\n const confirmInstall = options.confirmInstall ?? defaultConfirmInstall;\n const installAccepted = await confirmInstall(`${options.updateMessage} Install now? [y/N] `);\n\n if (!installAccepted) {\n return { continueExecution: true };\n }\n\n const runCommand = options.runCommand ?? runCommandWithSpawn;\n const notify = options.notify ?? defaultNotify;\n const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';\n const installExitCode = await runCommand(\n npmCommand,\n ['install', '-g', `${options.packageName}@latest`],\n {\n env: options.env,\n stdio: 'inherit',\n },\n );\n\n if (installExitCode !== 0) {\n notify(`Failed to install ${options.packageName}@latest (exit code ${installExitCode}).`);\n return { continueExecution: true };\n }\n\n const restartArgs = options.argv.slice(1);\n const restartEnv: NodeJS.ProcessEnv = {\n ...options.env,\n [options.skipUpdateCheckEnvVar]: '1',\n };\n\n const restartExitCode = await runCommand(options.execPath ?? process.execPath, restartArgs, {\n env: restartEnv,\n stdio: 'inherit',\n });\n\n return {\n continueExecution: false,\n exitCode: restartExitCode,\n };\n}\n","import {\n getDefaultUpdateCheckCachePath,\n getSessionScopedCachePath,\n resolveLatestVersion,\n type ResolveLatestVersionOptions,\n} from './update-cache-repository.js';\nimport {\n isInteractiveSession,\n runInteractiveInstallAndRestart,\n type CommandRunner,\n type ConfirmInstall,\n type Notify,\n} from './update-install-runner.js';\nimport { shouldOfferUpdate } from './version-utils.js';\n\nexport {\n UPDATE_CHECK_CACHE_SCOPE_ENV_VAR,\n UPDATE_CHECK_CACHE_SESSION_KEY_ENV_VAR,\n getDefaultUpdateCheckCachePath,\n getSessionScopedCachePath,\n isCacheFresh,\n readUpdateCheckCachePayload,\n resolveLatestVersion,\n writeUpdateCheckCachePayload,\n type ResolveLatestVersionOptions,\n type UpdateCheckCachePayload,\n} from './update-cache-repository.js';\nexport {\n compareVersions,\n parseVersion,\n shouldOfferUpdate,\n type ParsedVersion,\n} from './version-utils.js';\nexport {\n defaultConfirmInstall,\n defaultNotify,\n isInteractiveSession,\n runCommandWithSpawn,\n runInteractiveInstallAndRestart,\n type CommandRunner,\n type ConfirmInstall,\n type Notify,\n type RunInteractiveInstallAndRestartOptions,\n type UpdateInstallRestartResult,\n} from './update-install-runner.js';\n\nexport const UPDATE_CHECK_SKIP_ENV_VAR = 'LLM_USAGE_SKIP_UPDATE_CHECK';\n\nexport type UpdateNotifierOptions = {\n packageName: string;\n currentVersion: string;\n cacheFilePath?: string;\n cacheTtlMs?: number;\n fetchTimeoutMs?: number;\n fetchImpl?: typeof fetch;\n now?: () => number;\n env?: NodeJS.ProcessEnv;\n argv?: string[];\n execPath?: string;\n stdinIsTTY?: boolean;\n stdoutIsTTY?: boolean;\n confirmInstall?: ConfirmInstall;\n runCommand?: CommandRunner;\n notify?: Notify;\n};\n\nexport type UpdateNotifierResult = {\n continueExecution: boolean;\n exitCode?: number;\n};\n\nfunction isTruthyEnvFlag(value: string | undefined): boolean {\n if (value === undefined) {\n return false;\n }\n\n const normalizedValue = value.trim().toLowerCase();\n\n if (normalizedValue.length === 0) {\n return false;\n }\n\n return ['1', 'true', 'yes', 'on'].includes(normalizedValue);\n}\n\nexport function shouldSkipUpdateCheckForArgv(argv: string[]): boolean {\n const executableArgs = argv.slice(2);\n const commandNames = new Set(['daily', 'weekly', 'monthly', 'efficiency', 'help', 'version']);\n\n if (executableArgs.length === 0) {\n return false;\n }\n\n if (executableArgs.some((arg) => ['-h', '--help', '-V', '--version'].includes(arg))) {\n return true;\n }\n\n const firstRecognizedCommand = executableArgs.find((arg) => commandNames.has(arg));\n\n return firstRecognizedCommand === 'help' || firstRecognizedCommand === 'version';\n}\n\nexport function isLikelyNpxExecution(argv: string[], env: NodeJS.ProcessEnv): boolean {\n const executablePath = argv[1] ?? '';\n\n if (/[\\\\/]_npx[\\\\/]/u.test(executablePath)) {\n return true;\n }\n\n const npmExecPath = env.npm_execpath ?? '';\n\n if (/npx(?:-cli)?\\.js$/u.test(npmExecPath) || /[\\\\/]npx[\\\\/]/u.test(npmExecPath)) {\n return true;\n }\n\n const npmCommand = env.npm_command ?? '';\n\n return npmCommand === 'exec' || npmCommand === 'npx';\n}\n\nexport function isLikelySourceExecution(argv: string[]): boolean {\n const executablePath = argv[1] ?? '';\n return /\\.[cm]?tsx?$/iu.test(executablePath);\n}\n\nfunction toResolveLatestVersionOptions(\n options: UpdateNotifierOptions,\n env: NodeJS.ProcessEnv,\n): ResolveLatestVersionOptions {\n const baseCacheFilePath = options.cacheFilePath ?? getDefaultUpdateCheckCachePath();\n const scopedCacheFilePath = getSessionScopedCachePath(baseCacheFilePath, env);\n\n return {\n packageName: options.packageName,\n cacheFilePath: scopedCacheFilePath,\n cacheTtlMs: options.cacheTtlMs,\n fetchTimeoutMs: options.fetchTimeoutMs,\n fetchImpl: options.fetchImpl,\n now: options.now,\n };\n}\n\nexport async function checkForUpdatesAndMaybeRestart(\n options: UpdateNotifierOptions,\n): Promise<UpdateNotifierResult> {\n const env = options.env ?? process.env;\n const argv = options.argv ?? process.argv;\n\n if (isTruthyEnvFlag(env[UPDATE_CHECK_SKIP_ENV_VAR])) {\n return { continueExecution: true };\n }\n\n if (shouldSkipUpdateCheckForArgv(argv)) {\n return { continueExecution: true };\n }\n\n if (isLikelyNpxExecution(argv, env)) {\n return { continueExecution: true };\n }\n\n if (isLikelySourceExecution(argv)) {\n return { continueExecution: true };\n }\n\n try {\n const latestVersion = await resolveLatestVersion(toResolveLatestVersionOptions(options, env));\n\n if (!latestVersion || !shouldOfferUpdate(options.currentVersion, latestVersion)) {\n return { continueExecution: true };\n }\n\n const updateMessage = `Update available for ${options.packageName}: ${options.currentVersion} → ${latestVersion}.`;\n const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY;\n const stdoutIsTTY = options.stdoutIsTTY ?? process.stdout.isTTY;\n\n if (!isInteractiveSession({ env, stdinIsTTY, stdoutIsTTY })) {\n (options.notify ?? console.error)(\n `${updateMessage} Run \"npm install -g ${options.packageName}@latest\" to update.`,\n );\n return { continueExecution: true };\n }\n\n return await runInteractiveInstallAndRestart({\n packageName: options.packageName,\n updateMessage,\n env,\n argv,\n execPath: options.execPath,\n skipUpdateCheckEnvVar: UPDATE_CHECK_SKIP_ENV_VAR,\n confirmInstall: options.confirmInstall,\n runCommand: options.runCommand,\n notify: options.notify,\n });\n } catch {\n return { continueExecution: true };\n }\n}\n","import { Command } from 'commander';\n\nimport { getDefaultSourceIds } from '../sources/create-default-adapters.js';\nimport { runEfficiencyReport } from './run-efficiency-report.js';\nimport { runUsageReport } from './run-usage-report.js';\nimport type { EfficiencyCommandOptions, ReportCommandOptions } from './usage-data-contracts.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\n\nexport type CreateCliOptions = {\n version?: string;\n};\n\nconst defaultTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';\n\nfunction collectRepeatedOption(value: string, previous: string[]): string[] {\n return [...previous, value];\n}\n\nfunction getSupportedSourceIds(): string[] {\n return getDefaultSourceIds();\n}\n\nfunction getAllowedSourcesLabel(supportedSourceIds: readonly string[]): string {\n return supportedSourceIds.join(', ');\n}\n\nfunction addSharedOptions(\n command: Command,\n options: { includePerModelColumns?: boolean } = {},\n): Command {\n const supportedSourceIds = getSupportedSourceIds();\n const allowedSourcesLabel = getAllowedSourcesLabel(supportedSourceIds);\n const supportedSourcesSummary = `(${supportedSourceIds.length}): ${allowedSourcesLabel}`;\n const includePerModelColumns = options.includePerModelColumns ?? true;\n\n const configuredCommand = command\n .option('--pi-dir <path>', 'Path to .pi sessions directory')\n .option('--codex-dir <path>', 'Path to .codex sessions directory')\n .option('--gemini-dir <path>', 'Path to .gemini directory')\n .option('--droid-dir <path>', 'Path to Droid sessions directory')\n .option('--opencode-db <path>', 'Path to OpenCode SQLite DB')\n .option(\n '--source-dir <source-id=path>',\n 'Override source directory for directory-backed sources (repeatable)',\n collectRepeatedOption,\n [],\n )\n .option(\n '--source <name>',\n `Filter by source id (repeatable or comma-separated, supported sources ${supportedSourcesSummary})`,\n collectRepeatedOption,\n [],\n )\n .option('--since <YYYY-MM-DD>', 'Inclusive start date filter')\n .option('--until <YYYY-MM-DD>', 'Inclusive end date filter')\n .option('--timezone <iana>', 'Timezone for bucketing', defaultTimezone)\n .option('--provider <name>', 'Provider filter (substring match, optional)')\n .option(\n '--model <name>',\n 'Filter by model (repeatable/comma-separated; exact when exact match exists after source/provider/date filters, otherwise substring)',\n collectRepeatedOption,\n [],\n )\n .option('--pricing-url <url>', 'Override LiteLLM pricing source URL')\n .option('--pricing-offline', 'Use cached LiteLLM pricing only (no network fetch)')\n .option(\n '--ignore-pricing-failures',\n 'Continue without estimated costs when pricing cannot be loaded',\n )\n .option('--markdown', 'Render output as markdown table')\n .option('--json', 'Render output as JSON');\n\n if (!includePerModelColumns) {\n return configuredCommand;\n }\n\n return configuredCommand.option(\n '--per-model-columns',\n 'Render per-model metrics as multiline aligned table columns (terminal/markdown)',\n );\n}\n\nfunction commandDescription(granularity: ReportGranularity): string {\n switch (granularity) {\n case 'daily':\n return 'Show daily usage report';\n case 'weekly':\n return 'Show weekly usage report (week starts Monday)';\n case 'monthly':\n return 'Show monthly usage report';\n }\n}\n\nfunction createCommand(granularity: ReportGranularity): Command {\n const command = new Command(granularity);\n\n addSharedOptions(command)\n .description(commandDescription(granularity))\n .action(async (options: ReportCommandOptions) => {\n await runUsageReport(granularity, options);\n });\n\n return command;\n}\n\nfunction parseGranularityArgument(value: string): ReportGranularity {\n const normalized = value.trim().toLowerCase();\n\n if (normalized === 'daily' || normalized === 'weekly' || normalized === 'monthly') {\n return normalized;\n }\n\n throw new Error(`Invalid granularity: ${value}. Expected one of: daily, weekly, monthly`);\n}\n\nfunction createEfficiencyCommand(): Command {\n const command = new Command('efficiency');\n\n addSharedOptions(command, { includePerModelColumns: false })\n .argument('<granularity>', 'Granularity: daily | weekly | monthly', parseGranularityArgument)\n .option('--repo-dir <path>', 'Path to repository for Git outcome metrics')\n .option('--include-merge-commits', 'Include merge commits in Git outcome metrics')\n .description('Show efficiency report by correlating usage metrics with local Git outcomes')\n .action(async (granularity: ReportGranularity, options: EfficiencyCommandOptions) => {\n await runEfficiencyReport(granularity, options);\n });\n\n return command;\n}\n\nfunction rootDescription(): string {\n const supportedSourceIds = getSupportedSourceIds();\n const allowedSourcesLabel = getAllowedSourcesLabel(supportedSourceIds);\n\n return [\n 'Aggregate local LLM usage metrics from supported local session sources',\n `Supported sources (${supportedSourceIds.length}): ${allowedSourcesLabel}`,\n '',\n 'Run `llm-usage <command> --help` to see command options (e.g. --json, --source).',\n '',\n 'Examples:',\n ' $ llm-usage daily',\n ' $ llm-usage daily --help',\n ' $ llm-usage weekly --timezone Europe/Paris',\n ' $ llm-usage monthly --since 2026-01-01 --until 2026-01-31 --source pi,codex --json',\n ' $ llm-usage monthly --source opencode --opencode-db /path/to/opencode.db --json',\n ' $ llm-usage monthly --model claude --per-model-columns',\n ' $ llm-usage daily --source-dir pi=/tmp/pi-sessions --source-dir gemini=/tmp/.gemini --source-dir droid=/tmp/droid-sessions',\n ' $ llm-usage daily --pi-dir /tmp/pi-sessions --gemini-dir /tmp/.gemini --droid-dir /tmp/droid-sessions',\n ' $ llm-usage efficiency weekly --repo-dir /path/to/repo --json',\n ' $ npx --yes llm-usage-metrics@latest daily',\n ].join('\\n');\n}\n\nexport function createCli(options: CreateCliOptions = {}): Command {\n const program = new Command();\n\n program\n .name('llm-usage')\n .description(rootDescription())\n .version(options.version ?? '0.0.0')\n .showHelpAfterError()\n .addCommand(createCommand('daily'))\n .addCommand(createCommand('weekly'))\n .addCommand(createCommand('monthly'))\n .addCommand(createEfficiencyCommand());\n\n return program;\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { normalizeNonNegativeInteger } from '../../domain/normalization.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverJsonlFiles } from '../../utils/discover-jsonl-files.js';\nimport { pathStat } from '../../utils/fs-helpers.js';\nimport { readJsonlObjects } from '../../utils/read-jsonl-objects.js';\nimport { asTrimmedText, isBlankText, toNumberLike } from '../parsing-utils.js';\nimport type { SourceAdapter } from '../source-adapter.js';\n\nconst defaultSessionsDir = path.join(os.homedir(), '.codex', 'sessions');\n\nexport const LEGACY_CODEX_MODEL_FALLBACK = 'legacy-codex-unknown';\n\ntype CodexUsage = {\n inputTokens: number;\n cacheReadTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n totalTokens: number;\n};\n\ntype CodexSessionState = {\n sessionId: string;\n repoRoot?: string;\n provider?: string;\n model?: string;\n previousTotalUsage?: CodexUsage;\n};\n\nexport type CodexSourceAdapterOptions = {\n sessionsDir?: string;\n requireSessionsDir?: boolean;\n};\n\nconst SESSION_META_LINE_PATTERN = /\"type\"\\s*:\\s*\"session_meta\"/u;\nconst TURN_CONTEXT_LINE_PATTERN = /\"type\"\\s*:\\s*\"turn_context\"/u;\nconst EVENT_MSG_LINE_PATTERN = /\"type\"\\s*:\\s*\"event_msg\"/u;\nconst TOKEN_COUNT_LINE_PATTERN = /\"type\"\\s*:\\s*\"token_count\"/u;\n\nfunction shouldParseCodexJsonlLine(lineText: string): boolean {\n if (SESSION_META_LINE_PATTERN.test(lineText) || TURN_CONTEXT_LINE_PATTERN.test(lineText)) {\n return true;\n }\n\n return EVENT_MSG_LINE_PATTERN.test(lineText) && TOKEN_COUNT_LINE_PATTERN.test(lineText);\n}\n\nfunction toUsage(value: unknown): CodexUsage | undefined {\n const usage = asRecord(value);\n\n if (!usage) {\n return undefined;\n }\n\n const rawInputTokens = normalizeNonNegativeInteger(toNumberLike(usage.input_tokens));\n const cacheReadTokens = normalizeNonNegativeInteger(toNumberLike(usage.cached_input_tokens));\n const outputTokens = normalizeNonNegativeInteger(toNumberLike(usage.output_tokens));\n\n const inputTokens = Math.max(0, rawInputTokens - cacheReadTokens);\n\n return {\n // Codex input_tokens includes cached_input_tokens. We store net input separately\n // to avoid double counting input + cache read in reports and estimated pricing.\n inputTokens,\n cacheReadTokens,\n outputTokens,\n reasoningTokens: normalizeNonNegativeInteger(toNumberLike(usage.reasoning_output_tokens)),\n // Match ccusage semantics: billable total excludes reasoning breakdown.\n totalTokens: inputTokens + outputTokens + cacheReadTokens,\n };\n}\n\nfunction subtractUsage(current: CodexUsage, previous: CodexUsage): CodexUsage {\n return {\n inputTokens: Math.max(0, current.inputTokens - previous.inputTokens),\n cacheReadTokens: Math.max(0, current.cacheReadTokens - previous.cacheReadTokens),\n outputTokens: Math.max(0, current.outputTokens - previous.outputTokens),\n reasoningTokens: Math.max(0, current.reasoningTokens - previous.reasoningTokens),\n totalTokens: Math.max(0, current.totalTokens - previous.totalTokens),\n };\n}\n\nfunction addUsage(left: CodexUsage, right: CodexUsage): CodexUsage {\n return {\n inputTokens: left.inputTokens + right.inputTokens,\n cacheReadTokens: left.cacheReadTokens + right.cacheReadTokens,\n outputTokens: left.outputTokens + right.outputTokens,\n reasoningTokens: left.reasoningTokens + right.reasoningTokens,\n totalTokens: left.totalTokens + right.totalTokens,\n };\n}\n\nfunction hasUsageSignal(usage: CodexUsage): boolean {\n return (\n usage.inputTokens > 0 ||\n usage.cacheReadTokens > 0 ||\n usage.outputTokens > 0 ||\n usage.reasoningTokens > 0 ||\n usage.totalTokens > 0\n );\n}\n\nfunction deriveDeltaUsage(\n info: Record<string, unknown>,\n previousTotalUsage: CodexUsage | undefined,\n): { deltaUsage?: CodexUsage; latestTotalUsage?: CodexUsage } {\n const totalUsage = toUsage(info.total_token_usage);\n const lastUsage = toUsage(info.last_token_usage);\n\n if (lastUsage) {\n return { deltaUsage: lastUsage, latestTotalUsage: totalUsage };\n }\n\n if (!totalUsage) {\n return {};\n }\n\n const deltaUsage = previousTotalUsage\n ? subtractUsage(totalUsage, previousTotalUsage)\n : totalUsage;\n\n return { deltaUsage, latestTotalUsage: totalUsage };\n}\n\nfunction getFallbackSessionId(filePath: string): string {\n return path.basename(filePath, '.jsonl');\n}\n\nfunction resolveRepoRootFromPayload(\n payload: Record<string, unknown> | undefined,\n): string | undefined {\n if (!payload) {\n return undefined;\n }\n\n return (\n asTrimmedText(payload.cwd) ??\n asTrimmedText(payload.repo_root) ??\n asTrimmedText(payload.repoRoot) ??\n asTrimmedText(payload.project_root) ??\n asTrimmedText(payload.projectRoot)\n );\n}\n\nexport class CodexSourceAdapter implements SourceAdapter {\n public readonly id = 'codex' as const;\n\n private readonly sessionsDir: string;\n private readonly requireSessionsDir: boolean;\n\n public constructor(options: CodexSourceAdapterOptions = {}) {\n this.sessionsDir = options.sessionsDir ?? defaultSessionsDir;\n this.requireSessionsDir = options.requireSessionsDir ?? false;\n }\n\n public async discoverFiles(): Promise<string[]> {\n if (isBlankText(this.sessionsDir)) {\n throw new Error('Codex sessions directory must be a non-empty path');\n }\n\n const normalizedSessionsDir = this.sessionsDir.trim();\n\n if (this.requireSessionsDir) {\n const sessionsDirStats = await pathStat(normalizedSessionsDir);\n\n if (!sessionsDirStats) {\n throw new Error(\n `Codex sessions directory is missing or unreadable: ${normalizedSessionsDir}`,\n );\n }\n\n if (!sessionsDirStats.isDirectory()) {\n throw new Error(`Codex sessions directory is not a directory: ${normalizedSessionsDir}`);\n }\n }\n\n return discoverJsonlFiles(normalizedSessionsDir);\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const events: UsageEvent[] = [];\n\n const state: CodexSessionState = {\n sessionId: getFallbackSessionId(filePath),\n provider: 'openai',\n };\n\n for await (const line of readJsonlObjects(filePath, {\n shouldParseLine: shouldParseCodexJsonlLine,\n })) {\n if (line.type === 'session_meta') {\n const payload = asRecord(line.payload);\n state.sessionId = asTrimmedText(payload?.id) ?? state.sessionId;\n state.provider = asTrimmedText(payload?.model_provider) ?? state.provider;\n state.repoRoot = resolveRepoRootFromPayload(payload) ?? state.repoRoot;\n continue;\n }\n\n if (line.type === 'turn_context') {\n const payload = asRecord(line.payload);\n state.model = asTrimmedText(payload?.model) ?? state.model;\n state.repoRoot = resolveRepoRootFromPayload(payload) ?? state.repoRoot;\n continue;\n }\n\n if (line.type !== 'event_msg') {\n continue;\n }\n\n const payload = asRecord(line.payload);\n\n if (payload?.type !== 'token_count') {\n continue;\n }\n\n const info = asRecord(payload.info);\n\n if (!info) {\n continue;\n }\n\n const { deltaUsage, latestTotalUsage } = deriveDeltaUsage(info, state.previousTotalUsage);\n\n if (!deltaUsage || !hasUsageSignal(deltaUsage)) {\n state.previousTotalUsage = latestTotalUsage ?? state.previousTotalUsage;\n continue;\n }\n\n const timestamp = asTrimmedText(line.timestamp);\n\n if (!timestamp) {\n state.previousTotalUsage = latestTotalUsage ?? state.previousTotalUsage;\n continue;\n }\n\n const model = state.model ?? LEGACY_CODEX_MODEL_FALLBACK;\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId: state.sessionId,\n timestamp,\n repoRoot: state.repoRoot,\n provider: state.provider,\n model,\n inputTokens: deltaUsage.inputTokens,\n outputTokens: deltaUsage.outputTokens,\n reasoningTokens: deltaUsage.reasoningTokens,\n cacheReadTokens: deltaUsage.cacheReadTokens,\n cacheWriteTokens: 0,\n totalTokens: deltaUsage.totalTokens,\n costMode: 'estimated',\n }),\n );\n } catch {\n // no-op: malformed lines are ignored by design\n }\n\n if (latestTotalUsage) {\n state.previousTotalUsage = latestTotalUsage;\n } else if (state.previousTotalUsage) {\n state.previousTotalUsage = addUsage(state.previousTotalUsage, deltaUsage);\n } else {\n state.previousTotalUsage = deltaUsage;\n }\n }\n\n return events;\n }\n}\n\nexport function getDefaultCodexSessionsDir(): string {\n return defaultSessionsDir;\n}\n","import { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\nexport type NumberLike = number | string | null | undefined;\n\nexport function normalizeNonNegativeInteger(value: NumberLike): number {\n if (value === null || value === undefined) {\n return 0;\n }\n\n const parsed = typeof value === 'number' ? value : Number(value);\n\n if (!Number.isFinite(parsed)) {\n return 0;\n }\n\n return Math.max(0, Math.trunc(parsed));\n}\n\nexport function normalizeUsdCost(value: NumberLike): number | undefined {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n if (typeof value === 'string' && value.trim() === '') {\n return undefined;\n }\n\n const parsed = typeof value === 'number' ? value : Number(value);\n\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n\n return Math.max(0, parsed);\n}\n\nexport function normalizeTimestamp(value: string | Date): string {\n const date = value instanceof Date ? value : new Date(value);\n\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid timestamp: ${String(value)}`);\n }\n\n return date.toISOString();\n}\n\nexport function normalizeModelList(models: Iterable<string | null | undefined>): string[] {\n const deduplicated = new Set<string>();\n\n for (const model of models) {\n if (!model) {\n continue;\n }\n\n const normalized = model.trim();\n\n if (!normalized) {\n continue;\n }\n\n deduplicated.add(normalized);\n }\n\n return [...deduplicated].sort(compareByCodePoint);\n}\n","import {\n normalizeNonNegativeInteger,\n normalizeTimestamp,\n normalizeUsdCost,\n type NumberLike,\n} from './normalization.js';\n\nexport type SourceId = 'pi' | 'codex' | (string & {});\n\nexport type CostMode = 'explicit' | 'estimated';\n\nexport type UsageEvent = {\n source: SourceId;\n sessionId: string;\n timestamp: string;\n repoRoot?: string;\n provider?: string;\n model?: string;\n\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n totalTokens: number;\n\n costUsd?: number;\n costMode: CostMode;\n};\n\nexport type UsageEventInput = {\n source: SourceId;\n sessionId: string;\n timestamp: string | Date;\n repoRoot?: string;\n provider?: string;\n model?: string;\n\n inputTokens?: NumberLike;\n outputTokens?: NumberLike;\n reasoningTokens?: NumberLike;\n cacheReadTokens?: NumberLike;\n cacheWriteTokens?: NumberLike;\n totalTokens?: NumberLike;\n\n costUsd?: NumberLike;\n costMode?: CostMode;\n};\n\nexport function normalizeSourceId(value: unknown): SourceId | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized || undefined;\n}\n\nfunction requireText(value: string, fieldName: string): string {\n const normalized = value.trim();\n\n if (!normalized) {\n throw new Error(`UsageEvent ${fieldName} must be a non-empty string`);\n }\n\n return normalized;\n}\n\nfunction normalizeOptionalText(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized || undefined;\n}\n\nfunction normalizeOptionalPath(value: string | undefined): string | undefined {\n return normalizeOptionalText(value);\n}\n\nfunction normalizeOptionalModel(value: string | undefined): string | undefined {\n const normalized = normalizeOptionalText(value);\n\n if (!normalized) {\n return undefined;\n }\n\n return normalized.toLowerCase();\n}\n\nfunction resolveCostMode(costMode: CostMode | undefined, costUsd: number | undefined): CostMode {\n if (costMode === 'explicit' && costUsd === undefined) {\n throw new Error('UsageEvent with costMode \"explicit\" requires costUsd');\n }\n\n if (costMode) {\n return costMode;\n }\n\n return costUsd === undefined ? 'estimated' : 'explicit';\n}\n\nexport function createUsageEvent(input: UsageEventInput): UsageEvent {\n const source = normalizeSourceId(input.source);\n\n if (!source) {\n throw new Error('UsageEvent source must be a non-empty string');\n }\n\n const inputTokens = normalizeNonNegativeInteger(input.inputTokens);\n const outputTokens = normalizeNonNegativeInteger(input.outputTokens);\n const reasoningTokens = normalizeNonNegativeInteger(input.reasoningTokens);\n const cacheReadTokens = normalizeNonNegativeInteger(input.cacheReadTokens);\n const cacheWriteTokens = normalizeNonNegativeInteger(input.cacheWriteTokens);\n const declaredTotalTokens = normalizeNonNegativeInteger(input.totalTokens);\n const componentTotalTokens =\n inputTokens + outputTokens + reasoningTokens + cacheReadTokens + cacheWriteTokens;\n const totalTokens = declaredTotalTokens > 0 ? declaredTotalTokens : componentTotalTokens;\n\n const costUsd = normalizeUsdCost(input.costUsd);\n const costMode = resolveCostMode(input.costMode, costUsd);\n\n return {\n source,\n sessionId: requireText(input.sessionId, 'sessionId'),\n timestamp: normalizeTimestamp(input.timestamp),\n repoRoot: normalizeOptionalPath(input.repoRoot),\n provider: normalizeOptionalText(input.provider),\n model: normalizeOptionalModel(input.model),\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costUsd,\n costMode,\n };\n}\n","import { readdir } from 'node:fs/promises';\nimport type { Dirent } from 'node:fs';\nimport path from 'node:path';\n\nimport { asRecord } from './as-record.js';\nimport { compareByCodePoint } from './compare-by-code-point.js';\n\nexport type DiscoverFilesOptions = {\n /** File extension to match (e.g., '.json', '.settings.json'). Case-insensitive. */\n extension: string;\n /** Whether to recurse into subdirectories. Default: true */\n recursive?: boolean;\n /** Skip permission errors (EACCES/EPERM) instead of throwing. Default: true */\n allowPermissionSkip?: boolean;\n /** Sort files by path for deterministic ordering. Default: true */\n sort?: boolean;\n};\n\nfunction getNodeErrorCode(error: unknown): string | undefined {\n const record = asRecord(error);\n return typeof record?.code === 'string' ? record.code : undefined;\n}\n\nfunction isSkippableDirectoryReadError(error: unknown): boolean {\n const code = getNodeErrorCode(error);\n return code === 'EACCES' || code === 'EPERM';\n}\n\nfunction matchesExtension(fileName: string, extension: string): boolean {\n const lowerFileName = fileName.toLowerCase();\n const lowerExtension = extension.toLowerCase();\n return lowerFileName.endsWith(lowerExtension);\n}\n\nfunction normalizeExtension(extension: string): string {\n const normalized = extension.trim();\n\n if (!normalized) {\n throw new Error('discoverFiles extension must be a non-empty string');\n }\n\n if (!normalized.startsWith('.')) {\n throw new Error('discoverFiles extension must start with \".\"');\n }\n\n return normalized;\n}\n\nasync function walkDirectory(\n rootDir: string,\n acc: string[],\n options: Required<DiscoverFilesOptions>,\n): Promise<void> {\n let entries: Dirent[];\n\n try {\n entries = await readdir(rootDir, { withFileTypes: true, encoding: 'utf8' });\n } catch (error) {\n if (getNodeErrorCode(error) === 'ENOENT') {\n return;\n }\n\n if (options.allowPermissionSkip && isSkippableDirectoryReadError(error)) {\n return;\n }\n\n throw error;\n }\n\n if (options.sort) {\n entries.sort((left, right) => compareByCodePoint(left.name, right.name));\n }\n\n for (const entry of entries) {\n const entryPath = path.join(rootDir, entry.name);\n\n if (entry.isDirectory() && options.recursive) {\n await walkDirectory(entryPath, acc, options);\n continue;\n }\n\n if (entry.isFile() && matchesExtension(entry.name, options.extension)) {\n acc.push(entryPath);\n }\n }\n}\n\n/**\n * Recursively discover files matching the given extension.\n * Returns empty array if rootDir doesn't exist.\n * Skips permission errors by default.\n */\nexport async function discoverFiles(\n rootDir: string,\n options: DiscoverFilesOptions,\n): Promise<string[]> {\n const files: string[] = [];\n const resolvedOptions: Required<DiscoverFilesOptions> = {\n extension: normalizeExtension(options.extension),\n recursive: options.recursive ?? true,\n allowPermissionSkip: options.allowPermissionSkip ?? true,\n sort: options.sort ?? true,\n };\n\n await walkDirectory(rootDir, files, resolvedOptions);\n\n return files;\n}\n","import { discoverFiles } from './discover-files.js';\n\n/**\n * Recursively discover .jsonl files in a directory.\n * Returns empty array if rootDir doesn't exist.\n * Skips permission errors in subdirectories (EACCES/EPERM).\n */\nexport async function discoverJsonlFiles(rootDir: string): Promise<string[]> {\n return discoverFiles(rootDir, { extension: '.jsonl' });\n}\n","import type { Stats } from 'node:fs';\nimport { access, constants, stat } from 'node:fs/promises';\n\nexport async function pathExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function pathReadable(filePath: string): Promise<boolean> {\n try {\n await access(filePath, constants.R_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function pathIsDirectory(filePath: string): Promise<boolean> {\n try {\n return (await stat(filePath)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function pathIsFile(filePath: string): Promise<boolean> {\n try {\n return (await stat(filePath)).isFile();\n } catch {\n return false;\n }\n}\n\nexport async function pathStat(filePath: string): Promise<Stats | undefined> {\n try {\n return await stat(filePath);\n } catch {\n return undefined;\n }\n}\n","import { createReadStream } from 'node:fs';\nimport { createInterface } from 'node:readline';\n\nimport { asRecord } from './as-record.js';\n\nexport async function* readJsonlObjects(\n filePath: string,\n options: { shouldParseLine?: (lineText: string) => boolean } = {},\n): AsyncGenerator<Record<string, unknown>, void, undefined> {\n const stream = createReadStream(filePath, {\n encoding: 'utf8',\n });\n const lineReader = createInterface({\n input: stream,\n crlfDelay: Infinity,\n });\n\n let isFirstLine = true;\n\n try {\n for await (const rawLine of lineReader) {\n const normalizedLine = isFirstLine ? rawLine.replace(/^\\uFEFF/u, '') : rawLine;\n isFirstLine = false;\n\n const lineText = normalizedLine.trim();\n\n if (!lineText) {\n continue;\n }\n\n if (options.shouldParseLine && !options.shouldParseLine(lineText)) {\n continue;\n }\n\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(lineText);\n } catch {\n continue;\n }\n\n const parsedObject = asRecord(parsed);\n\n if (!parsedObject) {\n continue;\n }\n\n yield parsedObject;\n }\n } finally {\n lineReader.close();\n stream.destroy();\n }\n}\n","import type { NumberLike } from '../domain/normalization.js';\n\nexport function asTrimmedText(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized || undefined;\n}\n\nexport function isBlankText(value: string): boolean {\n return value.trim().length === 0;\n}\n\nexport function toNumberLike(value: unknown): NumberLike {\n if (\n value === null ||\n value === undefined ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n return value;\n }\n\n return undefined;\n}\n","import { readFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { normalizeNonNegativeInteger } from '../../domain/normalization.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverFiles } from '../../utils/discover-files.js';\nimport { pathIsDirectory, pathReadable } from '../../utils/fs-helpers.js';\nimport { readJsonlObjects } from '../../utils/read-jsonl-objects.js';\nimport { asTrimmedText, isBlankText, toNumberLike } from '../parsing-utils.js';\nimport { incrementSkippedReason, toParseDiagnostics } from '../parse-diagnostics.js';\nimport type { SourceAdapter, SourceParseFileDiagnostics } from '../source-adapter.js';\n\nconst defaultSessionsDir = path.join(os.homedir(), '.factory', 'sessions');\n\nexport type DroidSourceAdapterOptions = {\n sessionsDir?: string;\n requireSessionsDir?: boolean;\n};\n\nconst DROID_SESSION_START_LINE_PATTERN = /\"type\"\\s*:\\s*\"session_start\"/u;\nconst DROID_MESSAGE_LINE_PATTERN = /\"type\"\\s*:\\s*\"message\"/u;\n\nfunction shouldParseDroidJsonlLine(lineText: string): boolean {\n return (\n DROID_SESSION_START_LINE_PATTERN.test(lineText) || DROID_MESSAGE_LINE_PATTERN.test(lineText)\n );\n}\n\nconst UNIX_SECONDS_ABS_CUTOFF = 10_000_000_000;\n\nfunction normalizeTimestampCandidate(candidate: unknown): string | undefined {\n let date: Date | undefined;\n\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n const timestampMs =\n Math.abs(candidate) <= UNIX_SECONDS_ABS_CUTOFF ? candidate * 1000 : candidate;\n date = new Date(timestampMs);\n } else {\n const normalizedText = asTrimmedText(candidate);\n\n if (!normalizedText) {\n return undefined;\n }\n\n date = new Date(normalizedText);\n }\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n}\n\nfunction getSettingsSessionId(filePath: string): string {\n return path.basename(filePath, '.settings.json');\n}\n\nfunction getSiblingJsonlPath(settingsPath: string): string {\n return path.join(path.dirname(settingsPath), `${getSettingsSessionId(settingsPath)}.jsonl`);\n}\n\nfunction isSessionStartRecord(line: Record<string, unknown>): boolean {\n return asTrimmedText(line.type) === 'session_start';\n}\n\nfunction isMessageRecord(line: Record<string, unknown>): boolean {\n return asTrimmedText(line.type) === 'message';\n}\n\nfunction resolveRepoRootFromSessionStart(line: Record<string, unknown>): string | undefined {\n const payload = asRecord(line.session_start);\n return asTrimmedText(payload?.cwd);\n}\n\nexport class DroidSourceAdapter implements SourceAdapter {\n public readonly id = 'droid' as const;\n\n private readonly sessionsDir: string;\n private readonly requireSessionsDir: boolean;\n\n public constructor(options: DroidSourceAdapterOptions = {}) {\n this.sessionsDir = options.sessionsDir ?? defaultSessionsDir;\n this.requireSessionsDir = options.requireSessionsDir ?? false;\n }\n\n private getNormalizedSessionsDir(): string {\n if (isBlankText(this.sessionsDir)) {\n throw new Error('Droid sessions directory must be a non-empty path');\n }\n\n return this.sessionsDir.trim();\n }\n\n public async discoverFiles(): Promise<string[]> {\n const normalizedDir = this.getNormalizedSessionsDir();\n\n if (this.requireSessionsDir && !(await pathReadable(normalizedDir))) {\n throw new Error(`Droid sessions directory is missing or unreadable: ${normalizedDir}`);\n }\n\n if (this.requireSessionsDir && !(await pathIsDirectory(normalizedDir))) {\n throw new Error(`Droid sessions directory is not a directory: ${normalizedDir}`);\n }\n\n return discoverFiles(normalizedDir, { extension: '.settings.json' });\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const { events } = await this.parseFileWithDiagnostics(filePath);\n return events;\n }\n\n public async parseFileWithDiagnostics(filePath: string): Promise<SourceParseFileDiagnostics> {\n const events: UsageEvent[] = [];\n let skippedRows = 0;\n const skippedRowReasons = new Map<string, number>();\n\n let settingsJson: unknown;\n\n try {\n const content = await readFile(filePath, 'utf8');\n settingsJson = JSON.parse(content) as unknown;\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'json_parse_error');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const settings = asRecord(settingsJson);\n\n if (!settings) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_settings_data');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const tokenUsage = asRecord(settings.tokenUsage);\n\n if (!tokenUsage) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'no_token_usage');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const inputTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.inputTokens));\n const outputTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.outputTokens));\n const reasoningTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.thinkingTokens));\n const cacheReadTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.cacheReadTokens));\n const cacheWriteTokens = normalizeNonNegativeInteger(\n toNumberLike(tokenUsage.cacheCreationTokens),\n );\n const billableTokens = inputTokens + outputTokens + cacheReadTokens + cacheWriteTokens;\n const totalTokens = billableTokens + reasoningTokens;\n\n if (billableTokens === 0) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'no_token_usage');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const provider = asTrimmedText(settings.providerLock);\n const model = asTrimmedText(settings.model);\n\n const primaryTimestamp = normalizeTimestampCandidate(settings.providerLockTimestamp);\n const hasValidPrimaryTimestamp = Boolean(primaryTimestamp);\n\n const jsonlPath = getSiblingJsonlPath(filePath);\n\n let repoRoot: string | undefined;\n let fallbackMessageTimestamp: string | undefined;\n\n try {\n for await (const line of readJsonlObjects(jsonlPath, {\n shouldParseLine: shouldParseDroidJsonlLine,\n })) {\n if (!repoRoot && isSessionStartRecord(line)) {\n repoRoot = resolveRepoRootFromSessionStart(line) ?? repoRoot;\n\n if (hasValidPrimaryTimestamp) {\n break;\n }\n\n continue;\n }\n\n if (!hasValidPrimaryTimestamp && isMessageRecord(line)) {\n fallbackMessageTimestamp = normalizeTimestampCandidate(line.timestamp);\n break;\n }\n }\n } catch {\n // fail-open: JSONL enrichment is optional\n }\n\n const timestamp = primaryTimestamp ?? fallbackMessageTimestamp;\n\n if (!timestamp) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_timestamp');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId: getSettingsSessionId(filePath),\n timestamp,\n repoRoot,\n provider,\n model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costMode: 'estimated',\n }),\n );\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'event_creation_failed');\n }\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n}\n\nexport function getDefaultDroidSessionsDir(): string {\n return defaultSessionsDir;\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport type { SourceParseFileDiagnostics, SourceSkippedRowReasonStat } from './source-adapter.js';\n\nexport function incrementSkippedReason(reasons: Map<string, number>, reason: string): void {\n const current = reasons.get(reason) ?? 0;\n reasons.set(reason, current + 1);\n}\n\nexport function toSkippedRowReasonStats(\n reasons: Map<string, number>,\n): SourceSkippedRowReasonStat[] {\n return [...reasons.entries()]\n .map(([reason, count]) => ({ reason, count }))\n .sort((left, right) => compareByCodePoint(left.reason, right.reason));\n}\n\nexport function toParseDiagnostics<Event extends UsageEvent>(\n events: Event[],\n skippedRows: number,\n skippedRowReasons: Map<string, number>,\n): SourceParseFileDiagnostics<Event> {\n return {\n events,\n skippedRows,\n skippedRowReasons: toSkippedRowReasonStats(skippedRowReasons),\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverFiles } from '../../utils/discover-files.js';\nimport { pathIsDirectory, pathReadable } from '../../utils/fs-helpers.js';\nimport { asTrimmedText, isBlankText } from '../parsing-utils.js';\nimport { incrementSkippedReason, toParseDiagnostics } from '../parse-diagnostics.js';\nimport type { SourceAdapter, SourceParseFileDiagnostics } from '../source-adapter.js';\n\nconst defaultGeminiDir = path.join(os.homedir(), '.gemini');\n\nexport type GeminiSourceAdapterOptions = {\n geminiDir?: string;\n requireGeminiDir?: boolean;\n};\n\nfunction parseProjectsJson(data: unknown): Map<string, string> {\n const mapping = new Map<string, string>();\n const record = asRecord(data);\n\n if (!record) {\n return mapping;\n }\n\n const projects = asRecord(record.projects);\n\n if (!projects) {\n return mapping;\n }\n\n for (const [key, value] of Object.entries(projects)) {\n const projectEntry = asRecord(value);\n const absolutePath = asTrimmedText(projectEntry?.absolutePath);\n\n if (absolutePath) {\n mapping.set(key, absolutePath);\n }\n }\n\n return mapping;\n}\n\nasync function loadProjectsJson(geminiDir: string): Promise<Map<string, string>> {\n const projectsPath = path.join(geminiDir, 'projects.json');\n\n try {\n const content = await readFile(projectsPath, 'utf8');\n const parsed = JSON.parse(content) as unknown;\n\n return parseProjectsJson(parsed);\n } catch {\n return new Map();\n }\n}\n\nasync function discoverSessionFiles(geminiDir: string): Promise<string[]> {\n const tmpDir = path.join(geminiDir, 'tmp');\n const allSessionFiles: string[] = [];\n const discoveredFiles = await discoverFiles(tmpDir, { extension: '.json' });\n\n for (const filePath of discoveredFiles) {\n const parentDir = path.basename(path.dirname(filePath));\n\n if (parentDir.toLowerCase() === 'chats') {\n allSessionFiles.push(filePath);\n }\n }\n\n return allSessionFiles;\n}\n\nfunction resolveRepoRoot(\n filePath: string,\n sessionData: Record<string, unknown>,\n projectMapping: Map<string, string>,\n): string | undefined {\n const projectHash = asTrimmedText(sessionData.projectHash);\n\n if (projectHash) {\n const mappedRoot = projectMapping.get(projectHash);\n\n if (mappedRoot) {\n return mappedRoot;\n }\n }\n\n const chatsDir = path.dirname(filePath);\n const projectDir = path.dirname(chatsDir);\n const projectIdentifier = path.basename(projectDir);\n\n return projectMapping.get(projectIdentifier);\n}\n\nfunction toFiniteNumber(value: unknown): number | undefined {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : undefined;\n }\n\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const trimmed = value.trim();\n\n if (!trimmed) {\n return undefined;\n }\n\n const parsed = Number(trimmed);\n\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n\n return parsed;\n}\n\nfunction extractTokenUsage(tokens: Record<string, unknown> | undefined): {\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n totalTokens: number;\n} | null {\n if (!tokens) {\n return null;\n }\n\n const input = Math.max(0, toFiniteNumber(tokens.input) ?? 0);\n const tool = Math.max(0, toFiniteNumber(tokens.tool) ?? 0);\n const output = Math.max(0, toFiniteNumber(tokens.output) ?? 0);\n const thoughts = Math.max(0, toFiniteNumber(tokens.thoughts) ?? 0);\n const cached = Math.max(0, toFiniteNumber(tokens.cached) ?? 0);\n\n const inputTokens = input + tool;\n const outputTokens = output;\n const reasoningTokens = thoughts;\n const cacheReadTokens = cached;\n\n const declaredTotal = Math.max(0, toFiniteNumber(tokens.total) ?? 0);\n const componentTotal = inputTokens + outputTokens + reasoningTokens + cacheReadTokens;\n const totalTokens = declaredTotal > 0 ? declaredTotal : componentTotal;\n\n if (inputTokens === 0 && outputTokens === 0 && reasoningTokens === 0 && cached === 0) {\n return null;\n }\n\n return {\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n totalTokens,\n };\n}\n\n// diagnostics helpers live in ../parse-diagnostics.ts\n\nfunction normalizeTimestamp(candidate: unknown): string | undefined {\n if (typeof candidate !== 'string' || isBlankText(candidate)) {\n return undefined;\n }\n\n const date = new Date(candidate.trim());\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n}\n\nexport class GeminiSourceAdapter implements SourceAdapter {\n public readonly id = 'gemini' as const;\n\n private readonly geminiDir: string;\n private readonly requireGeminiDir: boolean;\n private projectMapping: Map<string, string> | null = null;\n\n public constructor(options: GeminiSourceAdapterOptions = {}) {\n this.geminiDir = options.geminiDir ?? defaultGeminiDir;\n this.requireGeminiDir = options.requireGeminiDir ?? false;\n }\n\n private getNormalizedGeminiDir(): string {\n if (isBlankText(this.geminiDir)) {\n throw new Error('Gemini directory must be a non-empty path');\n }\n\n return this.geminiDir.trim();\n }\n\n private async getProjectMapping(normalizedGeminiDir: string): Promise<Map<string, string>> {\n if (this.projectMapping) {\n return this.projectMapping;\n }\n\n this.projectMapping = await loadProjectsJson(normalizedGeminiDir);\n return this.projectMapping;\n }\n\n private async getProjectMappingForParse(): Promise<Map<string, string>> {\n if (this.projectMapping) {\n return this.projectMapping;\n }\n\n if (isBlankText(this.geminiDir)) {\n return new Map();\n }\n\n this.projectMapping = await loadProjectsJson(this.geminiDir.trim());\n return this.projectMapping;\n }\n\n public async discoverFiles(): Promise<string[]> {\n const normalizedDir = this.getNormalizedGeminiDir();\n\n if (this.requireGeminiDir && !(await pathReadable(normalizedDir))) {\n throw new Error(`Gemini directory is missing or unreadable: ${normalizedDir}`);\n }\n\n if (this.requireGeminiDir && !(await pathIsDirectory(normalizedDir))) {\n throw new Error(`Gemini directory is not a directory: ${normalizedDir}`);\n }\n\n await this.getProjectMapping(normalizedDir);\n\n return discoverSessionFiles(normalizedDir);\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const { events } = await this.parseFileWithDiagnostics(filePath);\n\n return events;\n }\n\n public async parseFileWithDiagnostics(filePath: string): Promise<SourceParseFileDiagnostics> {\n const events: UsageEvent[] = [];\n let skippedRows = 0;\n const skippedRowReasons = new Map<string, number>();\n\n let sessionData: unknown;\n\n try {\n const content = await readFile(filePath, 'utf8');\n sessionData = JSON.parse(content) as unknown;\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'json_parse_error');\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const sessionDataRecord = asRecord(sessionData);\n\n if (!sessionDataRecord) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_session_data');\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const sessionId =\n asTrimmedText(sessionDataRecord.sessionId) ?? path.basename(filePath, '.json');\n\n const projectMapping = await this.getProjectMappingForParse();\n const repoRoot = resolveRepoRoot(filePath, sessionDataRecord, projectMapping);\n\n if (!Array.isArray(sessionDataRecord.messages)) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_messages_array');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const messages = sessionDataRecord.messages;\n\n for (const rawMessage of messages) {\n const message = asRecord(rawMessage);\n\n if (!message) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_message');\n\n continue;\n }\n\n if (message.type !== 'gemini') {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'non_gemini_message');\n\n continue;\n }\n\n const tokens = extractTokenUsage(asRecord(message.tokens));\n\n if (!tokens) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'no_token_usage');\n\n continue;\n }\n\n const timestamp = normalizeTimestamp(message.timestamp);\n\n if (!timestamp) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_timestamp');\n\n continue;\n }\n\n const model = asTrimmedText(message.model);\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId,\n timestamp,\n repoRoot,\n provider: 'google',\n model,\n ...tokens,\n costMode: 'estimated',\n }),\n );\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'event_creation_failed');\n }\n }\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n}\n\nexport function getDefaultGeminiDir(): string {\n return defaultGeminiDir;\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nexport type OpenCodeDbPathResolverOptions = {\n platform?: NodeJS.Platform;\n homeDir?: string;\n env?: NodeJS.ProcessEnv;\n};\n\nfunction deduplicate(paths: string[]): string[] {\n return [...new Set(paths)];\n}\n\nfunction getLinuxLikeCandidates(homeDir: string, env: NodeJS.ProcessEnv): string[] {\n const xdgDataHome = env.XDG_DATA_HOME ?? path.join(homeDir, '.local', 'share');\n\n return [\n path.join(xdgDataHome, 'opencode', 'opencode.db'),\n path.join(xdgDataHome, 'opencode', 'db.sqlite'),\n path.join(homeDir, '.opencode', 'opencode.db'),\n path.join(homeDir, '.opencode', 'db.sqlite'),\n ];\n}\n\nfunction getMacOsCandidates(homeDir: string): string[] {\n const appSupportDir = path.join(homeDir, 'Library', 'Application Support');\n\n return [\n path.join(appSupportDir, 'opencode', 'opencode.db'),\n path.join(appSupportDir, 'opencode', 'db.sqlite'),\n path.join(homeDir, '.opencode', 'opencode.db'),\n path.join(homeDir, '.opencode', 'db.sqlite'),\n ];\n}\n\nfunction getWindowsCandidates(homeDir: string, env: NodeJS.ProcessEnv): string[] {\n const roamingBase =\n env.APPDATA ??\n env.LOCALAPPDATA ??\n (env.USERPROFILE ? path.join(env.USERPROFILE, 'AppData', 'Roaming') : undefined);\n\n const roamingCandidates = roamingBase\n ? [\n path.join(roamingBase, 'opencode', 'opencode.db'),\n path.join(roamingBase, 'opencode', 'db.sqlite'),\n ]\n : [];\n\n return [\n ...roamingCandidates,\n path.join(homeDir, '.opencode', 'opencode.db'),\n path.join(homeDir, '.opencode', 'db.sqlite'),\n ];\n}\n\nexport function getDefaultOpenCodeDbPathCandidates(\n options: OpenCodeDbPathResolverOptions = {},\n): string[] {\n const platform = options.platform ?? process.platform;\n const homeDir = options.homeDir ?? os.homedir();\n const env = options.env ?? process.env;\n\n switch (platform) {\n case 'win32':\n return deduplicate(getWindowsCandidates(homeDir, env));\n case 'darwin':\n return deduplicate(getMacOsCandidates(homeDir));\n default:\n return deduplicate(getLinuxLikeCandidates(homeDir, env));\n }\n}\n","import { createRequire } from 'node:module';\n\nimport { asRecord } from '../../utils/as-record.js';\nimport { withSuppressedSqliteExperimentalWarning } from './sqlite-warning-suppression.js';\n\nexport type SqliteModule = {\n DatabaseSync: new (\n filePath: string,\n options?: {\n readOnly?: boolean;\n timeout?: number;\n },\n ) => {\n prepare: (sql: string) => {\n all: (...anonymousParameters: unknown[]) => Record<string, unknown>[];\n iterate?: (...anonymousParameters: unknown[]) => IterableIterator<Record<string, unknown>>;\n };\n close: () => void;\n };\n};\n\ntype RequireFn = (moduleId: string) => unknown;\n\nconst require = createRequire(import.meta.url);\n\nfunction isSqliteModule(value: unknown): value is SqliteModule {\n const moduleRecord = asRecord(value);\n return typeof moduleRecord?.DatabaseSync === 'function';\n}\n\nexport function loadNodeSqliteModuleFromRequire(requireFn: RequireFn): SqliteModule {\n try {\n const moduleValue = withSuppressedSqliteExperimentalWarning(() => requireFn('node:sqlite'));\n\n if (!isSqliteModule(moduleValue)) {\n throw new Error('node:sqlite loaded but did not expose a DatabaseSync constructor.');\n }\n\n return moduleValue;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(\n `OpenCode source requires Node.js 24+ runtime with node:sqlite support: ${reason}`,\n { cause: error },\n );\n }\n}\n\nexport async function loadNodeSqliteModule(): Promise<SqliteModule> {\n return loadNodeSqliteModuleFromRequire(require);\n}\n","const sqliteExperimentalWarningText =\n 'SQLite is an experimental feature and might change at any time';\n\nexport function isSqliteExperimentalWarning(\n warning: unknown,\n warningType: string | undefined,\n): boolean {\n const message =\n warning instanceof Error ? warning.message : typeof warning === 'string' ? warning : '';\n const derivedType =\n warningType ??\n (warning instanceof Error ? warning.name : typeof warning === 'string' ? '' : '');\n\n return derivedType === 'ExperimentalWarning' && message.includes(sqliteExperimentalWarningText);\n}\n\nexport function withSuppressedSqliteExperimentalWarning<T>(load: () => T): T {\n const originalEmitWarning = process.emitWarning.bind(process);\n const patchedEmitWarning = ((warning: unknown, ...args: unknown[]): void => {\n const firstArgument = args[0];\n const warningType =\n typeof firstArgument === 'string'\n ? firstArgument\n : typeof firstArgument === 'object' &&\n firstArgument !== null &&\n 'type' in firstArgument &&\n typeof firstArgument.type === 'string'\n ? firstArgument.type\n : undefined;\n\n if (isSqliteExperimentalWarning(warning, warningType)) {\n return;\n }\n\n Reflect.apply(originalEmitWarning, process, [warning, ...args]);\n }) as typeof process.emitWarning;\n\n process.emitWarning = patchedEmitWarning;\n\n try {\n return load();\n } finally {\n process.emitWarning = originalEmitWarning;\n }\n}\n","import { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { compareByCodePoint } from '../../utils/compare-by-code-point.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { asTrimmedText, toNumberLike } from '../parsing-utils.js';\nimport type { SourceParseFileDiagnostics } from '../source-adapter.js';\nimport type { OpenCodeSqliteRow } from './opencode-sqlite-query.js';\n\nconst UNIX_SECONDS_ABS_CUTOFF = 10_000_000_000;\n\ntype SkippedRowReason =\n | 'missing_data_json'\n | 'invalid_data_json'\n | 'missing_timestamp'\n | 'missing_session_id'\n | 'missing_usage_signal'\n | 'invalid_usage_event';\n\nfunction normalizeTimestampCandidate(candidate: unknown): string | undefined {\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n const timestampMs =\n Math.abs(candidate) <= UNIX_SECONDS_ABS_CUTOFF ? candidate * 1000 : candidate;\n const date = new Date(timestampMs);\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n }\n\n if (typeof candidate === 'string') {\n const trimmed = candidate.trim();\n\n if (!trimmed) {\n return undefined;\n }\n\n const numericTimestamp = Number(trimmed);\n\n if (Number.isFinite(numericTimestamp)) {\n return normalizeTimestampCandidate(numericTimestamp);\n }\n\n const date = new Date(trimmed);\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n }\n\n return undefined;\n}\n\nfunction resolveTimestamp(\n rowTimestamp: unknown,\n messagePayload: Record<string, unknown>,\n): string | undefined {\n const timestampCandidates = [\n rowTimestamp,\n messagePayload.timestamp,\n messagePayload.timeCreated,\n messagePayload.time_created,\n ];\n\n for (const candidate of timestampCandidates) {\n const resolved = normalizeTimestampCandidate(candidate);\n\n if (resolved) {\n return resolved;\n }\n }\n\n return undefined;\n}\n\nfunction parseNonNegativeNumber(value: unknown): number | undefined {\n const parsed = toNumberLike(value);\n\n if (parsed === undefined || parsed === null) {\n return undefined;\n }\n\n if (typeof parsed === 'string' && parsed.trim() === '') {\n return undefined;\n }\n\n const numberValue = typeof parsed === 'number' ? parsed : Number(parsed);\n\n if (!Number.isFinite(numberValue) || numberValue < 0) {\n return undefined;\n }\n\n return numberValue;\n}\n\nfunction normalizeSessionIdCandidate(value: unknown): string | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return String(value);\n }\n\n return asTrimmedText(value);\n}\n\nfunction resolveRepoRoot(messagePayload: Record<string, unknown>): string | undefined {\n const pathPayload = asRecord(messagePayload.path);\n\n return (\n asTrimmedText(pathPayload?.root) ??\n asTrimmedText(pathPayload?.cwd) ??\n asTrimmedText(messagePayload.cwd) ??\n asTrimmedText(messagePayload.repo_root) ??\n asTrimmedText(messagePayload.repoRoot) ??\n asTrimmedText(messagePayload.project_root) ??\n asTrimmedText(messagePayload.projectRoot)\n );\n}\n\nfunction hasUsageSignal(usageFields: Array<unknown>, explicitCost: number | undefined): boolean {\n if (explicitCost !== undefined) {\n return true;\n }\n\n return usageFields.some((value) => {\n const parsed = parseNonNegativeNumber(value);\n return parsed !== undefined && parsed > 0;\n });\n}\n\nexport function parseOpenCodeMessageRows(\n rows: Iterable<OpenCodeSqliteRow>,\n sourceId: UsageEvent['source'],\n): SourceParseFileDiagnostics {\n const events: UsageEvent[] = [];\n let skippedRows = 0;\n const skippedRowReasons = new Map<SkippedRowReason, number>();\n\n const recordSkippedRow = (reason: SkippedRowReason): void => {\n skippedRows += 1;\n skippedRowReasons.set(reason, (skippedRowReasons.get(reason) ?? 0) + 1);\n };\n\n for (const row of rows) {\n const dataJson = asTrimmedText(row.data_json);\n\n if (!dataJson) {\n recordSkippedRow('missing_data_json');\n continue;\n }\n\n let payload: Record<string, unknown>;\n\n try {\n const parsedPayload = asRecord(JSON.parse(dataJson));\n\n if (!parsedPayload) {\n recordSkippedRow('invalid_data_json');\n continue;\n }\n\n payload = parsedPayload;\n } catch {\n recordSkippedRow('invalid_data_json');\n continue;\n }\n\n const role = asTrimmedText(payload.role) ?? asTrimmedText(payload.type);\n\n if (role?.toLowerCase() !== 'assistant') {\n continue;\n }\n\n const timestamp = resolveTimestamp(row.row_time, payload);\n\n if (!timestamp) {\n recordSkippedRow('missing_timestamp');\n continue;\n }\n\n const sessionId =\n normalizeSessionIdCandidate(row.row_session_id) ??\n normalizeSessionIdCandidate(payload.sessionID) ??\n normalizeSessionIdCandidate(payload.sessionId) ??\n normalizeSessionIdCandidate(payload.session_id) ??\n normalizeSessionIdCandidate(row.row_id);\n\n if (!sessionId) {\n recordSkippedRow('missing_session_id');\n continue;\n }\n\n const provider = asTrimmedText(payload.providerID) ?? asTrimmedText(payload.provider);\n const model = asTrimmedText(payload.modelID) ?? asTrimmedText(payload.model);\n const repoRoot = resolveRepoRoot(payload);\n const tokens = asRecord(payload.tokens);\n const tokenCache = asRecord(tokens?.cache);\n const inputTokens = toNumberLike(tokens?.input);\n const outputTokens = toNumberLike(tokens?.output);\n const reasoningTokens = toNumberLike(tokens?.reasoning);\n const cacheReadTokens = toNumberLike(tokenCache?.read);\n const cacheWriteTokens = toNumberLike(tokenCache?.write);\n const totalTokens = toNumberLike(tokens?.total);\n const explicitCost = parseNonNegativeNumber(payload.cost);\n\n if (\n !hasUsageSignal(\n [\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n ],\n explicitCost,\n )\n ) {\n recordSkippedRow('missing_usage_signal');\n continue;\n }\n\n try {\n events.push(\n createUsageEvent({\n source: sourceId,\n sessionId,\n timestamp,\n repoRoot,\n provider,\n model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costUsd: explicitCost,\n costMode: explicitCost === undefined ? 'estimated' : 'explicit',\n }),\n );\n } catch {\n recordSkippedRow('invalid_usage_event');\n }\n }\n\n return {\n events,\n skippedRows,\n skippedRowReasons: [...skippedRowReasons.entries()]\n .map(([reason, count]) => ({ reason, count }))\n .sort((left, right) => compareByCodePoint(left.reason, right.reason)),\n };\n}\n","import { asRecord } from '../../utils/as-record.js';\nimport { asTrimmedText } from '../parsing-utils.js';\n\nexport function isBusyOrLockedSqliteError(error: unknown): boolean {\n const asError = asRecord(error);\n const code = asTrimmedText(asError?.code);\n const message = error instanceof Error ? error.message : String(error);\n const busySignal = /SQLITE_BUSY|SQLITE_LOCKED|database is locked|database table is locked/u;\n\n return (\n code === 'SQLITE_BUSY' ||\n code === 'SQLITE_LOCKED' ||\n code === 'ERR_SQLITE_BUSY' ||\n busySignal.test(message)\n );\n}\n\nexport function formatSqliteError(error: unknown): string {\n if (!(error instanceof Error)) {\n return String(error);\n }\n\n const errorRecord = asRecord(error);\n const code = asTrimmedText(errorRecord?.code);\n\n if (!code) {\n return error.message;\n }\n\n return `${code}: ${error.message}`;\n}\n","import { formatSqliteError, isBusyOrLockedSqliteError } from './opencode-sqlite-errors.js';\n\nexport type SleepFn = (delayMs: number) => Promise<void>;\n\nexport async function runWithBusyRetries<T>(\n operation: () => Promise<T>,\n options: {\n dbPath: string;\n maxBusyRetries: number;\n busyRetryDelayMs: number;\n sleep: SleepFn;\n },\n): Promise<T> {\n for (let attempt = 0; attempt <= options.maxBusyRetries; attempt += 1) {\n try {\n return await operation();\n } catch (error) {\n const isBusy = isBusyOrLockedSqliteError(error);\n\n if (isBusy && attempt < options.maxBusyRetries) {\n await options.sleep(options.busyRetryDelayMs * (attempt + 1));\n continue;\n }\n\n if (isBusy) {\n throw new Error(\n `OpenCode DB is busy/locked: ${options.dbPath}. Retries exhausted after ${options.maxBusyRetries + 1} attempt(s). Close active OpenCode processes and retry.`,\n { cause: error },\n );\n }\n\n throw new Error(\n `Could not read OpenCode DB at ${options.dbPath}: ${formatSqliteError(error)}`,\n { cause: error },\n );\n }\n }\n\n throw new Error('Unexpected OpenCode retry state: loop exhausted without result');\n}\n","import { asTrimmedText } from '../parsing-utils.js';\n\nexport type OpenCodeSqliteRow = Record<string, unknown>;\n\ntype OpenCodeSqliteDatabase = {\n prepare: (sql: string) => {\n all: (...anonymousParameters: unknown[]) => OpenCodeSqliteRow[];\n iterate?: (...anonymousParameters: unknown[]) => IterableIterator<OpenCodeSqliteRow>;\n };\n};\n\ntype MessageQueryColumns = {\n idColumn: string;\n timestampColumn: string;\n dataColumn: string;\n sessionIdColumn: string | undefined;\n};\n\nfunction shouldFallbackToNonJsonExtractQuery(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return /no such function:\\s*json_(?:extract|valid)|malformed JSON/iu.test(message);\n}\n\nfunction escapeIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction resolveIdentifierCaseInsensitive(\n identifiers: readonly string[],\n candidates: readonly string[],\n): string | undefined {\n for (const candidate of candidates) {\n const normalizedCandidate = candidate.toLowerCase();\n const matchedIdentifier = identifiers.find(\n (identifier) => identifier.toLowerCase() === normalizedCandidate,\n );\n\n if (matchedIdentifier) {\n return matchedIdentifier;\n }\n }\n\n return undefined;\n}\n\nfunction resolveRequiredMessageColumns(messageColumns: readonly string[]): MessageQueryColumns {\n const dataColumn = resolveIdentifierCaseInsensitive(messageColumns, ['data']);\n\n if (!dataColumn) {\n throw new Error(\n 'OpenCode schema drift: \"message.data\" column not found. Inspect schema with `opencode db` commands.',\n );\n }\n\n const idColumn = resolveIdentifierCaseInsensitive(messageColumns, ['id', 'message_id']);\n const timestampColumn = resolveIdentifierCaseInsensitive(messageColumns, [\n 'time_created',\n 'created_at',\n 'timestamp',\n ]);\n const sessionIdColumn = resolveIdentifierCaseInsensitive(messageColumns, [\n 'session_id',\n 'sessionid',\n ]);\n\n if (!idColumn || !timestampColumn) {\n throw new Error(\n 'OpenCode schema drift: required message id/timestamp columns are unavailable. Inspect schema with `opencode db` commands.',\n );\n }\n\n return {\n idColumn,\n timestampColumn,\n dataColumn,\n sessionIdColumn,\n };\n}\n\nfunction createPrimaryQuery(tableName: string, columns: MessageQueryColumns): string {\n const rowSessionId = columns.sessionIdColumn\n ? `${escapeIdentifier(columns.sessionIdColumn)} AS row_session_id`\n : 'NULL AS row_session_id';\n\n return [\n 'SELECT',\n ` ${escapeIdentifier(columns.idColumn)} AS row_id,`,\n ` ${escapeIdentifier(columns.timestampColumn)} AS row_time,`,\n ` ${rowSessionId},`,\n ` ${escapeIdentifier(columns.dataColumn)} AS data_json`,\n `FROM ${escapeIdentifier(tableName)}`,\n [\n 'WHERE CASE',\n ` WHEN json_valid(${escapeIdentifier(columns.dataColumn)}) = 1`,\n ` THEN lower(trim(coalesce(json_extract(${escapeIdentifier(columns.dataColumn)}, '$.role'), json_extract(${escapeIdentifier(columns.dataColumn)}, '$.type'))))`,\n \" ELSE 'assistant'\",\n \"END = 'assistant'\",\n ].join('\\n'),\n `ORDER BY ${escapeIdentifier(columns.timestampColumn)} ASC, ${escapeIdentifier(columns.idColumn)} ASC`,\n ].join('\\n');\n}\n\nfunction createFallbackQuery(tableName: string, columns: MessageQueryColumns): string {\n const rowSessionId = columns.sessionIdColumn\n ? `${escapeIdentifier(columns.sessionIdColumn)} AS row_session_id`\n : 'NULL AS row_session_id';\n\n return [\n 'SELECT',\n ` ${escapeIdentifier(columns.idColumn)} AS row_id,`,\n ` ${escapeIdentifier(columns.timestampColumn)} AS row_time,`,\n ` ${rowSessionId},`,\n ` ${escapeIdentifier(columns.dataColumn)} AS data_json`,\n `FROM ${escapeIdentifier(tableName)}`,\n `ORDER BY ${escapeIdentifier(columns.timestampColumn)} ASC, ${escapeIdentifier(columns.idColumn)} ASC`,\n ].join('\\n');\n}\n\nfunction resolveMessageTableName(database: OpenCodeSqliteDatabase): string {\n const tablesResult = database\n .prepare(\"SELECT name FROM sqlite_master WHERE type = 'table'\")\n .all()\n .map((row) => asTrimmedText(row.name))\n .filter((value): value is string => Boolean(value));\n const messageTableName = resolveIdentifierCaseInsensitive(tablesResult, ['message']);\n\n if (!messageTableName) {\n throw new Error(\n 'OpenCode schema drift: required \"message\" table not found. Inspect schema with `opencode db` commands.',\n );\n }\n\n return messageTableName;\n}\n\nfunction resolveMessageQueryColumns(\n database: OpenCodeSqliteDatabase,\n messageTableName: string,\n): MessageQueryColumns {\n const escapedMessageTableName = messageTableName.replaceAll(\"'\", \"''\");\n const messageColumns = database\n .prepare(`PRAGMA table_info('${escapedMessageTableName}')`)\n .all()\n .map((row) => asTrimmedText(row.name))\n .filter((value): value is string => Boolean(value));\n\n return resolveRequiredMessageColumns(messageColumns);\n}\n\nfunction executeQueryRows(\n database: OpenCodeSqliteDatabase,\n query: string,\n): Iterable<OpenCodeSqliteRow> {\n const statement = database.prepare(query);\n\n if (statement.iterate) {\n const iterator = statement.iterate();\n const firstResult = iterator.next();\n\n return (function* iterRows(): IterableIterator<OpenCodeSqliteRow> {\n if (!firstResult.done) {\n yield firstResult.value;\n }\n\n yield* iterator;\n })();\n }\n\n return statement.all();\n}\n\nexport function queryOpenCodeMessageRows(\n database: OpenCodeSqliteDatabase,\n): Iterable<OpenCodeSqliteRow> {\n const messageTableName = resolveMessageTableName(database);\n const columns = resolveMessageQueryColumns(database, messageTableName);\n const primaryQuery = createPrimaryQuery(messageTableName, columns);\n\n try {\n return executeQueryRows(database, primaryQuery);\n } catch (error) {\n if (!shouldFallbackToNonJsonExtractQuery(error)) {\n throw error;\n }\n\n return executeQueryRows(database, createFallbackQuery(messageTableName, columns));\n }\n}\n","import type { UsageEvent } from '../../domain/usage-event.js';\nimport { pathExists, pathIsFile, pathReadable } from '../../utils/fs-helpers.js';\nimport type { SourceAdapter, SourceParseFileDiagnostics } from '../source-adapter.js';\nimport { getDefaultOpenCodeDbPathCandidates } from './opencode-db-path-resolver.js';\nimport { loadNodeSqliteModule, type SqliteModule } from './node-sqlite-loader.js';\nimport { parseOpenCodeMessageRows } from './opencode-row-parser.js';\nimport { runWithBusyRetries, type SleepFn } from './opencode-retry-policy.js';\nimport { queryOpenCodeMessageRows } from './opencode-sqlite-query.js';\n\nconst DEFAULT_BUSY_RETRY_COUNT = 2;\nconst DEFAULT_BUSY_RETRY_DELAY_MS = 50;\n\ntype PathPredicate = (filePath: string) => Promise<boolean>;\n\nexport type OpenCodeSourceAdapterOptions = {\n dbPath?: string;\n resolveDefaultDbPaths?: () => string[];\n pathExists?: PathPredicate;\n pathReadable?: PathPredicate;\n pathIsFile?: PathPredicate;\n loadSqliteModule?: () => Promise<SqliteModule>;\n maxBusyRetries?: number;\n busyRetryDelayMs?: number;\n sleep?: SleepFn;\n};\n\nfunction isBlankText(value: string): boolean {\n return value.trim().length === 0;\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n}\n\nexport class OpenCodeSourceAdapter implements SourceAdapter {\n public readonly id = 'opencode' as const;\n\n private readonly explicitDbPath?: string;\n private readonly resolveDefaultDbPaths: () => string[];\n private readonly pathExists: PathPredicate;\n private readonly pathReadable: PathPredicate;\n private readonly pathIsFile: PathPredicate;\n private readonly loadSqliteModule: () => Promise<SqliteModule>;\n private readonly maxBusyRetries: number;\n private readonly busyRetryDelayMs: number;\n private readonly sleep: SleepFn;\n\n public constructor(options: OpenCodeSourceAdapterOptions = {}) {\n this.explicitDbPath = options.dbPath;\n this.resolveDefaultDbPaths =\n options.resolveDefaultDbPaths ?? getDefaultOpenCodeDbPathCandidates;\n this.pathExists = options.pathExists ?? pathExists;\n this.pathReadable = options.pathReadable ?? pathReadable;\n this.pathIsFile = options.pathIsFile ?? pathIsFile;\n this.loadSqliteModule = options.loadSqliteModule ?? loadNodeSqliteModule;\n this.maxBusyRetries = Math.max(0, options.maxBusyRetries ?? DEFAULT_BUSY_RETRY_COUNT);\n this.busyRetryDelayMs = Math.max(1, options.busyRetryDelayMs ?? DEFAULT_BUSY_RETRY_DELAY_MS);\n this.sleep = options.sleep ?? sleep;\n }\n\n public async discoverFiles(): Promise<string[]> {\n if (this.explicitDbPath !== undefined) {\n if (isBlankText(this.explicitDbPath)) {\n throw new Error('--opencode-db must be a non-empty path');\n }\n\n const explicitDbPath = this.explicitDbPath.trim();\n const readable = await this.pathReadable(explicitDbPath);\n\n if (!readable) {\n throw new Error(`OpenCode DB path is missing or unreadable: ${explicitDbPath}`);\n }\n\n if ((await this.pathExists(explicitDbPath)) && !(await this.pathIsFile(explicitDbPath))) {\n throw new Error(`OpenCode DB path is not a file: ${explicitDbPath}`);\n }\n\n return [explicitDbPath];\n }\n\n let firstUnreadableCandidatePath: string | undefined;\n\n for (const candidatePath of this.resolveDefaultDbPaths()) {\n if (await this.pathReadable(candidatePath)) {\n if ((await this.pathExists(candidatePath)) && !(await this.pathIsFile(candidatePath))) {\n throw new Error(`OpenCode DB path is not a file: ${candidatePath}`);\n }\n\n return [candidatePath];\n }\n\n if (!firstUnreadableCandidatePath && (await this.pathExists(candidatePath))) {\n firstUnreadableCandidatePath = candidatePath;\n }\n }\n\n if (firstUnreadableCandidatePath) {\n throw new Error(`OpenCode DB path is unreadable: ${firstUnreadableCandidatePath}`);\n }\n\n return [];\n }\n\n public async parseFile(dbPath: string): Promise<UsageEvent[]> {\n const parseDiagnostics = await this.parseFileWithDiagnostics(dbPath);\n return parseDiagnostics.events;\n }\n\n public async parseFileWithDiagnostics(dbPath: string): Promise<SourceParseFileDiagnostics> {\n if (isBlankText(dbPath)) {\n throw new Error('OpenCode DB path must be a non-empty path');\n }\n\n const normalizedDbPath = dbPath.trim();\n const readable = await this.pathReadable(normalizedDbPath);\n\n if (!readable) {\n throw new Error(`OpenCode DB path is unreadable: ${normalizedDbPath}`);\n }\n\n if ((await this.pathExists(normalizedDbPath)) && !(await this.pathIsFile(normalizedDbPath))) {\n throw new Error(`OpenCode DB path is not a file: ${normalizedDbPath}`);\n }\n\n return runWithBusyRetries(() => this.parseFileOnce(normalizedDbPath), {\n dbPath: normalizedDbPath,\n maxBusyRetries: this.maxBusyRetries,\n busyRetryDelayMs: this.busyRetryDelayMs,\n sleep: this.sleep,\n });\n }\n\n private async parseFileOnce(dbPath: string): Promise<SourceParseFileDiagnostics> {\n const sqlite = await this.loadSqliteModule();\n const database = new sqlite.DatabaseSync(dbPath, { readOnly: true, timeout: 0 });\n\n try {\n const messageRows = queryOpenCodeMessageRows(database);\n return parseOpenCodeMessageRows(messageRows, this.id);\n } finally {\n database.close();\n }\n }\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport type { NumberLike } from '../../domain/normalization.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverJsonlFiles } from '../../utils/discover-jsonl-files.js';\nimport { pathIsDirectory, pathReadable } from '../../utils/fs-helpers.js';\nimport { readJsonlObjects } from '../../utils/read-jsonl-objects.js';\nimport { asTrimmedText, isBlankText, toNumberLike } from '../parsing-utils.js';\nimport type { SourceAdapter } from '../source-adapter.js';\n\nconst defaultSessionsDir = path.join(os.homedir(), '.pi', 'agent', 'sessions');\n\ntype ProviderFilter = (provider: string | undefined) => boolean;\n\ntype PiSessionState = {\n sessionId?: string;\n sessionTimestamp?: string;\n repoRoot?: string;\n provider?: string;\n model?: string;\n};\n\ntype PiUsageExtract = {\n inputTokens?: NumberLike;\n outputTokens?: NumberLike;\n reasoningTokens?: NumberLike;\n cacheReadTokens?: NumberLike;\n cacheWriteTokens?: NumberLike;\n totalTokens?: NumberLike;\n costUsd?: NumberLike;\n};\n\nexport type PiSourceAdapterOptions = {\n sessionsDir?: string;\n providerFilter?: ProviderFilter;\n requireSessionsDir?: boolean;\n};\n\nconst PI_MESSAGE_LINE_PATTERN = /\"type\"\\s*:\\s*\"message\"/u;\nconst PI_SESSION_LINE_PATTERN = /\"type\"\\s*:\\s*\"session\"/u;\nconst PI_MODEL_CHANGE_LINE_PATTERN = /\"type\"\\s*:\\s*\"model_change\"/u;\n\nfunction shouldParsePiJsonlLine(lineText: string): boolean {\n return (\n PI_MESSAGE_LINE_PATTERN.test(lineText) ||\n PI_SESSION_LINE_PATTERN.test(lineText) ||\n PI_MODEL_CHANGE_LINE_PATTERN.test(lineText)\n );\n}\n\nconst allowAllProviders: ProviderFilter = () => true;\n\nconst UNIX_SECONDS_ABS_CUTOFF = 10_000_000_000;\n\nfunction normalizeTimestampCandidate(candidate: unknown): string | undefined {\n let date: Date | undefined;\n\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n const timestampMs =\n Math.abs(candidate) <= UNIX_SECONDS_ABS_CUTOFF ? candidate * 1000 : candidate;\n date = new Date(timestampMs);\n } else {\n const normalizedText = asTrimmedText(candidate);\n\n if (!normalizedText) {\n return undefined;\n }\n\n date = new Date(normalizedText);\n }\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n}\n\nfunction resolveTimestamp(\n line: Record<string, unknown>,\n message: Record<string, unknown> | undefined,\n state: PiSessionState,\n): string | undefined {\n const candidates = [line.timestamp, message?.timestamp, state.sessionTimestamp];\n\n for (const candidate of candidates) {\n const normalizedTimestamp = normalizeTimestampCandidate(candidate);\n\n if (normalizedTimestamp) {\n return normalizedTimestamp;\n }\n }\n\n return undefined;\n}\n\nfunction extractUsageFromRecord(usage: Record<string, unknown>): PiUsageExtract | undefined {\n const cost = asRecord(usage.cost);\n\n const extracted: PiUsageExtract = {\n inputTokens: toNumberLike(usage.input),\n outputTokens: toNumberLike(usage.output),\n reasoningTokens: toNumberLike(\n usage.reasoning ?? usage.reasoningTokens ?? usage.reasoningOutput ?? usage.outputReasoning,\n ),\n cacheReadTokens: toNumberLike(usage.cacheRead),\n cacheWriteTokens: toNumberLike(usage.cacheWrite),\n totalTokens: toNumberLike(usage.totalTokens),\n costUsd: toNumberLike(cost?.total),\n };\n\n const toFiniteNumber = (value: NumberLike | undefined): number | undefined => {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n if (typeof value === 'string' && value.trim().length === 0) {\n return undefined;\n }\n\n const parsed = typeof value === 'number' ? value : Number(value);\n\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n\n return parsed;\n };\n\n const usageCandidates = [\n extracted.inputTokens,\n extracted.outputTokens,\n extracted.reasoningTokens,\n extracted.cacheReadTokens,\n extracted.cacheWriteTokens,\n extracted.totalTokens,\n ];\n const hasPositiveUsageSignal = usageCandidates.some((value) => {\n const parsed = toFiniteNumber(value);\n return parsed !== undefined && parsed > 0;\n });\n const explicitCost = toFiniteNumber(extracted.costUsd);\n const hasPositiveCostSignal = explicitCost !== undefined && explicitCost > 0;\n\n return hasPositiveUsageSignal || hasPositiveCostSignal ? extracted : undefined;\n}\n\nfunction extractUsage(line: Record<string, unknown>, message: Record<string, unknown> | undefined) {\n const lineUsage = asRecord(line.usage);\n const messageUsage = asRecord(message?.usage);\n\n if (lineUsage) {\n const extractedLineUsage = extractUsageFromRecord(lineUsage);\n\n if (extractedLineUsage) {\n return extractedLineUsage;\n }\n }\n\n if (!messageUsage) {\n return undefined;\n }\n\n return extractUsageFromRecord(messageUsage);\n}\n\nfunction getFallbackSessionId(filePath: string): string {\n return path.basename(filePath, '.jsonl');\n}\n\nfunction resolveRepoRootFromRecord(\n record: Record<string, unknown> | undefined,\n): string | undefined {\n if (!record) {\n return undefined;\n }\n\n const pathRecord = asRecord(record.path);\n\n return (\n asTrimmedText(pathRecord?.root) ??\n asTrimmedText(pathRecord?.cwd) ??\n asTrimmedText(record.cwd) ??\n asTrimmedText(record.repo_root) ??\n asTrimmedText(record.repoRoot) ??\n asTrimmedText(record.project_root) ??\n asTrimmedText(record.projectRoot)\n );\n}\n\nexport class PiSourceAdapter implements SourceAdapter {\n public readonly id = 'pi' as const;\n\n private readonly sessionsDir: string;\n private readonly providerFilter: ProviderFilter;\n private readonly requireSessionsDir: boolean;\n\n public constructor(options: PiSourceAdapterOptions = {}) {\n this.sessionsDir = options.sessionsDir ?? defaultSessionsDir;\n this.providerFilter = options.providerFilter ?? allowAllProviders;\n this.requireSessionsDir = options.requireSessionsDir ?? false;\n }\n\n public async discoverFiles(): Promise<string[]> {\n if (isBlankText(this.sessionsDir)) {\n throw new Error('PI sessions directory must be a non-empty path');\n }\n\n const normalizedSessionsDir = this.sessionsDir.trim();\n\n if (this.requireSessionsDir && !(await pathReadable(normalizedSessionsDir))) {\n throw new Error(`PI sessions directory is missing or unreadable: ${normalizedSessionsDir}`);\n }\n\n if (this.requireSessionsDir && !(await pathIsDirectory(normalizedSessionsDir))) {\n throw new Error(`PI sessions directory is not a directory: ${normalizedSessionsDir}`);\n }\n\n return discoverJsonlFiles(normalizedSessionsDir);\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const events: UsageEvent[] = [];\n const state: PiSessionState = { sessionId: getFallbackSessionId(filePath) };\n\n for await (const line of readJsonlObjects(filePath, {\n shouldParseLine: shouldParsePiJsonlLine,\n })) {\n if (line.type === 'session') {\n state.sessionId = asTrimmedText(line.id) ?? state.sessionId;\n state.sessionTimestamp = asTrimmedText(line.timestamp) ?? state.sessionTimestamp;\n state.repoRoot = resolveRepoRootFromRecord(line) ?? state.repoRoot;\n continue;\n }\n\n if (line.type === 'model_change') {\n state.provider = asTrimmedText(line.provider) ?? state.provider;\n state.model = asTrimmedText(line.modelId) ?? asTrimmedText(line.model) ?? state.model;\n state.repoRoot = resolveRepoRootFromRecord(line) ?? state.repoRoot;\n continue;\n }\n\n if (line.type !== 'message') {\n continue;\n }\n\n const message = asRecord(line.message);\n const usage = extractUsage(line, message);\n\n if (!usage) {\n continue;\n }\n\n const provider =\n asTrimmedText(line.provider) ?? asTrimmedText(message?.provider) ?? state.provider;\n\n if (!this.providerFilter(provider)) {\n continue;\n }\n\n const timestamp = resolveTimestamp(line, message, state);\n\n if (!timestamp || !state.sessionId) {\n continue;\n }\n\n const model =\n asTrimmedText(line.model) ??\n asTrimmedText(line.modelId) ??\n asTrimmedText(message?.model) ??\n state.model;\n const repoRoot =\n resolveRepoRootFromRecord(line) ?? resolveRepoRootFromRecord(message) ?? state.repoRoot;\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId: state.sessionId,\n timestamp,\n repoRoot,\n provider,\n model,\n ...usage,\n }),\n );\n } catch {\n continue;\n }\n }\n\n return events;\n }\n}\n\nexport function getDefaultPiSessionsDir(): string {\n return defaultSessionsDir;\n}\n","import { CodexSourceAdapter } from './codex/codex-source-adapter.js';\nimport { DroidSourceAdapter } from './droid/droid-source-adapter.js';\nimport { GeminiSourceAdapter } from './gemini/gemini-source-adapter.js';\nimport { OpenCodeSourceAdapter } from './opencode/opencode-source-adapter.js';\nimport { PiSourceAdapter } from './pi/pi-source-adapter.js';\nimport type { SourceAdapter } from './source-adapter.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\ntype SourceRegistration = {\n id: string;\n sourceDirOverride: { kind: 'directory' } | { kind: 'unsupported'; flag: string };\n create: (\n options: CreateDefaultAdaptersOptions,\n sourceDirectoryOverrides: ReadonlyMap<string, string>,\n ) => SourceAdapter;\n};\n\nexport type CreateDefaultAdaptersOptions = {\n piDir?: string;\n codexDir?: string;\n geminiDir?: string;\n droidDir?: string;\n opencodeDb?: string;\n sourceDir?: string[];\n};\n\nfunction parseSourceDirectoryOverrides(entries: string[] | undefined): Map<string, string> {\n const overrides = new Map<string, string>();\n\n if (!entries || entries.length === 0) {\n return overrides;\n }\n\n for (const entry of entries) {\n const separatorIndex = entry.indexOf('=');\n\n if (separatorIndex <= 0 || separatorIndex >= entry.length - 1) {\n throw new Error('--source-dir must use format <source-id>=<path>');\n }\n\n const sourceId = entry.slice(0, separatorIndex).trim().toLowerCase();\n const directoryPath = entry.slice(separatorIndex + 1).trim();\n\n if (!sourceId || !directoryPath) {\n throw new Error('--source-dir must use non-empty <source-id>=<path> values');\n }\n\n if (overrides.has(sourceId)) {\n throw new Error(`Duplicate --source-dir source id: ${sourceId}`);\n }\n\n overrides.set(sourceId, directoryPath);\n }\n\n return overrides;\n}\n\nconst sourceRegistrations: readonly SourceRegistration[] = [\n {\n id: 'pi',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig('pi', options.piDir, sourceDirectoryOverrides);\n\n return new PiSourceAdapter({\n sessionsDir: directoryConfig.path,\n requireSessionsDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'codex',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig(\n 'codex',\n options.codexDir,\n sourceDirectoryOverrides,\n );\n\n return new CodexSourceAdapter({\n sessionsDir: directoryConfig.path,\n requireSessionsDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'gemini',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig(\n 'gemini',\n options.geminiDir,\n sourceDirectoryOverrides,\n );\n\n return new GeminiSourceAdapter({\n geminiDir: directoryConfig.path,\n requireGeminiDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'droid',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig(\n 'droid',\n options.droidDir,\n sourceDirectoryOverrides,\n );\n\n return new DroidSourceAdapter({\n sessionsDir: directoryConfig.path,\n requireSessionsDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'opencode',\n sourceDirOverride: { kind: 'unsupported', flag: '--opencode-db' },\n create: (options) =>\n new OpenCodeSourceAdapter({\n dbPath: options.opencodeDb,\n }),\n },\n];\n\nconst sourceDirUnsupportedFlags = new Map(\n sourceRegistrations\n .filter(\n (\n source,\n ): source is SourceRegistration & {\n sourceDirOverride: { kind: 'unsupported'; flag: string };\n } => source.sourceDirOverride.kind === 'unsupported',\n )\n .map((source) => [source.id, source.sourceDirOverride.flag]),\n);\n\nconst sourceDirSupportedIds = new Set(\n sourceRegistrations\n .filter(\n (source): source is SourceRegistration & { sourceDirOverride: { kind: 'directory' } } =>\n source.sourceDirOverride.kind === 'directory',\n )\n .map((source) => source.id),\n);\n\nfunction validateSourceDirectoryOverrideIds(\n sourceDirectoryOverrides: ReadonlyMap<string, string>,\n): void {\n const nonDirectorySourceOverrides = [...sourceDirectoryOverrides.keys()].filter((sourceId) =>\n sourceDirUnsupportedFlags.has(sourceId),\n );\n\n if (nonDirectorySourceOverrides.length > 0) {\n const sourceId = nonDirectorySourceOverrides[0];\n const flag = sourceDirUnsupportedFlags.get(sourceId);\n\n throw new Error(`--source-dir does not support \"${sourceId}\". Use ${flag} instead.`);\n }\n\n const unknownSourceIds = [...sourceDirectoryOverrides.keys()].filter(\n (sourceId) => !sourceDirSupportedIds.has(sourceId),\n );\n\n if (unknownSourceIds.length === 0) {\n return;\n }\n\n const allowedSourceIds = [...sourceDirSupportedIds].sort(compareByCodePoint);\n\n throw new Error(\n `Unknown --source-dir source id(s): ${unknownSourceIds.join(', ')}. Allowed values: ${allowedSourceIds.join(', ')}`,\n );\n}\n\nfunction validateOpencodeOverride(opencodeDb: string | undefined): void {\n if (opencodeDb === undefined) {\n return;\n }\n\n if (opencodeDb.trim().length === 0) {\n throw new Error('--opencode-db must be a non-empty path');\n }\n}\n\nfunction validateDirectoryOverride(\n optionName: '--pi-dir' | '--codex-dir' | '--gemini-dir' | '--droid-dir',\n value: string | undefined,\n): void {\n if (value === undefined) {\n return;\n }\n\n if (value.trim().length === 0) {\n throw new Error(`${optionName} must be a non-empty path`);\n }\n}\n\nfunction resolveDirectoryConfig(\n sourceId: string,\n explicitDirectory: string | undefined,\n sourceDirectoryOverrides: ReadonlyMap<string, string>,\n): {\n path: string | undefined;\n requireExistingPath: boolean;\n} {\n if (explicitDirectory !== undefined) {\n return {\n path: explicitDirectory,\n requireExistingPath: true,\n };\n }\n\n const sourceDirOverride = sourceDirectoryOverrides.get(sourceId);\n\n if (sourceDirOverride !== undefined) {\n return {\n path: sourceDirOverride,\n requireExistingPath: true,\n };\n }\n\n return {\n path: undefined,\n requireExistingPath: false,\n };\n}\n\nexport function getDefaultSourceIds(): string[] {\n return sourceRegistrations.map((source) => source.id);\n}\n\nexport function createDefaultAdapters(options: CreateDefaultAdaptersOptions): SourceAdapter[] {\n validateOpencodeOverride(options.opencodeDb);\n validateDirectoryOverride('--pi-dir', options.piDir);\n validateDirectoryOverride('--codex-dir', options.codexDir);\n validateDirectoryOverride('--gemini-dir', options.geminiDir);\n validateDirectoryOverride('--droid-dir', options.droidDir);\n\n const sourceDirectoryOverrides = parseSourceDirectoryOverrides(options.sourceDir);\n validateSourceDirectoryOverrideIds(sourceDirectoryOverrides);\n\n return sourceRegistrations.map((source) => source.create(options, sourceDirectoryOverrides));\n}\n","export type ReportGranularity = 'daily' | 'weekly' | 'monthly';\n\ntype LocalDateParts = {\n year: number;\n month: number;\n day: number;\n};\n\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\n\nfunction getDateFormatter(timezone: string): Intl.DateTimeFormat {\n const cachedFormatter = formatterCache.get(timezone);\n\n if (cachedFormatter) {\n return cachedFormatter;\n }\n\n const formatter = new Intl.DateTimeFormat('en-CA', {\n timeZone: timezone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n });\n formatterCache.set(timezone, formatter);\n return formatter;\n}\n\nfunction extractLocalDateParts(timestampIso: string, timezone: string): LocalDateParts {\n const date = new Date(timestampIso);\n\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid event timestamp: ${timestampIso}`);\n }\n\n const formatter = getDateFormatter(timezone);\n const parts = formatter.formatToParts(date);\n\n const year = Number(parts.find((part) => part.type === 'year')?.value);\n const month = Number(parts.find((part) => part.type === 'month')?.value);\n const day = Number(parts.find((part) => part.type === 'day')?.value);\n\n if (!year || !month || !day) {\n throw new Error(`Could not resolve local date parts for timestamp: ${timestampIso}`);\n }\n\n return { year, month, day };\n}\n\nfunction createUtcDate(localDate: LocalDateParts): Date {\n return new Date(Date.UTC(localDate.year, localDate.month - 1, localDate.day));\n}\n\nfunction addDays(date: Date, days: number): Date {\n return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);\n}\n\nfunction toIsoDayOfWeek(date: Date): number {\n const utcDay = date.getUTCDay();\n return utcDay === 0 ? 7 : utcDay;\n}\n\nfunction getIsoWeekParts(localDate: LocalDateParts): { weekYear: number; weekNumber: number } {\n const localUtcDate = createUtcDate(localDate);\n const isoDay = toIsoDayOfWeek(localUtcDate);\n\n const currentWeekMonday = addDays(localUtcDate, -(isoDay - 1));\n const currentWeekThursday = addDays(localUtcDate, 4 - isoDay);\n const weekYear = currentWeekThursday.getUTCFullYear();\n\n const jan4 = new Date(Date.UTC(weekYear, 0, 4));\n const jan4IsoDay = toIsoDayOfWeek(jan4);\n const firstWeekMonday = addDays(jan4, -(jan4IsoDay - 1));\n\n const diffMs = currentWeekMonday.getTime() - firstWeekMonday.getTime();\n const weekNumber = Math.floor(diffMs / (7 * 24 * 60 * 60 * 1000)) + 1;\n\n return { weekYear, weekNumber };\n}\n\nexport function getPeriodKey(\n timestampIso: string,\n granularity: ReportGranularity,\n timezone: string,\n): string {\n const localDate = extractLocalDateParts(timestampIso, timezone);\n\n if (granularity === 'daily') {\n return `${localDate.year}-${String(localDate.month).padStart(2, '0')}-${String(localDate.day).padStart(2, '0')}`;\n }\n\n if (granularity === 'monthly') {\n return `${localDate.year}-${String(localDate.month).padStart(2, '0')}`;\n }\n\n const isoWeek = getIsoWeekParts(localDate);\n return `${isoWeek.weekYear}-W${String(isoWeek.weekNumber).padStart(2, '0')}`;\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport type {\n GrandTotalRow,\n ModelUsageBreakdown,\n PeriodCombinedRow,\n PeriodSourceRow,\n UsageReportRow,\n UsageTotals,\n} from '../domain/usage-report-row.js';\nimport { normalizeModelList } from '../domain/normalization.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport { getPeriodKey, type ReportGranularity } from '../utils/time-buckets.js';\n\nexport type AggregateUsageOptions = {\n granularity: ReportGranularity;\n timezone: string;\n sourceOrder?: string[];\n};\n\ntype RowAccumulator = {\n totals: UsageTotals;\n modelTotals: Map<string, UsageTotals>;\n};\n\nconst USD_PRECISION_SCALE = 1_000_000_000_000;\n\nfunction addUsd(left: number, right: number): number {\n return Math.round((left + right) * USD_PRECISION_SCALE) / USD_PRECISION_SCALE;\n}\n\nfunction createEmptyTotals(): UsageTotals {\n return {\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n totalTokens: 0,\n };\n}\n\nfunction createRowAccumulator(): RowAccumulator {\n return {\n totals: createEmptyTotals(),\n modelTotals: new Map<string, UsageTotals>(),\n };\n}\n\nfunction addEventToTotals(target: UsageTotals, event: UsageEvent): void {\n target.inputTokens += event.inputTokens;\n target.outputTokens += event.outputTokens;\n target.reasoningTokens += event.reasoningTokens;\n target.cacheReadTokens += event.cacheReadTokens;\n target.cacheWriteTokens += event.cacheWriteTokens;\n target.totalTokens += event.totalTokens;\n\n if (event.costUsd === undefined) {\n target.costIncomplete = true;\n return;\n }\n\n target.costUsd = addUsd(target.costUsd ?? 0, event.costUsd);\n}\n\nfunction normalizeModelKey(model: string | undefined): string | undefined {\n if (!model) {\n return undefined;\n }\n\n const normalized = model.trim().toLowerCase();\n return normalized || undefined;\n}\n\nfunction addEventToAccumulator(accumulator: RowAccumulator, event: UsageEvent): void {\n addEventToTotals(accumulator.totals, event);\n\n const normalizedModel = normalizeModelKey(event.model);\n\n if (!normalizedModel) {\n return;\n }\n\n const existingTotals = accumulator.modelTotals.get(normalizedModel) ?? createEmptyTotals();\n addEventToTotals(existingTotals, event);\n accumulator.modelTotals.set(normalizedModel, existingTotals);\n}\n\nfunction addTotals(target: UsageTotals, source: UsageTotals): void {\n target.inputTokens += source.inputTokens;\n target.outputTokens += source.outputTokens;\n target.reasoningTokens += source.reasoningTokens;\n target.cacheReadTokens += source.cacheReadTokens;\n target.cacheWriteTokens += source.cacheWriteTokens;\n target.totalTokens += source.totalTokens;\n\n if (source.costUsd !== undefined) {\n target.costUsd = addUsd(target.costUsd ?? 0, source.costUsd);\n }\n\n if (source.costIncomplete) {\n target.costIncomplete = true;\n }\n}\n\nfunction mergeModelTotals(\n targetModelTotals: Map<string, UsageTotals>,\n sourceModelTotals: ReadonlyMap<string, UsageTotals>,\n): void {\n for (const [model, sourceTotals] of sourceModelTotals) {\n const targetTotals = targetModelTotals.get(model) ?? createEmptyTotals();\n addTotals(targetTotals, sourceTotals);\n targetModelTotals.set(model, targetTotals);\n }\n}\n\nfunction toModelUsageBreakdown(\n modelTotals: ReadonlyMap<string, UsageTotals>,\n): ModelUsageBreakdown[] {\n const sortedModels = normalizeModelList(modelTotals.keys());\n\n return sortedModels.map((model) => {\n const totals = modelTotals.get(model) ?? createEmptyTotals();\n\n return {\n model,\n ...totals,\n };\n });\n}\n\nfunction sourceSortComparator(\n left: string,\n right: string,\n sourceWeightMap: ReadonlyMap<string, number>,\n): number {\n const leftWeight = sourceWeightMap.get(left) ?? Number.MAX_SAFE_INTEGER;\n const rightWeight = sourceWeightMap.get(right) ?? Number.MAX_SAFE_INTEGER;\n\n if (leftWeight !== rightWeight) {\n return leftWeight - rightWeight;\n }\n\n return compareByCodePoint(left, right);\n}\n\nexport function aggregateUsage(\n events: UsageEvent[],\n options: AggregateUsageOptions,\n): UsageReportRow[] {\n const sourceWeightMap = new Map<string, number>();\n\n for (const [index, source] of (options.sourceOrder ?? []).entries()) {\n sourceWeightMap.set(source, index);\n }\n\n const periodMap = new Map<string, Map<string, RowAccumulator>>();\n\n for (const event of events) {\n const periodKey = getPeriodKey(event.timestamp, options.granularity, options.timezone);\n const periodSources = periodMap.get(periodKey) ?? new Map<string, RowAccumulator>();\n periodMap.set(periodKey, periodSources);\n\n const rowAccumulator = periodSources.get(event.source) ?? createRowAccumulator();\n periodSources.set(event.source, rowAccumulator);\n\n addEventToAccumulator(rowAccumulator, event);\n }\n\n const sortedPeriodKeys = [...periodMap.keys()].sort(compareByCodePoint);\n const rows: UsageReportRow[] = [];\n const grandTotals = createEmptyTotals();\n const grandModelTotals = new Map<string, UsageTotals>();\n\n for (const periodKey of sortedPeriodKeys) {\n const sourceMap = periodMap.get(periodKey);\n\n if (!sourceMap) {\n continue;\n }\n\n const periodCombinedTotals = createEmptyTotals();\n const periodCombinedModelTotals = new Map<string, UsageTotals>();\n\n const sortedSources = [...sourceMap.keys()].sort((left, right) =>\n sourceSortComparator(left, right, sourceWeightMap),\n );\n\n for (const source of sortedSources) {\n const accumulator = sourceMap.get(source);\n\n if (!accumulator) {\n continue;\n }\n\n const sourceRow: PeriodSourceRow = {\n rowType: 'period_source',\n periodKey,\n source,\n models: normalizeModelList(accumulator.modelTotals.keys()),\n modelBreakdown: toModelUsageBreakdown(accumulator.modelTotals),\n ...accumulator.totals,\n };\n\n rows.push(sourceRow);\n\n addTotals(periodCombinedTotals, accumulator.totals);\n addTotals(grandTotals, accumulator.totals);\n mergeModelTotals(periodCombinedModelTotals, accumulator.modelTotals);\n mergeModelTotals(grandModelTotals, accumulator.modelTotals);\n }\n\n if (sortedSources.length > 1) {\n const combinedRow: PeriodCombinedRow = {\n rowType: 'period_combined',\n periodKey,\n source: 'combined',\n models: normalizeModelList(periodCombinedModelTotals.keys()),\n modelBreakdown: toModelUsageBreakdown(periodCombinedModelTotals),\n ...periodCombinedTotals,\n };\n\n rows.push(combinedRow);\n }\n }\n\n const finalizedGrandTotals =\n events.length === 0 && grandTotals.costUsd === undefined && grandTotals.costIncomplete !== true\n ? { ...grandTotals, costUsd: 0 }\n : grandTotals;\n\n const grandTotalRow: GrandTotalRow = {\n rowType: 'grand_total',\n periodKey: 'ALL',\n source: 'combined',\n models: normalizeModelList(grandModelTotals.keys()),\n modelBreakdown: toModelUsageBreakdown(grandModelTotals),\n ...finalizedGrandTotals,\n };\n\n rows.push(grandTotalRow);\n\n return rows;\n}\n","export type EfficiencyUsageTotals = {\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n totalTokens: number;\n costUsd?: number;\n costIncomplete?: boolean;\n};\n\nexport type EfficiencyOutcomeTotals = {\n commitCount: number;\n linesAdded: number;\n linesDeleted: number;\n linesChanged: number;\n};\n\nexport type EfficiencyDerivedMetrics = {\n usdPerCommit?: number;\n usdPer1kLinesChanged?: number;\n tokensPerCommit?: number;\n nonCacheTokensPerCommit?: number;\n commitsPerUsd?: number;\n};\n\nexport type EfficiencyPeriodRow = EfficiencyUsageTotals &\n EfficiencyOutcomeTotals &\n EfficiencyDerivedMetrics & {\n rowType: 'period';\n periodKey: string;\n };\n\nexport type EfficiencyGrandTotalRow = EfficiencyUsageTotals &\n EfficiencyOutcomeTotals &\n EfficiencyDerivedMetrics & {\n rowType: 'grand_total';\n periodKey: 'ALL';\n };\n\nexport type EfficiencyRow = EfficiencyPeriodRow | EfficiencyGrandTotalRow;\n\nexport function createEmptyEfficiencyUsageTotals(): EfficiencyUsageTotals {\n return {\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n totalTokens: 0,\n costUsd: 0,\n };\n}\n\nexport function createEmptyEfficiencyOutcomeTotals(): EfficiencyOutcomeTotals {\n return {\n commitCount: 0,\n linesAdded: 0,\n linesDeleted: 0,\n linesChanged: 0,\n };\n}\n","import type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport {\n createEmptyEfficiencyOutcomeTotals,\n createEmptyEfficiencyUsageTotals,\n type EfficiencyDerivedMetrics,\n type EfficiencyOutcomeTotals,\n type EfficiencyRow,\n type EfficiencyUsageTotals,\n} from './efficiency-row.js';\n\nconst USD_PRECISION_SCALE = 1_000_000_000_000;\n\nexport type AggregateEfficiencyOptions = {\n usageRows: UsageReportRow[];\n periodOutcomes: ReadonlyMap<string, EfficiencyOutcomeTotals>;\n};\n\nfunction addUsd(left: number, right: number): number {\n return Math.round((left + right) * USD_PRECISION_SCALE) / USD_PRECISION_SCALE;\n}\n\nfunction toUsageTotals(row: UsageReportRow): EfficiencyUsageTotals {\n return {\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n costUsd: row.costUsd,\n costIncomplete: row.costIncomplete,\n };\n}\n\nfunction buildUsageTotalsByPeriod(usageRows: UsageReportRow[]): Map<string, EfficiencyUsageTotals> {\n const combinedByPeriod = new Map<string, EfficiencyUsageTotals>();\n const sourceByPeriod = new Map<string, EfficiencyUsageTotals>();\n\n for (const row of usageRows) {\n if (row.rowType === 'grand_total') {\n continue;\n }\n\n if (row.rowType === 'period_combined') {\n combinedByPeriod.set(row.periodKey, toUsageTotals(row));\n continue;\n }\n\n const existingSourceTotals =\n sourceByPeriod.get(row.periodKey) ?? createEmptyEfficiencyUsageTotals();\n sourceByPeriod.set(row.periodKey, addUsageTotals(existingSourceTotals, toUsageTotals(row)));\n }\n\n const periodKeys = new Set<string>([...combinedByPeriod.keys(), ...sourceByPeriod.keys()]);\n const usageTotalsByPeriod = new Map<string, EfficiencyUsageTotals>();\n\n for (const periodKey of periodKeys) {\n usageTotalsByPeriod.set(\n periodKey,\n combinedByPeriod.get(periodKey) ??\n sourceByPeriod.get(periodKey) ??\n createEmptyEfficiencyUsageTotals(),\n );\n }\n\n return usageTotalsByPeriod;\n}\n\nfunction addOutcomeTotals(\n left: EfficiencyOutcomeTotals,\n right: EfficiencyOutcomeTotals,\n): EfficiencyOutcomeTotals {\n return {\n commitCount: left.commitCount + right.commitCount,\n linesAdded: left.linesAdded + right.linesAdded,\n linesDeleted: left.linesDeleted + right.linesDeleted,\n linesChanged: left.linesChanged + right.linesChanged,\n };\n}\n\nfunction addUsageTotals(\n left: EfficiencyUsageTotals,\n right: EfficiencyUsageTotals,\n): EfficiencyUsageTotals {\n const hasUnknownCost =\n (left.costIncomplete === true && left.costUsd === undefined) ||\n (right.costIncomplete === true && right.costUsd === undefined);\n const isNeutralZeroCost = (value: EfficiencyUsageTotals): boolean =>\n value.totalTokens === 0 && value.costUsd === 0 && value.costIncomplete !== true;\n const leftKnownCost =\n left.costUsd !== undefined && !isNeutralZeroCost(left) ? left.costUsd : undefined;\n const rightKnownCost =\n right.costUsd !== undefined && !isNeutralZeroCost(right) ? right.costUsd : undefined;\n\n let costUsd =\n leftKnownCost !== undefined && rightKnownCost !== undefined\n ? addUsd(leftKnownCost, rightKnownCost)\n : (leftKnownCost ?? rightKnownCost);\n\n if (hasUnknownCost && (costUsd === undefined || costUsd === 0)) {\n costUsd = undefined;\n }\n\n return {\n inputTokens: left.inputTokens + right.inputTokens,\n outputTokens: left.outputTokens + right.outputTokens,\n reasoningTokens: left.reasoningTokens + right.reasoningTokens,\n cacheReadTokens: left.cacheReadTokens + right.cacheReadTokens,\n cacheWriteTokens: left.cacheWriteTokens + right.cacheWriteTokens,\n totalTokens: left.totalTokens + right.totalTokens,\n costUsd,\n costIncomplete: left.costIncomplete || right.costIncomplete ? true : undefined,\n };\n}\n\nfunction computeDerivedMetrics(\n usage: EfficiencyUsageTotals,\n outcomes: EfficiencyOutcomeTotals,\n): EfficiencyDerivedMetrics {\n const costUsd = usage.costUsd;\n const nonCacheTotalTokens = usage.inputTokens + usage.outputTokens + usage.reasoningTokens;\n\n return {\n usdPerCommit:\n costUsd !== undefined && outcomes.commitCount > 0\n ? costUsd / outcomes.commitCount\n : undefined,\n usdPer1kLinesChanged:\n costUsd !== undefined && outcomes.linesChanged > 0\n ? costUsd / (outcomes.linesChanged / 1_000)\n : undefined,\n tokensPerCommit:\n outcomes.commitCount > 0 ? usage.totalTokens / outcomes.commitCount : undefined,\n nonCacheTokensPerCommit:\n outcomes.commitCount > 0 ? nonCacheTotalTokens / outcomes.commitCount : undefined,\n commitsPerUsd:\n costUsd !== undefined && costUsd > 0 ? outcomes.commitCount / costUsd : undefined,\n };\n}\n\nexport function aggregateEfficiency(options: AggregateEfficiencyOptions): EfficiencyRow[] {\n const usageTotalsByPeriod = buildUsageTotalsByPeriod(options.usageRows);\n const periodKeys = [\n ...new Set([...usageTotalsByPeriod.keys(), ...options.periodOutcomes.keys()]),\n ].sort(compareByCodePoint);\n\n const rows: EfficiencyRow[] = [];\n let totalUsage = createEmptyEfficiencyUsageTotals();\n let totalOutcomes = createEmptyEfficiencyOutcomeTotals();\n\n for (const periodKey of periodKeys) {\n const usageTotals = usageTotalsByPeriod.get(periodKey) ?? createEmptyEfficiencyUsageTotals();\n const outcomeTotals =\n options.periodOutcomes.get(periodKey) ?? createEmptyEfficiencyOutcomeTotals();\n const hasUsageRow = usageTotalsByPeriod.has(periodKey);\n const hasUsageSignal =\n hasUsageRow &&\n (usageTotals.totalTokens > 0 ||\n usageTotals.costUsd !== undefined ||\n usageTotals.costIncomplete === true);\n\n if (outcomeTotals.commitCount === 0 || !hasUsageSignal) {\n continue;\n }\n\n const derived = computeDerivedMetrics(usageTotals, outcomeTotals);\n\n rows.push({\n rowType: 'period',\n periodKey,\n ...usageTotals,\n ...outcomeTotals,\n ...derived,\n });\n\n totalUsage = addUsageTotals(totalUsage, usageTotals);\n totalOutcomes = addOutcomeTotals(totalOutcomes, outcomeTotals);\n }\n\n const finalizedTotalUsage =\n totalUsage.costUsd === undefined &&\n totalUsage.costIncomplete !== true &&\n totalUsage.totalTokens === 0\n ? { ...totalUsage, costUsd: 0 }\n : totalUsage;\n\n rows.push({\n rowType: 'grand_total',\n periodKey: 'ALL',\n ...finalizedTotalUsage,\n ...totalOutcomes,\n ...computeDerivedMetrics(finalizedTotalUsage, totalOutcomes),\n });\n\n return rows;\n}\n","import { spawn } from 'node:child_process';\nimport { createInterface } from 'node:readline';\nimport path from 'node:path';\nimport { stat } from 'node:fs/promises';\n\nimport { getPeriodKey, type ReportGranularity } from '../utils/time-buckets.js';\nimport {\n createEmptyEfficiencyOutcomeTotals,\n type EfficiencyOutcomeTotals,\n} from './efficiency-row.js';\n\nconst GIT_COMMIT_MARKER = '\\u001f';\nconst SHORTSTAT_PATTERN =\n /(\\d+)\\s+files?\\s+changed(?:,\\s+(\\d+)\\s+insertions?\\(\\+\\))?(?:,\\s+(\\d+)\\s+deletions?\\(-\\))?/u;\n\nexport type GitOutcomeCollectorOptions = {\n repoDir?: string;\n granularity: ReportGranularity;\n timezone: string;\n since?: string;\n until?: string;\n includeMergeCommits?: boolean;\n activeUsageDays?: ReadonlySet<string>;\n};\n\nexport type GitOutcomeEvent = {\n sha: string;\n timestamp: string;\n linesAdded: number;\n linesDeleted: number;\n linesChanged: number;\n};\n\nexport type GitOutcomeCollectionDiagnostics = {\n repoDir: string;\n includeMergeCommits: boolean;\n commitsCollected: number;\n linesAdded: number;\n linesDeleted: number;\n};\n\nexport type GitOutcomeCollectionResult = {\n periodOutcomes: Map<string, EfficiencyOutcomeTotals>;\n totalOutcomes: EfficiencyOutcomeTotals;\n diagnostics: GitOutcomeCollectionDiagnostics;\n};\n\ntype MutableGitOutcomeEvent = {\n sha: string;\n timestampSeconds: number;\n authorEmail: string;\n linesAdded: number;\n linesDeleted: number;\n};\n\ntype GitCommandResult = {\n lines: string[];\n stderr: string;\n exitCode: number;\n};\n\nexport type GitOutcomeCollectorDeps = {\n runGitCommand?: (repoDir: string, args: string[]) => Promise<GitCommandResult>;\n};\n\nfunction shiftDate(value: string, days: number): string {\n const date = new Date(`${value}T00:00:00.000Z`);\n\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid date value: ${value}`);\n }\n\n date.setUTCDate(date.getUTCDate() + days);\n return date.toISOString().slice(0, 10);\n}\n\nfunction escapeGitRegexLiteral(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&');\n}\n\nfunction resolveGitCommandFailureReason(result: GitCommandResult): string {\n return result.stderr.trim() || `git exited with code ${result.exitCode}`;\n}\n\nfunction resolveRepoDir(repoDir: string | undefined): string {\n if (repoDir === undefined) {\n return path.resolve(process.cwd());\n }\n\n const normalizedRepoDir = repoDir.trim();\n\n if (!normalizedRepoDir) {\n throw new Error('--repo-dir must be a non-empty path');\n }\n\n return path.resolve(normalizedRepoDir);\n}\n\nfunction getNodeErrorCode(error: unknown): string | undefined {\n if (typeof error !== 'object' || error === null || !('code' in error)) {\n return undefined;\n }\n\n const record = error as { code?: unknown };\n return typeof record.code === 'string' ? record.code : undefined;\n}\n\nasync function assertRepoDirReadable(repoDir: string): Promise<void> {\n let directoryStats: Awaited<ReturnType<typeof stat>>;\n\n try {\n directoryStats = await stat(repoDir);\n } catch (error) {\n const code = getNodeErrorCode(error);\n\n if (code === 'ENOENT') {\n throw new Error(`Repository path does not exist: ${repoDir}`, { cause: error });\n }\n\n if (code === 'EACCES' || code === 'EPERM') {\n throw new Error(`Repository path is unreadable: ${repoDir}`, { cause: error });\n }\n\n throw error;\n }\n\n if (!directoryStats.isDirectory()) {\n throw new Error(`Repository path is not a directory: ${repoDir}`);\n }\n}\n\nasync function assertGitRepository(\n repoDir: string,\n runCommand: (repoDir: string, args: string[]) => Promise<GitCommandResult>,\n): Promise<void> {\n const gitRepoResult = await runCommand(repoDir, ['rev-parse', '--is-inside-work-tree']);\n\n if (gitRepoResult.exitCode === 0) {\n return;\n }\n\n throw new Error(`Repository is not a git repository: ${repoDir}`);\n}\n\nfunction isNoCommitHistoryFailure(result: GitCommandResult): boolean {\n if (result.exitCode !== 128) {\n return false;\n }\n\n const reason = result.stderr.toLowerCase();\n\n return (\n reason.includes('does not have any commits yet') ||\n reason.includes('needed a single revision') ||\n reason.includes('unknown revision or path not in the working tree') ||\n reason.includes(\"bad revision 'head'\")\n );\n}\n\nfunction createEmptyOutcomeCollection(\n repoDir: string,\n includeMergeCommits: boolean,\n): GitOutcomeCollectionResult {\n return {\n periodOutcomes: new Map(),\n totalOutcomes: createEmptyEfficiencyOutcomeTotals(),\n diagnostics: {\n repoDir,\n includeMergeCommits,\n commitsCollected: 0,\n linesAdded: 0,\n linesDeleted: 0,\n },\n };\n}\n\nfunction isMissingGitUserEmailError(error: unknown): boolean {\n return error instanceof Error && error.message.startsWith('Git user.email is not configured for');\n}\n\nfunction resolveConfiguredEmailFromLines(lines: string[]): string | undefined {\n return lines.map((line) => line.trim()).find((line) => line.length > 0);\n}\n\nfunction resolveEmailFromGitAuthorIdent(lines: string[]): string | undefined {\n const identLine = lines.map((line) => line.trim()).find((line) => line.length > 0);\n\n if (!identLine) {\n return undefined;\n }\n\n const emailMatch = /<([^>]+)>/u.exec(identLine);\n const email = emailMatch?.[1]?.trim();\n\n return email && email.length > 0 ? email : undefined;\n}\n\nasync function resolveConfiguredAuthorEmail(\n repoDir: string,\n runCommand: (repoDir: string, args: string[]) => Promise<GitCommandResult>,\n): Promise<string> {\n const configLookupAttempts: string[][] = [\n ['config', '--get', 'user.email'],\n ['config', '--global', '--get', 'user.email'],\n ];\n\n for (const args of configLookupAttempts) {\n const configResult = await runCommand(repoDir, args);\n\n if (configResult.exitCode === 0) {\n const configuredEmail = resolveConfiguredEmailFromLines(configResult.lines);\n\n if (configuredEmail) {\n return configuredEmail;\n }\n\n continue;\n }\n\n if (configResult.exitCode !== 1) {\n const reason = resolveGitCommandFailureReason(configResult);\n throw new Error(`Failed to resolve git user.email from ${repoDir}: ${reason}`);\n }\n }\n\n const gitAuthorIdentResult = await runCommand(repoDir, ['var', 'GIT_AUTHOR_IDENT']);\n\n if (gitAuthorIdentResult.exitCode === 0) {\n const authorIdentEmail = resolveEmailFromGitAuthorIdent(gitAuthorIdentResult.lines);\n\n if (authorIdentEmail) {\n return authorIdentEmail;\n }\n }\n\n throw new Error(\n `Git user.email is not configured for ${repoDir}. Run: git -C ${repoDir} config user.email \"you@example.com\"`,\n );\n}\n\nfunction toIsoTimestamp(timestampSeconds: number): string {\n const timestamp = new Date(timestampSeconds * 1000);\n\n if (Number.isNaN(timestamp.getTime())) {\n throw new Error(`Invalid git commit timestamp: ${timestampSeconds}`);\n }\n\n return timestamp.toISOString();\n}\n\nfunction parseShortstatLine(\n line: string,\n): { linesAdded: number; linesDeleted: number } | undefined {\n const shortstatMatch = SHORTSTAT_PATTERN.exec(line.trim());\n\n if (!shortstatMatch) {\n return undefined;\n }\n\n const linesAddedRaw = shortstatMatch[2];\n const linesDeletedRaw = shortstatMatch[3];\n\n return {\n linesAdded: linesAddedRaw ? Number.parseInt(linesAddedRaw, 10) : 0,\n linesDeleted: linesDeletedRaw ? Number.parseInt(linesDeletedRaw, 10) : 0,\n };\n}\n\nfunction finalizeCurrentEvent(\n currentEvent: MutableGitOutcomeEvent | undefined,\n events: GitOutcomeEvent[],\n authorEmail: string | undefined,\n): void {\n if (!currentEvent) {\n return;\n }\n\n if (\n authorEmail &&\n currentEvent.authorEmail.trim().toLowerCase() !== authorEmail.trim().toLowerCase()\n ) {\n return;\n }\n\n const timestamp = toIsoTimestamp(currentEvent.timestampSeconds);\n\n events.push({\n sha: currentEvent.sha,\n timestamp,\n linesAdded: currentEvent.linesAdded,\n linesDeleted: currentEvent.linesDeleted,\n linesChanged: currentEvent.linesAdded + currentEvent.linesDeleted,\n });\n}\n\nexport function parseGitLogShortstatLines(\n lines: Iterable<string>,\n authorEmail?: string,\n): GitOutcomeEvent[] {\n const events: GitOutcomeEvent[] = [];\n let currentEvent: MutableGitOutcomeEvent | undefined;\n\n for (const line of lines) {\n if (line.startsWith(GIT_COMMIT_MARKER)) {\n const commitParts = line.slice(1).split(GIT_COMMIT_MARKER);\n const timestampPart = commitParts[0];\n const shaPart = commitParts[1];\n const authorPart = commitParts[2];\n\n if (\n commitParts.length !== 3 ||\n !/^\\d+$/u.test(timestampPart) ||\n !/^[0-9a-f]{7,64}$/iu.test(shaPart) ||\n authorPart.trim().length === 0\n ) {\n throw new Error(`Malformed git commit boundary line: ${line}`);\n }\n\n finalizeCurrentEvent(currentEvent, events, authorEmail);\n currentEvent = {\n timestampSeconds: Number.parseInt(timestampPart, 10),\n sha: shaPart,\n authorEmail: authorPart,\n linesAdded: 0,\n linesDeleted: 0,\n };\n continue;\n }\n\n if (!currentEvent) {\n continue;\n }\n\n const shortstat = parseShortstatLine(line);\n\n if (!shortstat) {\n continue;\n }\n\n currentEvent.linesAdded += shortstat.linesAdded;\n currentEvent.linesDeleted += shortstat.linesDeleted;\n }\n\n finalizeCurrentEvent(currentEvent, events, authorEmail);\n return events;\n}\n\nasync function runGitCommand(repoDir: string, args: string[]): Promise<GitCommandResult> {\n return await new Promise<GitCommandResult>((resolve, reject) => {\n const child = spawn('git', args, {\n cwd: repoDir,\n env: {\n ...process.env,\n LC_ALL: 'C',\n LANG: 'C',\n },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n const lines: string[] = [];\n let stderr = '';\n\n const stdoutReader = createInterface({ input: child.stdout });\n const stdoutPromise = (async () => {\n for await (const line of stdoutReader) {\n lines.push(line);\n }\n })();\n\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n\n child.once('error', (error) => {\n reject(error);\n });\n\n child.once('close', (exitCode) => {\n void stdoutPromise\n .then(() => {\n resolve({\n lines,\n stderr,\n exitCode: exitCode ?? 1,\n });\n })\n .catch((error: unknown) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n });\n}\n\nfunction filterEventsByDateRange(\n events: GitOutcomeEvent[],\n timezone: string,\n since: string | undefined,\n until: string | undefined,\n): GitOutcomeEvent[] {\n const normalizedSince = since ? shiftDate(since, 0) : undefined;\n const normalizedUntil = until ? shiftDate(until, 0) : undefined;\n\n return events.filter((event) => {\n const eventDate = getPeriodKey(event.timestamp, 'daily', timezone);\n\n if (normalizedSince && eventDate < normalizedSince) {\n return false;\n }\n\n if (normalizedUntil && eventDate > normalizedUntil) {\n return false;\n }\n\n return true;\n });\n}\n\nfunction filterEventsByActiveUsageDays(\n events: GitOutcomeEvent[],\n timezone: string,\n activeUsageDays: ReadonlySet<string> | undefined,\n): GitOutcomeEvent[] {\n if (activeUsageDays === undefined) {\n return events;\n }\n\n if (activeUsageDays.size === 0) {\n return [];\n }\n\n return events.filter((event) =>\n activeUsageDays.has(getPeriodKey(event.timestamp, 'daily', timezone)),\n );\n}\n\nfunction aggregatePeriodOutcomes(\n events: GitOutcomeEvent[],\n granularity: ReportGranularity,\n timezone: string,\n): {\n periodOutcomes: Map<string, EfficiencyOutcomeTotals>;\n totalOutcomes: EfficiencyOutcomeTotals;\n} {\n const periodOutcomes = new Map<string, EfficiencyOutcomeTotals>();\n const totalOutcomes = createEmptyEfficiencyOutcomeTotals();\n\n for (const event of events) {\n const periodKey = getPeriodKey(event.timestamp, granularity, timezone);\n const periodTotals = periodOutcomes.get(periodKey) ?? createEmptyEfficiencyOutcomeTotals();\n\n periodTotals.commitCount += 1;\n periodTotals.linesAdded += event.linesAdded;\n periodTotals.linesDeleted += event.linesDeleted;\n periodTotals.linesChanged += event.linesChanged;\n\n periodOutcomes.set(periodKey, periodTotals);\n\n totalOutcomes.commitCount += 1;\n totalOutcomes.linesAdded += event.linesAdded;\n totalOutcomes.linesDeleted += event.linesDeleted;\n totalOutcomes.linesChanged += event.linesChanged;\n }\n\n return {\n periodOutcomes,\n totalOutcomes,\n };\n}\n\nfunction buildGitLogArgs(options: {\n since?: string;\n until?: string;\n includeMergeCommits: boolean;\n authorEmail: string;\n}): string[] {\n const args = [\n 'log',\n `--pretty=format:${GIT_COMMIT_MARKER}%ct${GIT_COMMIT_MARKER}%H${GIT_COMMIT_MARKER}%ae`,\n '--shortstat',\n '--regexp-ignore-case',\n `--author=<${escapeGitRegexLiteral(options.authorEmail)}>`,\n ];\n\n if (!options.includeMergeCommits) {\n args.push('--no-merges');\n }\n\n if (options.since) {\n args.push(`--since=${shiftDate(options.since, -1)}T00:00:00Z`);\n }\n\n if (options.until) {\n args.push(`--until=${shiftDate(options.until, 1)}T23:59:59Z`);\n }\n\n return args;\n}\n\nfunction resolveGitLogDateWindow(options: {\n since?: string;\n until?: string;\n activeUsageDays?: ReadonlySet<string>;\n}): {\n since?: string;\n until?: string;\n} {\n if (!options.activeUsageDays || options.activeUsageDays.size === 0) {\n return {\n since: options.since,\n until: options.until,\n };\n }\n\n let earliestUsageDay: string | undefined;\n let latestUsageDay: string | undefined;\n\n for (const usageDay of options.activeUsageDays) {\n if (!earliestUsageDay || usageDay < earliestUsageDay) {\n earliestUsageDay = usageDay;\n }\n\n if (!latestUsageDay || usageDay > latestUsageDay) {\n latestUsageDay = usageDay;\n }\n }\n\n return {\n since: options.since ?? earliestUsageDay,\n until: options.until ?? latestUsageDay,\n };\n}\n\nexport async function collectGitOutcomes(\n options: GitOutcomeCollectorOptions,\n deps: GitOutcomeCollectorDeps = {},\n): Promise<GitOutcomeCollectionResult> {\n const repoDir = resolveRepoDir(options.repoDir);\n const includeMergeCommits = options.includeMergeCommits ?? false;\n const runCommand = deps.runGitCommand ?? runGitCommand;\n\n if (options.activeUsageDays?.size === 0) {\n return createEmptyOutcomeCollection(repoDir, includeMergeCommits);\n }\n\n if (!deps.runGitCommand) {\n await assertRepoDirReadable(repoDir);\n await assertGitRepository(repoDir, runCommand);\n }\n\n let authorEmail: string;\n\n try {\n authorEmail = await resolveConfiguredAuthorEmail(repoDir, runCommand);\n } catch (error) {\n if (!isMissingGitUserEmailError(error)) {\n throw error;\n }\n\n const headResult = await runCommand(repoDir, ['rev-parse', '--verify', 'HEAD']);\n\n if (isNoCommitHistoryFailure(headResult)) {\n return createEmptyOutcomeCollection(repoDir, includeMergeCommits);\n }\n\n throw error;\n }\n\n const gitLogDateWindow = resolveGitLogDateWindow({\n since: options.since,\n until: options.until,\n activeUsageDays: options.activeUsageDays,\n });\n\n const gitResult = await runCommand(\n repoDir,\n buildGitLogArgs({\n since: gitLogDateWindow.since,\n until: gitLogDateWindow.until,\n includeMergeCommits,\n authorEmail,\n }),\n );\n\n if (gitResult.exitCode !== 0) {\n if (isNoCommitHistoryFailure(gitResult)) {\n return createEmptyOutcomeCollection(repoDir, includeMergeCommits);\n }\n\n const reason = resolveGitCommandFailureReason(gitResult);\n throw new Error(`Failed to collect git outcomes from ${repoDir}: ${reason}`);\n }\n\n const allEvents = parseGitLogShortstatLines(gitResult.lines, authorEmail);\n const filteredEvents = filterEventsByDateRange(\n allEvents,\n options.timezone,\n options.since,\n options.until,\n );\n const usageAttributedEvents = filterEventsByActiveUsageDays(\n filteredEvents,\n options.timezone,\n options.activeUsageDays,\n );\n const { periodOutcomes, totalOutcomes } = aggregatePeriodOutcomes(\n usageAttributedEvents,\n options.granularity,\n options.timezone,\n );\n\n return {\n periodOutcomes,\n totalOutcomes,\n diagnostics: {\n repoDir,\n includeMergeCommits,\n commitsCollected: totalOutcomes.commitCount,\n linesAdded: totalOutcomes.linesAdded,\n linesDeleted: totalOutcomes.linesDeleted,\n },\n };\n}\n","import { access, constants, realpath } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { UsageEvent } from '../domain/usage-event.js';\n\nexport type RepoAttributionResult = {\n matchedEvents: UsageEvent[];\n matchedEventCount: number;\n excludedEventCount: number;\n unattributedEventCount: number;\n};\n\nexport type RepoRootResolver = (pathHint: string) => Promise<string | undefined>;\n\nasync function hasGitMarker(directoryPath: string): Promise<boolean> {\n try {\n await access(path.join(directoryPath, '.git'), constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction normalizeComparablePath(value: string): string {\n const normalizedPath = path.normalize(path.resolve(value));\n return process.platform === 'win32' ? normalizedPath.toLowerCase() : normalizedPath;\n}\n\nasync function resolveComparablePath(value: string): Promise<string> {\n const resolvedPath = path.resolve(value);\n\n try {\n return normalizeComparablePath(await realpath(resolvedPath));\n } catch {\n return normalizeComparablePath(resolvedPath);\n }\n}\n\nexport async function resolveRepoRootFromPathHint(pathHint: string): Promise<string | undefined> {\n const trimmedPath = pathHint.trim();\n\n if (!trimmedPath) {\n return undefined;\n }\n\n let currentPath = path.resolve(trimmedPath);\n\n for (;;) {\n if (await hasGitMarker(currentPath)) {\n return currentPath;\n }\n\n const parentPath = path.dirname(currentPath);\n\n if (parentPath === currentPath) {\n return undefined;\n }\n\n currentPath = parentPath;\n }\n}\n\nexport async function attributeUsageEventsToRepo(\n events: UsageEvent[],\n repoDir: string,\n resolveRepoRoot: RepoRootResolver = resolveRepoRootFromPathHint,\n): Promise<RepoAttributionResult> {\n const resolvedTargetRepoRoot = await resolveRepoRoot(repoDir).catch(() => undefined);\n const targetRepoPath = await resolveComparablePath(resolvedTargetRepoRoot ?? repoDir);\n const rootCache = new Map<\n string,\n Promise<{ resolvedRoot: string; comparableRoot: string } | undefined>\n >();\n const matchedEvents: UsageEvent[] = [];\n let excludedEventCount = 0;\n let unattributedEventCount = 0;\n\n for (const event of events) {\n if (!event.repoRoot) {\n unattributedEventCount += 1;\n continue;\n }\n const eventRepoRoot = event.repoRoot;\n\n const cachedRootPromise =\n rootCache.get(eventRepoRoot) ??\n (async () => {\n const resolvedRoot = await resolveRepoRoot(eventRepoRoot).catch(() => undefined);\n\n if (!resolvedRoot) {\n return undefined;\n }\n\n return {\n resolvedRoot,\n comparableRoot: await resolveComparablePath(resolvedRoot),\n };\n })();\n rootCache.set(eventRepoRoot, cachedRootPromise);\n const resolvedRoot = await cachedRootPromise;\n\n if (!resolvedRoot) {\n unattributedEventCount += 1;\n continue;\n }\n\n if (resolvedRoot.comparableRoot !== targetRepoPath) {\n excludedEventCount += 1;\n continue;\n }\n\n matchedEvents.push({\n ...event,\n repoRoot: resolvedRoot.resolvedRoot,\n });\n }\n\n return {\n matchedEvents,\n matchedEventCount: matchedEvents.length,\n excludedEventCount,\n unattributedEventCount,\n };\n}\n","export type EnvVarOverride = {\n name: string;\n value: string;\n description: string;\n};\n\nconst ENV_VARS_TO_DISPLAY: Array<{ name: string; description: string }> = [\n { name: 'LLM_USAGE_SKIP_UPDATE_CHECK', description: 'skip startup update check' },\n {\n name: 'LLM_USAGE_UPDATE_CACHE_SCOPE',\n description: 'update-check cache scope (global/session)',\n },\n { name: 'LLM_USAGE_UPDATE_CACHE_SESSION_KEY', description: 'update-check session cache key' },\n { name: 'LLM_USAGE_UPDATE_CACHE_TTL_MS', description: 'update-check cache TTL' },\n { name: 'LLM_USAGE_UPDATE_FETCH_TIMEOUT_MS', description: 'update-check fetch timeout' },\n { name: 'LLM_USAGE_PRICING_CACHE_TTL_MS', description: 'pricing cache TTL' },\n { name: 'LLM_USAGE_PRICING_FETCH_TIMEOUT_MS', description: 'pricing fetch timeout' },\n { name: 'LLM_USAGE_PARSE_MAX_PARALLEL', description: 'max parallel file parsing' },\n { name: 'LLM_USAGE_PARSE_CACHE_ENABLED', description: 'enable file parse cache' },\n { name: 'LLM_USAGE_PARSE_CACHE_TTL_MS', description: 'file parse cache TTL' },\n { name: 'LLM_USAGE_PARSE_CACHE_MAX_ENTRIES', description: 'file parse cache max entries' },\n { name: 'LLM_USAGE_PARSE_CACHE_MAX_BYTES', description: 'file parse cache max bytes' },\n];\n\nexport function getActiveEnvVarOverrides(): EnvVarOverride[] {\n const overrides: EnvVarOverride[] = [];\n\n for (const { name, description } of ENV_VARS_TO_DISPLAY) {\n const value = process.env[name];\n if (value !== undefined && value !== '') {\n overrides.push({ name, value, description });\n }\n }\n\n return overrides;\n}\n\nexport function formatEnvVarOverrides(overrides: EnvVarOverride[]): string[] {\n if (overrides.length === 0) {\n return [];\n }\n\n const lines: string[] = [];\n lines.push('Active environment overrides:');\n\n for (const { name, value, description } of overrides) {\n lines.push(` ${name}=${value} (${description})`);\n }\n\n return lines;\n}\n","import type { UsageReportRow } from '../domain/usage-report-row.js';\nimport type { SourceAdapter } from '../sources/source-adapter.js';\n\nimport type { AdapterParseResult } from './build-usage-data-parsing.js';\nimport type {\n UsageDataResult,\n UsageDiagnostics,\n UsagePricingOrigin,\n UsageSourceFailure,\n} from './usage-data-contracts.js';\n\ntype BuildUsageDiagnosticsParams = {\n adaptersToParse: SourceAdapter[];\n successfulParseResults: AdapterParseResult[];\n sourceFailures: UsageSourceFailure[];\n pricingOrigin: UsagePricingOrigin;\n pricingWarning?: string;\n activeEnvOverrides: UsageDiagnostics['activeEnvOverrides'];\n timezone: string;\n};\n\nexport function buildUsageDiagnostics(params: BuildUsageDiagnosticsParams): UsageDiagnostics {\n const parseResultBySource = new Map(\n params.successfulParseResults.map((result) => [result.source.toLowerCase(), result]),\n );\n\n const sessionStats = params.adaptersToParse.map((adapter) => {\n const parseResult = parseResultBySource.get(adapter.id.toLowerCase());\n\n return {\n source: adapter.id,\n filesFound: parseResult?.filesFound ?? 0,\n eventsParsed: parseResult?.events.length ?? 0,\n };\n });\n\n const skippedRows = params.successfulParseResults\n .filter((result) => result.skippedRows > 0)\n .map((result) => ({\n source: result.source,\n skippedRows: result.skippedRows,\n reasons: result.skippedRowReasons,\n }));\n\n return {\n sessionStats,\n sourceFailures: params.sourceFailures,\n skippedRows,\n pricingOrigin: params.pricingOrigin,\n pricingWarning: params.pricingWarning,\n activeEnvOverrides: params.activeEnvOverrides,\n timezone: params.timezone,\n };\n}\n\nexport function assembleUsageDataResult(\n events: UsageDataResult['events'],\n rows: UsageReportRow[],\n diagnostics: UsageDiagnostics,\n): UsageDataResult {\n return {\n events,\n rows,\n diagnostics,\n };\n}\n","import type { SourceAdapter } from '../sources/source-adapter.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\nimport type { ReportCommandOptions } from './usage-data-contracts.js';\n\nexport type NormalizedBuildUsageInputs = {\n timezone: string;\n providerFilter: string | undefined;\n sourceFilter: Set<string> | undefined;\n modelFilter: string[] | undefined;\n explicitSourceIds: Set<string>;\n pricingUrl: string | undefined;\n};\n\nexport function validateDateInput(value: string, flagName: '--since' | '--until'): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/u.test(value)) {\n throw new Error(`${flagName} must use format YYYY-MM-DD`);\n }\n\n const parsed = new Date(`${value}T00:00:00.000Z`);\n\n if (Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== value) {\n throw new Error(`${flagName} has an invalid calendar date`);\n }\n}\n\nexport function validateTimezone(timezone: string): void {\n const normalizedTimezone = timezone.trim();\n\n try {\n new Intl.DateTimeFormat('en-US', { timeZone: normalizedTimezone }).format(new Date());\n } catch {\n throw new Error(`Invalid timezone: ${normalizedTimezone}`);\n }\n}\n\nexport function normalizeProviderFilter(provider: string | undefined): string | undefined {\n if (!provider) {\n return undefined;\n }\n\n const normalized = provider.trim().toLowerCase();\n return normalized || undefined;\n}\n\nexport function normalizeSourceFilter(\n source: string | string[] | undefined,\n): Set<string> | undefined {\n if (!source || (Array.isArray(source) && source.length === 0)) {\n return undefined;\n }\n\n const sourceCandidates = Array.isArray(source) ? source : [source];\n const normalizedSources = sourceCandidates\n .flatMap((candidate) => candidate.split(','))\n .map((candidate) => candidate.trim().toLowerCase())\n .filter((candidate) => candidate.length > 0);\n\n if (normalizedSources.length === 0) {\n throw new Error('--source must contain at least one non-empty source id');\n }\n\n return new Set(normalizedSources);\n}\n\nexport function normalizeModelFilter(model: string | string[] | undefined): string[] | undefined {\n if (!model || (Array.isArray(model) && model.length === 0)) {\n return undefined;\n }\n\n const modelCandidates = Array.isArray(model) ? model : [model];\n const normalizedModels = modelCandidates\n .flatMap((candidate) => candidate.split(','))\n .map((candidate) => candidate.trim().toLowerCase())\n .filter((candidate) => candidate.length > 0);\n\n if (normalizedModels.length === 0) {\n throw new Error('--model must contain at least one non-empty model filter');\n }\n\n return [...new Set(normalizedModels)];\n}\n\nexport function validateSourceFilterValues(\n sourceFilter: Set<string> | undefined,\n availableSourceIds: ReadonlySet<string>,\n): void {\n if (!sourceFilter) {\n return;\n }\n\n const unknownSources = [...sourceFilter].filter((source) => !availableSourceIds.has(source));\n\n if (unknownSources.length === 0) {\n return;\n }\n\n const allowedSources = [...availableSourceIds].sort(compareByCodePoint);\n\n throw new Error(\n `Unknown --source value(s): ${unknownSources.join(', ')}. Allowed values: ${allowedSources.join(', ')}`,\n );\n}\n\nexport function validatePricingUrl(pricingUrl: string | undefined): string | undefined {\n if (pricingUrl === undefined) {\n return undefined;\n }\n\n const normalizedPricingUrl = pricingUrl.trim();\n\n if (normalizedPricingUrl.length === 0) {\n throw new Error('--pricing-url must be a valid http(s) URL');\n }\n\n try {\n const parsedUrl = new URL(normalizedPricingUrl);\n\n if (!['http:', 'https:'].includes(parsedUrl.protocol)) {\n throw new Error('Unsupported protocol');\n }\n } catch {\n throw new Error('--pricing-url must be a valid http(s) URL');\n }\n\n return normalizedPricingUrl;\n}\n\nexport function validateBuildOptions(options: ReportCommandOptions): {\n normalizedPricingUrl: string | undefined;\n} {\n if (options.since) {\n validateDateInput(options.since, '--since');\n }\n\n if (options.until) {\n validateDateInput(options.until, '--until');\n }\n\n if (options.since && options.until && options.since > options.until) {\n throw new Error('--since must be less than or equal to --until');\n }\n\n return {\n normalizedPricingUrl: validatePricingUrl(options.pricingUrl),\n };\n}\n\nfunction parseSourceDirOverrideIds(sourceDirEntries: string[] | undefined): Set<string> {\n const overrideIds = new Set<string>();\n\n if (!sourceDirEntries || sourceDirEntries.length === 0) {\n return overrideIds;\n }\n\n for (const entry of sourceDirEntries) {\n const separatorIndex = entry.indexOf('=');\n\n if (separatorIndex <= 0) {\n continue;\n }\n\n const sourceId = entry.slice(0, separatorIndex).trim().toLowerCase();\n\n if (sourceId.length > 0) {\n overrideIds.add(sourceId);\n }\n }\n\n return overrideIds;\n}\n\nexport function resolveExplicitSourceIds(\n options: ReportCommandOptions,\n sourceFilter: Set<string> | undefined,\n): Set<string> {\n const explicitSourceIds = new Set<string>();\n\n if (sourceFilter) {\n for (const sourceId of sourceFilter) {\n explicitSourceIds.add(sourceId);\n }\n }\n\n for (const sourceId of parseSourceDirOverrideIds(options.sourceDir)) {\n explicitSourceIds.add(sourceId);\n }\n\n if (options.piDir) {\n explicitSourceIds.add('pi');\n }\n\n if (options.codexDir) {\n explicitSourceIds.add('codex');\n }\n\n if (options.geminiDir) {\n explicitSourceIds.add('gemini');\n }\n\n if (options.droidDir) {\n explicitSourceIds.add('droid');\n }\n\n if (options.opencodeDb) {\n explicitSourceIds.add('opencode');\n }\n\n return explicitSourceIds;\n}\n\nfunction detectDefaultTimezone(): string {\n const detectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n if (typeof detectedTimezone === 'string') {\n const trimmedDetectedTimezone = detectedTimezone.trim();\n\n if (trimmedDetectedTimezone.length > 0) {\n return trimmedDetectedTimezone;\n }\n }\n\n return 'UTC';\n}\n\nexport function normalizeBuildUsageInputs(\n options: ReportCommandOptions,\n): NormalizedBuildUsageInputs {\n const { normalizedPricingUrl } = validateBuildOptions(options);\n\n const timezone =\n options.timezone !== undefined ? options.timezone.trim() : detectDefaultTimezone();\n validateTimezone(timezone);\n\n const providerFilter = normalizeProviderFilter(options.provider);\n const sourceFilter = normalizeSourceFilter(options.source);\n const modelFilter = normalizeModelFilter(options.model);\n const explicitSourceIds = resolveExplicitSourceIds(options, sourceFilter);\n\n return {\n timezone,\n providerFilter,\n sourceFilter,\n modelFilter,\n explicitSourceIds,\n pricingUrl: normalizedPricingUrl,\n };\n}\n\nexport function selectAdaptersForParsing(\n adapters: SourceAdapter[],\n sourceFilter: Set<string> | undefined,\n): SourceAdapter[] {\n const availableSourceIds = new Set(adapters.map((adapter) => adapter.id.toLowerCase()));\n validateSourceFilterValues(sourceFilter, availableSourceIds);\n\n return sourceFilter\n ? adapters.filter((adapter) => sourceFilter.has(adapter.id.toLowerCase()))\n : adapters;\n}\n","import { stat } from 'node:fs/promises';\n\nimport type { UsageEvent } from '../domain/usage-event.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport type {\n SourceAdapter,\n SourceParseFileDiagnostics,\n SourceSkippedRowReasonStat,\n} from '../sources/source-adapter.js';\nimport { normalizeSkippedRowReasons } from './normalize-skipped-row-reasons.js';\nimport { getPeriodKey } from '../utils/time-buckets.js';\nimport { ParseFileCache } from './parse-file-cache.js';\n\nimport type { UsageSourceFailure } from './usage-data-contracts.js';\n\nexport type AdapterParseResult = {\n source: string;\n events: UsageEvent[];\n filesFound: number;\n skippedRows: number;\n skippedRowReasons: SourceSkippedRowReasonStat[];\n};\n\nexport type ParsedAdaptersResult = {\n successfulParseResults: AdapterParseResult[];\n sourceFailures: UsageSourceFailure[];\n};\n\nexport type ParseCacheRuntimeConfig = {\n enabled: boolean;\n ttlMs: number;\n maxEntries: number;\n maxBytes: number;\n};\n\nexport type ParseSelectedAdaptersOptions = {\n parseCache?: ParseCacheRuntimeConfig;\n parseCacheFilePath?: string;\n now?: () => number;\n};\n\nfunction getDefaultParseFileDiagnostics(events: UsageEvent[]): SourceParseFileDiagnostics {\n return { events, skippedRows: 0, skippedRowReasons: [] };\n}\n\nfunction normalizeSkippedRowsCount(value: unknown): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return 0;\n }\n\n return Math.max(0, Math.trunc(value));\n}\n\nexport async function parseAdapterEvents(\n adapter: SourceAdapter,\n maxParallelFileParsing: number,\n parseFileCache?: ParseFileCache,\n): Promise<AdapterParseResult> {\n const files = await adapter.discoverFiles();\n\n if (files.length === 0) {\n return {\n source: adapter.id,\n events: [],\n filesFound: 0,\n skippedRows: 0,\n skippedRowReasons: [],\n };\n }\n\n const safeMaxParallelFileParsing =\n Number.isFinite(maxParallelFileParsing) && maxParallelFileParsing > 0\n ? Math.max(1, Math.floor(maxParallelFileParsing))\n : 1;\n const parsedByFile: UsageEvent[][] = Array.from({ length: files.length }, () => []);\n const skippedRowsByFile: number[] = Array.from({ length: files.length }, () => 0);\n const skippedRowReasons = new Map<string, number>();\n const workerCount = Math.min(safeMaxParallelFileParsing, files.length);\n let nextFileIndex = 0;\n\n const workers = Array.from({ length: workerCount }, async () => {\n while (nextFileIndex < files.length) {\n const fileIndex = nextFileIndex;\n nextFileIndex += 1;\n\n const filePath = files[fileIndex];\n let fileFingerprint:\n | {\n size: number;\n mtimeMs: number;\n }\n | undefined;\n let parseFileDiagnostics: SourceParseFileDiagnostics | undefined;\n\n if (parseFileCache) {\n try {\n const fileStat = await stat(filePath);\n fileFingerprint = {\n size: fileStat.size,\n mtimeMs: fileStat.mtimeMs,\n };\n parseFileDiagnostics = parseFileCache.get(adapter.id, filePath, fileFingerprint);\n } catch {\n // Some adapters may return virtual/non-file identifiers. In that case, bypass cache.\n }\n }\n\n if (!parseFileDiagnostics) {\n parseFileDiagnostics = adapter.parseFileWithDiagnostics\n ? await adapter.parseFileWithDiagnostics(filePath)\n : getDefaultParseFileDiagnostics(await adapter.parseFile(filePath));\n if (parseFileCache && fileFingerprint) {\n parseFileCache.set(adapter.id, filePath, fileFingerprint, parseFileDiagnostics);\n }\n }\n\n parsedByFile[fileIndex] = parseFileDiagnostics.events;\n skippedRowsByFile[fileIndex] = normalizeSkippedRowsCount(parseFileDiagnostics.skippedRows);\n for (const reasonStat of normalizeSkippedRowReasons(parseFileDiagnostics.skippedRowReasons)) {\n skippedRowReasons.set(\n reasonStat.reason,\n (skippedRowReasons.get(reasonStat.reason) ?? 0) + reasonStat.count,\n );\n }\n }\n });\n\n await Promise.all(workers);\n\n return {\n source: adapter.id,\n events: parsedByFile.flat(),\n filesFound: files.length,\n skippedRows: skippedRowsByFile.reduce((sum, skippedRowsCount) => sum + skippedRowsCount, 0),\n skippedRowReasons: [...skippedRowReasons.entries()]\n .map(([reason, count]) => ({ reason, count }))\n .sort((left, right) => compareByCodePoint(left.reason, right.reason)),\n };\n}\n\nfunction getErrorReason(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n return String(error);\n}\n\nexport async function parseSelectedAdapters(\n adaptersToParse: SourceAdapter[],\n maxParallelFileParsing: number,\n options: ParseSelectedAdaptersOptions = {},\n): Promise<ParsedAdaptersResult> {\n const parseCache = options.parseCache?.enabled\n ? await ParseFileCache.load({\n cacheFilePath: options.parseCacheFilePath,\n limits: {\n ttlMs: options.parseCache.ttlMs,\n maxEntries: options.parseCache.maxEntries,\n maxBytes: options.parseCache.maxBytes,\n },\n now: options.now,\n })\n : undefined;\n\n const parseResults = await Promise.allSettled(\n adaptersToParse.map((adapter) =>\n parseAdapterEvents(adapter, maxParallelFileParsing, parseCache),\n ),\n );\n\n if (parseCache) {\n try {\n await parseCache.persist();\n } catch {\n // Parse cache persistence is best-effort.\n }\n }\n\n const sourceFailures: UsageSourceFailure[] = [];\n const successfulParseResults: AdapterParseResult[] = [];\n\n for (const [index, parseResult] of parseResults.entries()) {\n const source = adaptersToParse[index].id;\n\n if (parseResult.status === 'fulfilled') {\n successfulParseResults.push(parseResult.value);\n continue;\n }\n\n sourceFailures.push({ source, reason: getErrorReason(parseResult.reason) });\n }\n\n return {\n successfulParseResults,\n sourceFailures,\n };\n}\n\nexport function throwOnExplicitSourceFailures(\n sourceFailures: UsageSourceFailure[],\n explicitSourceIds: ReadonlySet<string>,\n): void {\n const explicitFailures = sourceFailures.filter((failure) =>\n explicitSourceIds.has(failure.source.toLowerCase()),\n );\n\n if (explicitFailures.length === 0) {\n return;\n }\n\n const details = explicitFailures\n .map((failure) => `${failure.source}: ${failure.reason}`)\n .join('; ');\n\n throw new Error(`Failed to parse explicitly requested source(s): ${details}`);\n}\n\nfunction matchesProvider(\n provider: string | undefined,\n providerFilter: string | undefined,\n): boolean {\n if (!providerFilter) {\n return true;\n }\n\n return provider?.toLowerCase().includes(providerFilter) ?? false;\n}\n\nfunction isEventWithinDateRange(\n event: UsageEvent,\n timezone: string,\n since: string | undefined,\n until: string | undefined,\n): boolean {\n const eventDate = getPeriodKey(event.timestamp, 'daily', timezone);\n\n if (since && eventDate < since) {\n return false;\n }\n\n if (until && eventDate > until) {\n return false;\n }\n\n return true;\n}\n\ntype ModelFilterRule = {\n value: string;\n mode: 'exact' | 'substring';\n};\n\nfunction resolveModelFilterRules(\n events: UsageEvent[],\n modelFilter: string[] | undefined,\n): ModelFilterRule[] | undefined {\n if (!modelFilter || modelFilter.length === 0) {\n return undefined;\n }\n\n const availableModels = new Set(\n events\n .map((event) => event.model?.toLowerCase())\n .filter((model): model is string => Boolean(model)),\n );\n\n return modelFilter.map((value) => ({\n value,\n mode: availableModels.has(value) ? 'exact' : 'substring',\n }));\n}\n\nfunction matchesModel(\n model: string | undefined,\n modelRules: ModelFilterRule[] | undefined,\n): boolean {\n if (!modelRules || modelRules.length === 0) {\n return true;\n }\n\n if (!model) {\n return false;\n }\n\n const normalizedModel = model.toLowerCase();\n\n return modelRules.some((rule) =>\n rule.mode === 'exact' ? normalizedModel === rule.value : normalizedModel.includes(rule.value),\n );\n}\n\nexport type UsageEventFilterOptions = {\n timezone: string;\n since?: string;\n until?: string;\n providerFilter?: string;\n modelFilter?: string[];\n};\n\nfunction filterByModelRules(events: UsageEvent[], modelFilter: string[] | undefined): UsageEvent[] {\n const modelFilterRules = resolveModelFilterRules(events, modelFilter);\n\n return events.filter((event) => matchesModel(event.model, modelFilterRules));\n}\n\nexport function filterUsageEvents(\n events: UsageEvent[],\n options: UsageEventFilterOptions,\n): UsageEvent[] {\n const providerAndDateFilteredEvents: UsageEvent[] = [];\n\n for (const event of events) {\n if (!matchesProvider(event.provider, options.providerFilter)) {\n continue;\n }\n\n if (!isEventWithinDateRange(event, options.timezone, options.since, options.until)) {\n continue;\n }\n\n providerAndDateFilteredEvents.push(event);\n }\n\n return filterByModelRules(providerAndDateFilteredEvents, options.modelFilter);\n}\n\nexport function filterParsedAdapterEvents(\n parseResults: AdapterParseResult[],\n options: UsageEventFilterOptions,\n): UsageEvent[] {\n const providerAndDateFilteredEvents: UsageEvent[] = [];\n\n for (const result of parseResults) {\n for (const event of result.events) {\n if (!matchesProvider(event.provider, options.providerFilter)) {\n continue;\n }\n\n if (!isEventWithinDateRange(event, options.timezone, options.since, options.until)) {\n continue;\n }\n\n providerAndDateFilteredEvents.push(event);\n }\n }\n\n return filterByModelRules(providerAndDateFilteredEvents, options.modelFilter);\n}\n","import type { SourceSkippedRowReasonStat } from '../sources/source-adapter.js';\nimport { asRecord } from '../utils/as-record.js';\n\nfunction toPositiveInteger(value: unknown): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {\n return undefined;\n }\n\n return Math.trunc(value);\n}\n\nexport function normalizeSkippedRowReasons(value: unknown): SourceSkippedRowReasonStat[] {\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.flatMap((entry) => {\n const record = asRecord(entry);\n\n if (!record) {\n return [];\n }\n\n const reason = typeof record.reason === 'string' ? record.reason.trim() : '';\n const count = toPositiveInteger(record.count);\n\n if (!reason || count === undefined) {\n return [];\n }\n\n return [{ reason, count }];\n });\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { normalizeSourceId, type UsageEvent } from '../domain/usage-event.js';\nimport type {\n SourceParseFileDiagnostics,\n SourceSkippedRowReasonStat,\n} from '../sources/source-adapter.js';\nimport { normalizeSkippedRowReasons } from './normalize-skipped-row-reasons.js';\nimport { asRecord } from '../utils/as-record.js';\nimport { getUserCacheRootDir } from '../utils/cache-root-dir.js';\n\nconst PARSE_FILE_CACHE_VERSION = 2;\nconst CACHE_KEY_SEPARATOR = '\\u0000';\n\nexport type ParseFileFingerprint = {\n size: number;\n mtimeMs: number;\n};\n\nexport type ParseFileCacheLimits = {\n ttlMs: number;\n maxEntries: number;\n maxBytes: number;\n};\n\ntype ParseFileCacheEntry = {\n source: string;\n filePath: string;\n fingerprint: ParseFileFingerprint;\n cachedAt: number;\n diagnostics: SourceParseFileDiagnostics;\n};\n\ntype ParseFileCachePayload = {\n version: number;\n entries: ParseFileCacheEntry[];\n};\n\nfunction createCacheKey(source: string, filePath: string): string {\n return `${source}${CACHE_KEY_SEPARATOR}${filePath}`;\n}\n\nfunction normalizeCacheSource(source: string): string {\n return normalizeSourceId(source)?.toLowerCase() ?? '';\n}\n\nfunction toNonNegativeInteger(value: unknown): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return Math.trunc(value);\n}\n\nfunction toNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return value;\n}\n\nfunction normalizeCachedTimestamp(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalized = value.trim();\n\n if (!normalized) {\n return undefined;\n }\n\n const timestamp = new Date(normalized);\n\n if (Number.isNaN(timestamp.getTime())) {\n return undefined;\n }\n\n return timestamp.toISOString() === normalized ? normalized : undefined;\n}\n\nfunction normalizeCachedUsageEvent(value: unknown): UsageEvent | undefined {\n const record = asRecord(value);\n\n if (!record) {\n return undefined;\n }\n\n const source = normalizeSourceId(record.source)?.toLowerCase();\n const sessionId = typeof record.sessionId === 'string' ? record.sessionId.trim() : '';\n const timestamp = normalizeCachedTimestamp(record.timestamp);\n const repoRoot = typeof record.repoRoot === 'string' ? record.repoRoot.trim() : '';\n\n if (!source || !sessionId || !timestamp) {\n return undefined;\n }\n\n const costMode =\n record.costMode === 'explicit' || record.costMode === 'estimated' ? record.costMode : undefined;\n\n if (!costMode) {\n return undefined;\n }\n\n const inputTokens = toNonNegativeInteger(record.inputTokens);\n const outputTokens = toNonNegativeInteger(record.outputTokens);\n const reasoningTokens = toNonNegativeInteger(record.reasoningTokens);\n const cacheReadTokens = toNonNegativeInteger(record.cacheReadTokens);\n const cacheWriteTokens = toNonNegativeInteger(record.cacheWriteTokens);\n const totalTokens = toNonNegativeInteger(record.totalTokens);\n\n if (\n inputTokens === undefined ||\n outputTokens === undefined ||\n reasoningTokens === undefined ||\n cacheReadTokens === undefined ||\n cacheWriteTokens === undefined ||\n totalTokens === undefined\n ) {\n return undefined;\n }\n\n const provider = typeof record.provider === 'string' ? record.provider.trim() : '';\n const model = typeof record.model === 'string' ? record.model.trim().toLowerCase() : '';\n const costUsd = toNonNegativeNumber(record.costUsd);\n\n if (costMode === 'explicit' && costUsd === undefined) {\n return undefined;\n }\n\n return {\n source,\n sessionId,\n timestamp,\n repoRoot: repoRoot || undefined,\n provider: provider || undefined,\n model: model || undefined,\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costUsd,\n costMode,\n };\n}\n\nfunction cloneUsageEvent(event: UsageEvent): UsageEvent {\n return { ...event };\n}\n\nfunction cloneUsageEvents(events: UsageEvent[]): UsageEvent[] {\n return events.map((event) => cloneUsageEvent(event));\n}\n\nfunction cloneSkippedRowReasons(\n skippedRowReasons: SourceSkippedRowReasonStat[] | undefined,\n): SourceSkippedRowReasonStat[] {\n return (skippedRowReasons ?? []).map((stat) => ({ reason: stat.reason, count: stat.count }));\n}\n\nfunction normalizeCachedEvents(value: unknown): UsageEvent[] | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const normalizedEvents: UsageEvent[] = [];\n\n for (const event of value) {\n const normalizedEvent = normalizeCachedUsageEvent(event);\n\n if (!normalizedEvent) {\n return undefined;\n }\n\n normalizedEvents.push(normalizedEvent);\n }\n\n return normalizedEvents;\n}\n\nfunction normalizeCacheEntry(value: unknown): ParseFileCacheEntry | undefined {\n const record = asRecord(value);\n\n if (!record) {\n return undefined;\n }\n\n const source = normalizeSourceId(record.source)?.toLowerCase() ?? '';\n const filePath = typeof record.filePath === 'string' ? record.filePath.trim() : '';\n const cachedAt = toNonNegativeInteger(record.cachedAt);\n const fingerprint = asRecord(record.fingerprint);\n const diagnostics = asRecord(record.diagnostics);\n const size = toNonNegativeInteger(fingerprint?.size);\n const mtimeMs = toNonNegativeNumber(fingerprint?.mtimeMs);\n const skippedRows = toNonNegativeInteger(diagnostics?.skippedRows) ?? 0;\n const events = normalizeCachedEvents(diagnostics?.events);\n\n if (\n !source ||\n !filePath ||\n size === undefined ||\n mtimeMs === undefined ||\n cachedAt === undefined\n ) {\n return undefined;\n }\n\n if (!events) {\n return undefined;\n }\n\n return {\n source,\n filePath,\n fingerprint: { size, mtimeMs },\n cachedAt,\n diagnostics: {\n events,\n skippedRows,\n skippedRowReasons: normalizeSkippedRowReasons(diagnostics?.skippedRowReasons),\n },\n };\n}\n\nexport function getDefaultParseFileCachePath(): string {\n return path.join(getUserCacheRootDir(), 'llm-usage-metrics', 'parse-file-cache.json');\n}\n\nexport class ParseFileCache {\n private readonly entriesByKey = new Map<string, ParseFileCacheEntry>();\n private dirty = false;\n\n private constructor(\n private readonly cacheFilePath: string,\n private readonly limits: ParseFileCacheLimits,\n private readonly now: () => number,\n ) {}\n\n public static async load(options: {\n cacheFilePath?: string;\n limits: ParseFileCacheLimits;\n now?: () => number;\n }): Promise<ParseFileCache> {\n const cache = new ParseFileCache(\n options.cacheFilePath ?? getDefaultParseFileCachePath(),\n options.limits,\n options.now ?? Date.now,\n );\n await cache.loadFromDisk();\n return cache;\n }\n\n public get(\n source: string,\n filePath: string,\n fingerprint: ParseFileFingerprint,\n ): SourceParseFileDiagnostics | undefined {\n const normalizedSource = normalizeCacheSource(source);\n const cacheKey = createCacheKey(normalizedSource, filePath);\n const entry = this.entriesByKey.get(cacheKey);\n\n if (!entry) {\n return undefined;\n }\n\n if (entry.cachedAt + this.limits.ttlMs < this.now()) {\n this.entriesByKey.delete(cacheKey);\n this.dirty = true;\n return undefined;\n }\n\n if (\n entry.fingerprint.size !== fingerprint.size ||\n entry.fingerprint.mtimeMs !== fingerprint.mtimeMs\n ) {\n this.entriesByKey.delete(cacheKey);\n this.dirty = true;\n return undefined;\n }\n\n return {\n events: cloneUsageEvents(entry.diagnostics.events),\n skippedRows: entry.diagnostics.skippedRows,\n skippedRowReasons: cloneSkippedRowReasons(entry.diagnostics.skippedRowReasons),\n };\n }\n\n public set(\n source: string,\n filePath: string,\n fingerprint: ParseFileFingerprint,\n diagnostics: SourceParseFileDiagnostics,\n ): void {\n const normalizedSource = normalizeCacheSource(source);\n this.entriesByKey.set(createCacheKey(normalizedSource, filePath), {\n source: normalizedSource,\n filePath,\n fingerprint: {\n size: fingerprint.size,\n mtimeMs: fingerprint.mtimeMs,\n },\n cachedAt: this.now(),\n diagnostics: {\n events: cloneUsageEvents(diagnostics.events),\n skippedRows: diagnostics.skippedRows,\n skippedRowReasons: cloneSkippedRowReasons(diagnostics.skippedRowReasons),\n },\n });\n this.dirty = true;\n }\n\n public async persist(): Promise<void> {\n if (!this.dirty) {\n return;\n }\n\n const sortedEntries = [...this.entriesByKey.values()]\n .filter((entry) => entry.cachedAt + this.limits.ttlMs >= this.now())\n .sort((left, right) => right.cachedAt - left.cachedAt);\n\n const keptEntries = sortedEntries.slice(0, this.limits.maxEntries);\n let payloadText = JSON.stringify(this.toPayload(keptEntries));\n\n if (Buffer.byteLength(payloadText, 'utf8') > this.limits.maxBytes) {\n let bestCount = 0;\n let bestPayloadText = JSON.stringify(this.toPayload([]));\n let low = 0;\n let high = keptEntries.length;\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const candidateText = JSON.stringify(this.toPayload(keptEntries.slice(0, mid)));\n\n if (Buffer.byteLength(candidateText, 'utf8') <= this.limits.maxBytes) {\n bestCount = mid;\n bestPayloadText = candidateText;\n low = mid + 1;\n continue;\n }\n\n high = mid - 1;\n }\n\n keptEntries.length = bestCount;\n payloadText = bestPayloadText;\n }\n\n await mkdir(path.dirname(this.cacheFilePath), { recursive: true });\n await writeFile(this.cacheFilePath, payloadText, 'utf8');\n this.dirty = false;\n }\n\n private toPayload(entries: ParseFileCacheEntry[]): ParseFileCachePayload {\n return {\n version: PARSE_FILE_CACHE_VERSION,\n entries: entries.map((entry) => ({\n source: entry.source,\n filePath: entry.filePath,\n fingerprint: entry.fingerprint,\n cachedAt: entry.cachedAt,\n diagnostics: {\n events: entry.diagnostics.events,\n skippedRows: entry.diagnostics.skippedRows,\n skippedRowReasons: cloneSkippedRowReasons(entry.diagnostics.skippedRowReasons),\n },\n })),\n };\n }\n\n private async loadFromDisk(): Promise<void> {\n let content: string;\n\n try {\n content = await readFile(this.cacheFilePath, 'utf8');\n } catch {\n return;\n }\n\n let parsedPayload: unknown;\n\n try {\n parsedPayload = JSON.parse(content);\n } catch {\n this.dirty = true;\n return;\n }\n\n const payloadRecord = asRecord(parsedPayload);\n\n if (!payloadRecord) {\n this.dirty = true;\n return;\n }\n\n const version = toNonNegativeInteger(payloadRecord.version);\n\n if (version !== PARSE_FILE_CACHE_VERSION) {\n this.dirty = true;\n return;\n }\n\n if (Buffer.byteLength(content, 'utf8') > this.limits.maxBytes) {\n this.dirty = true;\n }\n\n const entries = Array.isArray(payloadRecord.entries) ? payloadRecord.entries : [];\n\n for (const rawEntry of entries) {\n const normalizedEntry = normalizeCacheEntry(rawEntry);\n\n if (!normalizedEntry) {\n this.dirty = true;\n continue;\n }\n\n if (normalizedEntry.cachedAt + this.limits.ttlMs < this.now()) {\n this.dirty = true;\n continue;\n }\n\n this.entriesByKey.set(\n createCacheKey(normalizedEntry.source, normalizedEntry.filePath),\n normalizedEntry,\n );\n }\n\n if (this.entriesByKey.size > this.limits.maxEntries) {\n this.dirty = true;\n }\n }\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport type { ModelPricing, PricingSource } from './types.js';\n\nconst ONE_MILLION = 1_000_000;\n\nfunction estimateTokenGroupCost(tokens: number, per1MUsd: number | undefined): number {\n if (!per1MUsd || tokens <= 0) {\n return 0;\n }\n\n return (tokens / ONE_MILLION) * per1MUsd;\n}\n\nexport function calculateEstimatedCostUsd(event: UsageEvent, pricing: ModelPricing): number {\n const reasoningBilling = pricing.reasoningBilling ?? 'included-in-output';\n\n const inputCost = estimateTokenGroupCost(event.inputTokens, pricing.inputPer1MUsd);\n const outputCost = estimateTokenGroupCost(event.outputTokens, pricing.outputPer1MUsd);\n const cacheReadCost = estimateTokenGroupCost(event.cacheReadTokens, pricing.cacheReadPer1MUsd);\n const cacheWriteCost = estimateTokenGroupCost(event.cacheWriteTokens, pricing.cacheWritePer1MUsd);\n\n const reasoningCost =\n reasoningBilling === 'separate'\n ? estimateTokenGroupCost(event.reasoningTokens, pricing.reasoningPer1MUsd)\n : 0;\n\n return inputCost + outputCost + cacheReadCost + cacheWriteCost + reasoningCost;\n}\n\nexport function applyPricingToEvent(event: UsageEvent, pricingSource: PricingSource): UsageEvent {\n const shouldRepriceExplicitZero =\n event.costMode === 'explicit' && event.costUsd === 0 && event.model !== undefined;\n\n if (event.costMode === 'explicit' && event.costUsd !== undefined && !shouldRepriceExplicitZero) {\n return event;\n }\n\n if (!event.model) {\n return { ...event, costMode: 'estimated' };\n }\n\n const pricing = pricingSource.getPricing(event.model);\n\n if (!pricing) {\n if (shouldRepriceExplicitZero) {\n return event;\n }\n\n return { ...event, costMode: 'estimated' };\n }\n\n return {\n ...event,\n costUsd: calculateEstimatedCostUsd(event, pricing),\n costMode: 'estimated',\n };\n}\n\nexport function applyPricingToEvents(\n events: UsageEvent[],\n pricingSource: PricingSource,\n): UsageEvent[] {\n return events.map((event) => applyPricingToEvent(event, pricingSource));\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { asRecord } from '../utils/as-record.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport { getUserCacheRootDir } from '../utils/cache-root-dir.js';\nimport litellmModelMapPayload from './litellm-model-map.json' with { type: 'json' };\nimport type { ModelPricing, PricingSource } from './types.js';\n\nconst ONE_MILLION = 1_000_000;\nconst DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst DEFAULT_FETCH_TIMEOUT_MS = 4000;\nconst DEFAULT_FETCH_RETRY_COUNT = 2;\nconst DEFAULT_FETCH_RETRY_DELAY_MS = 200;\n\nexport const DEFAULT_LITELLM_PRICING_URL =\n 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json';\n\ntype LiteLLMCachePayload = {\n fetchedAt: number;\n sourceUrl: string;\n pricingByModel: Record<string, ModelPricing>;\n};\n\nexport type LiteLLMPricingFetcherOptions = {\n sourceUrl?: string;\n cacheFilePath?: string;\n cacheTtlMs?: number;\n fetchTimeoutMs?: number;\n fetchRetryCount?: number;\n fetchRetryDelayMs?: number;\n offline?: boolean;\n fetchImpl?: typeof fetch;\n now?: () => number;\n sleep?: (delayMs: number) => Promise<void>;\n};\n\ntype LiteLLMModelMapPayload = {\n aliases?: unknown;\n preferredPricingKeyByCanonicalModel?: unknown;\n};\n\ntype LiteLLMModelMap = {\n aliasToCanonicalModel: Map<string, string>;\n canonicalizedAliasToCanonicalModel: Map<string, string>;\n preferredPricingKeyByCanonicalModel: Map<string, string>;\n};\n\nclass RetryableLiteLLMFetchError extends Error {\n public constructor(message: string) {\n super(message);\n this.name = 'RetryableLiteLLMFetchError';\n }\n}\n\nfunction isRetryableHttpStatus(status: number): boolean {\n return [408, 425, 429, 500, 502, 503, 504].includes(status);\n}\n\nfunction isRetryableFetchFailure(error: unknown): boolean {\n if (error instanceof RetryableLiteLLMFetchError) {\n return true;\n }\n\n if (!(error instanceof Error)) {\n return false;\n }\n\n if (error.name === 'AbortError' || error.name === 'TimeoutError') {\n return true;\n }\n\n if (error instanceof TypeError) {\n return true;\n }\n\n return /timeout|timed out|network|econn|enotfound|eai_again/iu.test(error.message);\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n}\n\nfunction normalizeKey(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction parseLiteLLMModelMap(payload: LiteLLMModelMapPayload): LiteLLMModelMap {\n const aliasToCanonicalModel = new Map<string, string>();\n const canonicalizedAliasToCanonicalModel = new Map<string, string>();\n const preferredPricingKeyByCanonicalModel = new Map<string, string>();\n\n const aliasesRecord = asRecord(payload.aliases);\n\n if (aliasesRecord) {\n for (const [alias, canonicalModel] of Object.entries(aliasesRecord)) {\n if (typeof canonicalModel !== 'string') {\n continue;\n }\n\n const normalizedAlias = normalizeKey(alias);\n const normalizedCanonicalModel = normalizeKey(canonicalModel);\n\n aliasToCanonicalModel.set(normalizedAlias, normalizedCanonicalModel);\n canonicalizedAliasToCanonicalModel.set(\n canonicalizeForFuzzy(normalizedAlias),\n normalizedCanonicalModel,\n );\n }\n }\n\n const preferredPricingRecord = asRecord(payload.preferredPricingKeyByCanonicalModel);\n\n if (preferredPricingRecord) {\n for (const [canonicalModel, preferredPricingKey] of Object.entries(preferredPricingRecord)) {\n if (typeof preferredPricingKey !== 'string') {\n continue;\n }\n\n preferredPricingKeyByCanonicalModel.set(\n normalizeKey(canonicalModel),\n normalizeKey(preferredPricingKey),\n );\n }\n }\n\n return {\n aliasToCanonicalModel,\n canonicalizedAliasToCanonicalModel,\n preferredPricingKeyByCanonicalModel,\n };\n}\n\nconst litellmModelMap = parseLiteLLMModelMap(litellmModelMapPayload);\n\nfunction toNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return value;\n }\n\n if (typeof value === 'string') {\n if (value.trim() === '') {\n return undefined;\n }\n\n const parsedValue = Number(value);\n\n if (!Number.isFinite(parsedValue) || parsedValue < 0) {\n return undefined;\n }\n\n return parsedValue;\n }\n\n return undefined;\n}\n\nfunction normalizeModelPricing(rawModelPricing: Record<string, unknown>): ModelPricing | undefined {\n const inputPerToken =\n toNonNegativeNumber(rawModelPricing.input_cost_per_token) ??\n toNonNegativeNumber(rawModelPricing.input_cost_per_token_priority);\n const outputPerToken =\n toNonNegativeNumber(rawModelPricing.output_cost_per_token) ??\n toNonNegativeNumber(rawModelPricing.output_cost_per_token_priority);\n\n if (inputPerToken === undefined || outputPerToken === undefined) {\n return undefined;\n }\n\n const cacheReadPerToken =\n toNonNegativeNumber(rawModelPricing.cache_read_input_token_cost) ??\n toNonNegativeNumber(rawModelPricing.cache_read_input_token_cost_priority);\n const cacheWritePerToken = toNonNegativeNumber(rawModelPricing.cache_creation_input_token_cost);\n const reasoningPerToken = toNonNegativeNumber(rawModelPricing.output_cost_per_reasoning_token);\n\n const modelPricing: ModelPricing = {\n inputPer1MUsd: inputPerToken * ONE_MILLION,\n outputPer1MUsd: outputPerToken * ONE_MILLION,\n };\n\n if (cacheReadPerToken !== undefined) {\n modelPricing.cacheReadPer1MUsd = cacheReadPerToken * ONE_MILLION;\n }\n\n if (cacheWritePerToken !== undefined) {\n modelPricing.cacheWritePer1MUsd = cacheWritePerToken * ONE_MILLION;\n }\n\n if (reasoningPerToken !== undefined) {\n modelPricing.reasoningPer1MUsd = reasoningPerToken * ONE_MILLION;\n modelPricing.reasoningBilling = 'separate';\n }\n\n return modelPricing;\n}\n\nfunction normalizeLitellmPricingPayload(payload: unknown): Map<string, ModelPricing> {\n const payloadRecord = asRecord(payload);\n\n if (!payloadRecord) {\n throw new Error('LiteLLM pricing payload must be a JSON object');\n }\n\n const normalizedPricing = new Map<string, ModelPricing>();\n\n for (const [modelName, rawModelPricing] of Object.entries(payloadRecord)) {\n const modelPricingRecord = asRecord(rawModelPricing);\n\n if (!modelPricingRecord) {\n continue;\n }\n\n const normalizedModelPricing = normalizeModelPricing(modelPricingRecord);\n\n if (!normalizedModelPricing) {\n continue;\n }\n\n normalizedPricing.set(normalizeKey(modelName), normalizedModelPricing);\n }\n\n if (normalizedPricing.size === 0) {\n throw new Error('LiteLLM pricing payload did not contain any usable model pricing entries');\n }\n\n return normalizedPricing;\n}\n\nexport function getDefaultLiteLLMPricingCachePath(): string {\n return path.join(getUserCacheRootDir(), 'llm-usage-metrics', 'litellm-pricing-cache.json');\n}\n\nfunction stripProviderPrefix(model: string): string {\n const slashIndex = model.lastIndexOf('/');\n\n if (slashIndex === -1) {\n return model;\n }\n\n return model.slice(slashIndex + 1);\n}\n\nfunction canonicalizeForFuzzy(value: string): string {\n return value.replace(/[^a-z0-9]/gu, '');\n}\n\nfunction isPrefixModelMatch(candidate: string, modelName: string): boolean {\n if (!candidate.startsWith(modelName)) {\n return false;\n }\n\n if (candidate.length === modelName.length) {\n return true;\n }\n\n const nextCharacter = candidate[modelName.length];\n return nextCharacter === '-' || nextCharacter === ':' || nextCharacter === '@';\n}\n\nfunction extractNumericTokens(value: string): string[] {\n return value.match(/\\d+/gu) ?? [];\n}\n\nfunction areNumericSignaturesCompatible(left: string, right: string): boolean {\n const leftTokens = extractNumericTokens(left);\n const rightTokens = extractNumericTokens(right);\n\n if (leftTokens.length === 0 || rightTokens.length === 0) {\n return true;\n }\n\n if (\n leftTokens.length === rightTokens.length &&\n leftTokens.every((token, index) => token === rightTokens[index])\n ) {\n return true;\n }\n\n if (leftTokens.length === 1 && rightTokens.length > 1 && rightTokens.join('') === leftTokens[0]) {\n return true;\n }\n\n if (rightTokens.length === 1 && leftTokens.length > 1 && leftTokens.join('') === rightTokens[0]) {\n return true;\n }\n\n return false;\n}\n\nfunction levenshteinDistance(left: string, right: string): number {\n const leftLength = left.length;\n const rightLength = right.length;\n\n const matrix = Array.from({ length: leftLength + 1 }, (_, rowIndex) => {\n return Array.from({ length: rightLength + 1 }, (_, columnIndex) => {\n if (rowIndex === 0) {\n return columnIndex;\n }\n\n if (columnIndex === 0) {\n return rowIndex;\n }\n\n return 0;\n });\n });\n\n for (let rowIndex = 1; rowIndex <= leftLength; rowIndex += 1) {\n for (let columnIndex = 1; columnIndex <= rightLength; columnIndex += 1) {\n const substitutionCost = left[rowIndex - 1] === right[columnIndex - 1] ? 0 : 1;\n\n matrix[rowIndex][columnIndex] = Math.min(\n matrix[rowIndex - 1][columnIndex] + 1,\n matrix[rowIndex][columnIndex - 1] + 1,\n matrix[rowIndex - 1][columnIndex - 1] + substitutionCost,\n );\n }\n }\n\n return matrix[leftLength][rightLength];\n}\n\nexport class LiteLLMPricingFetcher implements PricingSource {\n private readonly sourceUrl: string;\n private readonly cacheFilePath: string;\n private readonly cacheTtlMs: number;\n private readonly fetchTimeoutMs: number;\n private readonly fetchRetryCount: number;\n private readonly fetchRetryDelayMs: number;\n private readonly offline: boolean;\n private readonly fetchImpl: typeof fetch;\n private readonly now: () => number;\n private readonly sleep: (delayMs: number) => Promise<void>;\n\n private pricingByModel = new Map<string, ModelPricing>();\n private resolvedAliasCache = new Map<string, string>();\n\n public constructor(options: LiteLLMPricingFetcherOptions = {}) {\n this.sourceUrl = options.sourceUrl ?? DEFAULT_LITELLM_PRICING_URL;\n this.cacheFilePath = options.cacheFilePath ?? getDefaultLiteLLMPricingCachePath();\n this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n this.fetchTimeoutMs = options.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;\n this.fetchRetryCount =\n Number.isFinite(options.fetchRetryCount) && (options.fetchRetryCount ?? 0) >= 0\n ? Math.trunc(options.fetchRetryCount ?? DEFAULT_FETCH_RETRY_COUNT)\n : DEFAULT_FETCH_RETRY_COUNT;\n this.fetchRetryDelayMs =\n Number.isFinite(options.fetchRetryDelayMs) && (options.fetchRetryDelayMs ?? 0) > 0\n ? Math.trunc(options.fetchRetryDelayMs ?? DEFAULT_FETCH_RETRY_DELAY_MS)\n : DEFAULT_FETCH_RETRY_DELAY_MS;\n this.offline = options.offline ?? false;\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.now = options.now ?? Date.now;\n this.sleep = options.sleep ?? sleep;\n }\n\n /**\n * Loads pricing data from cache or remote.\n * @returns Promise<boolean> True if loaded from cache, false if from network\n */\n public async load(): Promise<boolean> {\n const cacheLoaded = await this.loadFromCache({ allowStale: false });\n\n if (cacheLoaded) {\n return true;\n }\n\n if (this.offline) {\n const staleCacheLoaded = await this.loadFromCache({ allowStale: true });\n\n if (!staleCacheLoaded) {\n throw new Error('Offline pricing mode enabled but no cached LiteLLM pricing is available');\n }\n\n return true;\n }\n\n try {\n await this.loadFromRemote();\n return false;\n } catch {\n const staleCacheLoaded = await this.loadFromCache({ allowStale: true });\n\n if (!staleCacheLoaded) {\n throw new Error('Could not load LiteLLM pricing from network or cache');\n }\n\n return true;\n }\n }\n\n public resolveModelAlias(model: string): string {\n const normalizedModel = normalizeKey(model);\n const cachedAlias = this.resolvedAliasCache.get(normalizedModel);\n\n if (cachedAlias) {\n return cachedAlias;\n }\n\n const mappedAlias = this.resolveMappedModelAlias(normalizedModel);\n\n if (mappedAlias) {\n this.resolvedAliasCache.set(normalizedModel, mappedAlias);\n return mappedAlias;\n }\n\n const directMatch = this.resolveDirectModelMatch(normalizedModel);\n\n if (directMatch) {\n this.resolvedAliasCache.set(normalizedModel, directMatch);\n return directMatch;\n }\n\n const providerPrefixedMatch = this.resolveProviderPrefixedModelMatch(normalizedModel);\n\n if (providerPrefixedMatch) {\n this.resolvedAliasCache.set(normalizedModel, providerPrefixedMatch);\n return providerPrefixedMatch;\n }\n\n const prefixMatch = this.resolvePrefixModelMatch(normalizedModel);\n\n if (prefixMatch) {\n this.resolvedAliasCache.set(normalizedModel, prefixMatch);\n return prefixMatch;\n }\n\n const fuzzyMatch = this.resolveFuzzyModelMatch(normalizedModel);\n const resolvedAlias = fuzzyMatch ?? normalizedModel;\n this.resolvedAliasCache.set(normalizedModel, resolvedAlias);\n\n return resolvedAlias;\n }\n\n public getPricing(model: string): ModelPricing | undefined {\n const resolvedModel = this.resolveModelAlias(model);\n return this.pricingByModel.get(resolvedModel);\n }\n\n private resolveMappedModelAlias(normalizedModel: string): string | undefined {\n const canonicalModel = this.resolveCanonicalModelName(normalizedModel);\n\n if (!canonicalModel) {\n return undefined;\n }\n\n const preferredPricingKey =\n litellmModelMap.preferredPricingKeyByCanonicalModel.get(canonicalModel);\n\n if (preferredPricingKey && this.pricingByModel.has(preferredPricingKey)) {\n return preferredPricingKey;\n }\n\n const directCanonicalMatch = this.resolveDirectModelMatch(canonicalModel);\n\n if (directCanonicalMatch) {\n return directCanonicalMatch;\n }\n\n const providerPrefixedCanonicalMatch = this.resolveProviderPrefixedModelMatch(canonicalModel);\n\n if (providerPrefixedCanonicalMatch) {\n return providerPrefixedCanonicalMatch;\n }\n\n const prefixCanonicalMatch = this.resolvePrefixModelMatch(canonicalModel);\n\n if (prefixCanonicalMatch) {\n return prefixCanonicalMatch;\n }\n\n return this.resolveFuzzyModelMatch(canonicalModel);\n }\n\n private resolveCanonicalModelName(normalizedModel: string): string | undefined {\n const strippedModel = stripProviderPrefix(normalizedModel);\n\n const directCanonicalMatch =\n litellmModelMap.aliasToCanonicalModel.get(normalizedModel) ??\n litellmModelMap.aliasToCanonicalModel.get(strippedModel);\n\n if (directCanonicalMatch) {\n return directCanonicalMatch;\n }\n\n const canonicalizedModel = canonicalizeForFuzzy(normalizedModel);\n const canonicalizedStrippedModel = canonicalizeForFuzzy(strippedModel);\n\n return (\n litellmModelMap.canonicalizedAliasToCanonicalModel.get(canonicalizedModel) ??\n litellmModelMap.canonicalizedAliasToCanonicalModel.get(canonicalizedStrippedModel)\n );\n }\n\n private resolveDirectModelMatch(normalizedModel: string): string | undefined {\n if (this.pricingByModel.has(normalizedModel)) {\n return normalizedModel;\n }\n\n const strippedModel = stripProviderPrefix(normalizedModel);\n\n if (this.pricingByModel.has(strippedModel)) {\n return strippedModel;\n }\n\n return undefined;\n }\n\n private resolveProviderPrefixedModelMatch(normalizedModel: string): string | undefined {\n const candidates = [normalizedModel, stripProviderPrefix(normalizedModel)];\n\n for (const candidate of candidates) {\n let bestMatch: string | undefined;\n\n for (const modelName of this.pricingByModel.keys()) {\n const isProviderPrefixedMatch =\n modelName.endsWith(`/${candidate}`) || modelName.endsWith(`.${candidate}`);\n\n if (!isProviderPrefixedMatch) {\n continue;\n }\n\n if (\n !bestMatch ||\n modelName.length < bestMatch.length ||\n (modelName.length === bestMatch.length && compareByCodePoint(modelName, bestMatch) < 0)\n ) {\n bestMatch = modelName;\n }\n }\n\n if (bestMatch) {\n return bestMatch;\n }\n }\n\n return undefined;\n }\n\n private resolvePrefixModelMatch(normalizedModel: string): string | undefined {\n const candidates = [normalizedModel, stripProviderPrefix(normalizedModel)];\n\n for (const candidate of candidates) {\n let bestMatch: string | undefined;\n\n for (const modelName of this.pricingByModel.keys()) {\n if (!isPrefixModelMatch(candidate, modelName)) {\n continue;\n }\n\n if (\n !bestMatch ||\n modelName.length > bestMatch.length ||\n (modelName.length === bestMatch.length && compareByCodePoint(modelName, bestMatch) < 0)\n ) {\n bestMatch = modelName;\n }\n }\n\n if (bestMatch) {\n return bestMatch;\n }\n }\n\n return undefined;\n }\n\n private resolveFuzzyModelMatch(normalizedModel: string): string | undefined {\n const strippedModel = stripProviderPrefix(normalizedModel);\n const fuzzyTarget = canonicalizeForFuzzy(strippedModel);\n\n if (!fuzzyTarget) {\n return undefined;\n }\n\n let bestMatch: { modelName: string; distance: number } | undefined;\n\n for (const modelName of this.pricingByModel.keys()) {\n if (!areNumericSignaturesCompatible(strippedModel, modelName)) {\n continue;\n }\n\n const fuzzyModelName = canonicalizeForFuzzy(modelName);\n\n if (!fuzzyModelName) {\n continue;\n }\n\n const distance = levenshteinDistance(fuzzyTarget, fuzzyModelName);\n\n if (!bestMatch || distance < bestMatch.distance) {\n bestMatch = { modelName, distance };\n }\n }\n\n if (!bestMatch) {\n return undefined;\n }\n\n const maxDistance = Math.max(2, Math.floor(fuzzyTarget.length * 0.2));\n\n if (bestMatch.distance > maxDistance) {\n return undefined;\n }\n\n return bestMatch.modelName;\n }\n\n private async fetchRemotePricingResponse(): Promise<Response> {\n const response = await this.fetchImpl(this.sourceUrl, {\n signal: AbortSignal.timeout(this.fetchTimeoutMs),\n });\n\n if (!response.ok) {\n if (isRetryableHttpStatus(response.status)) {\n throw new RetryableLiteLLMFetchError(\n `Retryable LiteLLM pricing response status: HTTP ${response.status}`,\n );\n }\n\n throw new Error(`Failed to fetch LiteLLM pricing: HTTP ${response.status}`);\n }\n\n return response;\n }\n\n private async fetchRemotePricingResponseWithRetry(): Promise<Response> {\n const maxAttempts = this.fetchRetryCount + 1;\n\n for (let attemptIndex = 0; attemptIndex < maxAttempts; attemptIndex += 1) {\n try {\n return await this.fetchRemotePricingResponse();\n } catch (error) {\n const shouldRetry = isRetryableFetchFailure(error) && attemptIndex < maxAttempts - 1;\n\n if (!shouldRetry) {\n throw error;\n }\n }\n\n const backoffDelay = this.fetchRetryDelayMs * 2 ** attemptIndex;\n await this.sleep(backoffDelay);\n }\n\n throw new Error('Failed to fetch LiteLLM pricing after retries');\n }\n\n private async loadFromRemote(): Promise<void> {\n const response = await this.fetchRemotePricingResponseWithRetry();\n const payload = (await response.json()) as unknown;\n const normalizedPricing = normalizeLitellmPricingPayload(payload);\n\n this.pricingByModel = normalizedPricing;\n this.resolvedAliasCache.clear();\n\n try {\n await this.writeCache();\n } catch {\n // Cache writes are best-effort. A successful remote fetch must still be usable.\n }\n }\n\n private async loadFromCache(options: { allowStale: boolean }): Promise<boolean> {\n const cacheFileContent = await this.readCachePayload();\n\n if (!cacheFileContent) {\n return false;\n }\n\n if (cacheFileContent.sourceUrl !== this.sourceUrl) {\n return false;\n }\n\n const nowTimestamp = this.now();\n const isStale =\n cacheFileContent.fetchedAt > nowTimestamp ||\n nowTimestamp - cacheFileContent.fetchedAt > this.cacheTtlMs;\n\n if (isStale && !options.allowStale) {\n return false;\n }\n\n this.pricingByModel = new Map(\n Object.entries(cacheFileContent.pricingByModel).map(([modelName, pricing]) => [\n normalizeKey(modelName),\n pricing,\n ]),\n );\n this.resolvedAliasCache.clear();\n\n return this.pricingByModel.size > 0;\n }\n\n private normalizeCachedPricing(rawPricing: unknown): ModelPricing | undefined {\n const pricingRecord = asRecord(rawPricing);\n\n if (!pricingRecord) {\n return undefined;\n }\n\n const inputPer1MUsd = toNonNegativeNumber(pricingRecord.inputPer1MUsd);\n const outputPer1MUsd = toNonNegativeNumber(pricingRecord.outputPer1MUsd);\n\n if (inputPer1MUsd === undefined || outputPer1MUsd === undefined) {\n return undefined;\n }\n\n const modelPricing: ModelPricing = {\n inputPer1MUsd,\n outputPer1MUsd,\n };\n\n const cacheReadPer1MUsd = toNonNegativeNumber(pricingRecord.cacheReadPer1MUsd);\n\n if (cacheReadPer1MUsd !== undefined) {\n modelPricing.cacheReadPer1MUsd = cacheReadPer1MUsd;\n }\n\n const cacheWritePer1MUsd = toNonNegativeNumber(pricingRecord.cacheWritePer1MUsd);\n\n if (cacheWritePer1MUsd !== undefined) {\n modelPricing.cacheWritePer1MUsd = cacheWritePer1MUsd;\n }\n\n const reasoningPer1MUsd = toNonNegativeNumber(pricingRecord.reasoningPer1MUsd);\n\n if (reasoningPer1MUsd !== undefined) {\n modelPricing.reasoningPer1MUsd = reasoningPer1MUsd;\n modelPricing.reasoningBilling = 'separate';\n }\n\n return modelPricing;\n }\n\n private async readCachePayload(): Promise<LiteLLMCachePayload | undefined> {\n let content: string;\n\n try {\n content = await readFile(this.cacheFilePath, 'utf8');\n } catch {\n return undefined;\n }\n\n let parsedPayload: unknown;\n\n try {\n parsedPayload = JSON.parse(content);\n } catch {\n return undefined;\n }\n\n const payloadRecord = asRecord(parsedPayload);\n\n if (!payloadRecord) {\n return undefined;\n }\n\n const fetchedAt = toNonNegativeNumber(payloadRecord.fetchedAt);\n const sourceUrl =\n typeof payloadRecord.sourceUrl === 'string' ? payloadRecord.sourceUrl : undefined;\n const pricingByModelRecord = asRecord(payloadRecord.pricingByModel);\n\n if (fetchedAt === undefined || !sourceUrl || !pricingByModelRecord) {\n return undefined;\n }\n\n const pricingByModel: Record<string, ModelPricing> = {};\n\n for (const [modelName, rawPricing] of Object.entries(pricingByModelRecord)) {\n const pricing = this.normalizeCachedPricing(rawPricing);\n\n if (!pricing) {\n continue;\n }\n\n pricingByModel[modelName] = pricing;\n }\n\n return {\n fetchedAt,\n sourceUrl,\n pricingByModel,\n };\n }\n\n private async writeCache(): Promise<void> {\n const directoryPath = path.dirname(this.cacheFilePath);\n await mkdir(directoryPath, { recursive: true });\n\n const payload: LiteLLMCachePayload = {\n fetchedAt: this.now(),\n sourceUrl: this.sourceUrl,\n pricingByModel: Object.fromEntries(this.pricingByModel.entries()),\n };\n\n await writeFile(this.cacheFilePath, JSON.stringify(payload), 'utf8');\n }\n}\n","{\n \"aliases\": {\n \"k2p5\": \"kimi-k2.5\",\n \"kimi-k2p5\": \"kimi-k2.5\",\n \"kimi-k2.5\": \"kimi-k2.5\",\n \"kimi-k2.5-free\": \"kimi-k2.5\",\n \"moonshotai.kimi-k2.5\": \"kimi-k2.5\",\n \"moonshot/kimi-k2.5\": \"kimi-k2.5\",\n\n \"gpt-5.3-codex-spark\": \"gpt-5.3-codex\",\n\n \"gemini-3-pro\": \"gemini-3-pro\",\n \"antigravity-gemini-3-flash\": \"gemini-3-flash\",\n \"antigravity-gemini-3-pro\": \"gemini-3-pro\",\n \"antigravity-gemini-3-pro-high\": \"gemini-3-pro\",\n\n \"minimax-m2.1\": \"minimax-m2.1\",\n \"minimax-m2.1-free\": \"minimax-m2.1\",\n \"minimax-m2.5\": \"minimax-m2.5\",\n \"minimax-m2.5-free\": \"minimax-m2.5\",\n\n \"claude sonnet 4.6\": \"claude-sonnet-4.6\",\n \"claude-sonnet-4.6\": \"claude-sonnet-4.6\",\n \"claude-sonnet-4-6\": \"claude-sonnet-4.6\",\n \"anthropic/claude-sonnet-4.6\": \"claude-sonnet-4.6\",\n \"anthropic.claude-sonnet-4-6\": \"claude-sonnet-4.6\"\n },\n \"notes\": {\n \"gpt-5.3-codex-spark\": \"Alias to gpt-5.3-codex because upstream publishes token pricing on the gpt-5.3-codex key\"\n },\n \"preferredPricingKeyByCanonicalModel\": {\n \"kimi-k2.5\": \"moonshot/kimi-k2.5\",\n \"gpt-5.3-codex\": \"gpt-5.3-codex\",\n \"gemini-3-flash\": \"gemini/gemini-3-flash-preview\",\n \"gemini-3-pro\": \"gemini/gemini-3-pro-preview\",\n \"minimax-m2.1\": \"openrouter/minimax/minimax-m2.1\",\n \"minimax-m2.5\": \"openrouter/minimax/minimax-m2.5\",\n \"claude-sonnet-4.6\": \"anthropic.claude-sonnet-4-6\"\n }\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport {\n getPricingFetcherRuntimeConfig,\n type PricingFetcherRuntimeConfig,\n} from '../config/runtime-overrides.js';\nimport { applyPricingToEvents } from '../pricing/cost-engine.js';\nimport { LiteLLMPricingFetcher } from '../pricing/litellm-pricing-fetcher.js';\n\nimport type {\n PricingLoadResult,\n ReportCommandOptions,\n UsagePricingOrigin,\n} from './usage-data-contracts.js';\n\nexport async function resolvePricingSource(\n options: ReportCommandOptions,\n runtimeConfig: PricingFetcherRuntimeConfig,\n): Promise<PricingLoadResult> {\n const litellmPricingFetcher = new LiteLLMPricingFetcher({\n sourceUrl: options.pricingUrl,\n offline: options.pricingOffline,\n cacheTtlMs: runtimeConfig.cacheTtlMs,\n fetchTimeoutMs: runtimeConfig.fetchTimeoutMs,\n });\n\n try {\n const fromCache = await litellmPricingFetcher.load();\n\n if (options.pricingOffline) {\n return { source: litellmPricingFetcher, origin: 'offline-cache' };\n }\n\n return { source: litellmPricingFetcher, origin: fromCache ? 'cache' : 'network' };\n } catch (error) {\n if (options.pricingOffline) {\n throw new Error('Offline pricing mode enabled but cached pricing is unavailable', {\n cause: error,\n });\n }\n\n const reason = error instanceof Error ? error.message : String(error);\n\n if (options.pricingUrl) {\n throw new Error(`Could not load pricing from --pricing-url: ${reason}`, {\n cause: error,\n });\n }\n\n throw new Error(`Could not load LiteLLM pricing: ${reason}`, { cause: error });\n }\n}\n\nexport function eventNeedsPricingLookup(event: UsageEvent): boolean {\n if (!event.model) {\n return false;\n }\n\n if (event.totalTokens <= 0) {\n return false;\n }\n\n return event.costMode !== 'explicit' || event.costUsd === undefined || event.costUsd === 0;\n}\n\nexport function shouldLoadPricingSource(events: UsageEvent[]): boolean {\n if (events.length === 0) {\n return false;\n }\n\n return events.some((event) => eventNeedsPricingLookup(event));\n}\n\ntype PricingSourceResolver = (\n options: ReportCommandOptions,\n runtimeConfig: PricingFetcherRuntimeConfig,\n) => Promise<PricingLoadResult>;\n\nexport async function resolveAndApplyPricingToEvents(\n events: UsageEvent[],\n options: ReportCommandOptions,\n runtimeConfig: PricingFetcherRuntimeConfig = getPricingFetcherRuntimeConfig(),\n loadPricingSource: PricingSourceResolver = resolvePricingSource,\n): Promise<{\n pricedEvents: UsageEvent[];\n pricingOrigin: UsagePricingOrigin;\n pricingWarning?: string;\n}> {\n let pricingOrigin: UsagePricingOrigin = 'none';\n\n if (!shouldLoadPricingSource(events)) {\n return {\n pricedEvents: events,\n pricingOrigin,\n };\n }\n\n let pricingResult: PricingLoadResult;\n\n try {\n pricingResult = await loadPricingSource(options, runtimeConfig);\n } catch (error) {\n if (!options.ignorePricingFailures) {\n throw error;\n }\n\n const reason = error instanceof Error ? error.message : String(error);\n const pricingWarning = reason.trim().startsWith('Could not load')\n ? reason\n : `Could not load pricing; continuing without estimated costs: ${reason}`;\n\n return {\n pricedEvents: events,\n pricingOrigin,\n pricingWarning,\n };\n }\n\n pricingOrigin = pricingResult.origin;\n\n return {\n pricedEvents: applyPricingToEvents(events, pricingResult.source),\n pricingOrigin,\n };\n}\n","import { aggregateUsage } from '../aggregate/aggregate-usage.js';\nimport { getActiveEnvVarOverrides } from '../config/env-var-display.js';\nimport {\n getParsingRuntimeConfig,\n getPricingFetcherRuntimeConfig,\n} from '../config/runtime-overrides.js';\nimport { createDefaultAdapters } from '../sources/create-default-adapters.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { assembleUsageDataResult, buildUsageDiagnostics } from './build-usage-data-diagnostics.js';\nimport { normalizeBuildUsageInputs, selectAdaptersForParsing } from './build-usage-data-inputs.js';\nimport {\n filterParsedAdapterEvents,\n parseSelectedAdapters,\n throwOnExplicitSourceFailures,\n} from './build-usage-data-parsing.js';\nimport {\n resolveAndApplyPricingToEvents,\n resolvePricingSource,\n} from './build-usage-data-pricing.js';\nimport type {\n BuildUsageDataDeps,\n ReportCommandOptions,\n UsageDataResult,\n} from './usage-data-contracts.js';\n\nfunction withNormalizedPricingUrl(\n options: ReportCommandOptions,\n normalizedPricingUrl: string | undefined,\n): ReportCommandOptions {\n if (options.pricingUrl === normalizedPricingUrl) {\n return options;\n }\n\n return {\n ...options,\n pricingUrl: normalizedPricingUrl,\n };\n}\n\nexport async function buildUsageData(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n deps: BuildUsageDataDeps = {},\n): Promise<UsageDataResult> {\n const normalizedInputs = normalizeBuildUsageInputs(options);\n\n const readParsingRuntimeConfig = deps.getParsingRuntimeConfig ?? getParsingRuntimeConfig;\n const readPricingRuntimeConfig =\n deps.getPricingFetcherRuntimeConfig ?? getPricingFetcherRuntimeConfig;\n const makeAdapters = deps.createAdapters ?? createDefaultAdapters;\n const loadPricingSource = deps.resolvePricingSource ?? resolvePricingSource;\n const readEnvVarOverrides = deps.getActiveEnvVarOverrides ?? getActiveEnvVarOverrides;\n\n const parsingRuntimeConfig = readParsingRuntimeConfig();\n const pricingRuntimeConfig = readPricingRuntimeConfig();\n const adapters = makeAdapters(options);\n const adaptersToParse = selectAdaptersForParsing(adapters, normalizedInputs.sourceFilter);\n\n const { successfulParseResults, sourceFailures } = await parseSelectedAdapters(\n adaptersToParse,\n parsingRuntimeConfig.maxParallelFileParsing,\n {\n parseCache: {\n enabled: parsingRuntimeConfig.parseCacheEnabled,\n ttlMs: parsingRuntimeConfig.parseCacheTtlMs,\n maxEntries: parsingRuntimeConfig.parseCacheMaxEntries,\n maxBytes: parsingRuntimeConfig.parseCacheMaxBytes,\n },\n },\n );\n\n throwOnExplicitSourceFailures(sourceFailures, normalizedInputs.explicitSourceIds);\n\n const filteredEvents = filterParsedAdapterEvents(successfulParseResults, {\n timezone: normalizedInputs.timezone,\n since: options.since,\n until: options.until,\n providerFilter: normalizedInputs.providerFilter,\n modelFilter: normalizedInputs.modelFilter,\n });\n\n const pricingOptions = withNormalizedPricingUrl(options, normalizedInputs.pricingUrl);\n\n const { pricedEvents, pricingOrigin, pricingWarning } = await resolveAndApplyPricingToEvents(\n filteredEvents,\n pricingOptions,\n pricingRuntimeConfig,\n loadPricingSource,\n );\n\n const rows = aggregateUsage(pricedEvents, {\n granularity,\n timezone: normalizedInputs.timezone,\n sourceOrder: adaptersToParse.map((adapter) => adapter.id),\n });\n\n const diagnostics = buildUsageDiagnostics({\n adaptersToParse,\n successfulParseResults,\n sourceFailures,\n pricingOrigin,\n pricingWarning,\n activeEnvOverrides: readEnvVarOverrides(),\n timezone: normalizedInputs.timezone,\n });\n\n return assembleUsageDataResult(pricedEvents, rows, diagnostics);\n}\n","import { aggregateUsage } from '../aggregate/aggregate-usage.js';\nimport { aggregateEfficiency } from '../efficiency/aggregate-efficiency.js';\nimport { collectGitOutcomes } from '../efficiency/git-outcome-collector.js';\nimport {\n attributeUsageEventsToRepo,\n resolveRepoRootFromPathHint,\n type RepoRootResolver,\n} from '../efficiency/repo-attribution.js';\nimport type { UsageEvent } from '../domain/usage-event.js';\nimport { getPeriodKey, type ReportGranularity } from '../utils/time-buckets.js';\nimport { buildUsageData } from './build-usage-data.js';\nimport type { EfficiencyCommandOptions, EfficiencyDataResult } from './usage-data-contracts.js';\n\nexport type BuildEfficiencyDataDeps = {\n buildUsageData?: typeof buildUsageData;\n collectGitOutcomes?: typeof collectGitOutcomes;\n resolveRepoRoot?: RepoRootResolver;\n};\n\nfunction hasActiveRepeatedFilter(value: string | string[] | undefined): boolean {\n if (!value) {\n return false;\n }\n\n const values = Array.isArray(value) ? value : [value];\n\n return values.some((entry) =>\n entry\n .split(',')\n .map((candidate) => candidate.trim())\n .some((candidate) => candidate.length > 0),\n );\n}\n\nfunction hasActiveProviderFilter(provider: string | undefined): boolean {\n return Boolean(provider?.trim());\n}\n\nfunction hasActiveTextOption(value: string | undefined): boolean {\n return Boolean(value?.trim());\n}\n\nfunction resolveScopeNote(options: EfficiencyCommandOptions): string | undefined {\n const activeFilters: string[] = [];\n\n if (hasActiveTextOption(options.piDir)) {\n activeFilters.push('--pi-dir');\n }\n\n if (hasActiveTextOption(options.codexDir)) {\n activeFilters.push('--codex-dir');\n }\n\n if (hasActiveTextOption(options.geminiDir)) {\n activeFilters.push('--gemini-dir');\n }\n\n if (hasActiveTextOption(options.droidDir)) {\n activeFilters.push('--droid-dir');\n }\n\n if (hasActiveTextOption(options.opencodeDb)) {\n activeFilters.push('--opencode-db');\n }\n\n if (hasActiveRepeatedFilter(options.sourceDir)) {\n activeFilters.push('--source-dir');\n }\n\n if (hasActiveRepeatedFilter(options.source)) {\n activeFilters.push('--source');\n }\n\n if (hasActiveProviderFilter(options.provider)) {\n activeFilters.push('--provider');\n }\n\n if (hasActiveRepeatedFilter(options.model)) {\n activeFilters.push('--model');\n }\n\n if (activeFilters.length === 0) {\n return undefined;\n }\n\n return `Usage filters (${activeFilters.join(', ')}) affect commit attribution too: only commit days with matching repo-attributed usage events are counted.`;\n}\n\nfunction hasMeaningfulEfficiencyUsageSignal(event: UsageEvent): boolean {\n return event.totalTokens > 0 || (event.costUsd !== undefined && event.costUsd > 0);\n}\n\nexport async function buildEfficiencyData(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n deps: BuildEfficiencyDataDeps = {},\n): Promise<EfficiencyDataResult> {\n const buildUsage = deps.buildUsageData ?? buildUsageData;\n const collectOutcomes = deps.collectGitOutcomes ?? collectGitOutcomes;\n const resolveRepoRoot = deps.resolveRepoRoot ?? resolveRepoRootFromPathHint;\n const repoDir = options.repoDir?.trim();\n\n if (options.repoDir !== undefined && !repoDir) {\n throw new Error('--repo-dir must be a non-empty path');\n }\n\n const usageData = await buildUsage(granularity, options);\n const attribution = await attributeUsageEventsToRepo(\n usageData.events,\n repoDir ?? process.cwd(),\n resolveRepoRoot,\n );\n const matchedEventsWithSignal = attribution.matchedEvents.filter((event) =>\n hasMeaningfulEfficiencyUsageSignal(event),\n );\n const activeUsageDays = new Set(\n matchedEventsWithSignal.map((event) =>\n getPeriodKey(event.timestamp, 'daily', usageData.diagnostics.timezone),\n ),\n );\n const gitOutcomes = await collectOutcomes({\n repoDir,\n granularity,\n timezone: usageData.diagnostics.timezone,\n since: options.since,\n until: options.until,\n includeMergeCommits: options.includeMergeCommits,\n activeUsageDays,\n });\n const repoScopedUsageRows = aggregateUsage(matchedEventsWithSignal, {\n granularity,\n timezone: usageData.diagnostics.timezone,\n });\n\n const rows = aggregateEfficiency({\n usageRows: repoScopedUsageRows,\n periodOutcomes: gitOutcomes.periodOutcomes,\n });\n\n return {\n rows,\n diagnostics: {\n usage: usageData.diagnostics,\n repoDir: gitOutcomes.diagnostics.repoDir,\n includeMergeCommits: gitOutcomes.diagnostics.includeMergeCommits,\n gitCommitCount: gitOutcomes.diagnostics.commitsCollected,\n gitLinesAdded: gitOutcomes.diagnostics.linesAdded,\n gitLinesDeleted: gitOutcomes.diagnostics.linesDeleted,\n repoMatchedUsageEvents: attribution.matchedEventCount,\n repoExcludedUsageEvents: attribution.excludedEventCount,\n repoUnattributedUsageEvents: attribution.unattributedEventCount,\n scopeNote: resolveScopeNote(options),\n },\n };\n}\n","import pc from 'picocolors';\n\ntype LogLevel = 'info' | 'warn' | 'dim';\n\nconst icons: Record<LogLevel, string> = {\n info: pc.blue('ℹ'),\n warn: pc.yellow('⚠'),\n dim: pc.gray('•'),\n};\n\nfunction formatMessage(level: LogLevel, message: string): string {\n const icon = icons[level];\n return `${icon} ${message}`;\n}\n\nexport const logger = {\n info: (message: string): void => {\n console.error(formatMessage('info', message));\n },\n warn: (message: string): void => {\n console.error(formatMessage('warn', message));\n },\n dim: (message: string): void => {\n console.error(formatMessage('dim', message));\n },\n};\n","import type { UsageDiagnostics } from './usage-data-contracts.js';\nimport { logger } from '../utils/logger.js';\n\nexport type DiagnosticsLogger = Pick<typeof logger, 'info' | 'warn' | 'dim'>;\n\nexport function emitDiagnostics(\n diagnostics: UsageDiagnostics,\n diagnosticsLogger: DiagnosticsLogger = logger,\n): void {\n const totalSessions = diagnostics.sessionStats.reduce(\n (sum, current) => sum + current.filesFound,\n 0,\n );\n const totalEvents = diagnostics.sessionStats.reduce(\n (sum, current) => sum + current.eventsParsed,\n 0,\n );\n\n if (totalSessions > 0) {\n diagnosticsLogger.info(`Found ${totalSessions} session file(s) with ${totalEvents} event(s)`);\n\n for (const session of diagnostics.sessionStats) {\n const eventsLabel = session.eventsParsed === 1 ? 'event' : 'events';\n diagnosticsLogger.dim(\n ` ${session.source}: ${session.filesFound} file(s), ${session.eventsParsed} ${eventsLabel}`,\n );\n }\n } else {\n diagnosticsLogger.warn('No sessions found');\n }\n\n if (diagnostics.sourceFailures.length > 0) {\n const sourceLabel = diagnostics.sourceFailures.length === 1 ? 'source' : 'sources';\n diagnosticsLogger.warn(`Failed to parse ${diagnostics.sourceFailures.length} ${sourceLabel}`);\n\n for (const failure of diagnostics.sourceFailures) {\n diagnosticsLogger.dim(` ${failure.source}: ${failure.reason}`);\n }\n }\n\n const totalSkippedRows = diagnostics.skippedRows.reduce(\n (sum, skippedRowsEntry) => sum + skippedRowsEntry.skippedRows,\n 0,\n );\n\n if (totalSkippedRows > 0) {\n const rowLabel = totalSkippedRows === 1 ? 'row' : 'rows';\n diagnosticsLogger.warn(`Skipped ${totalSkippedRows} malformed ${rowLabel}`);\n\n for (const skippedRowsEntry of diagnostics.skippedRows) {\n const reasonSummary = skippedRowsEntry.reasons\n ?.filter((reasonStat) => reasonStat.count > 0)\n .map((reasonStat) => `${reasonStat.reason}: ${reasonStat.count}`)\n .join(', ');\n\n diagnosticsLogger.dim(\n reasonSummary\n ? ` ${skippedRowsEntry.source}: ${skippedRowsEntry.skippedRows} skipped (${reasonSummary})`\n : ` ${skippedRowsEntry.source}: ${skippedRowsEntry.skippedRows} skipped`,\n );\n }\n }\n\n switch (diagnostics.pricingOrigin) {\n case 'offline-cache':\n diagnosticsLogger.info('Using cached pricing (offline mode)');\n break;\n case 'cache':\n diagnosticsLogger.info('Loaded pricing from cache');\n break;\n case 'network':\n diagnosticsLogger.info('Fetched pricing from LiteLLM');\n break;\n case 'none':\n break;\n }\n\n if (diagnostics.pricingWarning) {\n diagnosticsLogger.warn(diagnostics.pricingWarning);\n }\n}\n","import { formatEnvVarOverrides, type EnvVarOverride } from '../config/env-var-display.js';\n\ntype EnvVarOverridesLogger = {\n info: (message: string) => void;\n dim: (message: string) => void;\n};\n\nexport function emitEnvVarOverrides(\n activeEnvOverrides: EnvVarOverride[],\n diagnosticsLogger: EnvVarOverridesLogger,\n): void {\n const envVarOverrideLines = formatEnvVarOverrides(activeEnvOverrides);\n\n if (envVarOverrideLines.length === 0) {\n return;\n }\n\n const [headerLine, ...envVarLines] = envVarOverrideLines;\n\n if (headerLine) {\n diagnosticsLogger.info(headerLine);\n }\n\n for (const envVarLine of envVarLines) {\n diagnosticsLogger.dim(envVarLine);\n }\n}\n","const ansiEscapePattern = new RegExp(String.raw`\\u001B\\[[0-9;]*m`, 'gu');\nconst combiningMarkPattern = /\\p{Mark}/u;\nconst extendedPictographicPattern = /\\p{Extended_Pictographic}/u;\nconst emojiPresentationPattern = /\\p{Emoji_Presentation}/u;\nconst regionalIndicatorPattern = /\\p{Regional_Indicator}/u;\nconst graphemeSegmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });\n\nexport type TerminalColumnsSource = {\n isTTY?: unknown;\n columns?: unknown;\n};\n\nfunction normalizeLineBreaks(value: string): string {\n return value.replace(/\\r\\n?/gu, '\\n');\n}\n\nexport function resolveTtyColumns(source: TerminalColumnsSource): number | undefined {\n if (source.isTTY !== true) {\n return undefined;\n }\n\n if (\n typeof source.columns !== 'number' ||\n !Number.isFinite(source.columns) ||\n source.columns <= 0\n ) {\n return undefined;\n }\n\n return Math.floor(source.columns);\n}\n\nfunction stripAnsi(value: string): string {\n return value.replaceAll(ansiEscapePattern, '');\n}\n\nfunction isControlCodePoint(codePoint: number): boolean {\n return codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f);\n}\n\nfunction isZeroWidthCodePoint(codePoint: number): boolean {\n return (\n codePoint === 0x200b ||\n codePoint === 0x200d ||\n codePoint === 0x2060 ||\n codePoint === 0xfeff ||\n (codePoint >= 0xfe00 && codePoint <= 0xfe0f)\n );\n}\n\n// Adapted from the is-fullwidth-code-point package to preserve table alignment\n// for East Asian wide characters without re-introducing a dependency.\nconst fullWidthCodePointRanges = [\n [0x1100, 0x115f],\n [0x2329, 0x232a],\n [0x2e80, 0x3247],\n [0x3250, 0x4dbf],\n [0x4e00, 0xa4c6],\n [0xa960, 0xa97c],\n [0xac00, 0xd7a3],\n [0xf900, 0xfaff],\n [0xfe10, 0xfe19],\n [0xfe30, 0xfe6b],\n [0xff01, 0xff60],\n [0xffe0, 0xffe6],\n [0x1b000, 0x1b001],\n [0x1f200, 0x1f251],\n [0x20000, 0x3fffd],\n] as const;\n\nconst fullWidthCodePointExclusions = new Set<number>([0x303f]);\n\nfunction isFullWidthCodePoint(codePoint: number): boolean {\n if (Number.isNaN(codePoint) || fullWidthCodePointExclusions.has(codePoint)) {\n return false;\n }\n\n for (const [start, end] of fullWidthCodePointRanges) {\n if (codePoint >= start && codePoint <= end) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction codePointDisplayWidth(character: string): number {\n const codePoint = character.codePointAt(0);\n\n if (codePoint === undefined) {\n return 0;\n }\n\n if (isControlCodePoint(codePoint) || isZeroWidthCodePoint(codePoint)) {\n return 0;\n }\n\n if (combiningMarkPattern.test(character)) {\n return 0;\n }\n\n if (isFullWidthCodePoint(codePoint)) {\n return 2;\n }\n\n return 1;\n}\n\nfunction segmentGraphemes(value: string): string[] {\n return Array.from(graphemeSegmenter.segment(value), (segment) => segment.segment);\n}\n\nfunction isEmojiGrapheme(grapheme: string): boolean {\n if (emojiPresentationPattern.test(grapheme)) {\n return true;\n }\n\n if (regionalIndicatorPattern.test(grapheme)) {\n return true;\n }\n\n if (grapheme.includes('\\u20E3')) {\n return true;\n }\n\n if (grapheme.includes('\\uFE0F')) {\n return true;\n }\n\n return grapheme.includes('\\u200D') && extendedPictographicPattern.test(grapheme);\n}\n\nfunction graphemeDisplayWidth(grapheme: string): number {\n if (isEmojiGrapheme(grapheme)) {\n return 2;\n }\n\n let width = 0;\n\n for (const character of grapheme) {\n width = Math.max(width, codePointDisplayWidth(character));\n }\n\n return width;\n}\n\nexport function visibleWidth(value: string): number {\n let width = 0;\n\n for (const grapheme of segmentGraphemes(stripAnsi(value))) {\n width += graphemeDisplayWidth(grapheme);\n }\n\n return width;\n}\n\nexport function splitCellLines(value: string): string[] {\n return normalizeLineBreaks(value).split('\\n');\n}\n\nfunction sliceByVisibleWidth(value: string, maxWidth: number): string {\n if (maxWidth <= 0) {\n return '';\n }\n\n let width = 0;\n let endOffset = 0;\n\n for (const grapheme of segmentGraphemes(value)) {\n const graphemeWidth = graphemeDisplayWidth(grapheme);\n\n if (width + graphemeWidth > maxWidth) {\n break;\n }\n\n width += graphemeWidth;\n endOffset += grapheme.length;\n }\n\n return value.slice(0, endOffset);\n}\n\nfunction getFirstGrapheme(value: string): string {\n for (const grapheme of segmentGraphemes(value)) {\n return grapheme;\n }\n\n return '';\n}\n\nfunction wrapPlainLine(line: string, width: number): string[] {\n if (visibleWidth(line) <= width) {\n return [line];\n }\n\n const wrappedLines: string[] = [];\n let remaining = line;\n\n while (visibleWidth(remaining) > width) {\n const slice = sliceByVisibleWidth(remaining, width + 1);\n const breakIndex = slice.lastIndexOf(' ');\n\n if (breakIndex > 0) {\n wrappedLines.push(remaining.slice(0, breakIndex));\n remaining = remaining.slice(breakIndex + 1);\n continue;\n }\n\n const chunk = sliceByVisibleWidth(remaining, width);\n\n if (chunk.length > 0) {\n wrappedLines.push(chunk);\n remaining = remaining.slice(chunk.length);\n continue;\n }\n\n const firstCharacter = getFirstGrapheme(remaining);\n\n wrappedLines.push(firstCharacter);\n remaining = remaining.slice(firstCharacter.length);\n }\n\n wrappedLines.push(remaining);\n\n return wrappedLines;\n}\n\nexport function wrapTableColumn(\n rows: string[][],\n options: { columnIndex: number; width: number },\n): string[][] {\n if (options.width <= 0) {\n throw new RangeError('wrapTableColumn width must be greater than 0');\n }\n\n return rows.map((row) => {\n const wrappedRow = [...row];\n const cell = wrappedRow[options.columnIndex] ?? '';\n const wrappedLines = splitCellLines(cell).flatMap((line) => wrapPlainLine(line, options.width));\n\n wrappedRow[options.columnIndex] = wrappedLines.join('\\n');\n\n return wrappedRow;\n });\n}\n","import {\n resolveTtyColumns,\n type TerminalColumnsSource,\n visibleWidth,\n} from '../render/table-text-layout.js';\n\nfunction detectTerminalOverflowColumns(\n reportOutput: string,\n stdoutState: TerminalColumnsSource,\n): number | undefined {\n const terminalColumns = resolveTtyColumns(stdoutState);\n\n if (terminalColumns === undefined) {\n return undefined;\n }\n\n const allLines = reportOutput.trimEnd().split('\\n');\n const tableLikeLinePattern = /[│╭╮╰╯├┼┬┴┌┐└┘]|^\\s*\\|.*\\|\\s*$/u;\n const tableLines = allLines.filter((line) => tableLikeLinePattern.test(line));\n\n if (tableLines.length === 0) {\n return undefined;\n }\n\n const maxLineWidth = tableLines.reduce(\n (maxWidth, line) => Math.max(maxWidth, visibleWidth(line)),\n 0,\n );\n\n if (maxLineWidth <= terminalColumns) {\n return undefined;\n }\n\n return maxLineWidth - terminalColumns;\n}\n\nexport function warnIfTerminalTableOverflows(\n reportOutput: string,\n warn: (message: string) => void,\n stdoutState: TerminalColumnsSource = process.stdout as TerminalColumnsSource,\n): void {\n const overflowColumns = detectTerminalOverflowColumns(reportOutput, stdoutState);\n\n if (overflowColumns !== undefined) {\n warn(\n `Report table is wider than terminal by ${overflowColumns} column(s). Use fullscreen/maximized terminal for better readability.`,\n );\n }\n}\n","import { markdownTable } from 'markdown-table';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\nimport type { EfficiencyDataResult } from '../cli/usage-data-contracts.js';\nimport type { EfficiencyRow } from '../efficiency/efficiency-row.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { renderReportHeader } from './report-header.js';\nimport { efficiencyTableHeaders, toEfficiencyTableCells } from './efficiency-row-cells.js';\nimport { shouldUseColorByDefault } from './terminal-table.js';\nimport { renderUnicodeTable } from './unicode-table.js';\n\nexport type EfficiencyReportFormat = 'terminal' | 'markdown' | 'json';\n\nexport type RenderEfficiencyReportOptions = {\n granularity: ReportGranularity;\n useColor?: boolean;\n};\n\nfunction getReportTitle(granularity: ReportGranularity): string {\n switch (granularity) {\n case 'daily':\n return 'Daily Efficiency Report';\n case 'weekly':\n return 'Weekly Efficiency Report';\n case 'monthly':\n return 'Monthly Efficiency Report';\n }\n}\n\nfunction toTableSortRow(row: EfficiencyRow): UsageReportRow {\n if (row.rowType === 'grand_total') {\n return {\n rowType: 'grand_total',\n periodKey: 'ALL',\n source: 'combined',\n models: [],\n modelBreakdown: [],\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n costUsd: row.costUsd,\n costIncomplete: row.costIncomplete,\n };\n }\n\n return {\n rowType: 'period_source',\n periodKey: row.periodKey,\n source: 'combined',\n models: [],\n modelBreakdown: [],\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n costUsd: row.costUsd,\n costIncomplete: row.costIncomplete,\n };\n}\n\nfunction renderTerminalEfficiencyTable(rows: EfficiencyRow[]): string {\n const bodyRows = toEfficiencyTableCells(rows);\n const tableSortRows = rows.map((row) => toTableSortRow(row));\n const periodColumnWidth = Math.max(\n efficiencyTableHeaders[0].length,\n ...rows.map((row) => row.periodKey.length),\n );\n\n return renderUnicodeTable({\n headerCells: efficiencyTableHeaders,\n bodyRows,\n measureHeaderCells: efficiencyTableHeaders,\n measureBodyRows: bodyRows,\n usageRows: tableSortRows,\n tableLayout: 'compact',\n modelsColumnIndex: 0,\n modelsColumnWidth: periodColumnWidth,\n });\n}\n\nfunction toMarkdownSafeCell(value: string): string {\n return value.replace(/\\r?\\n/gu, '<br>');\n}\n\nfunction renderMarkdownEfficiencyTable(rows: EfficiencyRow[]): string {\n const bodyRows = toEfficiencyTableCells(rows).map((row) =>\n row.map((cell) => toMarkdownSafeCell(cell)),\n );\n const tableRows = [Array.from(efficiencyTableHeaders), ...bodyRows];\n const alignment = efficiencyTableHeaders.map((_, index) => (index === 0 ? 'l' : 'r')) as (\n | 'l'\n | 'r'\n )[];\n\n return markdownTable(tableRows, {\n align: alignment,\n });\n}\n\nfunction renderTerminalEfficiencyReport(\n efficiencyData: EfficiencyDataResult,\n options: RenderEfficiencyReportOptions,\n): string {\n const outputLines: string[] = [];\n const useColor = options.useColor ?? shouldUseColorByDefault();\n\n outputLines.push(\n renderReportHeader({\n title: getReportTitle(options.granularity),\n useColor,\n }),\n );\n\n outputLines.push('');\n outputLines.push(renderTerminalEfficiencyTable(efficiencyData.rows));\n\n return outputLines.join('\\n');\n}\n\nexport function renderEfficiencyReport(\n efficiencyData: EfficiencyDataResult,\n format: EfficiencyReportFormat,\n options: RenderEfficiencyReportOptions,\n): string {\n switch (format) {\n case 'json':\n return JSON.stringify(efficiencyData.rows, null, 2);\n case 'markdown':\n return renderMarkdownEfficiencyTable(efficiencyData.rows);\n case 'terminal':\n return renderTerminalEfficiencyReport(efficiencyData, options);\n }\n}\n","import pc from 'picocolors';\nimport { visibleWidth } from './table-text-layout.js';\n\nexport type ReportHeaderOptions = {\n title: string;\n useColor?: boolean;\n};\n\nfunction getBoxWidth(content: string): number {\n return visibleWidth(content) + 4;\n}\n\nfunction drawBoxLine(width: number, left: string, middle: string, right: string): string {\n return left + middle.repeat(width - 2) + right;\n}\n\nfunction padLine(content: string, width: number): string {\n const padding = width - 2 - visibleWidth(content);\n const leftPad = Math.floor(padding / 2);\n const rightPad = padding - leftPad;\n return '│' + ' '.repeat(leftPad) + content + ' '.repeat(rightPad) + '│';\n}\n\nexport function renderReportHeader(options: ReportHeaderOptions): string {\n const { title, useColor = true } = options;\n const boxWidth = getBoxWidth(title);\n\n const lines: string[] = [];\n\n const topBorder = drawBoxLine(boxWidth, '┌', '─', '┐');\n lines.push(useColor ? pc.gray(topBorder) : topBorder);\n\n const titleLine = padLine(title, boxWidth);\n lines.push(useColor ? pc.white(titleLine) : titleLine);\n\n const bottomBorder = drawBoxLine(boxWidth, '└', '─', '┘');\n lines.push(useColor ? pc.gray(bottomBorder) : bottomBorder);\n\n return lines.join('\\n');\n}\n","import type { EfficiencyRow } from '../efficiency/efficiency-row.js';\n\nexport const efficiencyTableHeaders = [\n 'Period',\n 'Commits',\n '+Lines',\n '-Lines',\n 'ΔLines',\n 'Input',\n 'Output',\n 'Reasoning',\n 'Cache Read',\n 'Cache Write',\n 'Total',\n 'Cost',\n '$/Commit',\n '$/1k Lines',\n 'All Tokens/Commit',\n 'Non-Cache/Commit',\n 'Commits/$',\n] as const;\n\nconst integerFormatter = new Intl.NumberFormat('en-US');\nconst decimalFormatter = new Intl.NumberFormat('en-US', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n});\nconst usdFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n});\nconst usdRateFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 4,\n maximumFractionDigits: 4,\n});\n\nfunction formatInteger(value: number): string {\n return integerFormatter.format(value);\n}\n\nfunction formatUsd(value: number | undefined, options: { approximate?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formatted = usdFormatter.format(value);\n return options.approximate ? `~${formatted}` : formatted;\n}\n\nfunction formatUsdRate(value: number | undefined, options: { approximate?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formatted = usdRateFormatter.format(value);\n return options.approximate ? `~${formatted}` : formatted;\n}\n\nfunction formatDecimal(value: number | undefined, options: { approximate?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formatted = decimalFormatter.format(value);\n return options.approximate ? `~${formatted}` : formatted;\n}\n\nexport function toEfficiencyTableCells(rows: EfficiencyRow[]): string[][] {\n return rows.map((row) => [\n row.periodKey,\n formatInteger(row.commitCount),\n formatInteger(row.linesAdded),\n formatInteger(row.linesDeleted),\n formatInteger(row.linesChanged),\n formatInteger(row.inputTokens),\n formatInteger(row.outputTokens),\n formatInteger(row.reasoningTokens),\n formatInteger(row.cacheReadTokens),\n formatInteger(row.cacheWriteTokens),\n formatInteger(row.totalTokens),\n formatUsd(row.costUsd, { approximate: row.costIncomplete }),\n formatUsdRate(row.usdPerCommit, { approximate: row.costIncomplete }),\n formatUsdRate(row.usdPer1kLinesChanged, { approximate: row.costIncomplete }),\n formatDecimal(row.tokensPerCommit),\n formatDecimal(row.nonCacheTokensPerCommit),\n formatDecimal(row.commitsPerUsd, { approximate: row.costIncomplete }),\n ]);\n}\n","import pc from 'picocolors';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { colorizeUsageBodyRows } from './terminal-style-policy.js';\nimport { toUsageTableCells, type UsageTableLayout, usageTableHeaders } from './row-cells.js';\nimport { resolveTtyColumns, visibleWidth, wrapTableColumn } from './table-text-layout.js';\nimport { renderUnicodeTable } from './unicode-table.js';\n\nconst modelsColumnIndex = 2;\nconst defaultModelsColumnWidth = 32;\nconst minimumModelsColumnWidth = 12;\n\ntype TerminalRenderOptions = {\n useColor?: boolean;\n tableLayout?: UsageTableLayout;\n terminalWidth?: number;\n};\n\nexport function shouldUseColorByDefault(): boolean {\n if (process.env.NO_COLOR !== undefined) {\n return false;\n }\n\n if (process.env.FORCE_COLOR !== undefined) {\n return process.env.FORCE_COLOR !== '0';\n }\n\n const stdoutIsTTY = (process.stdout as { isTTY: unknown }).isTTY;\n return stdoutIsTTY === true;\n}\n\nfunction colorizeHeader(useColor: boolean): string[] {\n const headerCells = Array.from(usageTableHeaders);\n\n if (!useColor) {\n return headerCells;\n }\n\n return headerCells.map((header) => pc.bold(pc.white(header)));\n}\n\nfunction isValidTerminalWidth(width: unknown): width is number {\n return typeof width === 'number' && Number.isFinite(width) && width > 0;\n}\n\nfunction resolveTerminalWidth(override: number | undefined): number | undefined {\n if (isValidTerminalWidth(override)) {\n return Math.floor(override);\n }\n\n return resolveTtyColumns(process.stdout as { isTTY?: unknown; columns?: unknown });\n}\n\nfunction measureTableWidth(tableOutput: string): number {\n return tableOutput\n .trimEnd()\n .split('\\n')\n .reduce((maxWidth, line) => Math.max(maxWidth, visibleWidth(line)), 0);\n}\n\nfunction renderTableWithModelsWidth(\n rows: UsageReportRow[],\n tableLayout: UsageTableLayout,\n useColor: boolean,\n modelsColumnWidth: number,\n): string {\n const uncoloredBodyRows = toUsageTableCells(rows, { layout: tableLayout });\n const wrappedBodyRows = wrapTableColumn(uncoloredBodyRows, {\n columnIndex: modelsColumnIndex,\n width: modelsColumnWidth,\n });\n const bodyRows = colorizeUsageBodyRows(wrappedBodyRows, rows, { useColor });\n\n return renderUnicodeTable({\n headerCells: colorizeHeader(useColor),\n bodyRows,\n measureHeaderCells: usageTableHeaders,\n measureBodyRows: wrappedBodyRows,\n usageRows: rows,\n tableLayout,\n modelsColumnIndex,\n modelsColumnWidth,\n });\n}\n\nexport function renderTerminalTable(\n rows: UsageReportRow[],\n options: TerminalRenderOptions = {},\n): string {\n const useColor = options.useColor ?? shouldUseColorByDefault();\n const tableLayout = options.tableLayout ?? 'compact';\n const hasExplicitTerminalWidth = isValidTerminalWidth(options.terminalWidth);\n const terminalWidth = resolveTerminalWidth(options.terminalWidth);\n let modelsColumnWidth = defaultModelsColumnWidth;\n let renderedTable = renderTableWithModelsWidth(rows, tableLayout, useColor, modelsColumnWidth);\n\n if (terminalWidth !== undefined) {\n let renderedTableWidth = measureTableWidth(renderedTable);\n\n while (renderedTableWidth > terminalWidth && modelsColumnWidth > minimumModelsColumnWidth) {\n const overflowColumns = renderedTableWidth - terminalWidth;\n const nextModelsColumnWidth = Math.max(\n minimumModelsColumnWidth,\n modelsColumnWidth - overflowColumns,\n );\n\n if (nextModelsColumnWidth === modelsColumnWidth) {\n break;\n }\n\n modelsColumnWidth = nextModelsColumnWidth;\n renderedTable = renderTableWithModelsWidth(rows, tableLayout, useColor, modelsColumnWidth);\n renderedTableWidth = measureTableWidth(renderedTable);\n }\n\n if (hasExplicitTerminalWidth && renderedTableWidth > terminalWidth) {\n throw new Error(\n `Configured terminal width (${terminalWidth}) is too narrow for table rendering (minimum ${renderedTableWidth}).`,\n );\n }\n }\n\n return renderedTable;\n}\n","import pc from 'picocolors';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\n\nexport type TextStyler = (text: string) => string;\n\nexport type TerminalStylePalette = {\n cyan: TextStyler;\n magenta: TextStyler;\n blue: TextStyler;\n yellow: TextStyler;\n green: TextStyler;\n white: TextStyler;\n bold: TextStyler;\n dim: TextStyler;\n};\n\nexport const defaultTerminalStylePalette: TerminalStylePalette = {\n cyan: pc.cyan,\n magenta: pc.magenta,\n blue: pc.blue,\n yellow: pc.yellow,\n green: pc.green,\n white: pc.white,\n bold: pc.bold,\n dim: pc.dim,\n};\n\nconst passthroughStyler: TextStyler = (text) => text;\n\nfunction styleCellLines(cell: string, styler: TextStyler): string {\n return cell\n .split('\\n')\n .map((line) => (line.length === 0 ? '' : styler(line)))\n .join('\\n');\n}\n\ntype SourceStylePolicy = (palette: TerminalStylePalette) => TextStyler;\n\nconst sourceStylePolicies = new Map<string, SourceStylePolicy>([\n ['pi', (palette) => palette.cyan],\n ['codex', (palette) => palette.magenta],\n ['opencode', (palette) => palette.blue],\n]);\n\nexport function resolveSourceStyler(\n source: string,\n palette: TerminalStylePalette = defaultTerminalStylePalette,\n): TextStyler {\n const stylePolicy = sourceStylePolicies.get(source);\n\n if (!stylePolicy) {\n return passthroughStyler;\n }\n\n return stylePolicy(palette);\n}\n\ntype RowTypeStylePolicy = (cells: string[], palette: TerminalStylePalette) => string[];\n\nconst rowTypeStylePolicies: Record<UsageReportRow['rowType'], RowTypeStylePolicy> = {\n period_source: (cells, palette) => {\n const styledCells = [...cells];\n const costColumnIndex = styledCells.length - 1;\n\n styledCells[costColumnIndex] = styleCellLines(styledCells[costColumnIndex], palette.yellow);\n\n return styledCells;\n },\n period_combined: (cells, palette) =>\n cells.map((cell, cellIndex) => {\n if (cellIndex === 1) {\n return styleCellLines(cell, (line) => palette.bold(palette.yellow(line)));\n }\n\n return styleCellLines(cell, palette.dim);\n }),\n grand_total: (cells, palette) =>\n cells.map((cell, cellIndex) => {\n if (cellIndex === 0) {\n return styleCellLines(cell, (line) => palette.bold(palette.white(line)));\n }\n\n if (cellIndex === 1) {\n return styleCellLines(cell, (line) => palette.bold(palette.green(line)));\n }\n\n return styleCellLines(cell, palette.bold);\n }),\n};\n\nexport function applyRowTypeStyle(\n rowType: UsageReportRow['rowType'],\n cells: string[],\n palette: TerminalStylePalette = defaultTerminalStylePalette,\n): string[] {\n return rowTypeStylePolicies[rowType](cells, palette);\n}\n\nfunction applyBaseCellStyle(\n cells: string[],\n palette: TerminalStylePalette,\n sourceStyler: TextStyler,\n): string[] {\n if (cells.length < 2) {\n return [...cells];\n }\n\n const styledCells = [...cells];\n\n styledCells[0] = styleCellLines(styledCells[0], palette.white);\n styledCells[1] = styleCellLines(styledCells[1], sourceStyler);\n\n return styledCells;\n}\n\nexport function colorizeUsageBodyRows(\n bodyRows: string[][],\n rows: UsageReportRow[],\n options: {\n useColor: boolean;\n palette?: TerminalStylePalette;\n },\n): string[][] {\n if (!options.useColor) {\n return bodyRows;\n }\n\n const palette = options.palette ?? defaultTerminalStylePalette;\n\n return rows.map((row, index) => {\n const sourceStyler =\n row.rowType === 'period_source'\n ? resolveSourceStyler(String(row.source), palette)\n : passthroughStyler;\n const baseStyledCells = applyBaseCellStyle(bodyRows[index], palette, sourceStyler);\n\n return applyRowTypeStyle(row.rowType, baseStyledCells, palette);\n });\n}\n","import type { ModelUsageBreakdown, UsageReportRow } from '../domain/usage-report-row.js';\n\nexport type UsageTableLayout = 'compact' | 'per_model_columns';\n\nexport const usageTableHeaders = [\n 'Period',\n 'Source',\n 'Models',\n 'Input',\n 'Output',\n 'Reasoning',\n 'Cache Read',\n 'Cache Write',\n 'Total',\n 'Cost',\n] as const;\n\nconst integerFormatter = new Intl.NumberFormat('en-US');\nconst usdFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n});\n\nfunction formatSource(row: UsageReportRow): string {\n if (row.rowType === 'grand_total') {\n return 'TOTAL';\n }\n\n return row.source;\n}\n\nfunction formatTokenCount(value: number | undefined): string {\n return integerFormatter.format(value ?? 0);\n}\n\nfunction formatUsd(value: number | undefined, options: { incomplete?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formattedUsd = usdFormatter.format(value);\n return options.incomplete ? `~${formattedUsd}` : formattedUsd;\n}\n\nfunction buildModelLines(row: UsageReportRow): string[] {\n if (row.modelBreakdown.length > 0) {\n return row.modelBreakdown.map((modelUsage) => `• ${modelUsage.model}`);\n }\n\n return row.models.map((model) => `• ${model}`);\n}\n\nfunction formatModels(row: UsageReportRow, layout: UsageTableLayout): string {\n const modelLines = buildModelLines(row);\n\n if (modelLines.length === 0) {\n return '-';\n }\n\n if (layout === 'per_model_columns' && row.modelBreakdown.length > 1) {\n return [...modelLines, 'Σ TOTAL'].join('\\n');\n }\n\n return modelLines.join('\\n');\n}\n\nfunction formatModelMetric(\n row: UsageReportRow,\n selector: (value: ModelUsageBreakdown | UsageReportRow) => number | undefined,\n formatter: (value: number | undefined) => string,\n layout: UsageTableLayout,\n): string {\n if (layout !== 'per_model_columns' || row.modelBreakdown.length === 0) {\n return formatter(selector(row));\n }\n\n const lines = row.modelBreakdown.map((modelUsage) => formatter(selector(modelUsage)));\n\n if (row.modelBreakdown.length > 1) {\n lines.push(formatter(selector(row)));\n }\n\n return lines.join('\\n');\n}\n\nfunction formatModelCostMetric(row: UsageReportRow, layout: UsageTableLayout): string {\n if (layout !== 'per_model_columns' || row.modelBreakdown.length === 0) {\n return formatUsd(row.costUsd, { incomplete: row.costIncomplete });\n }\n\n const lines = row.modelBreakdown.map((modelUsage) =>\n formatUsd(modelUsage.costUsd, { incomplete: modelUsage.costIncomplete }),\n );\n\n if (row.modelBreakdown.length > 1) {\n lines.push(formatUsd(row.costUsd, { incomplete: row.costIncomplete }));\n }\n\n return lines.join('\\n');\n}\n\nexport function toUsageTableCells(\n rows: UsageReportRow[],\n options: { layout?: UsageTableLayout } = {},\n): string[][] {\n const layout = options.layout ?? 'compact';\n\n return rows.map((row) => [\n row.periodKey,\n formatSource(row),\n formatModels(row, layout),\n formatModelMetric(row, (value) => value.inputTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.outputTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.reasoningTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.cacheReadTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.cacheWriteTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.totalTokens, formatTokenCount, layout),\n formatModelCostMetric(row, layout),\n ]);\n}\n","import type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { splitCellLines, visibleWidth } from './table-text-layout.js';\nimport type { UsageTableLayout } from './row-cells.js';\n\ntype TableAlignment = 'left' | 'right';\ntype TableVerticalAlignment = 'top' | 'middle';\n\ntype RenderUnicodeTableOptions = {\n headerCells: readonly string[];\n bodyRows: string[][];\n measureHeaderCells: readonly string[];\n measureBodyRows: string[][];\n usageRows: UsageReportRow[];\n tableLayout: UsageTableLayout;\n modelsColumnIndex: number;\n modelsColumnWidth: number;\n};\n\ntype BorderChars = {\n left: string;\n join: string;\n right: string;\n};\n\ntype RowType = UsageReportRow['rowType'];\n\ntype RenderableUsageRow = {\n usageRow: UsageReportRow;\n bodyRow: string[];\n measureBodyRow: string[];\n originalIndex: number;\n};\n\nfunction getColumnAlignment(columnIndex: number, modelsColumnIndex: number): TableAlignment {\n if (columnIndex <= modelsColumnIndex) {\n return 'left';\n }\n\n return 'right';\n}\n\nfunction getVerticalAlignment(\n columnIndex: number,\n tableLayout: UsageTableLayout,\n modelsColumnIndex: number,\n): TableVerticalAlignment {\n if (columnIndex === modelsColumnIndex) {\n return 'top';\n }\n\n return tableLayout === 'per_model_columns' ? 'top' : 'middle';\n}\n\nfunction alignCellLine(value: string, width: number, alignment: TableAlignment): string {\n const padding = Math.max(0, width - visibleWidth(value));\n\n if (alignment === 'right') {\n return `${' '.repeat(padding)}${value}`;\n }\n\n return `${value}${' '.repeat(padding)}`;\n}\n\nfunction padCellLines(\n lines: string[],\n rowHeight: number,\n verticalAlignment: TableVerticalAlignment,\n): string[] {\n const missingLineCount = rowHeight - lines.length;\n\n if (missingLineCount <= 0) {\n return lines;\n }\n\n if (verticalAlignment === 'top') {\n return [...lines, ...Array.from({ length: missingLineCount }, () => '')];\n }\n\n const topPadding = Math.floor(missingLineCount / 2);\n const bottomPadding = missingLineCount - topPadding;\n\n return [\n ...Array.from({ length: topPadding }, () => ''),\n ...lines,\n ...Array.from({ length: bottomPadding }, () => ''),\n ];\n}\n\nfunction toRenderableRowLines(\n row: readonly string[],\n options: {\n widths: number[];\n tableLayout: UsageTableLayout;\n modelsColumnIndex: number;\n },\n): string[] {\n const cellLines = row.map((cell) => splitCellLines(cell));\n const rowHeight = cellLines.reduce((max, lines) => Math.max(max, lines.length), 1);\n\n const paddedAlignedColumns = cellLines.map((lines, columnIndex) => {\n const verticalAlignment = getVerticalAlignment(\n columnIndex,\n options.tableLayout,\n options.modelsColumnIndex,\n );\n const alignedLines = padCellLines(lines, rowHeight, verticalAlignment);\n const horizontalAlignment = getColumnAlignment(columnIndex, options.modelsColumnIndex);\n\n return alignedLines.map((line) =>\n alignCellLine(line, options.widths[columnIndex], horizontalAlignment),\n );\n });\n\n return Array.from({ length: rowHeight }, (_, lineIndex) => {\n const lineCells = paddedAlignedColumns.map((columnLines) => columnLines[lineIndex]);\n return `│ ${lineCells.join(' │ ')} │`;\n });\n}\n\nfunction buildBorderLine(widths: number[], chars: BorderChars): string {\n const segments = widths.map((width) => '─'.repeat(width + 2));\n return `${chars.left}${segments.join(chars.join)}${chars.right}`;\n}\n\nfunction shouldDrawBodySeparator(index: number, usageRows: UsageReportRow[]): boolean {\n if (index < 0 || index >= usageRows.length - 1) {\n return false;\n }\n\n const previousRow = usageRows[index];\n const nextRow = usageRows[index + 1];\n\n return (\n previousRow.rowType === 'period_combined' ||\n nextRow.rowType === 'grand_total' ||\n previousRow.periodKey !== nextRow.periodKey\n );\n}\n\nfunction getRowTypeWeight(rowType: RowType): number {\n switch (rowType) {\n case 'period_source':\n return 0;\n case 'period_combined':\n return 1;\n case 'grand_total':\n return 2;\n }\n}\n\nfunction getPeriodSortTuple(periodKey: string): [number, string] {\n if (periodKey === 'ALL') {\n return [1, periodKey];\n }\n\n return [0, periodKey];\n}\n\nfunction compareUsageRows(left: UsageReportRow, right: UsageReportRow): number {\n const [leftPeriodGroup, leftPeriodKey] = getPeriodSortTuple(left.periodKey);\n const [rightPeriodGroup, rightPeriodKey] = getPeriodSortTuple(right.periodKey);\n\n if (leftPeriodGroup !== rightPeriodGroup) {\n return leftPeriodGroup - rightPeriodGroup;\n }\n\n if (leftPeriodKey !== rightPeriodKey) {\n return leftPeriodKey < rightPeriodKey ? -1 : 1;\n }\n\n return getRowTypeWeight(left.rowType) - getRowTypeWeight(right.rowType);\n}\n\nfunction padRowToColumnCount(row: string[] | undefined, columnCount: number): string[] {\n const normalizedRow = row ?? [];\n\n if (normalizedRow.length >= columnCount) {\n return normalizedRow;\n }\n\n return [\n ...normalizedRow,\n ...Array.from({ length: columnCount - normalizedRow.length }, () => ''),\n ];\n}\n\nfunction getMaxRowColumnCount(\n rows: readonly (readonly string[])[],\n minimumColumnCount: number,\n): number {\n return rows.reduce(\n (maxColumnCount, row) => Math.max(maxColumnCount, row.length),\n minimumColumnCount,\n );\n}\n\nfunction normalizeRenderableUsageRows(options: {\n usageRows: UsageReportRow[];\n bodyRows: string[][];\n measureBodyRows: string[][];\n columnCount: number;\n}): RenderableUsageRow[] {\n const hasAlignedRowCounts =\n options.usageRows.length === options.bodyRows.length &&\n options.usageRows.length === options.measureBodyRows.length;\n\n if (!hasAlignedRowCounts) {\n return options.usageRows.map((usageRow, index) => ({\n usageRow,\n bodyRow: padRowToColumnCount(options.bodyRows[index], options.columnCount),\n measureBodyRow: padRowToColumnCount(options.measureBodyRows[index], options.columnCount),\n originalIndex: index,\n }));\n }\n\n return options.usageRows\n .map((usageRow, index) => ({\n usageRow,\n bodyRow: padRowToColumnCount(options.bodyRows[index], options.columnCount),\n measureBodyRow: padRowToColumnCount(options.measureBodyRows[index], options.columnCount),\n originalIndex: index,\n }))\n .sort((left, right) => {\n const comparison = compareUsageRows(left.usageRow, right.usageRow);\n\n if (comparison !== 0) {\n return comparison;\n }\n\n return left.originalIndex - right.originalIndex;\n });\n}\n\nfunction computeColumnWidths(\n measureRows: readonly (readonly string[])[],\n options: { modelsColumnIndex: number; modelsColumnWidth: number },\n): number[] {\n const columnCount = measureRows.reduce(\n (maxColumnCount, row) => Math.max(maxColumnCount, row.length),\n 0,\n );\n const widths = Array.from({ length: columnCount }, () => 0);\n\n for (const row of measureRows) {\n for (let columnIndex = 0; columnIndex < columnCount; columnIndex += 1) {\n for (const line of splitCellLines(row[columnIndex] ?? '')) {\n widths[columnIndex] = Math.max(widths[columnIndex], visibleWidth(line));\n }\n }\n }\n\n widths[options.modelsColumnIndex] = options.modelsColumnWidth;\n\n return widths;\n}\n\nexport function renderUnicodeTable(options: RenderUnicodeTableOptions): string {\n const bodyColumnCount = getMaxRowColumnCount(options.bodyRows, options.headerCells.length);\n const measureColumnCount = getMaxRowColumnCount(\n options.measureBodyRows,\n options.measureHeaderCells.length,\n );\n const sharedColumnCount = Math.max(bodyColumnCount, measureColumnCount);\n const normalizedHeaderCells = padRowToColumnCount([...options.headerCells], sharedColumnCount);\n const normalizedMeasureHeaderCells = padRowToColumnCount(\n [...options.measureHeaderCells],\n sharedColumnCount,\n );\n const normalizedRenderableRows = normalizeRenderableUsageRows({\n usageRows: options.usageRows,\n bodyRows: options.bodyRows,\n measureBodyRows: options.measureBodyRows,\n columnCount: sharedColumnCount,\n });\n const normalizedBodyRows = normalizedRenderableRows.map((row) => row.bodyRow);\n const normalizedMeasureBodyRows = normalizedRenderableRows.map((row) => row.measureBodyRow);\n const normalizedUsageRows = normalizedRenderableRows.map((row) => row.usageRow);\n const measureRows = [normalizedMeasureHeaderCells, ...normalizedMeasureBodyRows];\n const widths = computeColumnWidths(measureRows, {\n modelsColumnIndex: options.modelsColumnIndex,\n modelsColumnWidth: options.modelsColumnWidth,\n });\n const renderedLines: string[] = [];\n\n renderedLines.push(\n buildBorderLine(widths, {\n left: '╭',\n join: '┬',\n right: '╮',\n }),\n );\n renderedLines.push(\n ...toRenderableRowLines(normalizedHeaderCells, {\n widths,\n tableLayout: 'per_model_columns',\n modelsColumnIndex: options.modelsColumnIndex,\n }),\n );\n renderedLines.push(\n buildBorderLine(widths, {\n left: '├',\n join: '┼',\n right: '┤',\n }),\n );\n\n normalizedBodyRows.forEach((row, rowIndex) => {\n renderedLines.push(\n ...toRenderableRowLines(row, {\n widths,\n tableLayout: options.tableLayout,\n modelsColumnIndex: options.modelsColumnIndex,\n }),\n );\n\n if (\n rowIndex < normalizedBodyRows.length - 1 &&\n shouldDrawBodySeparator(rowIndex, normalizedUsageRows)\n ) {\n renderedLines.push(\n buildBorderLine(widths, {\n left: '├',\n join: '┼',\n right: '┤',\n }),\n );\n }\n });\n\n renderedLines.push(\n buildBorderLine(widths, {\n left: '╰',\n join: '┴',\n right: '╯',\n }),\n );\n\n return `${renderedLines.join('\\n')}\\n`;\n}\n","import { buildEfficiencyData } from './build-efficiency-data.js';\nimport { emitDiagnostics } from './emit-diagnostics.js';\nimport { emitEnvVarOverrides } from './emit-env-var-overrides.js';\nimport { warnIfTerminalTableOverflows } from './terminal-overflow-warning.js';\nimport type { EfficiencyCommandOptions, EfficiencyDiagnostics } from './usage-data-contracts.js';\nimport {\n renderEfficiencyReport,\n type EfficiencyReportFormat,\n} from '../render/render-efficiency-report.js';\nimport { logger } from '../utils/logger.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\n\ntype PreparedEfficiencyReport = {\n format: EfficiencyReportFormat;\n output: string;\n diagnostics: EfficiencyDiagnostics;\n};\n\nfunction validateOutputFormatOptions(options: EfficiencyCommandOptions): void {\n if (options.markdown && options.json) {\n throw new Error('Choose either --markdown or --json, not both');\n }\n}\n\nfunction resolveReportFormat(options: EfficiencyCommandOptions): EfficiencyReportFormat {\n if (options.json) {\n return 'json';\n }\n\n if (options.markdown) {\n return 'markdown';\n }\n\n return 'terminal';\n}\n\nasync function prepareEfficiencyReport(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n): Promise<PreparedEfficiencyReport> {\n validateOutputFormatOptions(options);\n\n const efficiencyData = await buildEfficiencyData(granularity, options);\n const format = resolveReportFormat(options);\n\n return {\n format,\n diagnostics: efficiencyData.diagnostics,\n output: renderEfficiencyReport(efficiencyData, format, {\n granularity,\n }),\n };\n}\n\nexport async function buildEfficiencyReport(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n): Promise<string> {\n const preparedReport = await prepareEfficiencyReport(granularity, options);\n return preparedReport.output;\n}\n\nexport async function runEfficiencyReport(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n): Promise<void> {\n const preparedReport = await prepareEfficiencyReport(granularity, options);\n\n emitDiagnostics(preparedReport.diagnostics.usage, logger);\n emitEnvVarOverrides(preparedReport.diagnostics.usage.activeEnvOverrides, logger);\n\n const mergeModeLabel = preparedReport.diagnostics.includeMergeCommits\n ? 'including merge commits'\n : 'excluding merge commits';\n logger.info(\n `Git outcomes (${mergeModeLabel}): ${preparedReport.diagnostics.gitCommitCount} commit(s), +${preparedReport.diagnostics.gitLinesAdded}/-${preparedReport.diagnostics.gitLinesDeleted} lines (${preparedReport.diagnostics.repoDir})`,\n );\n logger.info(\n `Repo-attributed usage events: ${preparedReport.diagnostics.repoMatchedUsageEvents} matched, ${preparedReport.diagnostics.repoExcludedUsageEvents} excluded, ${preparedReport.diagnostics.repoUnattributedUsageEvents} unattributed`,\n );\n\n if (preparedReport.diagnostics.scopeNote) {\n logger.warn(preparedReport.diagnostics.scopeNote);\n }\n\n if (preparedReport.format === 'terminal') {\n warnIfTerminalTableOverflows(preparedReport.output, (message) => {\n logger.warn(message);\n });\n }\n\n console.log(preparedReport.output);\n}\n","import { markdownTable } from 'markdown-table';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { toUsageTableCells, type UsageTableLayout, usageTableHeaders } from './row-cells.js';\n\nconst alignment: ('l' | 'r')[] = ['l', 'l', 'l', 'r', 'r', 'r', 'r', 'r', 'r', 'r'];\n\ntype MarkdownRenderOptions = {\n tableLayout?: UsageTableLayout;\n};\n\nfunction toMarkdownSafeCell(value: string): string {\n return value.replace(/\\r?\\n/gu, '<br>');\n}\n\nexport function renderMarkdownTable(\n rows: UsageReportRow[],\n options: MarkdownRenderOptions = {},\n): string {\n const tableLayout = options.tableLayout ?? 'compact';\n const bodyRows = toUsageTableCells(rows, { layout: tableLayout }).map((row) =>\n row.map((cell) => toMarkdownSafeCell(cell)),\n );\n const tableRows = [Array.from(usageTableHeaders), ...bodyRows];\n\n return markdownTable(tableRows, {\n align: alignment,\n });\n}\n","import type { UsageDataResult } from '../cli/usage-data-contracts.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { renderMarkdownTable } from './markdown-table.js';\nimport { renderReportHeader } from './report-header.js';\nimport type { UsageTableLayout } from './row-cells.js';\nimport { renderTerminalTable, shouldUseColorByDefault } from './terminal-table.js';\n\nexport type UsageReportFormat = 'terminal' | 'markdown' | 'json';\n\nexport type RenderUsageReportOptions = {\n granularity: ReportGranularity;\n useColor?: boolean;\n tableLayout?: UsageTableLayout;\n};\n\nfunction getReportTitle(granularity: ReportGranularity): string {\n switch (granularity) {\n case 'daily':\n return 'Daily Token Usage Report';\n case 'weekly':\n return 'Weekly Token Usage Report';\n case 'monthly':\n return 'Monthly Token Usage Report';\n }\n}\n\nfunction renderTerminalUsageReport(\n usageData: UsageDataResult,\n options: RenderUsageReportOptions,\n): string {\n const outputLines: string[] = [];\n const useColor = options.useColor ?? shouldUseColorByDefault();\n const tableLayout = options.tableLayout ?? 'compact';\n\n outputLines.push(\n renderReportHeader({\n title: getReportTitle(options.granularity),\n useColor,\n }),\n );\n\n outputLines.push('');\n outputLines.push(renderTerminalTable(usageData.rows, { useColor, tableLayout }));\n\n return outputLines.join('\\n');\n}\n\nexport function renderUsageReport(\n usageData: UsageDataResult,\n format: UsageReportFormat,\n options: RenderUsageReportOptions,\n): string {\n const tableLayout = options.tableLayout ?? 'compact';\n\n switch (format) {\n case 'json':\n return JSON.stringify(usageData.rows, null, 2);\n case 'markdown':\n return renderMarkdownTable(usageData.rows, { tableLayout });\n case 'terminal':\n return renderTerminalUsageReport(usageData, options);\n }\n}\n","import { buildUsageData } from './build-usage-data.js';\nimport { emitDiagnostics } from './emit-diagnostics.js';\nimport { emitEnvVarOverrides } from './emit-env-var-overrides.js';\nimport type { ReportCommandOptions, UsageDiagnostics } from './usage-data-contracts.js';\nimport { warnIfTerminalTableOverflows } from './terminal-overflow-warning.js';\nimport { renderUsageReport, type UsageReportFormat } from '../render/render-usage-report.js';\nimport type { UsageTableLayout } from '../render/row-cells.js';\nimport { logger } from '../utils/logger.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\n\ntype PreparedUsageReport = {\n format: UsageReportFormat;\n output: string;\n diagnostics: UsageDiagnostics;\n};\n\nfunction validateOutputFormatOptions(options: ReportCommandOptions): void {\n if (options.markdown && options.json) {\n throw new Error('Choose either --markdown or --json, not both');\n }\n}\n\nfunction resolveReportFormat(options: ReportCommandOptions): UsageReportFormat {\n if (options.json) {\n return 'json';\n }\n\n if (options.markdown) {\n return 'markdown';\n }\n\n return 'terminal';\n}\n\nfunction resolveTableLayout(options: ReportCommandOptions): UsageTableLayout {\n return options.perModelColumns ? 'per_model_columns' : 'compact';\n}\n\nasync function prepareUsageReport(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n): Promise<PreparedUsageReport> {\n validateOutputFormatOptions(options);\n\n const usageData = await buildUsageData(granularity, options);\n const format = resolveReportFormat(options);\n\n return {\n format,\n diagnostics: usageData.diagnostics,\n output: renderUsageReport(usageData, format, {\n granularity,\n tableLayout: resolveTableLayout(options),\n }),\n };\n}\n\nexport async function buildUsageReport(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n): Promise<string> {\n const preparedReport = await prepareUsageReport(granularity, options);\n return preparedReport.output;\n}\n\nexport async function runUsageReport(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n): Promise<void> {\n const preparedReport = await prepareUsageReport(granularity, options);\n emitDiagnostics(preparedReport.diagnostics, logger);\n emitEnvVarOverrides(preparedReport.diagnostics.activeEnvOverrides, logger);\n\n if (preparedReport.format === 'terminal') {\n warnIfTerminalTableOverflows(preparedReport.output, (message) => {\n logger.warn(message);\n });\n }\n\n console.log(preparedReport.output);\n}\n","import { createRequire } from 'node:module';\n\nimport { asRecord } from '../utils/as-record.js';\n\nexport type PackageMetadata = {\n packageName: string;\n packageVersion: string;\n};\n\nconst DEFAULT_PACKAGE_NAME = 'llm-usage-metrics';\nconst DEFAULT_PACKAGE_VERSION = '0.0.0';\n\nconst defaultPackageJsonCandidates = ['../package.json', '../../package.json'] as const;\n\ntype JsonLoader = (path: string) => unknown;\n\nfunction normalizeMetadata(candidate: unknown): PackageMetadata | undefined {\n const packageJson = asRecord(candidate);\n\n if (!packageJson) {\n return undefined;\n }\n\n const packageName = typeof packageJson.name === 'string' ? packageJson.name.trim() : undefined;\n const packageVersion =\n typeof packageJson.version === 'string' ? packageJson.version.trim() : undefined;\n\n if (!packageName || !packageVersion) {\n return undefined;\n }\n\n return {\n packageName,\n packageVersion,\n };\n}\n\nexport function resolvePackageMetadata(\n loadJson: JsonLoader,\n packageJsonCandidates: readonly string[] = defaultPackageJsonCandidates,\n): PackageMetadata {\n for (const candidatePath of packageJsonCandidates) {\n try {\n const metadata = normalizeMetadata(loadJson(candidatePath));\n\n if (metadata) {\n return metadata;\n }\n } catch {\n continue;\n }\n }\n\n return {\n packageName: DEFAULT_PACKAGE_NAME,\n packageVersion: DEFAULT_PACKAGE_VERSION,\n };\n}\n\nexport function loadPackageMetadataFromRuntime(): PackageMetadata {\n const require = createRequire(import.meta.url);\n return resolvePackageMetadata((candidatePath) => require(candidatePath));\n}\n","#!/usr/bin/env node\n\nimport { getUpdateNotifierRuntimeConfig } from '../config/runtime-overrides.js';\nimport { checkForUpdatesAndMaybeRestart } from '../update/update-notifier.js';\nimport { createCli } from './create-cli.js';\nimport { loadPackageMetadataFromRuntime } from './package-metadata.js';\n\nconst { packageName, packageVersion } = loadPackageMetadataFromRuntime();\nconst updateRuntimeConfig = getUpdateNotifierRuntimeConfig();\n\nconst cli = createCli({ version: packageVersion });\n\ntry {\n const updateResult = await checkForUpdatesAndMaybeRestart({\n packageName,\n currentVersion: packageVersion,\n cacheTtlMs: updateRuntimeConfig.cacheTtlMs,\n fetchTimeoutMs: updateRuntimeConfig.fetchTimeoutMs,\n });\n\n if (!updateResult.continueExecution) {\n process.exitCode = updateResult.exitCode ?? 0;\n } else {\n await cli.parseAsync(process.argv);\n }\n} catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exitCode = 1;\n}\n"],"mappings":";;;AAAA,IAAM,YAAY;AAClB,IAAM,UAAU,KAAK;AACrB,IAAM,SAAS,KAAK,KAAK,KAAK;AAE9B,IAAM,8BAA8B;AACpC,IAAM,kCAAkC;AACxC,IAAM,+BAA+B;AACrC,IAAM,mCAAmC;AACzC,IAAM,6BAA6B;AACnC,IAAM,8BAA8B;AACpC,IAAM,6BAA6B,IAAI;AACvC,IAAM,kCAAkC;AACxC,IAAM,gCAAgC,KAAK,OAAO;AAElD,SAAS,yBACP,UACA,UAKQ;AACR,MAAI,aAAa,QAAW;AAC1B,WAAO,SAAS;AAAA,EAClB;AAEA,QAAM,eAAe,SAAS,KAAK;AAEnC,MAAI,aAAa,WAAW,GAAG;AAC7B,WAAO,SAAS;AAAA,EAClB;AAEA,MAAI,CAAC,cAAc,KAAK,YAAY,GAAG;AACrC,WAAO,SAAS;AAAA,EAClB;AAEA,QAAM,cAAc,OAAO,SAAS,cAAc,EAAE;AAEpD,MAAI,cAAc,SAAS,KAAK;AAC9B,WAAO,SAAS;AAAA,EAClB;AAEA,MAAI,cAAc,SAAS,KAAK;AAC9B,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,UAA8B,UAA4B;AACnF,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,SAAS,KAAK,EAAE,YAAY;AAEpD,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,KAAK,QAAQ,OAAO,IAAI,EAAE,SAAS,eAAe,GAAG;AACxD,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,KAAK,SAAS,MAAM,KAAK,EAAE,SAAS,eAAe,GAAG;AACzD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAoBO,SAAS,+BACd,MAAyB,QAAQ,KACJ;AAC7B,SAAO;AAAA,IACL,YAAY,yBAAyB,IAAI,+BAA+B;AAAA,MACtE,UAAU;AAAA,MACV,KAAK;AAAA,MACL,KAAK,KAAK;AAAA,IACZ,CAAC;AAAA,IACD,gBAAgB,yBAAyB,IAAI,mCAAmC;AAAA,MAC9E,UAAU;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AACF;AAEO,SAAS,+BACd,MAAyB,QAAQ,KACJ;AAC7B,SAAO;AAAA,IACL,YAAY,yBAAyB,IAAI,gCAAgC;AAAA,MACvE,UAAU;AAAA,MACV,KAAK;AAAA,MACL,KAAK,KAAK;AAAA,IACZ,CAAC;AAAA,IACD,gBAAgB,yBAAyB,IAAI,oCAAoC;AAAA,MAC/E,UAAU;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AACF;AAEO,SAAS,wBACd,MAAyB,QAAQ,KACX;AACtB,SAAO;AAAA,IACL,wBAAwB,yBAAyB,IAAI,8BAA8B;AAAA,MACjF,UAAU;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,IACP,CAAC;AAAA,IACD,mBAAmB;AAAA,MACjB,IAAI;AAAA,MACJ;AAAA,IACF;AAAA,IACA,iBAAiB,yBAAyB,IAAI,8BAA8B;AAAA,MAC1E,UAAU;AAAA,MACV,KAAK;AAAA,MACL,KAAK,KAAK;AAAA,IACZ,CAAC;AAAA,IACD,sBAAsB,yBAAyB,IAAI,mCAAmC;AAAA,MACpF,UAAU;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,IACP,CAAC;AAAA,IACD,oBAAoB,yBAAyB,IAAI,iCAAiC;AAAA,MAChF,UAAU;AAAA,MACV,KAAK,OAAO;AAAA,MACZ,KAAK,MAAM,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AACF;;;ACxJA,SAAS,OAAO,UAAU,iBAAiB;AAC3C,OAAOA,WAAU;;;ACDjB,SAAS,SAAS,OAAkD;AAClE,SAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEO,SAAS,SAAS,OAAqD;AAC5E,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACVA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEV,SAAS,oBACd,MAAyB,QAAQ,KACjC,WAA4B,QAAQ,UACpC,UAAkB,GAAG,QAAQ,GACrB;AACR,QAAM,cAAc,IAAI;AAExB,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,SAAS;AACxB,UAAM,eAAe,IAAI;AAEzB,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO,KAAK,KAAK,SAAS,QAAQ;AACpC;;;ACvBO,SAAS,mBAAmB,MAAc,OAAuB;AACtE,MAAI,SAAS,OAAO;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,KAAK,OAAO,QAAQ,EAAE;AAC3C,QAAM,gBAAgB,MAAM,OAAO,QAAQ,EAAE;AAE7C,aAAS;AACP,UAAM,WAAW,aAAa,KAAK;AACnC,UAAM,YAAY,cAAc,KAAK;AAErC,QAAI,SAAS,QAAQ,UAAU,MAAM;AACnC,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,MAAM;AACjB,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,MAAM;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,SAAS,MAAM,YAAY,CAAC,KAAK;AACvD,UAAM,iBAAiB,UAAU,MAAM,YAAY,CAAC,KAAK;AAEzD,QAAI,kBAAkB,gBAAgB;AACpC,aAAO,gBAAgB,iBAAiB,KAAK;AAAA,IAC/C;AAAA,EACF;AACF;;;ACtBO,SAAS,aAAa,OAA0C;AACrE,QAAM,QAAQ,sEAAsE;AAAA,IAClF,MAAM,KAAK;AAAA,EACb;AAEA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC7B,QAAM,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC7B,QAAM,QAAQ,OAAO,MAAM,CAAC,CAAC;AAE7B,MAAI,CAAC,CAAC,OAAO,OAAO,KAAK,EAAE,MAAM,CAAC,SAAS,OAAO,cAAc,IAAI,CAAC,GAAG;AACtE,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;AAErD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,OAAwB;AACnD,SAAO,SAAS,KAAK,KAAK;AAC5B;AAEA,SAAS,6BAA6B,MAAc,OAAuB;AACzE,QAAM,gBAAgB,oBAAoB,IAAI;AAC9C,QAAM,iBAAiB,oBAAoB,KAAK;AAEhD,MAAI,iBAAiB,gBAAgB;AACnC,WAAO,OAAO,IAAI,IAAI,OAAO,KAAK;AAAA,EACpC;AAEA,MAAI,iBAAiB,CAAC,gBAAgB;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,iBAAiB,gBAAgB;AACpC,WAAO;AAAA,EACT;AAEA,SAAO,mBAAmB,MAAM,KAAK;AACvC;AAEA,SAAS,aAAa,SAA0B;AAC9C,QAAM,SAAS,aAAa,OAAO;AACnC,SAAO,QAAQ,UAAU,OAAO,WAAW,SAAS,CAAC;AACvD;AAEO,SAAS,gBAAgB,MAAc,OAAuB;AACnE,QAAM,aAAa,aAAa,IAAI;AACpC,QAAM,cAAc,aAAa,KAAK;AAEtC,MAAI,CAAC,cAAc,CAAC,aAAa;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,UAAU,YAAY,OAAO;AAC1C,WAAO,WAAW,QAAQ,YAAY;AAAA,EACxC;AAEA,MAAI,WAAW,UAAU,YAAY,OAAO;AAC1C,WAAO,WAAW,QAAQ,YAAY;AAAA,EACxC;AAEA,MAAI,WAAW,UAAU,YAAY,OAAO;AAC1C,WAAO,WAAW,QAAQ,YAAY;AAAA,EACxC;AAEA,QAAM,iBAAiB,WAAW;AAClC,QAAM,kBAAkB,YAAY;AAEpC,MAAI,eAAe,WAAW,KAAK,gBAAgB,WAAW,GAAG;AAC/D,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,mBAAmB,KAAK,IAAI,eAAe,QAAQ,gBAAgB,MAAM;AAE/E,WAAS,QAAQ,GAAG,QAAQ,kBAAkB,SAAS,GAAG;AACxD,UAAM,aAAa,6BAA6B,eAAe,KAAK,GAAG,gBAAgB,KAAK,CAAC;AAE7F,QAAI,eAAe,GAAG;AACpB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO,eAAe,SAAS,gBAAgB;AACjD;AAEO,SAAS,kBAAkB,gBAAwB,eAAgC;AACxF,MAAI,aAAa,aAAa,KAAK,CAAC,aAAa,cAAc,GAAG;AAChE,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,eAAe,cAAc,IAAI;AAC1D;;;AJ/GA,IAAM,uBAAuB,KAAK,KAAK;AACvC,IAAM,2BAA2B;AACjC,IAAM,4BAA4B;AAClC,IAAM,+BAA+B;AAE9B,IAAM,mCAAmC;AACzC,IAAM,yCAAyC;AAmBtD,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC/B,YAAY,SAAiB;AAClC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,sBAAsB,QAAyB;AACtD,SAAO,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,EAAE,SAAS,MAAM;AAC5D;AAEA,SAAS,wBAAwB,OAAyB;AACxD,MAAI,iBAAiB,qBAAqB;AACxC,WAAO;AAAA,EACT;AAEA,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,gBAAgB;AAChE,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,WAAW;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,wDAAwD,KAAK,MAAM,OAAO;AACnF;AAEA,eAAe,MAAM,SAAgC;AACnD,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,eAAW,SAAS,OAAO;AAAA,EAC7B,CAAC;AACH;AAEO,SAAS,iCAAyC;AACvD,SAAOC,MAAK,KAAK,oBAAoB,GAAG,qBAAqB,mBAAmB;AAClF;AAEA,SAAS,0BAA0B,OAAuB;AACxD,SAAO,MAAM,QAAQ,qBAAqB,GAAG;AAC/C;AAEA,SAAS,kBAAkB,OAA+C;AACxE,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM,KAAK;AAEhC,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,0BAA0B,YAAY;AAC7D,SAAO,kBAAkB;AAC3B;AAEO,SAAS,0BACd,mBACA,KACA,UAAkC,CAAC,GAC3B;AACR,QAAM,aAAa,IAAI,gCAAgC,GAAG,KAAK,EAAE,YAAY;AAE7E,MAAI,eAAe,WAAW;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,QAAQ,aAAa,QAAQ;AAC/C,QAAM,aACJ,kBAAkB,IAAI,sCAAsC,CAAC,KAAK,QAAQ,SAAS;AAErF,QAAM,aAAaA,MAAK,MAAM,iBAAiB;AAC/C,SAAOA,MAAK,KAAK,WAAW,KAAK,GAAG,WAAW,IAAI,IAAI,UAAU,GAAG,WAAW,GAAG,EAAE;AACtF;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,OAAwB;AAC9C,SAAO,aAAa,KAAK,MAAM;AACjC;AAEO,SAAS,aACd,SACA,YACA,KACS;AACT,QAAM,eAAe,IAAI;AAEzB,MAAI,QAAQ,YAAY,cAAc;AACpC,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,QAAQ,aAAa;AAC7C;AAEA,eAAsB,4BACpB,eAC8C;AAC9C,MAAI;AAEJ,MAAI;AACF,cAAU,MAAM,SAAS,eAAe,MAAM;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI;AAEJ,MAAI;AACF,oBAAgB,KAAK,MAAM,OAAO;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,SAAS,aAAa;AAErC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,oBAAoB,OAAO,SAAS;AACtD,QAAM,gBAAgB,OAAO,OAAO,kBAAkB,WAAW,OAAO,cAAc,KAAK,IAAI;AAE/F,MAAI,cAAc,UAAa,CAAC,iBAAiB,CAAC,eAAe,aAAa,GAAG;AAC/E,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,6BACpB,eACA,SACe;AACf,QAAM,MAAMA,MAAK,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5D,QAAM,UAAU,eAAe,KAAK,UAAU,OAAO,GAAG,MAAM;AAChE;AAEA,eAAe,mBACbC,cACA,WACA,gBAC6B;AAC7B,QAAM,WAAW,MAAM;AAAA,IACrB,8BAA8B,mBAAmBA,YAAW,CAAC;AAAA,IAC7D;AAAA,MACE,QAAQ,YAAY,QAAQ,cAAc;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,QAAI,sBAAsB,SAAS,MAAM,GAAG;AAC1C,YAAM,IAAI;AAAA,QACR,gDAAgD,SAAS,MAAM;AAAA,MACjE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,MAAI;AAEJ,MAAI;AACF,cAAW,MAAM,SAAS,KAAK;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,SAAS,OAAO;AAEtC,MAAI,CAAC,eAAe;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,cAAc,YAAY,WAAW,cAAc,QAAQ,KAAK,IAAI;AAE3F,MAAI,CAAC,WAAW,CAAC,eAAe,OAAO,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,4BACbA,cACA,WACA,gBACA,iBACA,mBACA,SAC6B;AAC7B,QAAM,iBACJ,OAAO,SAAS,eAAe,KAAK,mBAAmB,IACnD,KAAK,MAAM,eAAe,IAC1B;AACN,QAAM,mBACJ,OAAO,SAAS,iBAAiB,KAAK,oBAAoB,IACtD,KAAK,MAAM,iBAAiB,IAC5B;AACN,QAAM,cAAc,iBAAiB;AAErC,WAAS,eAAe,GAAG,eAAe,aAAa,gBAAgB,GAAG;AACxE,QAAI;AACF,aAAO,MAAM,mBAAmBA,cAAa,WAAW,cAAc;AAAA,IACxE,SAAS,OAAO;AACd,YAAM,cAAc,wBAAwB,KAAK,KAAK,eAAe,cAAc;AAEnF,UAAI,CAAC,aAAa;AAChB,cAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,eAAe,mBAAmB,KAAK;AAC7C,UAAM,QAAQ,YAAY;AAAA,EAC5B;AAEA,SAAO;AACT;AAEA,eAAsB,qBACpB,SAC6B;AAC7B,QAAM,gBAAgB,QAAQ,iBAAiB,+BAA+B;AAC9E,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,QAAM,oBAAoB,QAAQ,qBAAqB;AACvD,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,UAAU,QAAQ,SAAS;AAEjC,QAAM,eAAe,MAAM,4BAA4B,aAAa;AAEpE,MAAI,gBAAgB,aAAa,cAAc,YAAY,GAAG,GAAG;AAC/D,WAAO,aAAa;AAAA,EACtB;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM;AAAA,MAC1B,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,CAAC,eAAe;AAClB,aAAO,cAAc;AAAA,IACvB;AAEA,QAAI;AACF,YAAM,6BAA6B,eAAe;AAAA,QAChD,WAAW,IAAI;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,cAAc;AAAA,EACvB;AACF;;;AKzTA,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAiCzB,SAAS,qBAAqB,SAIzB;AACV,QAAM,UAAU,QAAQ,IAAI;AAC5B,QAAM,oBAAoB,SAAS,KAAK,EAAE,YAAY;AACtD,QAAM,YACJ,sBAAsB,UACtB,kBAAkB,SAAS,KAC3B,CAAC,CAAC,KAAK,SAAS,MAAM,KAAK,EAAE,SAAS,iBAAiB;AAEzD,SAAO,QAAQ,cAAc,QAAQ,eAAe,CAAC;AACvD;AAEA,eAAsB,sBAAsB,QAAkC;AAC5E,QAAM,WAAW,gBAAgB;AAAA,IAC/B,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED,MAAI;AACF,UAAM,SAAS,MAAM,SAAS,SAAS,MAAM;AAC7C,WAAO,CAAC,KAAK,KAAK,EAAE,SAAS,OAAO,KAAK,EAAE,YAAY,CAAC;AAAA,EAC1D,UAAE;AACA,aAAS,MAAM;AAAA,EACjB;AACF;AAEA,eAAsB,oBACpB,SACA,MACA,UAAgC,CAAC,GAChB;AACjB,SAAO,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AACpD,UAAM,QAAQ,MAAM,SAAS,MAAM;AAAA,MACjC,KAAK,QAAQ;AAAA,MACb,OAAO,QAAQ,SAAS;AAAA,IAC1B,CAAC;AAED,UAAM,KAAK,SAAS,CAAC,UAAU;AAC7B,aAAO,KAAK;AAAA,IACd,CAAC;AAED,UAAM,KAAK,SAAS,CAAC,aAAa;AAChC,cAAQ,YAAY,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH;AAEO,SAAS,cAAc,SAAuB;AACnD,UAAQ,MAAM,OAAO;AACvB;AAEA,eAAsB,gCACpB,SACqC;AACrC,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,kBAAkB,MAAM,eAAe,GAAG,QAAQ,aAAa,sBAAsB;AAE3F,MAAI,CAAC,iBAAiB;AACpB,WAAO,EAAE,mBAAmB,KAAK;AAAA,EACnC;AAEA,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,aAAa,QAAQ,aAAa,UAAU,YAAY;AAC9D,QAAM,kBAAkB,MAAM;AAAA,IAC5B;AAAA,IACA,CAAC,WAAW,MAAM,GAAG,QAAQ,WAAW,SAAS;AAAA,IACjD;AAAA,MACE,KAAK,QAAQ;AAAA,MACb,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,oBAAoB,GAAG;AACzB,WAAO,qBAAqB,QAAQ,WAAW,sBAAsB,eAAe,IAAI;AACxF,WAAO,EAAE,mBAAmB,KAAK;AAAA,EACnC;AAEA,QAAM,cAAc,QAAQ,KAAK,MAAM,CAAC;AACxC,QAAM,aAAgC;AAAA,IACpC,GAAG,QAAQ;AAAA,IACX,CAAC,QAAQ,qBAAqB,GAAG;AAAA,EACnC;AAEA,QAAM,kBAAkB,MAAM,WAAW,QAAQ,YAAY,QAAQ,UAAU,aAAa;AAAA,IAC1F,KAAK;AAAA,IACL,OAAO;AAAA,EACT,CAAC;AAED,SAAO;AAAA,IACL,mBAAmB;AAAA,IACnB,UAAU;AAAA,EACZ;AACF;;;ACpFO,IAAM,4BAA4B;AAyBzC,SAAS,gBAAgB,OAAoC;AAC3D,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,MAAM,KAAK,EAAE,YAAY;AAEjD,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,KAAK,QAAQ,OAAO,IAAI,EAAE,SAAS,eAAe;AAC5D;AAEO,SAAS,6BAA6B,MAAyB;AACpE,QAAM,iBAAiB,KAAK,MAAM,CAAC;AACnC,QAAM,eAAe,oBAAI,IAAI,CAAC,SAAS,UAAU,WAAW,cAAc,QAAQ,SAAS,CAAC;AAE5F,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,KAAK,CAAC,QAAQ,CAAC,MAAM,UAAU,MAAM,WAAW,EAAE,SAAS,GAAG,CAAC,GAAG;AACnF,WAAO;AAAA,EACT;AAEA,QAAM,yBAAyB,eAAe,KAAK,CAAC,QAAQ,aAAa,IAAI,GAAG,CAAC;AAEjF,SAAO,2BAA2B,UAAU,2BAA2B;AACzE;AAEO,SAAS,qBAAqB,MAAgB,KAAiC;AACpF,QAAM,iBAAiB,KAAK,CAAC,KAAK;AAElC,MAAI,kBAAkB,KAAK,cAAc,GAAG;AAC1C,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,IAAI,gBAAgB;AAExC,MAAI,qBAAqB,KAAK,WAAW,KAAK,iBAAiB,KAAK,WAAW,GAAG;AAChF,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,IAAI,eAAe;AAEtC,SAAO,eAAe,UAAU,eAAe;AACjD;AAEO,SAAS,wBAAwB,MAAyB;AAC/D,QAAM,iBAAiB,KAAK,CAAC,KAAK;AAClC,SAAO,iBAAiB,KAAK,cAAc;AAC7C;AAEA,SAAS,8BACP,SACA,KAC6B;AAC7B,QAAM,oBAAoB,QAAQ,iBAAiB,+BAA+B;AAClF,QAAM,sBAAsB,0BAA0B,mBAAmB,GAAG;AAE5E,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,eAAe;AAAA,IACf,YAAY,QAAQ;AAAA,IACpB,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,KAAK,QAAQ;AAAA,EACf;AACF;AAEA,eAAsB,+BACpB,SAC+B;AAC/B,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,QAAM,OAAO,QAAQ,QAAQ,QAAQ;AAErC,MAAI,gBAAgB,IAAI,yBAAyB,CAAC,GAAG;AACnD,WAAO,EAAE,mBAAmB,KAAK;AAAA,EACnC;AAEA,MAAI,6BAA6B,IAAI,GAAG;AACtC,WAAO,EAAE,mBAAmB,KAAK;AAAA,EACnC;AAEA,MAAI,qBAAqB,MAAM,GAAG,GAAG;AACnC,WAAO,EAAE,mBAAmB,KAAK;AAAA,EACnC;AAEA,MAAI,wBAAwB,IAAI,GAAG;AACjC,WAAO,EAAE,mBAAmB,KAAK;AAAA,EACnC;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,qBAAqB,8BAA8B,SAAS,GAAG,CAAC;AAE5F,QAAI,CAAC,iBAAiB,CAAC,kBAAkB,QAAQ,gBAAgB,aAAa,GAAG;AAC/E,aAAO,EAAE,mBAAmB,KAAK;AAAA,IACnC;AAEA,UAAM,gBAAgB,wBAAwB,QAAQ,WAAW,KAAK,QAAQ,cAAc,WAAM,aAAa;AAC/G,UAAM,aAAa,QAAQ,cAAc,QAAQ,MAAM;AACvD,UAAM,cAAc,QAAQ,eAAe,QAAQ,OAAO;AAE1D,QAAI,CAAC,qBAAqB,EAAE,KAAK,YAAY,YAAY,CAAC,GAAG;AAC3D,OAAC,QAAQ,UAAU,QAAQ;AAAA,QACzB,GAAG,aAAa,wBAAwB,QAAQ,WAAW;AAAA,MAC7D;AACA,aAAO,EAAE,mBAAmB,KAAK;AAAA,IACnC;AAEA,WAAO,MAAM,gCAAgC;AAAA,MAC3C,aAAa,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB,uBAAuB;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,YAAY,QAAQ;AAAA,MACpB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH,QAAQ;AACN,WAAO,EAAE,mBAAmB,KAAK;AAAA,EACnC;AACF;;;ACpMA,SAAS,eAAe;;;ACAxB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACGV,SAAS,4BAA4B,OAA2B;AACrE,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAE/D,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC;AACvC;AAEO,SAAS,iBAAiB,OAAuC;AACtE,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAE/D,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,IAAI,GAAG,MAAM;AAC3B;AAEO,SAAS,mBAAmB,OAA8B;AAC/D,QAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AAE3D,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,UAAM,IAAI,MAAM,sBAAsB,OAAO,KAAK,CAAC,EAAE;AAAA,EACvD;AAEA,SAAO,KAAK,YAAY;AAC1B;AAEO,SAAS,mBAAmB,QAAuD;AACxF,QAAM,eAAe,oBAAI,IAAY;AAErC,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,KAAK;AAE9B,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,iBAAa,IAAI,UAAU;AAAA,EAC7B;AAEA,SAAO,CAAC,GAAG,YAAY,EAAE,KAAK,kBAAkB;AAClD;;;ACfO,SAAS,kBAAkB,OAAsC;AACtE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,KAAK;AAC9B,SAAO,cAAc;AACvB;AAEA,SAAS,YAAY,OAAe,WAA2B;AAC7D,QAAM,aAAa,MAAM,KAAK;AAE9B,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,cAAc,SAAS,6BAA6B;AAAA,EACtE;AAEA,SAAO;AACT;AAEA,SAAS,sBAAsB,OAA+C;AAC5E,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,KAAK;AAC9B,SAAO,cAAc;AACvB;AAEA,SAAS,sBAAsB,OAA+C;AAC5E,SAAO,sBAAsB,KAAK;AACpC;AAEA,SAAS,uBAAuB,OAA+C;AAC7E,QAAM,aAAa,sBAAsB,KAAK;AAE9C,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,SAAO,WAAW,YAAY;AAChC;AAEA,SAAS,gBAAgB,UAAgC,SAAuC;AAC9F,MAAI,aAAa,cAAc,YAAY,QAAW;AACpD,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AAEA,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AAEA,SAAO,YAAY,SAAY,cAAc;AAC/C;AAEO,SAAS,iBAAiB,OAAoC;AACnE,QAAM,SAAS,kBAAkB,MAAM,MAAM;AAE7C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAEA,QAAM,cAAc,4BAA4B,MAAM,WAAW;AACjE,QAAM,eAAe,4BAA4B,MAAM,YAAY;AACnE,QAAM,kBAAkB,4BAA4B,MAAM,eAAe;AACzE,QAAM,kBAAkB,4BAA4B,MAAM,eAAe;AACzE,QAAM,mBAAmB,4BAA4B,MAAM,gBAAgB;AAC3E,QAAM,sBAAsB,4BAA4B,MAAM,WAAW;AACzE,QAAM,uBACJ,cAAc,eAAe,kBAAkB,kBAAkB;AACnE,QAAM,cAAc,sBAAsB,IAAI,sBAAsB;AAEpE,QAAM,UAAU,iBAAiB,MAAM,OAAO;AAC9C,QAAM,WAAW,gBAAgB,MAAM,UAAU,OAAO;AAExD,SAAO;AAAA,IACL;AAAA,IACA,WAAW,YAAY,MAAM,WAAW,WAAW;AAAA,IACnD,WAAW,mBAAmB,MAAM,SAAS;AAAA,IAC7C,UAAU,sBAAsB,MAAM,QAAQ;AAAA,IAC9C,UAAU,sBAAsB,MAAM,QAAQ;AAAA,IAC9C,OAAO,uBAAuB,MAAM,KAAK;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC3IA,SAAS,eAAe;AAExB,OAAOC,WAAU;AAgBjB,SAAS,iBAAiB,OAAoC;AAC5D,QAAM,SAAS,SAAS,KAAK;AAC7B,SAAO,OAAO,QAAQ,SAAS,WAAW,OAAO,OAAO;AAC1D;AAEA,SAAS,8BAA8B,OAAyB;AAC9D,QAAM,OAAO,iBAAiB,KAAK;AACnC,SAAO,SAAS,YAAY,SAAS;AACvC;AAEA,SAAS,iBAAiB,UAAkB,WAA4B;AACtE,QAAM,gBAAgB,SAAS,YAAY;AAC3C,QAAM,iBAAiB,UAAU,YAAY;AAC7C,SAAO,cAAc,SAAS,cAAc;AAC9C;AAEA,SAAS,mBAAmB,WAA2B;AACrD,QAAM,aAAa,UAAU,KAAK;AAElC,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,MAAI,CAAC,WAAW,WAAW,GAAG,GAAG;AAC/B,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AAEA,SAAO;AACT;AAEA,eAAe,cACb,SACA,KACA,SACe;AACf,MAAI;AAEJ,MAAI;AACF,cAAU,MAAM,QAAQ,SAAS,EAAE,eAAe,MAAM,UAAU,OAAO,CAAC;AAAA,EAC5E,SAAS,OAAO;AACd,QAAI,iBAAiB,KAAK,MAAM,UAAU;AACxC;AAAA,IACF;AAEA,QAAI,QAAQ,uBAAuB,8BAA8B,KAAK,GAAG;AACvE;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AAEA,MAAI,QAAQ,MAAM;AAChB,YAAQ,KAAK,CAAC,MAAM,UAAU,mBAAmB,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,EACzE;AAEA,aAAW,SAAS,SAAS;AAC3B,UAAM,YAAYC,MAAK,KAAK,SAAS,MAAM,IAAI;AAE/C,QAAI,MAAM,YAAY,KAAK,QAAQ,WAAW;AAC5C,YAAM,cAAc,WAAW,KAAK,OAAO;AAC3C;AAAA,IACF;AAEA,QAAI,MAAM,OAAO,KAAK,iBAAiB,MAAM,MAAM,QAAQ,SAAS,GAAG;AACrE,UAAI,KAAK,SAAS;AAAA,IACpB;AAAA,EACF;AACF;AAOA,eAAsB,cACpB,SACA,SACmB;AACnB,QAAM,QAAkB,CAAC;AACzB,QAAM,kBAAkD;AAAA,IACtD,WAAW,mBAAmB,QAAQ,SAAS;AAAA,IAC/C,WAAW,QAAQ,aAAa;AAAA,IAChC,qBAAqB,QAAQ,uBAAuB;AAAA,IACpD,MAAM,QAAQ,QAAQ;AAAA,EACxB;AAEA,QAAM,cAAc,SAAS,OAAO,eAAe;AAEnD,SAAO;AACT;;;ACpGA,eAAsB,mBAAmB,SAAoC;AAC3E,SAAO,cAAc,SAAS,EAAE,WAAW,SAAS,CAAC;AACvD;;;ACRA,SAAS,QAAQ,WAAW,YAAY;AAExC,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,UAAM,OAAO,UAAU,UAAU,IAAI;AACrC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,aAAa,UAAoC;AACrE,MAAI;AACF,UAAM,OAAO,UAAU,UAAU,IAAI;AACrC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBAAgB,UAAoC;AACxE,MAAI;AACF,YAAQ,MAAM,KAAK,QAAQ,GAAG,YAAY;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,YAAQ,MAAM,KAAK,QAAQ,GAAG,OAAO;AAAA,EACvC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,SAAS,UAA8C;AAC3E,MAAI;AACF,WAAO,MAAM,KAAK,QAAQ;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC3CA,SAAS,wBAAwB;AACjC,SAAS,mBAAAC,wBAAuB;AAIhC,gBAAuB,iBACrB,UACA,UAA+D,CAAC,GACN;AAC1D,QAAM,SAAS,iBAAiB,UAAU;AAAA,IACxC,UAAU;AAAA,EACZ,CAAC;AACD,QAAM,aAAaC,iBAAgB;AAAA,IACjC,OAAO;AAAA,IACP,WAAW;AAAA,EACb,CAAC;AAED,MAAI,cAAc;AAElB,MAAI;AACF,qBAAiB,WAAW,YAAY;AACtC,YAAM,iBAAiB,cAAc,QAAQ,QAAQ,YAAY,EAAE,IAAI;AACvE,oBAAc;AAEd,YAAM,WAAW,eAAe,KAAK;AAErC,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AAEA,UAAI,QAAQ,mBAAmB,CAAC,QAAQ,gBAAgB,QAAQ,GAAG;AACjE;AAAA,MACF;AAEA,UAAI;AAEJ,UAAI;AACF,iBAAS,KAAK,MAAM,QAAQ;AAAA,MAC9B,QAAQ;AACN;AAAA,MACF;AAEA,YAAM,eAAe,SAAS,MAAM;AAEpC,UAAI,CAAC,cAAc;AACjB;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAAA,EACF,UAAE;AACA,eAAW,MAAM;AACjB,WAAO,QAAQ;AAAA,EACjB;AACF;;;ACpDO,SAAS,cAAc,OAAoC;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,KAAK;AAC9B,SAAO,cAAc;AACvB;AAEO,SAAS,YAAY,OAAwB;AAClD,SAAO,MAAM,KAAK,EAAE,WAAW;AACjC;AAEO,SAAS,aAAa,OAA4B;AACvD,MACE,UAAU,QACV,UAAU,UACV,OAAO,UAAU,YACjB,OAAO,UAAU,UACjB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;APbA,IAAM,qBAAqBC,MAAK,KAAKC,IAAG,QAAQ,GAAG,UAAU,UAAU;AAEhE,IAAM,8BAA8B;AAuB3C,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAClC,IAAM,yBAAyB;AAC/B,IAAM,2BAA2B;AAEjC,SAAS,0BAA0B,UAA2B;AAC5D,MAAI,0BAA0B,KAAK,QAAQ,KAAK,0BAA0B,KAAK,QAAQ,GAAG;AACxF,WAAO;AAAA,EACT;AAEA,SAAO,uBAAuB,KAAK,QAAQ,KAAK,yBAAyB,KAAK,QAAQ;AACxF;AAEA,SAAS,QAAQ,OAAwC;AACvD,QAAM,QAAQ,SAAS,KAAK;AAE5B,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,4BAA4B,aAAa,MAAM,YAAY,CAAC;AACnF,QAAM,kBAAkB,4BAA4B,aAAa,MAAM,mBAAmB,CAAC;AAC3F,QAAM,eAAe,4BAA4B,aAAa,MAAM,aAAa,CAAC;AAElF,QAAM,cAAc,KAAK,IAAI,GAAG,iBAAiB,eAAe;AAEhE,SAAO;AAAA;AAAA;AAAA,IAGL;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,4BAA4B,aAAa,MAAM,uBAAuB,CAAC;AAAA;AAAA,IAExF,aAAa,cAAc,eAAe;AAAA,EAC5C;AACF;AAEA,SAAS,cAAc,SAAqB,UAAkC;AAC5E,SAAO;AAAA,IACL,aAAa,KAAK,IAAI,GAAG,QAAQ,cAAc,SAAS,WAAW;AAAA,IACnE,iBAAiB,KAAK,IAAI,GAAG,QAAQ,kBAAkB,SAAS,eAAe;AAAA,IAC/E,cAAc,KAAK,IAAI,GAAG,QAAQ,eAAe,SAAS,YAAY;AAAA,IACtE,iBAAiB,KAAK,IAAI,GAAG,QAAQ,kBAAkB,SAAS,eAAe;AAAA,IAC/E,aAAa,KAAK,IAAI,GAAG,QAAQ,cAAc,SAAS,WAAW;AAAA,EACrE;AACF;AAEA,SAAS,SAAS,MAAkB,OAA+B;AACjE,SAAO;AAAA,IACL,aAAa,KAAK,cAAc,MAAM;AAAA,IACtC,iBAAiB,KAAK,kBAAkB,MAAM;AAAA,IAC9C,cAAc,KAAK,eAAe,MAAM;AAAA,IACxC,iBAAiB,KAAK,kBAAkB,MAAM;AAAA,IAC9C,aAAa,KAAK,cAAc,MAAM;AAAA,EACxC;AACF;AAEA,SAAS,eAAe,OAA4B;AAClD,SACE,MAAM,cAAc,KACpB,MAAM,kBAAkB,KACxB,MAAM,eAAe,KACrB,MAAM,kBAAkB,KACxB,MAAM,cAAc;AAExB;AAEA,SAAS,iBACP,MACA,oBAC4D;AAC5D,QAAM,aAAa,QAAQ,KAAK,iBAAiB;AACjD,QAAM,YAAY,QAAQ,KAAK,gBAAgB;AAE/C,MAAI,WAAW;AACb,WAAO,EAAE,YAAY,WAAW,kBAAkB,WAAW;AAAA,EAC/D;AAEA,MAAI,CAAC,YAAY;AACf,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,aAAa,qBACf,cAAc,YAAY,kBAAkB,IAC5C;AAEJ,SAAO,EAAE,YAAY,kBAAkB,WAAW;AACpD;AAEA,SAAS,qBAAqB,UAA0B;AACtD,SAAOD,MAAK,SAAS,UAAU,QAAQ;AACzC;AAEA,SAAS,2BACP,SACoB;AACpB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SACE,cAAc,QAAQ,GAAG,KACzB,cAAc,QAAQ,SAAS,KAC/B,cAAc,QAAQ,QAAQ,KAC9B,cAAc,QAAQ,YAAY,KAClC,cAAc,QAAQ,WAAW;AAErC;AAEO,IAAM,qBAAN,MAAkD;AAAA,EACvC,KAAK;AAAA,EAEJ;AAAA,EACA;AAAA,EAEV,YAAY,UAAqC,CAAC,GAAG;AAC1D,SAAK,cAAc,QAAQ,eAAe;AAC1C,SAAK,qBAAqB,QAAQ,sBAAsB;AAAA,EAC1D;AAAA,EAEA,MAAa,gBAAmC;AAC9C,QAAI,YAAY,KAAK,WAAW,GAAG;AACjC,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AAEA,UAAM,wBAAwB,KAAK,YAAY,KAAK;AAEpD,QAAI,KAAK,oBAAoB;AAC3B,YAAM,mBAAmB,MAAM,SAAS,qBAAqB;AAE7D,UAAI,CAAC,kBAAkB;AACrB,cAAM,IAAI;AAAA,UACR,sDAAsD,qBAAqB;AAAA,QAC7E;AAAA,MACF;AAEA,UAAI,CAAC,iBAAiB,YAAY,GAAG;AACnC,cAAM,IAAI,MAAM,gDAAgD,qBAAqB,EAAE;AAAA,MACzF;AAAA,IACF;AAEA,WAAO,mBAAmB,qBAAqB;AAAA,EACjD;AAAA,EAEA,MAAa,UAAU,UAAyC;AAC9D,UAAM,SAAuB,CAAC;AAE9B,UAAM,QAA2B;AAAA,MAC/B,WAAW,qBAAqB,QAAQ;AAAA,MACxC,UAAU;AAAA,IACZ;AAEA,qBAAiB,QAAQ,iBAAiB,UAAU;AAAA,MAClD,iBAAiB;AAAA,IACnB,CAAC,GAAG;AACF,UAAI,KAAK,SAAS,gBAAgB;AAChC,cAAME,WAAU,SAAS,KAAK,OAAO;AACrC,cAAM,YAAY,cAAcA,UAAS,EAAE,KAAK,MAAM;AACtD,cAAM,WAAW,cAAcA,UAAS,cAAc,KAAK,MAAM;AACjE,cAAM,WAAW,2BAA2BA,QAAO,KAAK,MAAM;AAC9D;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,gBAAgB;AAChC,cAAMA,WAAU,SAAS,KAAK,OAAO;AACrC,cAAM,QAAQ,cAAcA,UAAS,KAAK,KAAK,MAAM;AACrD,cAAM,WAAW,2BAA2BA,QAAO,KAAK,MAAM;AAC9D;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,aAAa;AAC7B;AAAA,MACF;AAEA,YAAM,UAAU,SAAS,KAAK,OAAO;AAErC,UAAI,SAAS,SAAS,eAAe;AACnC;AAAA,MACF;AAEA,YAAM,OAAO,SAAS,QAAQ,IAAI;AAElC,UAAI,CAAC,MAAM;AACT;AAAA,MACF;AAEA,YAAM,EAAE,YAAY,iBAAiB,IAAI,iBAAiB,MAAM,MAAM,kBAAkB;AAExF,UAAI,CAAC,cAAc,CAAC,eAAe,UAAU,GAAG;AAC9C,cAAM,qBAAqB,oBAAoB,MAAM;AACrD;AAAA,MACF;AAEA,YAAM,YAAY,cAAc,KAAK,SAAS;AAE9C,UAAI,CAAC,WAAW;AACd,cAAM,qBAAqB,oBAAoB,MAAM;AACrD;AAAA,MACF;AAEA,YAAM,QAAQ,MAAM,SAAS;AAE7B,UAAI;AACF,eAAO;AAAA,UACL,iBAAiB;AAAA,YACf,QAAQ,KAAK;AAAA,YACb,WAAW,MAAM;AAAA,YACjB;AAAA,YACA,UAAU,MAAM;AAAA,YAChB,UAAU,MAAM;AAAA,YAChB;AAAA,YACA,aAAa,WAAW;AAAA,YACxB,cAAc,WAAW;AAAA,YACzB,iBAAiB,WAAW;AAAA,YAC5B,iBAAiB,WAAW;AAAA,YAC5B,kBAAkB;AAAA,YAClB,aAAa,WAAW;AAAA,YACxB,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,UAAI,kBAAkB;AACpB,cAAM,qBAAqB;AAAA,MAC7B,WAAW,MAAM,oBAAoB;AACnC,cAAM,qBAAqB,SAAS,MAAM,oBAAoB,UAAU;AAAA,MAC1E,OAAO;AACL,cAAM,qBAAqB;AAAA,MAC7B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AQlRA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACEV,SAAS,uBAAuB,SAA8B,QAAsB;AACzF,QAAM,UAAU,QAAQ,IAAI,MAAM,KAAK;AACvC,UAAQ,IAAI,QAAQ,UAAU,CAAC;AACjC;AAEO,SAAS,wBACd,SAC8B;AAC9B,SAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC,EACzB,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,QAAQ,MAAM,EAAE,EAC5C,KAAK,CAAC,MAAM,UAAU,mBAAmB,KAAK,QAAQ,MAAM,MAAM,CAAC;AACxE;AAEO,SAAS,mBACd,QACA,aACA,mBACmC;AACnC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,mBAAmB,wBAAwB,iBAAiB;AAAA,EAC9D;AACF;;;ADZA,IAAMC,sBAAqBC,MAAK,KAAKC,IAAG,QAAQ,GAAG,YAAY,UAAU;AAOzE,IAAM,mCAAmC;AACzC,IAAM,6BAA6B;AAEnC,SAAS,0BAA0B,UAA2B;AAC5D,SACE,iCAAiC,KAAK,QAAQ,KAAK,2BAA2B,KAAK,QAAQ;AAE/F;AAEA,IAAM,0BAA0B;AAEhC,SAAS,4BAA4B,WAAwC;AAC3E,MAAI;AAEJ,MAAI,OAAO,cAAc,YAAY,OAAO,SAAS,SAAS,GAAG;AAC/D,UAAM,cACJ,KAAK,IAAI,SAAS,KAAK,0BAA0B,YAAY,MAAO;AACtE,WAAO,IAAI,KAAK,WAAW;AAAA,EAC7B,OAAO;AACL,UAAM,iBAAiB,cAAc,SAAS;AAE9C,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,IACT;AAEA,WAAO,IAAI,KAAK,cAAc;AAAA,EAChC;AAEA,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,YAAY;AAC1B;AAEA,SAAS,qBAAqB,UAA0B;AACtD,SAAOD,MAAK,SAAS,UAAU,gBAAgB;AACjD;AAEA,SAAS,oBAAoB,cAA8B;AACzD,SAAOA,MAAK,KAAKA,MAAK,QAAQ,YAAY,GAAG,GAAG,qBAAqB,YAAY,CAAC,QAAQ;AAC5F;AAEA,SAAS,qBAAqB,MAAwC;AACpE,SAAO,cAAc,KAAK,IAAI,MAAM;AACtC;AAEA,SAAS,gBAAgB,MAAwC;AAC/D,SAAO,cAAc,KAAK,IAAI,MAAM;AACtC;AAEA,SAAS,gCAAgC,MAAmD;AAC1F,QAAM,UAAU,SAAS,KAAK,aAAa;AAC3C,SAAO,cAAc,SAAS,GAAG;AACnC;AAEO,IAAM,qBAAN,MAAkD;AAAA,EACvC,KAAK;AAAA,EAEJ;AAAA,EACA;AAAA,EAEV,YAAY,UAAqC,CAAC,GAAG;AAC1D,SAAK,cAAc,QAAQ,eAAeD;AAC1C,SAAK,qBAAqB,QAAQ,sBAAsB;AAAA,EAC1D;AAAA,EAEQ,2BAAmC;AACzC,QAAI,YAAY,KAAK,WAAW,GAAG;AACjC,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AAEA,WAAO,KAAK,YAAY,KAAK;AAAA,EAC/B;AAAA,EAEA,MAAa,gBAAmC;AAC9C,UAAM,gBAAgB,KAAK,yBAAyB;AAEpD,QAAI,KAAK,sBAAsB,CAAE,MAAM,aAAa,aAAa,GAAI;AACnE,YAAM,IAAI,MAAM,sDAAsD,aAAa,EAAE;AAAA,IACvF;AAEA,QAAI,KAAK,sBAAsB,CAAE,MAAM,gBAAgB,aAAa,GAAI;AACtE,YAAM,IAAI,MAAM,gDAAgD,aAAa,EAAE;AAAA,IACjF;AAEA,WAAO,cAAc,eAAe,EAAE,WAAW,iBAAiB,CAAC;AAAA,EACrE;AAAA,EAEA,MAAa,UAAU,UAAyC;AAC9D,UAAM,EAAE,OAAO,IAAI,MAAM,KAAK,yBAAyB,QAAQ;AAC/D,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,yBAAyB,UAAuD;AAC3F,UAAM,SAAuB,CAAC;AAC9B,QAAI,cAAc;AAClB,UAAM,oBAAoB,oBAAI,IAAoB;AAElD,QAAI;AAEJ,QAAI;AACF,YAAM,UAAU,MAAMG,UAAS,UAAU,MAAM;AAC/C,qBAAe,KAAK,MAAM,OAAO;AAAA,IACnC,QAAQ;AACN;AACA,6BAAuB,mBAAmB,kBAAkB;AAC5D,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,UAAM,WAAW,SAAS,YAAY;AAEtC,QAAI,CAAC,UAAU;AACb;AACA,6BAAuB,mBAAmB,uBAAuB;AACjE,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,UAAM,aAAa,SAAS,SAAS,UAAU;AAE/C,QAAI,CAAC,YAAY;AACf;AACA,6BAAuB,mBAAmB,gBAAgB;AAC1D,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,UAAM,cAAc,4BAA4B,aAAa,WAAW,WAAW,CAAC;AACpF,UAAM,eAAe,4BAA4B,aAAa,WAAW,YAAY,CAAC;AACtF,UAAM,kBAAkB,4BAA4B,aAAa,WAAW,cAAc,CAAC;AAC3F,UAAM,kBAAkB,4BAA4B,aAAa,WAAW,eAAe,CAAC;AAC5F,UAAM,mBAAmB;AAAA,MACvB,aAAa,WAAW,mBAAmB;AAAA,IAC7C;AACA,UAAM,iBAAiB,cAAc,eAAe,kBAAkB;AACtE,UAAM,cAAc,iBAAiB;AAErC,QAAI,mBAAmB,GAAG;AACxB;AACA,6BAAuB,mBAAmB,gBAAgB;AAC1D,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,UAAM,WAAW,cAAc,SAAS,YAAY;AACpD,UAAM,QAAQ,cAAc,SAAS,KAAK;AAE1C,UAAM,mBAAmB,4BAA4B,SAAS,qBAAqB;AACnF,UAAM,2BAA2B,QAAQ,gBAAgB;AAEzD,UAAM,YAAY,oBAAoB,QAAQ;AAE9C,QAAI;AACJ,QAAI;AAEJ,QAAI;AACF,uBAAiB,QAAQ,iBAAiB,WAAW;AAAA,QACnD,iBAAiB;AAAA,MACnB,CAAC,GAAG;AACF,YAAI,CAAC,YAAY,qBAAqB,IAAI,GAAG;AAC3C,qBAAW,gCAAgC,IAAI,KAAK;AAEpD,cAAI,0BAA0B;AAC5B;AAAA,UACF;AAEA;AAAA,QACF;AAEA,YAAI,CAAC,4BAA4B,gBAAgB,IAAI,GAAG;AACtD,qCAA2B,4BAA4B,KAAK,SAAS;AACrE;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,UAAM,YAAY,oBAAoB;AAEtC,QAAI,CAAC,WAAW;AACd;AACA,6BAAuB,mBAAmB,mBAAmB;AAC7D,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,QAAI;AACF,aAAO;AAAA,QACL,iBAAiB;AAAA,UACf,QAAQ,KAAK;AAAA,UACb,WAAW,qBAAqB,QAAQ;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF,QAAQ;AACN;AACA,6BAAuB,mBAAmB,uBAAuB;AAAA,IACnE;AAEA,WAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,EAClE;AACF;;;AEvOA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAWjB,IAAM,mBAAmBC,MAAK,KAAKC,IAAG,QAAQ,GAAG,SAAS;AAO1D,SAAS,kBAAkB,MAAoC;AAC7D,QAAM,UAAU,oBAAI,IAAoB;AACxC,QAAM,SAAS,SAAS,IAAI;AAE5B,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,SAAS,OAAO,QAAQ;AAEzC,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAM,eAAe,SAAS,KAAK;AACnC,UAAM,eAAe,cAAc,cAAc,YAAY;AAE7D,QAAI,cAAc;AAChB,cAAQ,IAAI,KAAK,YAAY;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,iBAAiB,WAAiD;AAC/E,QAAM,eAAeD,MAAK,KAAK,WAAW,eAAe;AAEzD,MAAI;AACF,UAAM,UAAU,MAAME,UAAS,cAAc,MAAM;AACnD,UAAM,SAAS,KAAK,MAAM,OAAO;AAEjC,WAAO,kBAAkB,MAAM;AAAA,EACjC,QAAQ;AACN,WAAO,oBAAI,IAAI;AAAA,EACjB;AACF;AAEA,eAAe,qBAAqB,WAAsC;AACxE,QAAM,SAASF,MAAK,KAAK,WAAW,KAAK;AACzC,QAAM,kBAA4B,CAAC;AACnC,QAAM,kBAAkB,MAAM,cAAc,QAAQ,EAAE,WAAW,QAAQ,CAAC;AAE1E,aAAW,YAAY,iBAAiB;AACtC,UAAM,YAAYA,MAAK,SAASA,MAAK,QAAQ,QAAQ,CAAC;AAEtD,QAAI,UAAU,YAAY,MAAM,SAAS;AACvC,sBAAgB,KAAK,QAAQ;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,gBACP,UACA,aACA,gBACoB;AACpB,QAAM,cAAc,cAAc,YAAY,WAAW;AAEzD,MAAI,aAAa;AACf,UAAM,aAAa,eAAe,IAAI,WAAW;AAEjD,QAAI,YAAY;AACd,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,WAAWA,MAAK,QAAQ,QAAQ;AACtC,QAAM,aAAaA,MAAK,QAAQ,QAAQ;AACxC,QAAM,oBAAoBA,MAAK,SAAS,UAAU;AAElD,SAAO,eAAe,IAAI,iBAAiB;AAC7C;AAEA,SAAS,eAAe,OAAoC;AAC1D,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAAA,EAC1C;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,KAAK;AAE3B,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,OAAO,OAAO;AAE7B,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,QAMlB;AACP,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,KAAK,IAAI,GAAG,eAAe,OAAO,KAAK,KAAK,CAAC;AAC3D,QAAM,OAAO,KAAK,IAAI,GAAG,eAAe,OAAO,IAAI,KAAK,CAAC;AACzD,QAAM,SAAS,KAAK,IAAI,GAAG,eAAe,OAAO,MAAM,KAAK,CAAC;AAC7D,QAAM,WAAW,KAAK,IAAI,GAAG,eAAe,OAAO,QAAQ,KAAK,CAAC;AACjE,QAAM,SAAS,KAAK,IAAI,GAAG,eAAe,OAAO,MAAM,KAAK,CAAC;AAE7D,QAAM,cAAc,QAAQ;AAC5B,QAAM,eAAe;AACrB,QAAM,kBAAkB;AACxB,QAAM,kBAAkB;AAExB,QAAM,gBAAgB,KAAK,IAAI,GAAG,eAAe,OAAO,KAAK,KAAK,CAAC;AACnE,QAAM,iBAAiB,cAAc,eAAe,kBAAkB;AACtE,QAAM,cAAc,gBAAgB,IAAI,gBAAgB;AAExD,MAAI,gBAAgB,KAAK,iBAAiB,KAAK,oBAAoB,KAAK,WAAW,GAAG;AACpF,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAIA,SAASG,oBAAmB,WAAwC;AAClE,MAAI,OAAO,cAAc,YAAY,YAAY,SAAS,GAAG;AAC3D,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,IAAI,KAAK,UAAU,KAAK,CAAC;AAEtC,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,YAAY;AAC1B;AAEO,IAAM,sBAAN,MAAmD;AAAA,EACxC,KAAK;AAAA,EAEJ;AAAA,EACA;AAAA,EACT,iBAA6C;AAAA,EAE9C,YAAY,UAAsC,CAAC,GAAG;AAC3D,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,mBAAmB,QAAQ,oBAAoB;AAAA,EACtD;AAAA,EAEQ,yBAAiC;AACvC,QAAI,YAAY,KAAK,SAAS,GAAG;AAC/B,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AAEA,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAc,kBAAkB,qBAA2D;AACzF,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK;AAAA,IACd;AAEA,SAAK,iBAAiB,MAAM,iBAAiB,mBAAmB;AAChE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,4BAA0D;AACtE,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,YAAY,KAAK,SAAS,GAAG;AAC/B,aAAO,oBAAI,IAAI;AAAA,IACjB;AAEA,SAAK,iBAAiB,MAAM,iBAAiB,KAAK,UAAU,KAAK,CAAC;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAa,gBAAmC;AAC9C,UAAM,gBAAgB,KAAK,uBAAuB;AAElD,QAAI,KAAK,oBAAoB,CAAE,MAAM,aAAa,aAAa,GAAI;AACjE,YAAM,IAAI,MAAM,8CAA8C,aAAa,EAAE;AAAA,IAC/E;AAEA,QAAI,KAAK,oBAAoB,CAAE,MAAM,gBAAgB,aAAa,GAAI;AACpE,YAAM,IAAI,MAAM,wCAAwC,aAAa,EAAE;AAAA,IACzE;AAEA,UAAM,KAAK,kBAAkB,aAAa;AAE1C,WAAO,qBAAqB,aAAa;AAAA,EAC3C;AAAA,EAEA,MAAa,UAAU,UAAyC;AAC9D,UAAM,EAAE,OAAO,IAAI,MAAM,KAAK,yBAAyB,QAAQ;AAE/D,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,yBAAyB,UAAuD;AAC3F,UAAM,SAAuB,CAAC;AAC9B,QAAI,cAAc;AAClB,UAAM,oBAAoB,oBAAI,IAAoB;AAElD,QAAI;AAEJ,QAAI;AACF,YAAM,UAAU,MAAMD,UAAS,UAAU,MAAM;AAC/C,oBAAc,KAAK,MAAM,OAAO;AAAA,IAClC,QAAQ;AACN;AACA,6BAAuB,mBAAmB,kBAAkB;AAE5D,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,UAAM,oBAAoB,SAAS,WAAW;AAE9C,QAAI,CAAC,mBAAmB;AACtB;AACA,6BAAuB,mBAAmB,sBAAsB;AAEhE,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,UAAM,YACJ,cAAc,kBAAkB,SAAS,KAAKF,MAAK,SAAS,UAAU,OAAO;AAE/E,UAAM,iBAAiB,MAAM,KAAK,0BAA0B;AAC5D,UAAM,WAAW,gBAAgB,UAAU,mBAAmB,cAAc;AAE5E,QAAI,CAAC,MAAM,QAAQ,kBAAkB,QAAQ,GAAG;AAC9C;AACA,6BAAuB,mBAAmB,wBAAwB;AAClE,aAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,IAClE;AAEA,UAAM,WAAW,kBAAkB;AAEnC,eAAW,cAAc,UAAU;AACjC,YAAM,UAAU,SAAS,UAAU;AAEnC,UAAI,CAAC,SAAS;AACZ;AACA,+BAAuB,mBAAmB,iBAAiB;AAE3D;AAAA,MACF;AAEA,UAAI,QAAQ,SAAS,UAAU;AAC7B;AACA,+BAAuB,mBAAmB,oBAAoB;AAE9D;AAAA,MACF;AAEA,YAAM,SAAS,kBAAkB,SAAS,QAAQ,MAAM,CAAC;AAEzD,UAAI,CAAC,QAAQ;AACX;AACA,+BAAuB,mBAAmB,gBAAgB;AAE1D;AAAA,MACF;AAEA,YAAM,YAAYG,oBAAmB,QAAQ,SAAS;AAEtD,UAAI,CAAC,WAAW;AACd;AACA,+BAAuB,mBAAmB,mBAAmB;AAE7D;AAAA,MACF;AAEA,YAAM,QAAQ,cAAc,QAAQ,KAAK;AAEzC,UAAI;AACF,eAAO;AAAA,UACL,iBAAiB;AAAA,YACf,QAAQ,KAAK;AAAA,YACb;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV;AAAA,YACA,GAAG;AAAA,YACH,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF,QAAQ;AACN;AACA,+BAAuB,mBAAmB,uBAAuB;AAAA,MACnE;AAAA,IACF;AAEA,WAAO,mBAAmB,QAAQ,aAAa,iBAAiB;AAAA,EAClE;AACF;;;AClVA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAQjB,SAAS,YAAY,OAA2B;AAC9C,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;AAC3B;AAEA,SAAS,uBAAuB,SAAiB,KAAkC;AACjF,QAAM,cAAc,IAAI,iBAAiBA,MAAK,KAAK,SAAS,UAAU,OAAO;AAE7E,SAAO;AAAA,IACLA,MAAK,KAAK,aAAa,YAAY,aAAa;AAAA,IAChDA,MAAK,KAAK,aAAa,YAAY,WAAW;AAAA,IAC9CA,MAAK,KAAK,SAAS,aAAa,aAAa;AAAA,IAC7CA,MAAK,KAAK,SAAS,aAAa,WAAW;AAAA,EAC7C;AACF;AAEA,SAAS,mBAAmB,SAA2B;AACrD,QAAM,gBAAgBA,MAAK,KAAK,SAAS,WAAW,qBAAqB;AAEzE,SAAO;AAAA,IACLA,MAAK,KAAK,eAAe,YAAY,aAAa;AAAA,IAClDA,MAAK,KAAK,eAAe,YAAY,WAAW;AAAA,IAChDA,MAAK,KAAK,SAAS,aAAa,aAAa;AAAA,IAC7CA,MAAK,KAAK,SAAS,aAAa,WAAW;AAAA,EAC7C;AACF;AAEA,SAAS,qBAAqB,SAAiB,KAAkC;AAC/E,QAAM,cACJ,IAAI,WACJ,IAAI,iBACH,IAAI,cAAcA,MAAK,KAAK,IAAI,aAAa,WAAW,SAAS,IAAI;AAExE,QAAM,oBAAoB,cACtB;AAAA,IACEA,MAAK,KAAK,aAAa,YAAY,aAAa;AAAA,IAChDA,MAAK,KAAK,aAAa,YAAY,WAAW;AAAA,EAChD,IACA,CAAC;AAEL,SAAO;AAAA,IACL,GAAG;AAAA,IACHA,MAAK,KAAK,SAAS,aAAa,aAAa;AAAA,IAC7CA,MAAK,KAAK,SAAS,aAAa,WAAW;AAAA,EAC7C;AACF;AAEO,SAAS,mCACd,UAAyC,CAAC,GAChC;AACV,QAAM,WAAW,QAAQ,YAAY,QAAQ;AAC7C,QAAM,UAAU,QAAQ,WAAWD,IAAG,QAAQ;AAC9C,QAAM,MAAM,QAAQ,OAAO,QAAQ;AAEnC,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,YAAY,qBAAqB,SAAS,GAAG,CAAC;AAAA,IACvD,KAAK;AACH,aAAO,YAAY,mBAAmB,OAAO,CAAC;AAAA,IAChD;AACE,aAAO,YAAY,uBAAuB,SAAS,GAAG,CAAC;AAAA,EAC3D;AACF;;;ACtEA,SAAS,qBAAqB;;;ACA9B,IAAM,gCACJ;AAEK,SAAS,4BACd,SACA,aACS;AACT,QAAM,UACJ,mBAAmB,QAAQ,QAAQ,UAAU,OAAO,YAAY,WAAW,UAAU;AACvF,QAAM,cACJ,gBACC,mBAAmB,QAAQ,QAAQ,OAAO,OAAO,YAAY,WAAW,KAAK;AAEhF,SAAO,gBAAgB,yBAAyB,QAAQ,SAAS,6BAA6B;AAChG;AAEO,SAAS,wCAA2C,MAAkB;AAC3E,QAAM,sBAAsB,QAAQ,YAAY,KAAK,OAAO;AAC5D,QAAM,sBAAsB,CAAC,YAAqB,SAA0B;AAC1E,UAAM,gBAAgB,KAAK,CAAC;AAC5B,UAAM,cACJ,OAAO,kBAAkB,WACrB,gBACA,OAAO,kBAAkB,YACvB,kBAAkB,QAClB,UAAU,iBACV,OAAO,cAAc,SAAS,WAC9B,cAAc,OACd;AAER,QAAI,4BAA4B,SAAS,WAAW,GAAG;AACrD;AAAA,IACF;AAEA,YAAQ,MAAM,qBAAqB,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;AAAA,EAChE;AAEA,UAAQ,cAAc;AAEtB,MAAI;AACF,WAAO,KAAK;AAAA,EACd,UAAE;AACA,YAAQ,cAAc;AAAA,EACxB;AACF;;;ADrBA,IAAME,WAAU,cAAc,YAAY,GAAG;AAE7C,SAAS,eAAe,OAAuC;AAC7D,QAAM,eAAe,SAAS,KAAK;AACnC,SAAO,OAAO,cAAc,iBAAiB;AAC/C;AAEO,SAAS,gCAAgC,WAAoC;AAClF,MAAI;AACF,UAAM,cAAc,wCAAwC,MAAM,UAAU,aAAa,CAAC;AAE1F,QAAI,CAAC,eAAe,WAAW,GAAG;AAChC,YAAM,IAAI,MAAM,mEAAmE;AAAA,IACrF;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACpE,UAAM,IAAI;AAAA,MACR,0EAA0E,MAAM;AAAA,MAChF,EAAE,OAAO,MAAM;AAAA,IACjB;AAAA,EACF;AACF;AAEA,eAAsB,uBAA8C;AAClE,SAAO,gCAAgCA,QAAO;AAChD;;;AE1CA,IAAMC,2BAA0B;AAUhC,SAASC,6BAA4B,WAAwC;AAC3E,MAAI,OAAO,cAAc,YAAY,OAAO,SAAS,SAAS,GAAG;AAC/D,UAAM,cACJ,KAAK,IAAI,SAAS,KAAKD,2BAA0B,YAAY,MAAO;AACtE,UAAM,OAAO,IAAI,KAAK,WAAW;AAEjC,QAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,YAAY;AAAA,EAC1B;AAEA,MAAI,OAAO,cAAc,UAAU;AACjC,UAAM,UAAU,UAAU,KAAK;AAE/B,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,mBAAmB,OAAO,OAAO;AAEvC,QAAI,OAAO,SAAS,gBAAgB,GAAG;AACrC,aAAOC,6BAA4B,gBAAgB;AAAA,IACrD;AAEA,UAAM,OAAO,IAAI,KAAK,OAAO;AAE7B,QAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,YAAY;AAAA,EAC1B;AAEA,SAAO;AACT;AAEA,SAAS,iBACP,cACA,gBACoB;AACpB,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA,eAAe;AAAA,IACf,eAAe;AAAA,IACf,eAAe;AAAA,EACjB;AAEA,aAAW,aAAa,qBAAqB;AAC3C,UAAM,WAAWA,6BAA4B,SAAS;AAEtD,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,OAAoC;AAClE,QAAM,SAAS,aAAa,KAAK;AAEjC,MAAI,WAAW,UAAa,WAAW,MAAM;AAC3C,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,YAAY,OAAO,KAAK,MAAM,IAAI;AACtD,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,OAAO,WAAW,WAAW,SAAS,OAAO,MAAM;AAEvE,MAAI,CAAC,OAAO,SAAS,WAAW,KAAK,cAAc,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,4BAA4B,OAAoC;AACvE,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG;AACvD,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,SAAO,cAAc,KAAK;AAC5B;AAEA,SAASC,iBAAgB,gBAA6D;AACpF,QAAM,cAAc,SAAS,eAAe,IAAI;AAEhD,SACE,cAAc,aAAa,IAAI,KAC/B,cAAc,aAAa,GAAG,KAC9B,cAAc,eAAe,GAAG,KAChC,cAAc,eAAe,SAAS,KACtC,cAAc,eAAe,QAAQ,KACrC,cAAc,eAAe,YAAY,KACzC,cAAc,eAAe,WAAW;AAE5C;AAEA,SAASC,gBAAe,aAA6B,cAA2C;AAC9F,MAAI,iBAAiB,QAAW;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,YAAY,KAAK,CAAC,UAAU;AACjC,UAAM,SAAS,uBAAuB,KAAK;AAC3C,WAAO,WAAW,UAAa,SAAS;AAAA,EAC1C,CAAC;AACH;AAEO,SAAS,yBACd,MACA,UAC4B;AAC5B,QAAM,SAAuB,CAAC;AAC9B,MAAI,cAAc;AAClB,QAAM,oBAAoB,oBAAI,IAA8B;AAE5D,QAAM,mBAAmB,CAAC,WAAmC;AAC3D,mBAAe;AACf,sBAAkB,IAAI,SAAS,kBAAkB,IAAI,MAAM,KAAK,KAAK,CAAC;AAAA,EACxE;AAEA,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,cAAc,IAAI,SAAS;AAE5C,QAAI,CAAC,UAAU;AACb,uBAAiB,mBAAmB;AACpC;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI;AACF,YAAM,gBAAgB,SAAS,KAAK,MAAM,QAAQ,CAAC;AAEnD,UAAI,CAAC,eAAe;AAClB,yBAAiB,mBAAmB;AACpC;AAAA,MACF;AAEA,gBAAU;AAAA,IACZ,QAAQ;AACN,uBAAiB,mBAAmB;AACpC;AAAA,IACF;AAEA,UAAM,OAAO,cAAc,QAAQ,IAAI,KAAK,cAAc,QAAQ,IAAI;AAEtE,QAAI,MAAM,YAAY,MAAM,aAAa;AACvC;AAAA,IACF;AAEA,UAAM,YAAY,iBAAiB,IAAI,UAAU,OAAO;AAExD,QAAI,CAAC,WAAW;AACd,uBAAiB,mBAAmB;AACpC;AAAA,IACF;AAEA,UAAM,YACJ,4BAA4B,IAAI,cAAc,KAC9C,4BAA4B,QAAQ,SAAS,KAC7C,4BAA4B,QAAQ,SAAS,KAC7C,4BAA4B,QAAQ,UAAU,KAC9C,4BAA4B,IAAI,MAAM;AAExC,QAAI,CAAC,WAAW;AACd,uBAAiB,oBAAoB;AACrC;AAAA,IACF;AAEA,UAAM,WAAW,cAAc,QAAQ,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACpF,UAAM,QAAQ,cAAc,QAAQ,OAAO,KAAK,cAAc,QAAQ,KAAK;AAC3E,UAAM,WAAWD,iBAAgB,OAAO;AACxC,UAAM,SAAS,SAAS,QAAQ,MAAM;AACtC,UAAM,aAAa,SAAS,QAAQ,KAAK;AACzC,UAAM,cAAc,aAAa,QAAQ,KAAK;AAC9C,UAAM,eAAe,aAAa,QAAQ,MAAM;AAChD,UAAM,kBAAkB,aAAa,QAAQ,SAAS;AACtD,UAAM,kBAAkB,aAAa,YAAY,IAAI;AACrD,UAAM,mBAAmB,aAAa,YAAY,KAAK;AACvD,UAAM,cAAc,aAAa,QAAQ,KAAK;AAC9C,UAAM,eAAe,uBAAuB,QAAQ,IAAI;AAExD,QACE,CAACC;AAAA,MACC;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,IACF,GACA;AACA,uBAAiB,sBAAsB;AACvC;AAAA,IACF;AAEA,QAAI;AACF,aAAO;AAAA,QACL,iBAAiB;AAAA,UACf,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT,UAAU,iBAAiB,SAAY,cAAc;AAAA,QACvD,CAAC;AAAA,MACH;AAAA,IACF,QAAQ;AACN,uBAAiB,qBAAqB;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,mBAAmB,CAAC,GAAG,kBAAkB,QAAQ,CAAC,EAC/C,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,QAAQ,MAAM,EAAE,EAC5C,KAAK,CAAC,MAAM,UAAU,mBAAmB,KAAK,QAAQ,MAAM,MAAM,CAAC;AAAA,EACxE;AACF;;;AC3PO,SAAS,0BAA0B,OAAyB;AACjE,QAAM,UAAU,SAAS,KAAK;AAC9B,QAAM,OAAO,cAAc,SAAS,IAAI;AACxC,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,QAAM,aAAa;AAEnB,SACE,SAAS,iBACT,SAAS,mBACT,SAAS,qBACT,WAAW,KAAK,OAAO;AAE3B;AAEO,SAAS,kBAAkB,OAAwB;AACxD,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,QAAM,cAAc,SAAS,KAAK;AAClC,QAAM,OAAO,cAAc,aAAa,IAAI;AAE5C,MAAI,CAAC,MAAM;AACT,WAAO,MAAM;AAAA,EACf;AAEA,SAAO,GAAG,IAAI,KAAK,MAAM,OAAO;AAClC;;;AC1BA,eAAsB,mBACpB,WACA,SAMY;AACZ,WAAS,UAAU,GAAG,WAAW,QAAQ,gBAAgB,WAAW,GAAG;AACrE,QAAI;AACF,aAAO,MAAM,UAAU;AAAA,IACzB,SAAS,OAAO;AACd,YAAM,SAAS,0BAA0B,KAAK;AAE9C,UAAI,UAAU,UAAU,QAAQ,gBAAgB;AAC9C,cAAM,QAAQ,MAAM,QAAQ,oBAAoB,UAAU,EAAE;AAC5D;AAAA,MACF;AAEA,UAAI,QAAQ;AACV,cAAM,IAAI;AAAA,UACR,+BAA+B,QAAQ,MAAM,6BAA6B,QAAQ,iBAAiB,CAAC;AAAA,UACpG,EAAE,OAAO,MAAM;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,IAAI;AAAA,QACR,iCAAiC,QAAQ,MAAM,KAAK,kBAAkB,KAAK,CAAC;AAAA,QAC5E,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,gEAAgE;AAClF;;;ACrBA,SAAS,oCAAoC,OAAyB;AACpE,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,SAAO,8DAA8D,KAAK,OAAO;AACnF;AAEA,SAAS,iBAAiB,YAA4B;AACpD,SAAO,IAAI,WAAW,WAAW,KAAK,IAAI,CAAC;AAC7C;AAEA,SAAS,iCACP,aACA,YACoB;AACpB,aAAW,aAAa,YAAY;AAClC,UAAM,sBAAsB,UAAU,YAAY;AAClD,UAAM,oBAAoB,YAAY;AAAA,MACpC,CAAC,eAAe,WAAW,YAAY,MAAM;AAAA,IAC/C;AAEA,QAAI,mBAAmB;AACrB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,8BAA8B,gBAAwD;AAC7F,QAAM,aAAa,iCAAiC,gBAAgB,CAAC,MAAM,CAAC;AAE5E,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,iCAAiC,gBAAgB,CAAC,MAAM,YAAY,CAAC;AACtF,QAAM,kBAAkB,iCAAiC,gBAAgB;AAAA,IACvE;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,kBAAkB,iCAAiC,gBAAgB;AAAA,IACvE;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,CAAC,YAAY,CAAC,iBAAiB;AACjC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,WAAmB,SAAsC;AACnF,QAAM,eAAe,QAAQ,kBACzB,GAAG,iBAAiB,QAAQ,eAAe,CAAC,uBAC5C;AAEJ,SAAO;AAAA,IACL;AAAA,IACA,KAAK,iBAAiB,QAAQ,QAAQ,CAAC;AAAA,IACvC,KAAK,iBAAiB,QAAQ,eAAe,CAAC;AAAA,IAC9C,KAAK,YAAY;AAAA,IACjB,KAAK,iBAAiB,QAAQ,UAAU,CAAC;AAAA,IACzC,QAAQ,iBAAiB,SAAS,CAAC;AAAA,IACnC;AAAA,MACE;AAAA,MACA,qBAAqB,iBAAiB,QAAQ,UAAU,CAAC;AAAA,MACzD,6CAA6C,iBAAiB,QAAQ,UAAU,CAAC,6BAA6B,iBAAiB,QAAQ,UAAU,CAAC;AAAA,MAClJ;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,IACX,YAAY,iBAAiB,QAAQ,eAAe,CAAC,SAAS,iBAAiB,QAAQ,QAAQ,CAAC;AAAA,EAClG,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,oBAAoB,WAAmB,SAAsC;AACpF,QAAM,eAAe,QAAQ,kBACzB,GAAG,iBAAiB,QAAQ,eAAe,CAAC,uBAC5C;AAEJ,SAAO;AAAA,IACL;AAAA,IACA,KAAK,iBAAiB,QAAQ,QAAQ,CAAC;AAAA,IACvC,KAAK,iBAAiB,QAAQ,eAAe,CAAC;AAAA,IAC9C,KAAK,YAAY;AAAA,IACjB,KAAK,iBAAiB,QAAQ,UAAU,CAAC;AAAA,IACzC,QAAQ,iBAAiB,SAAS,CAAC;AAAA,IACnC,YAAY,iBAAiB,QAAQ,eAAe,CAAC,SAAS,iBAAiB,QAAQ,QAAQ,CAAC;AAAA,EAClG,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,wBAAwB,UAA0C;AACzE,QAAM,eAAe,SAClB,QAAQ,qDAAqD,EAC7D,IAAI,EACJ,IAAI,CAAC,QAAQ,cAAc,IAAI,IAAI,CAAC,EACpC,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC;AACpD,QAAM,mBAAmB,iCAAiC,cAAc,CAAC,SAAS,CAAC;AAEnF,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,2BACP,UACA,kBACqB;AACrB,QAAM,0BAA0B,iBAAiB,WAAW,KAAK,IAAI;AACrE,QAAM,iBAAiB,SACpB,QAAQ,sBAAsB,uBAAuB,IAAI,EACzD,IAAI,EACJ,IAAI,CAAC,QAAQ,cAAc,IAAI,IAAI,CAAC,EACpC,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC;AAEpD,SAAO,8BAA8B,cAAc;AACrD;AAEA,SAAS,iBACP,UACA,OAC6B;AAC7B,QAAM,YAAY,SAAS,QAAQ,KAAK;AAExC,MAAI,UAAU,SAAS;AACrB,UAAM,WAAW,UAAU,QAAQ;AACnC,UAAM,cAAc,SAAS,KAAK;AAElC,YAAQ,UAAU,WAAgD;AAChE,UAAI,CAAC,YAAY,MAAM;AACrB,cAAM,YAAY;AAAA,MACpB;AAEA,aAAO;AAAA,IACT,GAAG;AAAA,EACL;AAEA,SAAO,UAAU,IAAI;AACvB;AAEO,SAAS,yBACd,UAC6B;AAC7B,QAAM,mBAAmB,wBAAwB,QAAQ;AACzD,QAAM,UAAU,2BAA2B,UAAU,gBAAgB;AACrE,QAAM,eAAe,mBAAmB,kBAAkB,OAAO;AAEjE,MAAI;AACF,WAAO,iBAAiB,UAAU,YAAY;AAAA,EAChD,SAAS,OAAO;AACd,QAAI,CAAC,oCAAoC,KAAK,GAAG;AAC/C,YAAM;AAAA,IACR;AAEA,WAAO,iBAAiB,UAAU,oBAAoB,kBAAkB,OAAO,CAAC;AAAA,EAClF;AACF;;;AClLA,IAAM,2BAA2B;AACjC,IAAM,8BAA8B;AAgBpC,SAASC,aAAY,OAAwB;AAC3C,SAAO,MAAM,KAAK,EAAE,WAAW;AACjC;AAEA,eAAeC,OAAM,SAAgC;AACnD,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,eAAW,SAAS,OAAO;AAAA,EAC7B,CAAC;AACH;AAEO,IAAM,wBAAN,MAAqD;AAAA,EAC1C,KAAK;AAAA,EAEJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEV,YAAY,UAAwC,CAAC,GAAG;AAC7D,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,wBACH,QAAQ,yBAAyB;AACnC,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,eAAe,QAAQ,gBAAgB;AAC5C,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,mBAAmB,QAAQ,oBAAoB;AACpD,SAAK,iBAAiB,KAAK,IAAI,GAAG,QAAQ,kBAAkB,wBAAwB;AACpF,SAAK,mBAAmB,KAAK,IAAI,GAAG,QAAQ,oBAAoB,2BAA2B;AAC3F,SAAK,QAAQ,QAAQ,SAASA;AAAA,EAChC;AAAA,EAEA,MAAa,gBAAmC;AAC9C,QAAI,KAAK,mBAAmB,QAAW;AACrC,UAAID,aAAY,KAAK,cAAc,GAAG;AACpC,cAAM,IAAI,MAAM,wCAAwC;AAAA,MAC1D;AAEA,YAAM,iBAAiB,KAAK,eAAe,KAAK;AAChD,YAAM,WAAW,MAAM,KAAK,aAAa,cAAc;AAEvD,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MAAM,8CAA8C,cAAc,EAAE;AAAA,MAChF;AAEA,UAAK,MAAM,KAAK,WAAW,cAAc,KAAM,CAAE,MAAM,KAAK,WAAW,cAAc,GAAI;AACvF,cAAM,IAAI,MAAM,mCAAmC,cAAc,EAAE;AAAA,MACrE;AAEA,aAAO,CAAC,cAAc;AAAA,IACxB;AAEA,QAAI;AAEJ,eAAW,iBAAiB,KAAK,sBAAsB,GAAG;AACxD,UAAI,MAAM,KAAK,aAAa,aAAa,GAAG;AAC1C,YAAK,MAAM,KAAK,WAAW,aAAa,KAAM,CAAE,MAAM,KAAK,WAAW,aAAa,GAAI;AACrF,gBAAM,IAAI,MAAM,mCAAmC,aAAa,EAAE;AAAA,QACpE;AAEA,eAAO,CAAC,aAAa;AAAA,MACvB;AAEA,UAAI,CAAC,gCAAiC,MAAM,KAAK,WAAW,aAAa,GAAI;AAC3E,uCAA+B;AAAA,MACjC;AAAA,IACF;AAEA,QAAI,8BAA8B;AAChC,YAAM,IAAI,MAAM,mCAAmC,4BAA4B,EAAE;AAAA,IACnF;AAEA,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC5D,UAAM,mBAAmB,MAAM,KAAK,yBAAyB,MAAM;AACnE,WAAO,iBAAiB;AAAA,EAC1B;AAAA,EAEA,MAAa,yBAAyB,QAAqD;AACzF,QAAIA,aAAY,MAAM,GAAG;AACvB,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AAEA,UAAM,mBAAmB,OAAO,KAAK;AACrC,UAAM,WAAW,MAAM,KAAK,aAAa,gBAAgB;AAEzD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,mCAAmC,gBAAgB,EAAE;AAAA,IACvE;AAEA,QAAK,MAAM,KAAK,WAAW,gBAAgB,KAAM,CAAE,MAAM,KAAK,WAAW,gBAAgB,GAAI;AAC3F,YAAM,IAAI,MAAM,mCAAmC,gBAAgB,EAAE;AAAA,IACvE;AAEA,WAAO,mBAAmB,MAAM,KAAK,cAAc,gBAAgB,GAAG;AAAA,MACpE,QAAQ;AAAA,MACR,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,KAAK;AAAA,MACvB,OAAO,KAAK;AAAA,IACd,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cAAc,QAAqD;AAC/E,UAAM,SAAS,MAAM,KAAK,iBAAiB;AAC3C,UAAM,WAAW,IAAI,OAAO,aAAa,QAAQ,EAAE,UAAU,MAAM,SAAS,EAAE,CAAC;AAE/E,QAAI;AACF,YAAM,cAAc,yBAAyB,QAAQ;AACrD,aAAO,yBAAyB,aAAa,KAAK,EAAE;AAAA,IACtD,UAAE;AACA,eAAS,MAAM;AAAA,IACjB;AAAA,EACF;AACF;;;ACjJA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AAYjB,IAAMC,sBAAqBC,MAAK,KAAKC,IAAG,QAAQ,GAAG,OAAO,SAAS,UAAU;AA4B7E,IAAM,0BAA0B;AAChC,IAAM,0BAA0B;AAChC,IAAM,+BAA+B;AAErC,SAAS,uBAAuB,UAA2B;AACzD,SACE,wBAAwB,KAAK,QAAQ,KACrC,wBAAwB,KAAK,QAAQ,KACrC,6BAA6B,KAAK,QAAQ;AAE9C;AAEA,IAAM,oBAAoC,MAAM;AAEhD,IAAMC,2BAA0B;AAEhC,SAASC,6BAA4B,WAAwC;AAC3E,MAAI;AAEJ,MAAI,OAAO,cAAc,YAAY,OAAO,SAAS,SAAS,GAAG;AAC/D,UAAM,cACJ,KAAK,IAAI,SAAS,KAAKD,2BAA0B,YAAY,MAAO;AACtE,WAAO,IAAI,KAAK,WAAW;AAAA,EAC7B,OAAO;AACL,UAAM,iBAAiB,cAAc,SAAS;AAE9C,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,IACT;AAEA,WAAO,IAAI,KAAK,cAAc;AAAA,EAChC;AAEA,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,YAAY;AAC1B;AAEA,SAASE,kBACP,MACA,SACA,OACoB;AACpB,QAAM,aAAa,CAAC,KAAK,WAAW,SAAS,WAAW,MAAM,gBAAgB;AAE9E,aAAW,aAAa,YAAY;AAClC,UAAM,sBAAsBD,6BAA4B,SAAS;AAEjE,QAAI,qBAAqB;AACvB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,OAA4D;AAC1F,QAAM,OAAO,SAAS,MAAM,IAAI;AAEhC,QAAM,YAA4B;AAAA,IAChC,aAAa,aAAa,MAAM,KAAK;AAAA,IACrC,cAAc,aAAa,MAAM,MAAM;AAAA,IACvC,iBAAiB;AAAA,MACf,MAAM,aAAa,MAAM,mBAAmB,MAAM,mBAAmB,MAAM;AAAA,IAC7E;AAAA,IACA,iBAAiB,aAAa,MAAM,SAAS;AAAA,IAC7C,kBAAkB,aAAa,MAAM,UAAU;AAAA,IAC/C,aAAa,aAAa,MAAM,WAAW;AAAA,IAC3C,SAAS,aAAa,MAAM,KAAK;AAAA,EACnC;AAEA,QAAME,kBAAiB,CAAC,UAAsD;AAC5E,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,WAAW,GAAG;AAC1D,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAE/D,QAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB;AAAA,IACtB,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AACA,QAAM,yBAAyB,gBAAgB,KAAK,CAAC,UAAU;AAC7D,UAAM,SAASA,gBAAe,KAAK;AACnC,WAAO,WAAW,UAAa,SAAS;AAAA,EAC1C,CAAC;AACD,QAAM,eAAeA,gBAAe,UAAU,OAAO;AACrD,QAAM,wBAAwB,iBAAiB,UAAa,eAAe;AAE3E,SAAO,0BAA0B,wBAAwB,YAAY;AACvE;AAEA,SAAS,aAAa,MAA+B,SAA8C;AACjG,QAAM,YAAY,SAAS,KAAK,KAAK;AACrC,QAAM,eAAe,SAAS,SAAS,KAAK;AAE5C,MAAI,WAAW;AACb,UAAM,qBAAqB,uBAAuB,SAAS;AAE3D,QAAI,oBAAoB;AACtB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,SAAO,uBAAuB,YAAY;AAC5C;AAEA,SAASC,sBAAqB,UAA0B;AACtD,SAAON,MAAK,SAAS,UAAU,QAAQ;AACzC;AAEA,SAAS,0BACP,QACoB;AACpB,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,SAAS,OAAO,IAAI;AAEvC,SACE,cAAc,YAAY,IAAI,KAC9B,cAAc,YAAY,GAAG,KAC7B,cAAc,OAAO,GAAG,KACxB,cAAc,OAAO,SAAS,KAC9B,cAAc,OAAO,QAAQ,KAC7B,cAAc,OAAO,YAAY,KACjC,cAAc,OAAO,WAAW;AAEpC;AAEO,IAAM,kBAAN,MAA+C;AAAA,EACpC,KAAK;AAAA,EAEJ;AAAA,EACA;AAAA,EACA;AAAA,EAEV,YAAY,UAAkC,CAAC,GAAG;AACvD,SAAK,cAAc,QAAQ,eAAeD;AAC1C,SAAK,iBAAiB,QAAQ,kBAAkB;AAChD,SAAK,qBAAqB,QAAQ,sBAAsB;AAAA,EAC1D;AAAA,EAEA,MAAa,gBAAmC;AAC9C,QAAI,YAAY,KAAK,WAAW,GAAG;AACjC,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAEA,UAAM,wBAAwB,KAAK,YAAY,KAAK;AAEpD,QAAI,KAAK,sBAAsB,CAAE,MAAM,aAAa,qBAAqB,GAAI;AAC3E,YAAM,IAAI,MAAM,mDAAmD,qBAAqB,EAAE;AAAA,IAC5F;AAEA,QAAI,KAAK,sBAAsB,CAAE,MAAM,gBAAgB,qBAAqB,GAAI;AAC9E,YAAM,IAAI,MAAM,6CAA6C,qBAAqB,EAAE;AAAA,IACtF;AAEA,WAAO,mBAAmB,qBAAqB;AAAA,EACjD;AAAA,EAEA,MAAa,UAAU,UAAyC;AAC9D,UAAM,SAAuB,CAAC;AAC9B,UAAM,QAAwB,EAAE,WAAWO,sBAAqB,QAAQ,EAAE;AAE1E,qBAAiB,QAAQ,iBAAiB,UAAU;AAAA,MAClD,iBAAiB;AAAA,IACnB,CAAC,GAAG;AACF,UAAI,KAAK,SAAS,WAAW;AAC3B,cAAM,YAAY,cAAc,KAAK,EAAE,KAAK,MAAM;AAClD,cAAM,mBAAmB,cAAc,KAAK,SAAS,KAAK,MAAM;AAChE,cAAM,WAAW,0BAA0B,IAAI,KAAK,MAAM;AAC1D;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,gBAAgB;AAChC,cAAM,WAAW,cAAc,KAAK,QAAQ,KAAK,MAAM;AACvD,cAAM,QAAQ,cAAc,KAAK,OAAO,KAAK,cAAc,KAAK,KAAK,KAAK,MAAM;AAChF,cAAM,WAAW,0BAA0B,IAAI,KAAK,MAAM;AAC1D;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,WAAW;AAC3B;AAAA,MACF;AAEA,YAAM,UAAU,SAAS,KAAK,OAAO;AACrC,YAAM,QAAQ,aAAa,MAAM,OAAO;AAExC,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AAEA,YAAM,WACJ,cAAc,KAAK,QAAQ,KAAK,cAAc,SAAS,QAAQ,KAAK,MAAM;AAE5E,UAAI,CAAC,KAAK,eAAe,QAAQ,GAAG;AAClC;AAAA,MACF;AAEA,YAAM,YAAYF,kBAAiB,MAAM,SAAS,KAAK;AAEvD,UAAI,CAAC,aAAa,CAAC,MAAM,WAAW;AAClC;AAAA,MACF;AAEA,YAAM,QACJ,cAAc,KAAK,KAAK,KACxB,cAAc,KAAK,OAAO,KAC1B,cAAc,SAAS,KAAK,KAC5B,MAAM;AACR,YAAM,WACJ,0BAA0B,IAAI,KAAK,0BAA0B,OAAO,KAAK,MAAM;AAEjF,UAAI;AACF,eAAO;AAAA,UACL,iBAAiB;AAAA,YACf,QAAQ,KAAK;AAAA,YACb,WAAW,MAAM;AAAA,YACjB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,GAAG;AAAA,UACL,CAAC;AAAA,QACH;AAAA,MACF,QAAQ;AACN;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AC9QA,SAAS,8BAA8B,SAAoD;AACzF,QAAM,YAAY,oBAAI,IAAoB;AAE1C,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WAAO;AAAA,EACT;AAEA,aAAW,SAAS,SAAS;AAC3B,UAAM,iBAAiB,MAAM,QAAQ,GAAG;AAExC,QAAI,kBAAkB,KAAK,kBAAkB,MAAM,SAAS,GAAG;AAC7D,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,cAAc,EAAE,KAAK,EAAE,YAAY;AACnE,UAAM,gBAAgB,MAAM,MAAM,iBAAiB,CAAC,EAAE,KAAK;AAE3D,QAAI,CAAC,YAAY,CAAC,eAAe;AAC/B,YAAM,IAAI,MAAM,2DAA2D;AAAA,IAC7E;AAEA,QAAI,UAAU,IAAI,QAAQ,GAAG;AAC3B,YAAM,IAAI,MAAM,qCAAqC,QAAQ,EAAE;AAAA,IACjE;AAEA,cAAU,IAAI,UAAU,aAAa;AAAA,EACvC;AAEA,SAAO;AACT;AAEA,IAAM,sBAAqD;AAAA,EACzD;AAAA,IACE,IAAI;AAAA,IACJ,mBAAmB,EAAE,MAAM,YAAY;AAAA,IACvC,QAAQ,CAAC,SAAS,6BAA6B;AAC7C,YAAM,kBAAkB,uBAAuB,MAAM,QAAQ,OAAO,wBAAwB;AAE5F,aAAO,IAAI,gBAAgB;AAAA,QACzB,aAAa,gBAAgB;AAAA,QAC7B,oBAAoB,gBAAgB;AAAA,MACtC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,mBAAmB,EAAE,MAAM,YAAY;AAAA,IACvC,QAAQ,CAAC,SAAS,6BAA6B;AAC7C,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAEA,aAAO,IAAI,mBAAmB;AAAA,QAC5B,aAAa,gBAAgB;AAAA,QAC7B,oBAAoB,gBAAgB;AAAA,MACtC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,mBAAmB,EAAE,MAAM,YAAY;AAAA,IACvC,QAAQ,CAAC,SAAS,6BAA6B;AAC7C,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAEA,aAAO,IAAI,oBAAoB;AAAA,QAC7B,WAAW,gBAAgB;AAAA,QAC3B,kBAAkB,gBAAgB;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,mBAAmB,EAAE,MAAM,YAAY;AAAA,IACvC,QAAQ,CAAC,SAAS,6BAA6B;AAC7C,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAEA,aAAO,IAAI,mBAAmB;AAAA,QAC5B,aAAa,gBAAgB;AAAA,QAC7B,oBAAoB,gBAAgB;AAAA,MACtC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,mBAAmB,EAAE,MAAM,eAAe,MAAM,gBAAgB;AAAA,IAChE,QAAQ,CAAC,YACP,IAAI,sBAAsB;AAAA,MACxB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACL;AACF;AAEA,IAAM,4BAA4B,IAAI;AAAA,EACpC,oBACG;AAAA,IACC,CACE,WAGG,OAAO,kBAAkB,SAAS;AAAA,EACzC,EACC,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,OAAO,kBAAkB,IAAI,CAAC;AAC/D;AAEA,IAAM,wBAAwB,IAAI;AAAA,EAChC,oBACG;AAAA,IACC,CAAC,WACC,OAAO,kBAAkB,SAAS;AAAA,EACtC,EACC,IAAI,CAAC,WAAW,OAAO,EAAE;AAC9B;AAEA,SAAS,mCACP,0BACM;AACN,QAAM,8BAA8B,CAAC,GAAG,yBAAyB,KAAK,CAAC,EAAE;AAAA,IAAO,CAAC,aAC/E,0BAA0B,IAAI,QAAQ;AAAA,EACxC;AAEA,MAAI,4BAA4B,SAAS,GAAG;AAC1C,UAAM,WAAW,4BAA4B,CAAC;AAC9C,UAAM,OAAO,0BAA0B,IAAI,QAAQ;AAEnD,UAAM,IAAI,MAAM,kCAAkC,QAAQ,UAAU,IAAI,WAAW;AAAA,EACrF;AAEA,QAAM,mBAAmB,CAAC,GAAG,yBAAyB,KAAK,CAAC,EAAE;AAAA,IAC5D,CAAC,aAAa,CAAC,sBAAsB,IAAI,QAAQ;AAAA,EACnD;AAEA,MAAI,iBAAiB,WAAW,GAAG;AACjC;AAAA,EACF;AAEA,QAAM,mBAAmB,CAAC,GAAG,qBAAqB,EAAE,KAAK,kBAAkB;AAE3E,QAAM,IAAI;AAAA,IACR,sCAAsC,iBAAiB,KAAK,IAAI,CAAC,qBAAqB,iBAAiB,KAAK,IAAI,CAAC;AAAA,EACnH;AACF;AAEA,SAAS,yBAAyB,YAAsC;AACtE,MAAI,eAAe,QAAW;AAC5B;AAAA,EACF;AAEA,MAAI,WAAW,KAAK,EAAE,WAAW,GAAG;AAClC,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AACF;AAEA,SAAS,0BACP,YACA,OACM;AACN,MAAI,UAAU,QAAW;AACvB;AAAA,EACF;AAEA,MAAI,MAAM,KAAK,EAAE,WAAW,GAAG;AAC7B,UAAM,IAAI,MAAM,GAAG,UAAU,2BAA2B;AAAA,EAC1D;AACF;AAEA,SAAS,uBACP,UACA,mBACA,0BAIA;AACA,MAAI,sBAAsB,QAAW;AACnC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,qBAAqB;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,oBAAoB,yBAAyB,IAAI,QAAQ;AAE/D,MAAI,sBAAsB,QAAW;AACnC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,qBAAqB;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,qBAAqB;AAAA,EACvB;AACF;AAEO,SAAS,sBAAgC;AAC9C,SAAO,oBAAoB,IAAI,CAAC,WAAW,OAAO,EAAE;AACtD;AAEO,SAAS,sBAAsB,SAAwD;AAC5F,2BAAyB,QAAQ,UAAU;AAC3C,4BAA0B,YAAY,QAAQ,KAAK;AACnD,4BAA0B,eAAe,QAAQ,QAAQ;AACzD,4BAA0B,gBAAgB,QAAQ,SAAS;AAC3D,4BAA0B,eAAe,QAAQ,QAAQ;AAEzD,QAAM,2BAA2B,8BAA8B,QAAQ,SAAS;AAChF,qCAAmC,wBAAwB;AAE3D,SAAO,oBAAoB,IAAI,CAAC,WAAW,OAAO,OAAO,SAAS,wBAAwB,CAAC;AAC7F;;;AC9OA,IAAM,iBAAiB,oBAAI,IAAiC;AAE5D,SAAS,iBAAiB,UAAuC;AAC/D,QAAM,kBAAkB,eAAe,IAAI,QAAQ;AAEnD,MAAI,iBAAiB;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,KAAK,eAAe,SAAS;AAAA,IACjD,UAAU;AAAA,IACV,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,EACP,CAAC;AACD,iBAAe,IAAI,UAAU,SAAS;AACtC,SAAO;AACT;AAEA,SAAS,sBAAsB,cAAsB,UAAkC;AACrF,QAAM,OAAO,IAAI,KAAK,YAAY;AAElC,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,UAAM,IAAI,MAAM,4BAA4B,YAAY,EAAE;AAAA,EAC5D;AAEA,QAAM,YAAY,iBAAiB,QAAQ;AAC3C,QAAM,QAAQ,UAAU,cAAc,IAAI;AAE1C,QAAM,OAAO,OAAO,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,MAAM,GAAG,KAAK;AACrE,QAAM,QAAQ,OAAO,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,OAAO,GAAG,KAAK;AACvE,QAAM,MAAM,OAAO,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,KAAK,GAAG,KAAK;AAEnE,MAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK;AAC3B,UAAM,IAAI,MAAM,qDAAqD,YAAY,EAAE;AAAA,EACrF;AAEA,SAAO,EAAE,MAAM,OAAO,IAAI;AAC5B;AAEA,SAAS,cAAc,WAAiC;AACtD,SAAO,IAAI,KAAK,KAAK,IAAI,UAAU,MAAM,UAAU,QAAQ,GAAG,UAAU,GAAG,CAAC;AAC9E;AAEA,SAAS,QAAQ,MAAY,MAAoB;AAC/C,SAAO,IAAI,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,KAAK,GAAI;AAC7D;AAEA,SAAS,eAAe,MAAoB;AAC1C,QAAM,SAAS,KAAK,UAAU;AAC9B,SAAO,WAAW,IAAI,IAAI;AAC5B;AAEA,SAAS,gBAAgB,WAAqE;AAC5F,QAAM,eAAe,cAAc,SAAS;AAC5C,QAAM,SAAS,eAAe,YAAY;AAE1C,QAAM,oBAAoB,QAAQ,cAAc,EAAE,SAAS,EAAE;AAC7D,QAAM,sBAAsB,QAAQ,cAAc,IAAI,MAAM;AAC5D,QAAM,WAAW,oBAAoB,eAAe;AAEpD,QAAM,OAAO,IAAI,KAAK,KAAK,IAAI,UAAU,GAAG,CAAC,CAAC;AAC9C,QAAM,aAAa,eAAe,IAAI;AACtC,QAAM,kBAAkB,QAAQ,MAAM,EAAE,aAAa,EAAE;AAEvD,QAAM,SAAS,kBAAkB,QAAQ,IAAI,gBAAgB,QAAQ;AACrE,QAAM,aAAa,KAAK,MAAM,UAAU,IAAI,KAAK,KAAK,KAAK,IAAK,IAAI;AAEpE,SAAO,EAAE,UAAU,WAAW;AAChC;AAEO,SAAS,aACd,cACA,aACA,UACQ;AACR,QAAM,YAAY,sBAAsB,cAAc,QAAQ;AAE9D,MAAI,gBAAgB,SAAS;AAC3B,WAAO,GAAG,UAAU,IAAI,IAAI,OAAO,UAAU,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,UAAU,GAAG,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EAChH;AAEA,MAAI,gBAAgB,WAAW;AAC7B,WAAO,GAAG,UAAU,IAAI,IAAI,OAAO,UAAU,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EACtE;AAEA,QAAM,UAAU,gBAAgB,SAAS;AACzC,SAAO,GAAG,QAAQ,QAAQ,KAAK,OAAO,QAAQ,UAAU,EAAE,SAAS,GAAG,GAAG,CAAC;AAC5E;;;ACxEA,IAAM,sBAAsB;AAE5B,SAAS,OAAO,MAAc,OAAuB;AACnD,SAAO,KAAK,OAAO,OAAO,SAAS,mBAAmB,IAAI;AAC5D;AAEA,SAAS,oBAAiC;AACxC,SAAO;AAAA,IACL,aAAa;AAAA,IACb,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,aAAa;AAAA,EACf;AACF;AAEA,SAAS,uBAAuC;AAC9C,SAAO;AAAA,IACL,QAAQ,kBAAkB;AAAA,IAC1B,aAAa,oBAAI,IAAyB;AAAA,EAC5C;AACF;AAEA,SAAS,iBAAiB,QAAqB,OAAyB;AACtE,SAAO,eAAe,MAAM;AAC5B,SAAO,gBAAgB,MAAM;AAC7B,SAAO,mBAAmB,MAAM;AAChC,SAAO,mBAAmB,MAAM;AAChC,SAAO,oBAAoB,MAAM;AACjC,SAAO,eAAe,MAAM;AAE5B,MAAI,MAAM,YAAY,QAAW;AAC/B,WAAO,iBAAiB;AACxB;AAAA,EACF;AAEA,SAAO,UAAU,OAAO,OAAO,WAAW,GAAG,MAAM,OAAO;AAC5D;AAEA,SAAS,kBAAkB,OAA+C;AACxE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAC5C,SAAO,cAAc;AACvB;AAEA,SAAS,sBAAsB,aAA6B,OAAyB;AACnF,mBAAiB,YAAY,QAAQ,KAAK;AAE1C,QAAM,kBAAkB,kBAAkB,MAAM,KAAK;AAErD,MAAI,CAAC,iBAAiB;AACpB;AAAA,EACF;AAEA,QAAM,iBAAiB,YAAY,YAAY,IAAI,eAAe,KAAK,kBAAkB;AACzF,mBAAiB,gBAAgB,KAAK;AACtC,cAAY,YAAY,IAAI,iBAAiB,cAAc;AAC7D;AAEA,SAAS,UAAU,QAAqB,QAA2B;AACjE,SAAO,eAAe,OAAO;AAC7B,SAAO,gBAAgB,OAAO;AAC9B,SAAO,mBAAmB,OAAO;AACjC,SAAO,mBAAmB,OAAO;AACjC,SAAO,oBAAoB,OAAO;AAClC,SAAO,eAAe,OAAO;AAE7B,MAAI,OAAO,YAAY,QAAW;AAChC,WAAO,UAAU,OAAO,OAAO,WAAW,GAAG,OAAO,OAAO;AAAA,EAC7D;AAEA,MAAI,OAAO,gBAAgB;AACzB,WAAO,iBAAiB;AAAA,EAC1B;AACF;AAEA,SAAS,iBACP,mBACA,mBACM;AACN,aAAW,CAAC,OAAO,YAAY,KAAK,mBAAmB;AACrD,UAAM,eAAe,kBAAkB,IAAI,KAAK,KAAK,kBAAkB;AACvE,cAAU,cAAc,YAAY;AACpC,sBAAkB,IAAI,OAAO,YAAY;AAAA,EAC3C;AACF;AAEA,SAAS,sBACP,aACuB;AACvB,QAAM,eAAe,mBAAmB,YAAY,KAAK,CAAC;AAE1D,SAAO,aAAa,IAAI,CAAC,UAAU;AACjC,UAAM,SAAS,YAAY,IAAI,KAAK,KAAK,kBAAkB;AAE3D,WAAO;AAAA,MACL;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF,CAAC;AACH;AAEA,SAAS,qBACP,MACA,OACA,iBACQ;AACR,QAAM,aAAa,gBAAgB,IAAI,IAAI,KAAK,OAAO;AACvD,QAAM,cAAc,gBAAgB,IAAI,KAAK,KAAK,OAAO;AAEzD,MAAI,eAAe,aAAa;AAC9B,WAAO,aAAa;AAAA,EACtB;AAEA,SAAO,mBAAmB,MAAM,KAAK;AACvC;AAEO,SAAS,eACd,QACA,SACkB;AAClB,QAAM,kBAAkB,oBAAI,IAAoB;AAEhD,aAAW,CAAC,OAAO,MAAM,MAAM,QAAQ,eAAe,CAAC,GAAG,QAAQ,GAAG;AACnE,oBAAgB,IAAI,QAAQ,KAAK;AAAA,EACnC;AAEA,QAAM,YAAY,oBAAI,IAAyC;AAE/D,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,aAAa,MAAM,WAAW,QAAQ,aAAa,QAAQ,QAAQ;AACrF,UAAM,gBAAgB,UAAU,IAAI,SAAS,KAAK,oBAAI,IAA4B;AAClF,cAAU,IAAI,WAAW,aAAa;AAEtC,UAAM,iBAAiB,cAAc,IAAI,MAAM,MAAM,KAAK,qBAAqB;AAC/E,kBAAc,IAAI,MAAM,QAAQ,cAAc;AAE9C,0BAAsB,gBAAgB,KAAK;AAAA,EAC7C;AAEA,QAAM,mBAAmB,CAAC,GAAG,UAAU,KAAK,CAAC,EAAE,KAAK,kBAAkB;AACtE,QAAM,OAAyB,CAAC;AAChC,QAAM,cAAc,kBAAkB;AACtC,QAAM,mBAAmB,oBAAI,IAAyB;AAEtD,aAAW,aAAa,kBAAkB;AACxC,UAAM,YAAY,UAAU,IAAI,SAAS;AAEzC,QAAI,CAAC,WAAW;AACd;AAAA,IACF;AAEA,UAAM,uBAAuB,kBAAkB;AAC/C,UAAM,4BAA4B,oBAAI,IAAyB;AAE/D,UAAM,gBAAgB,CAAC,GAAG,UAAU,KAAK,CAAC,EAAE;AAAA,MAAK,CAAC,MAAM,UACtD,qBAAqB,MAAM,OAAO,eAAe;AAAA,IACnD;AAEA,eAAW,UAAU,eAAe;AAClC,YAAM,cAAc,UAAU,IAAI,MAAM;AAExC,UAAI,CAAC,aAAa;AAChB;AAAA,MACF;AAEA,YAAM,YAA6B;AAAA,QACjC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,QAAQ,mBAAmB,YAAY,YAAY,KAAK,CAAC;AAAA,QACzD,gBAAgB,sBAAsB,YAAY,WAAW;AAAA,QAC7D,GAAG,YAAY;AAAA,MACjB;AAEA,WAAK,KAAK,SAAS;AAEnB,gBAAU,sBAAsB,YAAY,MAAM;AAClD,gBAAU,aAAa,YAAY,MAAM;AACzC,uBAAiB,2BAA2B,YAAY,WAAW;AACnE,uBAAiB,kBAAkB,YAAY,WAAW;AAAA,IAC5D;AAEA,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM,cAAiC;AAAA,QACrC,SAAS;AAAA,QACT;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ,mBAAmB,0BAA0B,KAAK,CAAC;AAAA,QAC3D,gBAAgB,sBAAsB,yBAAyB;AAAA,QAC/D,GAAG;AAAA,MACL;AAEA,WAAK,KAAK,WAAW;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,uBACJ,OAAO,WAAW,KAAK,YAAY,YAAY,UAAa,YAAY,mBAAmB,OACvF,EAAE,GAAG,aAAa,SAAS,EAAE,IAC7B;AAEN,QAAM,gBAA+B;AAAA,IACnC,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ,mBAAmB,iBAAiB,KAAK,CAAC;AAAA,IAClD,gBAAgB,sBAAsB,gBAAgB;AAAA,IACtD,GAAG;AAAA,EACL;AAEA,OAAK,KAAK,aAAa;AAEvB,SAAO;AACT;;;ACxMO,SAAS,mCAA0D;AACxE,SAAO;AAAA,IACL,aAAa;AAAA,IACb,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAEO,SAAS,qCAA8D;AAC5E,SAAO;AAAA,IACL,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,cAAc;AAAA,EAChB;AACF;;;AClDA,IAAMG,uBAAsB;AAO5B,SAASC,QAAO,MAAc,OAAuB;AACnD,SAAO,KAAK,OAAO,OAAO,SAASD,oBAAmB,IAAIA;AAC5D;AAEA,SAAS,cAAc,KAA4C;AACjE,SAAO;AAAA,IACL,aAAa,IAAI;AAAA,IACjB,cAAc,IAAI;AAAA,IAClB,iBAAiB,IAAI;AAAA,IACrB,iBAAiB,IAAI;AAAA,IACrB,kBAAkB,IAAI;AAAA,IACtB,aAAa,IAAI;AAAA,IACjB,SAAS,IAAI;AAAA,IACb,gBAAgB,IAAI;AAAA,EACtB;AACF;AAEA,SAAS,yBAAyB,WAAiE;AACjG,QAAM,mBAAmB,oBAAI,IAAmC;AAChE,QAAM,iBAAiB,oBAAI,IAAmC;AAE9D,aAAW,OAAO,WAAW;AAC3B,QAAI,IAAI,YAAY,eAAe;AACjC;AAAA,IACF;AAEA,QAAI,IAAI,YAAY,mBAAmB;AACrC,uBAAiB,IAAI,IAAI,WAAW,cAAc,GAAG,CAAC;AACtD;AAAA,IACF;AAEA,UAAM,uBACJ,eAAe,IAAI,IAAI,SAAS,KAAK,iCAAiC;AACxE,mBAAe,IAAI,IAAI,WAAW,eAAe,sBAAsB,cAAc,GAAG,CAAC,CAAC;AAAA,EAC5F;AAEA,QAAM,aAAa,oBAAI,IAAY,CAAC,GAAG,iBAAiB,KAAK,GAAG,GAAG,eAAe,KAAK,CAAC,CAAC;AACzF,QAAM,sBAAsB,oBAAI,IAAmC;AAEnE,aAAW,aAAa,YAAY;AAClC,wBAAoB;AAAA,MAClB;AAAA,MACA,iBAAiB,IAAI,SAAS,KAC5B,eAAe,IAAI,SAAS,KAC5B,iCAAiC;AAAA,IACrC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,iBACP,MACA,OACyB;AACzB,SAAO;AAAA,IACL,aAAa,KAAK,cAAc,MAAM;AAAA,IACtC,YAAY,KAAK,aAAa,MAAM;AAAA,IACpC,cAAc,KAAK,eAAe,MAAM;AAAA,IACxC,cAAc,KAAK,eAAe,MAAM;AAAA,EAC1C;AACF;AAEA,SAAS,eACP,MACA,OACuB;AACvB,QAAM,iBACH,KAAK,mBAAmB,QAAQ,KAAK,YAAY,UACjD,MAAM,mBAAmB,QAAQ,MAAM,YAAY;AACtD,QAAM,oBAAoB,CAAC,UACzB,MAAM,gBAAgB,KAAK,MAAM,YAAY,KAAK,MAAM,mBAAmB;AAC7E,QAAM,gBACJ,KAAK,YAAY,UAAa,CAAC,kBAAkB,IAAI,IAAI,KAAK,UAAU;AAC1E,QAAM,iBACJ,MAAM,YAAY,UAAa,CAAC,kBAAkB,KAAK,IAAI,MAAM,UAAU;AAE7E,MAAI,UACF,kBAAkB,UAAa,mBAAmB,SAC9CC,QAAO,eAAe,cAAc,IACnC,iBAAiB;AAExB,MAAI,mBAAmB,YAAY,UAAa,YAAY,IAAI;AAC9D,cAAU;AAAA,EACZ;AAEA,SAAO;AAAA,IACL,aAAa,KAAK,cAAc,MAAM;AAAA,IACtC,cAAc,KAAK,eAAe,MAAM;AAAA,IACxC,iBAAiB,KAAK,kBAAkB,MAAM;AAAA,IAC9C,iBAAiB,KAAK,kBAAkB,MAAM;AAAA,IAC9C,kBAAkB,KAAK,mBAAmB,MAAM;AAAA,IAChD,aAAa,KAAK,cAAc,MAAM;AAAA,IACtC;AAAA,IACA,gBAAgB,KAAK,kBAAkB,MAAM,iBAAiB,OAAO;AAAA,EACvE;AACF;AAEA,SAAS,sBACP,OACA,UAC0B;AAC1B,QAAM,UAAU,MAAM;AACtB,QAAM,sBAAsB,MAAM,cAAc,MAAM,eAAe,MAAM;AAE3E,SAAO;AAAA,IACL,cACE,YAAY,UAAa,SAAS,cAAc,IAC5C,UAAU,SAAS,cACnB;AAAA,IACN,sBACE,YAAY,UAAa,SAAS,eAAe,IAC7C,WAAW,SAAS,eAAe,OACnC;AAAA,IACN,iBACE,SAAS,cAAc,IAAI,MAAM,cAAc,SAAS,cAAc;AAAA,IACxE,yBACE,SAAS,cAAc,IAAI,sBAAsB,SAAS,cAAc;AAAA,IAC1E,eACE,YAAY,UAAa,UAAU,IAAI,SAAS,cAAc,UAAU;AAAA,EAC5E;AACF;AAEO,SAAS,oBAAoB,SAAsD;AACxF,QAAM,sBAAsB,yBAAyB,QAAQ,SAAS;AACtE,QAAM,aAAa;AAAA,IACjB,GAAG,oBAAI,IAAI,CAAC,GAAG,oBAAoB,KAAK,GAAG,GAAG,QAAQ,eAAe,KAAK,CAAC,CAAC;AAAA,EAC9E,EAAE,KAAK,kBAAkB;AAEzB,QAAM,OAAwB,CAAC;AAC/B,MAAI,aAAa,iCAAiC;AAClD,MAAI,gBAAgB,mCAAmC;AAEvD,aAAW,aAAa,YAAY;AAClC,UAAM,cAAc,oBAAoB,IAAI,SAAS,KAAK,iCAAiC;AAC3F,UAAM,gBACJ,QAAQ,eAAe,IAAI,SAAS,KAAK,mCAAmC;AAC9E,UAAM,cAAc,oBAAoB,IAAI,SAAS;AACrD,UAAMC,kBACJ,gBACC,YAAY,cAAc,KACzB,YAAY,YAAY,UACxB,YAAY,mBAAmB;AAEnC,QAAI,cAAc,gBAAgB,KAAK,CAACA,iBAAgB;AACtD;AAAA,IACF;AAEA,UAAM,UAAU,sBAAsB,aAAa,aAAa;AAEhE,SAAK,KAAK;AAAA,MACR,SAAS;AAAA,MACT;AAAA,MACA,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACL,CAAC;AAED,iBAAa,eAAe,YAAY,WAAW;AACnD,oBAAgB,iBAAiB,eAAe,aAAa;AAAA,EAC/D;AAEA,QAAM,sBACJ,WAAW,YAAY,UACvB,WAAW,mBAAmB,QAC9B,WAAW,gBAAgB,IACvB,EAAE,GAAG,YAAY,SAAS,EAAE,IAC5B;AAEN,OAAK,KAAK;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,sBAAsB,qBAAqB,aAAa;AAAA,EAC7D,CAAC;AAED,SAAO;AACT;;;ACpMA,SAAS,SAAAC,cAAa;AACtB,SAAS,mBAAAC,wBAAuB;AAChC,OAAOC,WAAU;AACjB,SAAS,QAAAC,aAAY;AAQrB,IAAM,oBAAoB;AAC1B,IAAM,oBACJ;AAoDF,SAAS,UAAU,OAAe,MAAsB;AACtD,QAAM,OAAO,oBAAI,KAAK,GAAG,KAAK,gBAAgB;AAE9C,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,UAAM,IAAI,MAAM,uBAAuB,KAAK,EAAE;AAAA,EAChD;AAEA,OAAK,WAAW,KAAK,WAAW,IAAI,IAAI;AACxC,SAAO,KAAK,YAAY,EAAE,MAAM,GAAG,EAAE;AACvC;AAEA,SAAS,sBAAsB,OAAuB;AACpD,SAAO,MAAM,QAAQ,wBAAwB,MAAM;AACrD;AAEA,SAAS,+BAA+B,QAAkC;AACxE,SAAO,OAAO,OAAO,KAAK,KAAK,wBAAwB,OAAO,QAAQ;AACxE;AAEA,SAAS,eAAe,SAAqC;AAC3D,MAAI,YAAY,QAAW;AACzB,WAAOC,MAAK,QAAQ,QAAQ,IAAI,CAAC;AAAA,EACnC;AAEA,QAAM,oBAAoB,QAAQ,KAAK;AAEvC,MAAI,CAAC,mBAAmB;AACtB,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AAEA,SAAOA,MAAK,QAAQ,iBAAiB;AACvC;AAEA,SAASC,kBAAiB,OAAoC;AAC5D,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,UAAU,QAAQ;AACrE,WAAO;AAAA,EACT;AAEA,QAAM,SAAS;AACf,SAAO,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;AACzD;AAEA,eAAe,sBAAsB,SAAgC;AACnE,MAAI;AAEJ,MAAI;AACF,qBAAiB,MAAMC,MAAK,OAAO;AAAA,EACrC,SAAS,OAAO;AACd,UAAM,OAAOD,kBAAiB,KAAK;AAEnC,QAAI,SAAS,UAAU;AACrB,YAAM,IAAI,MAAM,mCAAmC,OAAO,IAAI,EAAE,OAAO,MAAM,CAAC;AAAA,IAChF;AAEA,QAAI,SAAS,YAAY,SAAS,SAAS;AACzC,YAAM,IAAI,MAAM,kCAAkC,OAAO,IAAI,EAAE,OAAO,MAAM,CAAC;AAAA,IAC/E;AAEA,UAAM;AAAA,EACR;AAEA,MAAI,CAAC,eAAe,YAAY,GAAG;AACjC,UAAM,IAAI,MAAM,uCAAuC,OAAO,EAAE;AAAA,EAClE;AACF;AAEA,eAAe,oBACb,SACA,YACe;AACf,QAAM,gBAAgB,MAAM,WAAW,SAAS,CAAC,aAAa,uBAAuB,CAAC;AAEtF,MAAI,cAAc,aAAa,GAAG;AAChC;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,uCAAuC,OAAO,EAAE;AAClE;AAEA,SAAS,yBAAyB,QAAmC;AACnE,MAAI,OAAO,aAAa,KAAK;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,OAAO,OAAO,YAAY;AAEzC,SACE,OAAO,SAAS,+BAA+B,KAC/C,OAAO,SAAS,0BAA0B,KAC1C,OAAO,SAAS,kDAAkD,KAClE,OAAO,SAAS,qBAAqB;AAEzC;AAEA,SAAS,6BACP,SACA,qBAC4B;AAC5B,SAAO;AAAA,IACL,gBAAgB,oBAAI,IAAI;AAAA,IACxB,eAAe,mCAAmC;AAAA,IAClD,aAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,MAClB,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,EACF;AACF;AAEA,SAAS,2BAA2B,OAAyB;AAC3D,SAAO,iBAAiB,SAAS,MAAM,QAAQ,WAAW,sCAAsC;AAClG;AAEA,SAAS,gCAAgC,OAAqC;AAC5E,SAAO,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC;AACxE;AAEA,SAAS,+BAA+B,OAAqC;AAC3E,QAAM,YAAY,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC;AAEjF,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,aAAa,KAAK,SAAS;AAC9C,QAAM,QAAQ,aAAa,CAAC,GAAG,KAAK;AAEpC,SAAO,SAAS,MAAM,SAAS,IAAI,QAAQ;AAC7C;AAEA,eAAe,6BACb,SACA,YACiB;AACjB,QAAM,uBAAmC;AAAA,IACvC,CAAC,UAAU,SAAS,YAAY;AAAA,IAChC,CAAC,UAAU,YAAY,SAAS,YAAY;AAAA,EAC9C;AAEA,aAAW,QAAQ,sBAAsB;AACvC,UAAM,eAAe,MAAM,WAAW,SAAS,IAAI;AAEnD,QAAI,aAAa,aAAa,GAAG;AAC/B,YAAM,kBAAkB,gCAAgC,aAAa,KAAK;AAE1E,UAAI,iBAAiB;AACnB,eAAO;AAAA,MACT;AAEA;AAAA,IACF;AAEA,QAAI,aAAa,aAAa,GAAG;AAC/B,YAAM,SAAS,+BAA+B,YAAY;AAC1D,YAAM,IAAI,MAAM,yCAAyC,OAAO,KAAK,MAAM,EAAE;AAAA,IAC/E;AAAA,EACF;AAEA,QAAM,uBAAuB,MAAM,WAAW,SAAS,CAAC,OAAO,kBAAkB,CAAC;AAElF,MAAI,qBAAqB,aAAa,GAAG;AACvC,UAAM,mBAAmB,+BAA+B,qBAAqB,KAAK;AAElF,QAAI,kBAAkB;AACpB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,wCAAwC,OAAO,iBAAiB,OAAO;AAAA,EACzE;AACF;AAEA,SAAS,eAAe,kBAAkC;AACxD,QAAM,YAAY,IAAI,KAAK,mBAAmB,GAAI;AAElD,MAAI,OAAO,MAAM,UAAU,QAAQ,CAAC,GAAG;AACrC,UAAM,IAAI,MAAM,iCAAiC,gBAAgB,EAAE;AAAA,EACrE;AAEA,SAAO,UAAU,YAAY;AAC/B;AAEA,SAAS,mBACP,MAC0D;AAC1D,QAAM,iBAAiB,kBAAkB,KAAK,KAAK,KAAK,CAAC;AAEzD,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,eAAe,CAAC;AACtC,QAAM,kBAAkB,eAAe,CAAC;AAExC,SAAO;AAAA,IACL,YAAY,gBAAgB,OAAO,SAAS,eAAe,EAAE,IAAI;AAAA,IACjE,cAAc,kBAAkB,OAAO,SAAS,iBAAiB,EAAE,IAAI;AAAA,EACzE;AACF;AAEA,SAAS,qBACP,cACA,QACA,aACM;AACN,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAEA,MACE,eACA,aAAa,YAAY,KAAK,EAAE,YAAY,MAAM,YAAY,KAAK,EAAE,YAAY,GACjF;AACA;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,aAAa,gBAAgB;AAE9D,SAAO,KAAK;AAAA,IACV,KAAK,aAAa;AAAA,IAClB;AAAA,IACA,YAAY,aAAa;AAAA,IACzB,cAAc,aAAa;AAAA,IAC3B,cAAc,aAAa,aAAa,aAAa;AAAA,EACvD,CAAC;AACH;AAEO,SAAS,0BACd,OACA,aACmB;AACnB,QAAM,SAA4B,CAAC;AACnC,MAAI;AAEJ,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,iBAAiB,GAAG;AACtC,YAAM,cAAc,KAAK,MAAM,CAAC,EAAE,MAAM,iBAAiB;AACzD,YAAM,gBAAgB,YAAY,CAAC;AACnC,YAAM,UAAU,YAAY,CAAC;AAC7B,YAAM,aAAa,YAAY,CAAC;AAEhC,UACE,YAAY,WAAW,KACvB,CAAC,SAAS,KAAK,aAAa,KAC5B,CAAC,qBAAqB,KAAK,OAAO,KAClC,WAAW,KAAK,EAAE,WAAW,GAC7B;AACA,cAAM,IAAI,MAAM,uCAAuC,IAAI,EAAE;AAAA,MAC/D;AAEA,2BAAqB,cAAc,QAAQ,WAAW;AACtD,qBAAe;AAAA,QACb,kBAAkB,OAAO,SAAS,eAAe,EAAE;AAAA,QACnD,KAAK;AAAA,QACL,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB;AACA;AAAA,IACF;AAEA,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,UAAM,YAAY,mBAAmB,IAAI;AAEzC,QAAI,CAAC,WAAW;AACd;AAAA,IACF;AAEA,iBAAa,cAAc,UAAU;AACrC,iBAAa,gBAAgB,UAAU;AAAA,EACzC;AAEA,uBAAqB,cAAc,QAAQ,WAAW;AACtD,SAAO;AACT;AAEA,eAAe,cAAc,SAAiB,MAA2C;AACvF,SAAO,MAAM,IAAI,QAA0B,CAAC,SAAS,WAAW;AAC9D,UAAM,QAAQE,OAAM,OAAO,MAAM;AAAA,MAC/B,KAAK;AAAA,MACL,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAClC,CAAC;AAED,UAAM,QAAkB,CAAC;AACzB,QAAI,SAAS;AAEb,UAAM,eAAeC,iBAAgB,EAAE,OAAO,MAAM,OAAO,CAAC;AAC5D,UAAM,iBAAiB,YAAY;AACjC,uBAAiB,QAAQ,cAAc;AACrC,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF,GAAG;AAEH,UAAM,OAAO,YAAY,MAAM;AAC/B,UAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,gBAAU;AAAA,IACZ,CAAC;AAED,UAAM,KAAK,SAAS,CAAC,UAAU;AAC7B,aAAO,KAAK;AAAA,IACd,CAAC;AAED,UAAM,KAAK,SAAS,CAAC,aAAa;AAChC,WAAK,cACF,KAAK,MAAM;AACV,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA,UAAU,YAAY;AAAA,QACxB,CAAC;AAAA,MACH,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,eAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,MAClE,CAAC;AAAA,IACL,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,wBACP,QACA,UACA,OACA,OACmB;AACnB,QAAM,kBAAkB,QAAQ,UAAU,OAAO,CAAC,IAAI;AACtD,QAAM,kBAAkB,QAAQ,UAAU,OAAO,CAAC,IAAI;AAEtD,SAAO,OAAO,OAAO,CAAC,UAAU;AAC9B,UAAM,YAAY,aAAa,MAAM,WAAW,SAAS,QAAQ;AAEjE,QAAI,mBAAmB,YAAY,iBAAiB;AAClD,aAAO;AAAA,IACT;AAEA,QAAI,mBAAmB,YAAY,iBAAiB;AAClD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,8BACP,QACA,UACA,iBACmB;AACnB,MAAI,oBAAoB,QAAW;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,OAAO;AAAA,IAAO,CAAC,UACpB,gBAAgB,IAAI,aAAa,MAAM,WAAW,SAAS,QAAQ,CAAC;AAAA,EACtE;AACF;AAEA,SAAS,wBACP,QACA,aACA,UAIA;AACA,QAAM,iBAAiB,oBAAI,IAAqC;AAChE,QAAM,gBAAgB,mCAAmC;AAEzD,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,aAAa,MAAM,WAAW,aAAa,QAAQ;AACrE,UAAM,eAAe,eAAe,IAAI,SAAS,KAAK,mCAAmC;AAEzF,iBAAa,eAAe;AAC5B,iBAAa,cAAc,MAAM;AACjC,iBAAa,gBAAgB,MAAM;AACnC,iBAAa,gBAAgB,MAAM;AAEnC,mBAAe,IAAI,WAAW,YAAY;AAE1C,kBAAc,eAAe;AAC7B,kBAAc,cAAc,MAAM;AAClC,kBAAc,gBAAgB,MAAM;AACpC,kBAAc,gBAAgB,MAAM;AAAA,EACtC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,SAKZ;AACX,QAAM,OAAO;AAAA,IACX;AAAA,IACA,mBAAmB,iBAAiB,MAAM,iBAAiB,KAAK,iBAAiB;AAAA,IACjF;AAAA,IACA;AAAA,IACA,aAAa,sBAAsB,QAAQ,WAAW,CAAC;AAAA,EACzD;AAEA,MAAI,CAAC,QAAQ,qBAAqB;AAChC,SAAK,KAAK,aAAa;AAAA,EACzB;AAEA,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,WAAW,UAAU,QAAQ,OAAO,EAAE,CAAC,YAAY;AAAA,EAC/D;AAEA,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,WAAW,UAAU,QAAQ,OAAO,CAAC,CAAC,YAAY;AAAA,EAC9D;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,SAO/B;AACA,MAAI,CAAC,QAAQ,mBAAmB,QAAQ,gBAAgB,SAAS,GAAG;AAClE,WAAO;AAAA,MACL,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AAEJ,aAAW,YAAY,QAAQ,iBAAiB;AAC9C,QAAI,CAAC,oBAAoB,WAAW,kBAAkB;AACpD,yBAAmB;AAAA,IACrB;AAEA,QAAI,CAAC,kBAAkB,WAAW,gBAAgB;AAChD,uBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ,SAAS;AAAA,IACxB,OAAO,QAAQ,SAAS;AAAA,EAC1B;AACF;AAEA,eAAsB,mBACpB,SACA,OAAgC,CAAC,GACI;AACrC,QAAM,UAAU,eAAe,QAAQ,OAAO;AAC9C,QAAM,sBAAsB,QAAQ,uBAAuB;AAC3D,QAAM,aAAa,KAAK,iBAAiB;AAEzC,MAAI,QAAQ,iBAAiB,SAAS,GAAG;AACvC,WAAO,6BAA6B,SAAS,mBAAmB;AAAA,EAClE;AAEA,MAAI,CAAC,KAAK,eAAe;AACvB,UAAM,sBAAsB,OAAO;AACnC,UAAM,oBAAoB,SAAS,UAAU;AAAA,EAC/C;AAEA,MAAI;AAEJ,MAAI;AACF,kBAAc,MAAM,6BAA6B,SAAS,UAAU;AAAA,EACtE,SAAS,OAAO;AACd,QAAI,CAAC,2BAA2B,KAAK,GAAG;AACtC,YAAM;AAAA,IACR;AAEA,UAAM,aAAa,MAAM,WAAW,SAAS,CAAC,aAAa,YAAY,MAAM,CAAC;AAE9E,QAAI,yBAAyB,UAAU,GAAG;AACxC,aAAO,6BAA6B,SAAS,mBAAmB;AAAA,IAClE;AAEA,UAAM;AAAA,EACR;AAEA,QAAM,mBAAmB,wBAAwB;AAAA,IAC/C,OAAO,QAAQ;AAAA,IACf,OAAO,QAAQ;AAAA,IACf,iBAAiB,QAAQ;AAAA,EAC3B,CAAC;AAED,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO,iBAAiB;AAAA,MACxB,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,UAAU,aAAa,GAAG;AAC5B,QAAI,yBAAyB,SAAS,GAAG;AACvC,aAAO,6BAA6B,SAAS,mBAAmB;AAAA,IAClE;AAEA,UAAM,SAAS,+BAA+B,SAAS;AACvD,UAAM,IAAI,MAAM,uCAAuC,OAAO,KAAK,MAAM,EAAE;AAAA,EAC7E;AAEA,QAAM,YAAY,0BAA0B,UAAU,OAAO,WAAW;AACxE,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,QAAM,wBAAwB;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,QAAM,EAAE,gBAAgB,cAAc,IAAI;AAAA,IACxC;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,aAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA,kBAAkB,cAAc;AAAA,MAChC,YAAY,cAAc;AAAA,MAC1B,cAAc,cAAc;AAAA,IAC9B;AAAA,EACF;AACF;;;AC9mBA,SAAS,UAAAC,SAAQ,aAAAC,YAAW,gBAAgB;AAC5C,OAAOC,YAAU;AAajB,eAAe,aAAa,eAAyC;AACnE,MAAI;AACF,UAAMF,QAAOE,OAAK,KAAK,eAAe,MAAM,GAAGD,WAAU,IAAI;AAC7D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,wBAAwB,OAAuB;AACtD,QAAM,iBAAiBC,OAAK,UAAUA,OAAK,QAAQ,KAAK,CAAC;AACzD,SAAO,QAAQ,aAAa,UAAU,eAAe,YAAY,IAAI;AACvE;AAEA,eAAe,sBAAsB,OAAgC;AACnE,QAAM,eAAeA,OAAK,QAAQ,KAAK;AAEvC,MAAI;AACF,WAAO,wBAAwB,MAAM,SAAS,YAAY,CAAC;AAAA,EAC7D,QAAQ;AACN,WAAO,wBAAwB,YAAY;AAAA,EAC7C;AACF;AAEA,eAAsB,4BAA4B,UAA+C;AAC/F,QAAM,cAAc,SAAS,KAAK;AAElC,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,cAAcA,OAAK,QAAQ,WAAW;AAE1C,aAAS;AACP,QAAI,MAAM,aAAa,WAAW,GAAG;AACnC,aAAO;AAAA,IACT;AAEA,UAAM,aAAaA,OAAK,QAAQ,WAAW;AAE3C,QAAI,eAAe,aAAa;AAC9B,aAAO;AAAA,IACT;AAEA,kBAAc;AAAA,EAChB;AACF;AAEA,eAAsB,2BACpB,QACA,SACAC,mBAAoC,6BACJ;AAChC,QAAM,yBAAyB,MAAMA,iBAAgB,OAAO,EAAE,MAAM,MAAM,MAAS;AACnF,QAAM,iBAAiB,MAAM,sBAAsB,0BAA0B,OAAO;AACpF,QAAM,YAAY,oBAAI,IAGpB;AACF,QAAM,gBAA8B,CAAC;AACrC,MAAI,qBAAqB;AACzB,MAAI,yBAAyB;AAE7B,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAM,UAAU;AACnB,gCAA0B;AAC1B;AAAA,IACF;AACA,UAAM,gBAAgB,MAAM;AAE5B,UAAM,oBACJ,UAAU,IAAI,aAAa,MAC1B,YAAY;AACX,YAAMC,gBAAe,MAAMD,iBAAgB,aAAa,EAAE,MAAM,MAAM,MAAS;AAE/E,UAAI,CAACC,eAAc;AACjB,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,cAAAA;AAAA,QACA,gBAAgB,MAAM,sBAAsBA,aAAY;AAAA,MAC1D;AAAA,IACF,GAAG;AACL,cAAU,IAAI,eAAe,iBAAiB;AAC9C,UAAM,eAAe,MAAM;AAE3B,QAAI,CAAC,cAAc;AACjB,gCAA0B;AAC1B;AAAA,IACF;AAEA,QAAI,aAAa,mBAAmB,gBAAgB;AAClD,4BAAsB;AACtB;AAAA,IACF;AAEA,kBAAc,KAAK;AAAA,MACjB,GAAG;AAAA,MACH,UAAU,aAAa;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA,mBAAmB,cAAc;AAAA,IACjC;AAAA,IACA;AAAA,EACF;AACF;;;ACrHA,IAAM,sBAAoE;AAAA,EACxE,EAAE,MAAM,+BAA+B,aAAa,4BAA4B;AAAA,EAChF;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,EAAE,MAAM,sCAAsC,aAAa,iCAAiC;AAAA,EAC5F,EAAE,MAAM,iCAAiC,aAAa,yBAAyB;AAAA,EAC/E,EAAE,MAAM,qCAAqC,aAAa,6BAA6B;AAAA,EACvF,EAAE,MAAM,kCAAkC,aAAa,oBAAoB;AAAA,EAC3E,EAAE,MAAM,sCAAsC,aAAa,wBAAwB;AAAA,EACnF,EAAE,MAAM,gCAAgC,aAAa,4BAA4B;AAAA,EACjF,EAAE,MAAM,iCAAiC,aAAa,0BAA0B;AAAA,EAChF,EAAE,MAAM,gCAAgC,aAAa,uBAAuB;AAAA,EAC5E,EAAE,MAAM,qCAAqC,aAAa,+BAA+B;AAAA,EACzF,EAAE,MAAM,mCAAmC,aAAa,6BAA6B;AACvF;AAEO,SAAS,2BAA6C;AAC3D,QAAM,YAA8B,CAAC;AAErC,aAAW,EAAE,MAAM,YAAY,KAAK,qBAAqB;AACvD,UAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,QAAI,UAAU,UAAa,UAAU,IAAI;AACvC,gBAAU,KAAK,EAAE,MAAM,OAAO,YAAY,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,sBAAsB,WAAuC;AAC3E,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,+BAA+B;AAE1C,aAAW,EAAE,MAAM,OAAO,YAAY,KAAK,WAAW;AACpD,UAAM,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,WAAW,GAAG;AAAA,EACnD;AAEA,SAAO;AACT;;;AC7BO,SAAS,sBAAsB,QAAuD;AAC3F,QAAM,sBAAsB,IAAI;AAAA,IAC9B,OAAO,uBAAuB,IAAI,CAAC,WAAW,CAAC,OAAO,OAAO,YAAY,GAAG,MAAM,CAAC;AAAA,EACrF;AAEA,QAAM,eAAe,OAAO,gBAAgB,IAAI,CAAC,YAAY;AAC3D,UAAM,cAAc,oBAAoB,IAAI,QAAQ,GAAG,YAAY,CAAC;AAEpE,WAAO;AAAA,MACL,QAAQ,QAAQ;AAAA,MAChB,YAAY,aAAa,cAAc;AAAA,MACvC,cAAc,aAAa,OAAO,UAAU;AAAA,IAC9C;AAAA,EACF,CAAC;AAED,QAAM,cAAc,OAAO,uBACxB,OAAO,CAAC,WAAW,OAAO,cAAc,CAAC,EACzC,IAAI,CAAC,YAAY;AAAA,IAChB,QAAQ,OAAO;AAAA,IACf,aAAa,OAAO;AAAA,IACpB,SAAS,OAAO;AAAA,EAClB,EAAE;AAEJ,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,OAAO;AAAA,IACvB;AAAA,IACA,eAAe,OAAO;AAAA,IACtB,gBAAgB,OAAO;AAAA,IACvB,oBAAoB,OAAO;AAAA,IAC3B,UAAU,OAAO;AAAA,EACnB;AACF;AAEO,SAAS,wBACd,QACA,MACA,aACiB;AACjB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACnDO,SAAS,kBAAkB,OAAe,UAAuC;AACtF,MAAI,CAAC,uBAAuB,KAAK,KAAK,GAAG;AACvC,UAAM,IAAI,MAAM,GAAG,QAAQ,6BAA6B;AAAA,EAC1D;AAEA,QAAM,SAAS,oBAAI,KAAK,GAAG,KAAK,gBAAgB;AAEhD,MAAI,OAAO,MAAM,OAAO,QAAQ,CAAC,KAAK,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,MAAM,OAAO;AACjF,UAAM,IAAI,MAAM,GAAG,QAAQ,+BAA+B;AAAA,EAC5D;AACF;AAEO,SAAS,iBAAiB,UAAwB;AACvD,QAAM,qBAAqB,SAAS,KAAK;AAEzC,MAAI;AACF,QAAI,KAAK,eAAe,SAAS,EAAE,UAAU,mBAAmB,CAAC,EAAE,OAAO,oBAAI,KAAK,CAAC;AAAA,EACtF,QAAQ;AACN,UAAM,IAAI,MAAM,qBAAqB,kBAAkB,EAAE;AAAA,EAC3D;AACF;AAEO,SAAS,wBAAwB,UAAkD;AACxF,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,SAAS,KAAK,EAAE,YAAY;AAC/C,SAAO,cAAc;AACvB;AAEO,SAAS,sBACd,QACyB;AACzB,MAAI,CAAC,UAAW,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAI;AAC7D,WAAO;AAAA,EACT;AAEA,QAAM,mBAAmB,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AACjE,QAAM,oBAAoB,iBACvB,QAAQ,CAAC,cAAc,UAAU,MAAM,GAAG,CAAC,EAC3C,IAAI,CAAC,cAAc,UAAU,KAAK,EAAE,YAAY,CAAC,EACjD,OAAO,CAAC,cAAc,UAAU,SAAS,CAAC;AAE7C,MAAI,kBAAkB,WAAW,GAAG;AAClC,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AAEA,SAAO,IAAI,IAAI,iBAAiB;AAClC;AAEO,SAAS,qBAAqB,OAA4D;AAC/F,MAAI,CAAC,SAAU,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAI;AAC1D,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC7D,QAAM,mBAAmB,gBACtB,QAAQ,CAAC,cAAc,UAAU,MAAM,GAAG,CAAC,EAC3C,IAAI,CAAC,cAAc,UAAU,KAAK,EAAE,YAAY,CAAC,EACjD,OAAO,CAAC,cAAc,UAAU,SAAS,CAAC;AAE7C,MAAI,iBAAiB,WAAW,GAAG;AACjC,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,SAAO,CAAC,GAAG,IAAI,IAAI,gBAAgB,CAAC;AACtC;AAEO,SAAS,2BACd,cACA,oBACM;AACN,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,GAAG,YAAY,EAAE,OAAO,CAAC,WAAW,CAAC,mBAAmB,IAAI,MAAM,CAAC;AAE3F,MAAI,eAAe,WAAW,GAAG;AAC/B;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,GAAG,kBAAkB,EAAE,KAAK,kBAAkB;AAEtE,QAAM,IAAI;AAAA,IACR,8BAA8B,eAAe,KAAK,IAAI,CAAC,qBAAqB,eAAe,KAAK,IAAI,CAAC;AAAA,EACvG;AACF;AAEO,SAAS,mBAAmB,YAAoD;AACrF,MAAI,eAAe,QAAW;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,uBAAuB,WAAW,KAAK;AAE7C,MAAI,qBAAqB,WAAW,GAAG;AACrC,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,MAAI;AACF,UAAM,YAAY,IAAI,IAAI,oBAAoB;AAE9C,QAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,SAAS,UAAU,QAAQ,GAAG;AACrD,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AAAA,EACF,QAAQ;AACN,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,SAAO;AACT;AAEO,SAAS,qBAAqB,SAEnC;AACA,MAAI,QAAQ,OAAO;AACjB,sBAAkB,QAAQ,OAAO,SAAS;AAAA,EAC5C;AAEA,MAAI,QAAQ,OAAO;AACjB,sBAAkB,QAAQ,OAAO,SAAS;AAAA,EAC5C;AAEA,MAAI,QAAQ,SAAS,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,OAAO;AACnE,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,SAAO;AAAA,IACL,sBAAsB,mBAAmB,QAAQ,UAAU;AAAA,EAC7D;AACF;AAEA,SAAS,0BAA0B,kBAAqD;AACtF,QAAM,cAAc,oBAAI,IAAY;AAEpC,MAAI,CAAC,oBAAoB,iBAAiB,WAAW,GAAG;AACtD,WAAO;AAAA,EACT;AAEA,aAAW,SAAS,kBAAkB;AACpC,UAAM,iBAAiB,MAAM,QAAQ,GAAG;AAExC,QAAI,kBAAkB,GAAG;AACvB;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,cAAc,EAAE,KAAK,EAAE,YAAY;AAEnE,QAAI,SAAS,SAAS,GAAG;AACvB,kBAAY,IAAI,QAAQ;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,yBACd,SACA,cACa;AACb,QAAM,oBAAoB,oBAAI,IAAY;AAE1C,MAAI,cAAc;AAChB,eAAW,YAAY,cAAc;AACnC,wBAAkB,IAAI,QAAQ;AAAA,IAChC;AAAA,EACF;AAEA,aAAW,YAAY,0BAA0B,QAAQ,SAAS,GAAG;AACnE,sBAAkB,IAAI,QAAQ;AAAA,EAChC;AAEA,MAAI,QAAQ,OAAO;AACjB,sBAAkB,IAAI,IAAI;AAAA,EAC5B;AAEA,MAAI,QAAQ,UAAU;AACpB,sBAAkB,IAAI,OAAO;AAAA,EAC/B;AAEA,MAAI,QAAQ,WAAW;AACrB,sBAAkB,IAAI,QAAQ;AAAA,EAChC;AAEA,MAAI,QAAQ,UAAU;AACpB,sBAAkB,IAAI,OAAO;AAAA,EAC/B;AAEA,MAAI,QAAQ,YAAY;AACtB,sBAAkB,IAAI,UAAU;AAAA,EAClC;AAEA,SAAO;AACT;AAEA,SAAS,wBAAgC;AACvC,QAAM,mBAAmB,KAAK,eAAe,EAAE,gBAAgB,EAAE;AAEjE,MAAI,OAAO,qBAAqB,UAAU;AACxC,UAAM,0BAA0B,iBAAiB,KAAK;AAEtD,QAAI,wBAAwB,SAAS,GAAG;AACtC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,0BACd,SAC4B;AAC5B,QAAM,EAAE,qBAAqB,IAAI,qBAAqB,OAAO;AAE7D,QAAM,WACJ,QAAQ,aAAa,SAAY,QAAQ,SAAS,KAAK,IAAI,sBAAsB;AACnF,mBAAiB,QAAQ;AAEzB,QAAM,iBAAiB,wBAAwB,QAAQ,QAAQ;AAC/D,QAAM,eAAe,sBAAsB,QAAQ,MAAM;AACzD,QAAM,cAAc,qBAAqB,QAAQ,KAAK;AACtD,QAAM,oBAAoB,yBAAyB,SAAS,YAAY;AAExE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EACd;AACF;AAEO,SAAS,yBACd,UACA,cACiB;AACjB,QAAM,qBAAqB,IAAI,IAAI,SAAS,IAAI,CAAC,YAAY,QAAQ,GAAG,YAAY,CAAC,CAAC;AACtF,6BAA2B,cAAc,kBAAkB;AAE3D,SAAO,eACH,SAAS,OAAO,CAAC,YAAY,aAAa,IAAI,QAAQ,GAAG,YAAY,CAAC,CAAC,IACvE;AACN;;;ACnQA,SAAS,QAAAC,aAAY;;;ACGrB,SAAS,kBAAkB,OAAoC;AAC7D,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AACtE,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEO,SAAS,2BAA2B,OAA8C;AACvF,MAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,MAAM,QAAQ,CAAC,UAAU;AAC9B,UAAM,SAAS,SAAS,KAAK;AAE7B,QAAI,CAAC,QAAQ;AACX,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,OAAO,KAAK,IAAI;AAC1E,UAAM,QAAQ,kBAAkB,OAAO,KAAK;AAE5C,QAAI,CAAC,UAAU,UAAU,QAAW;AAClC,aAAO,CAAC;AAAA,IACV;AAEA,WAAO,CAAC,EAAE,QAAQ,MAAM,CAAC;AAAA,EAC3B,CAAC;AACH;;;AChCA,SAAS,SAAAC,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AAC3C,OAAOC,YAAU;AAWjB,IAAM,2BAA2B;AACjC,IAAM,sBAAsB;AA0B5B,SAAS,eAAe,QAAgB,UAA0B;AAChE,SAAO,GAAG,MAAM,GAAG,mBAAmB,GAAG,QAAQ;AACnD;AAEA,SAAS,qBAAqB,QAAwB;AACpD,SAAO,kBAAkB,MAAM,GAAG,YAAY,KAAK;AACrD;AAEA,SAAS,qBAAqB,OAAoC;AAChE,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACrE,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,SAASC,qBAAoB,OAAoC;AAC/D,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACrE,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,yBAAyB,OAAoC;AACpE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,KAAK;AAE9B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,KAAK,UAAU;AAErC,MAAI,OAAO,MAAM,UAAU,QAAQ,CAAC,GAAG;AACrC,WAAO;AAAA,EACT;AAEA,SAAO,UAAU,YAAY,MAAM,aAAa,aAAa;AAC/D;AAEA,SAAS,0BAA0B,OAAwC;AACzE,QAAM,SAAS,SAAS,KAAK;AAE7B,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,kBAAkB,OAAO,MAAM,GAAG,YAAY;AAC7D,QAAM,YAAY,OAAO,OAAO,cAAc,WAAW,OAAO,UAAU,KAAK,IAAI;AACnF,QAAM,YAAY,yBAAyB,OAAO,SAAS;AAC3D,QAAM,WAAW,OAAO,OAAO,aAAa,WAAW,OAAO,SAAS,KAAK,IAAI;AAEhF,MAAI,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,WACJ,OAAO,aAAa,cAAc,OAAO,aAAa,cAAc,OAAO,WAAW;AAExF,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,qBAAqB,OAAO,WAAW;AAC3D,QAAM,eAAe,qBAAqB,OAAO,YAAY;AAC7D,QAAM,kBAAkB,qBAAqB,OAAO,eAAe;AACnE,QAAM,kBAAkB,qBAAqB,OAAO,eAAe;AACnE,QAAM,mBAAmB,qBAAqB,OAAO,gBAAgB;AACrE,QAAM,cAAc,qBAAqB,OAAO,WAAW;AAE3D,MACE,gBAAgB,UAChB,iBAAiB,UACjB,oBAAoB,UACpB,oBAAoB,UACpB,qBAAqB,UACrB,gBAAgB,QAChB;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,OAAO,OAAO,aAAa,WAAW,OAAO,SAAS,KAAK,IAAI;AAChF,QAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,MAAM,KAAK,EAAE,YAAY,IAAI;AACrF,QAAM,UAAUA,qBAAoB,OAAO,OAAO;AAElD,MAAI,aAAa,cAAc,YAAY,QAAW;AACpD,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,YAAY;AAAA,IACtB,UAAU,YAAY;AAAA,IACtB,OAAO,SAAS;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,OAA+B;AACtD,SAAO,EAAE,GAAG,MAAM;AACpB;AAEA,SAAS,iBAAiB,QAAoC;AAC5D,SAAO,OAAO,IAAI,CAAC,UAAU,gBAAgB,KAAK,CAAC;AACrD;AAEA,SAAS,uBACP,mBAC8B;AAC9B,UAAQ,qBAAqB,CAAC,GAAG,IAAI,CAACC,WAAU,EAAE,QAAQA,MAAK,QAAQ,OAAOA,MAAK,MAAM,EAAE;AAC7F;AAEA,SAAS,sBAAsB,OAA0C;AACvE,MAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,mBAAiC,CAAC;AAExC,aAAW,SAAS,OAAO;AACzB,UAAM,kBAAkB,0BAA0B,KAAK;AAEvD,QAAI,CAAC,iBAAiB;AACpB,aAAO;AAAA,IACT;AAEA,qBAAiB,KAAK,eAAe;AAAA,EACvC;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAAiD;AAC5E,QAAM,SAAS,SAAS,KAAK;AAE7B,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,kBAAkB,OAAO,MAAM,GAAG,YAAY,KAAK;AAClE,QAAM,WAAW,OAAO,OAAO,aAAa,WAAW,OAAO,SAAS,KAAK,IAAI;AAChF,QAAM,WAAW,qBAAqB,OAAO,QAAQ;AACrD,QAAM,cAAc,SAAS,OAAO,WAAW;AAC/C,QAAM,cAAc,SAAS,OAAO,WAAW;AAC/C,QAAM,OAAO,qBAAqB,aAAa,IAAI;AACnD,QAAM,UAAUD,qBAAoB,aAAa,OAAO;AACxD,QAAM,cAAc,qBAAqB,aAAa,WAAW,KAAK;AACtE,QAAM,SAAS,sBAAsB,aAAa,MAAM;AAExD,MACE,CAAC,UACD,CAAC,YACD,SAAS,UACT,YAAY,UACZ,aAAa,QACb;AACA,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,aAAa,EAAE,MAAM,QAAQ;AAAA,IAC7B;AAAA,IACA,aAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA,mBAAmB,2BAA2B,aAAa,iBAAiB;AAAA,IAC9E;AAAA,EACF;AACF;AAEO,SAAS,+BAAuC;AACrD,SAAOE,OAAK,KAAK,oBAAoB,GAAG,qBAAqB,uBAAuB;AACtF;AAEO,IAAM,iBAAN,MAAM,gBAAe;AAAA,EAIlB,YACW,eACA,QACA,KACjB;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAPc,eAAe,oBAAI,IAAiC;AAAA,EAC7D,QAAQ;AAAA,EAQhB,aAAoB,KAAK,SAIG;AAC1B,UAAM,QAAQ,IAAI;AAAA,MAChB,QAAQ,iBAAiB,6BAA6B;AAAA,MACtD,QAAQ;AAAA,MACR,QAAQ,OAAO,KAAK;AAAA,IACtB;AACA,UAAM,MAAM,aAAa;AACzB,WAAO;AAAA,EACT;AAAA,EAEO,IACL,QACA,UACA,aACwC;AACxC,UAAM,mBAAmB,qBAAqB,MAAM;AACpD,UAAM,WAAW,eAAe,kBAAkB,QAAQ;AAC1D,UAAM,QAAQ,KAAK,aAAa,IAAI,QAAQ;AAE5C,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,WAAW,KAAK,OAAO,QAAQ,KAAK,IAAI,GAAG;AACnD,WAAK,aAAa,OAAO,QAAQ;AACjC,WAAK,QAAQ;AACb,aAAO;AAAA,IACT;AAEA,QACE,MAAM,YAAY,SAAS,YAAY,QACvC,MAAM,YAAY,YAAY,YAAY,SAC1C;AACA,WAAK,aAAa,OAAO,QAAQ;AACjC,WAAK,QAAQ;AACb,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,QAAQ,iBAAiB,MAAM,YAAY,MAAM;AAAA,MACjD,aAAa,MAAM,YAAY;AAAA,MAC/B,mBAAmB,uBAAuB,MAAM,YAAY,iBAAiB;AAAA,IAC/E;AAAA,EACF;AAAA,EAEO,IACL,QACA,UACA,aACA,aACM;AACN,UAAM,mBAAmB,qBAAqB,MAAM;AACpD,SAAK,aAAa,IAAI,eAAe,kBAAkB,QAAQ,GAAG;AAAA,MAChE,QAAQ;AAAA,MACR;AAAA,MACA,aAAa;AAAA,QACX,MAAM,YAAY;AAAA,QAClB,SAAS,YAAY;AAAA,MACvB;AAAA,MACA,UAAU,KAAK,IAAI;AAAA,MACnB,aAAa;AAAA,QACX,QAAQ,iBAAiB,YAAY,MAAM;AAAA,QAC3C,aAAa,YAAY;AAAA,QACzB,mBAAmB,uBAAuB,YAAY,iBAAiB;AAAA,MACzE;AAAA,IACF,CAAC;AACD,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAa,UAAyB;AACpC,QAAI,CAAC,KAAK,OAAO;AACf;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,GAAG,KAAK,aAAa,OAAO,CAAC,EACjD,OAAO,CAAC,UAAU,MAAM,WAAW,KAAK,OAAO,SAAS,KAAK,IAAI,CAAC,EAClE,KAAK,CAAC,MAAM,UAAU,MAAM,WAAW,KAAK,QAAQ;AAEvD,UAAM,cAAc,cAAc,MAAM,GAAG,KAAK,OAAO,UAAU;AACjE,QAAI,cAAc,KAAK,UAAU,KAAK,UAAU,WAAW,CAAC;AAE5D,QAAI,OAAO,WAAW,aAAa,MAAM,IAAI,KAAK,OAAO,UAAU;AACjE,UAAI,YAAY;AAChB,UAAI,kBAAkB,KAAK,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC;AACvD,UAAI,MAAM;AACV,UAAI,OAAO,YAAY;AAEvB,aAAO,OAAO,MAAM;AAClB,cAAM,MAAM,KAAK,OAAO,MAAM,QAAQ,CAAC;AACvC,cAAM,gBAAgB,KAAK,UAAU,KAAK,UAAU,YAAY,MAAM,GAAG,GAAG,CAAC,CAAC;AAE9E,YAAI,OAAO,WAAW,eAAe,MAAM,KAAK,KAAK,OAAO,UAAU;AACpE,sBAAY;AACZ,4BAAkB;AAClB,gBAAM,MAAM;AACZ;AAAA,QACF;AAEA,eAAO,MAAM;AAAA,MACf;AAEA,kBAAY,SAAS;AACrB,oBAAc;AAAA,IAChB;AAEA,UAAMC,OAAMD,OAAK,QAAQ,KAAK,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;AACjE,UAAME,WAAU,KAAK,eAAe,aAAa,MAAM;AACvD,SAAK,QAAQ;AAAA,EACf;AAAA,EAEQ,UAAU,SAAuD;AACvE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,QAC/B,QAAQ,MAAM;AAAA,QACd,UAAU,MAAM;AAAA,QAChB,aAAa,MAAM;AAAA,QACnB,UAAU,MAAM;AAAA,QAChB,aAAa;AAAA,UACX,QAAQ,MAAM,YAAY;AAAA,UAC1B,aAAa,MAAM,YAAY;AAAA,UAC/B,mBAAmB,uBAAuB,MAAM,YAAY,iBAAiB;AAAA,QAC/E;AAAA,MACF,EAAE;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAc,eAA8B;AAC1C,QAAI;AAEJ,QAAI;AACF,gBAAU,MAAMC,UAAS,KAAK,eAAe,MAAM;AAAA,IACrD,QAAQ;AACN;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI;AACF,sBAAgB,KAAK,MAAM,OAAO;AAAA,IACpC,QAAQ;AACN,WAAK,QAAQ;AACb;AAAA,IACF;AAEA,UAAM,gBAAgB,SAAS,aAAa;AAE5C,QAAI,CAAC,eAAe;AAClB,WAAK,QAAQ;AACb;AAAA,IACF;AAEA,UAAM,UAAU,qBAAqB,cAAc,OAAO;AAE1D,QAAI,YAAY,0BAA0B;AACxC,WAAK,QAAQ;AACb;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,SAAS,MAAM,IAAI,KAAK,OAAO,UAAU;AAC7D,WAAK,QAAQ;AAAA,IACf;AAEA,UAAM,UAAU,MAAM,QAAQ,cAAc,OAAO,IAAI,cAAc,UAAU,CAAC;AAEhF,eAAW,YAAY,SAAS;AAC9B,YAAM,kBAAkB,oBAAoB,QAAQ;AAEpD,UAAI,CAAC,iBAAiB;AACpB,aAAK,QAAQ;AACb;AAAA,MACF;AAEA,UAAI,gBAAgB,WAAW,KAAK,OAAO,QAAQ,KAAK,IAAI,GAAG;AAC7D,aAAK,QAAQ;AACb;AAAA,MACF;AAEA,WAAK,aAAa;AAAA,QAChB,eAAe,gBAAgB,QAAQ,gBAAgB,QAAQ;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,aAAa,OAAO,KAAK,OAAO,YAAY;AACnD,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AACF;;;AFzYA,SAAS,+BAA+B,QAAkD;AACxF,SAAO,EAAE,QAAQ,aAAa,GAAG,mBAAmB,CAAC,EAAE;AACzD;AAEA,SAAS,0BAA0B,OAAwB;AACzD,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACtC;AAEA,eAAsB,mBACpB,SACA,wBACA,gBAC6B;AAC7B,QAAM,QAAQ,MAAM,QAAQ,cAAc;AAE1C,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL,QAAQ,QAAQ;AAAA,MAChB,QAAQ,CAAC;AAAA,MACT,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,mBAAmB,CAAC;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,6BACJ,OAAO,SAAS,sBAAsB,KAAK,yBAAyB,IAChE,KAAK,IAAI,GAAG,KAAK,MAAM,sBAAsB,CAAC,IAC9C;AACN,QAAM,eAA+B,MAAM,KAAK,EAAE,QAAQ,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC;AAClF,QAAM,oBAA8B,MAAM,KAAK,EAAE,QAAQ,MAAM,OAAO,GAAG,MAAM,CAAC;AAChF,QAAM,oBAAoB,oBAAI,IAAoB;AAClD,QAAM,cAAc,KAAK,IAAI,4BAA4B,MAAM,MAAM;AACrE,MAAI,gBAAgB;AAEpB,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,YAAY;AAC9D,WAAO,gBAAgB,MAAM,QAAQ;AACnC,YAAM,YAAY;AAClB,uBAAiB;AAEjB,YAAM,WAAW,MAAM,SAAS;AAChC,UAAI;AAMJ,UAAI;AAEJ,UAAI,gBAAgB;AAClB,YAAI;AACF,gBAAM,WAAW,MAAMC,MAAK,QAAQ;AACpC,4BAAkB;AAAA,YAChB,MAAM,SAAS;AAAA,YACf,SAAS,SAAS;AAAA,UACpB;AACA,iCAAuB,eAAe,IAAI,QAAQ,IAAI,UAAU,eAAe;AAAA,QACjF,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,UAAI,CAAC,sBAAsB;AACzB,+BAAuB,QAAQ,2BAC3B,MAAM,QAAQ,yBAAyB,QAAQ,IAC/C,+BAA+B,MAAM,QAAQ,UAAU,QAAQ,CAAC;AACpE,YAAI,kBAAkB,iBAAiB;AACrC,yBAAe,IAAI,QAAQ,IAAI,UAAU,iBAAiB,oBAAoB;AAAA,QAChF;AAAA,MACF;AAEA,mBAAa,SAAS,IAAI,qBAAqB;AAC/C,wBAAkB,SAAS,IAAI,0BAA0B,qBAAqB,WAAW;AACzF,iBAAW,cAAc,2BAA2B,qBAAqB,iBAAiB,GAAG;AAC3F,0BAAkB;AAAA,UAChB,WAAW;AAAA,WACV,kBAAkB,IAAI,WAAW,MAAM,KAAK,KAAK,WAAW;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,IAAI,OAAO;AAEzB,SAAO;AAAA,IACL,QAAQ,QAAQ;AAAA,IAChB,QAAQ,aAAa,KAAK;AAAA,IAC1B,YAAY,MAAM;AAAA,IAClB,aAAa,kBAAkB,OAAO,CAAC,KAAK,qBAAqB,MAAM,kBAAkB,CAAC;AAAA,IAC1F,mBAAmB,CAAC,GAAG,kBAAkB,QAAQ,CAAC,EAC/C,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,QAAQ,MAAM,EAAE,EAC5C,KAAK,CAAC,MAAM,UAAU,mBAAmB,KAAK,QAAQ,MAAM,MAAM,CAAC;AAAA,EACxE;AACF;AAEA,SAAS,eAAe,OAAwB;AAC9C,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AAEA,SAAO,OAAO,KAAK;AACrB;AAEA,eAAsB,sBACpB,iBACA,wBACA,UAAwC,CAAC,GACV;AAC/B,QAAM,aAAa,QAAQ,YAAY,UACnC,MAAM,eAAe,KAAK;AAAA,IACxB,eAAe,QAAQ;AAAA,IACvB,QAAQ;AAAA,MACN,OAAO,QAAQ,WAAW;AAAA,MAC1B,YAAY,QAAQ,WAAW;AAAA,MAC/B,UAAU,QAAQ,WAAW;AAAA,IAC/B;AAAA,IACA,KAAK,QAAQ;AAAA,EACf,CAAC,IACD;AAEJ,QAAM,eAAe,MAAM,QAAQ;AAAA,IACjC,gBAAgB;AAAA,MAAI,CAAC,YACnB,mBAAmB,SAAS,wBAAwB,UAAU;AAAA,IAChE;AAAA,EACF;AAEA,MAAI,YAAY;AACd,QAAI;AACF,YAAM,WAAW,QAAQ;AAAA,IAC3B,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,iBAAuC,CAAC;AAC9C,QAAM,yBAA+C,CAAC;AAEtD,aAAW,CAAC,OAAO,WAAW,KAAK,aAAa,QAAQ,GAAG;AACzD,UAAM,SAAS,gBAAgB,KAAK,EAAE;AAEtC,QAAI,YAAY,WAAW,aAAa;AACtC,6BAAuB,KAAK,YAAY,KAAK;AAC7C;AAAA,IACF;AAEA,mBAAe,KAAK,EAAE,QAAQ,QAAQ,eAAe,YAAY,MAAM,EAAE,CAAC;AAAA,EAC5E;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,8BACd,gBACA,mBACM;AACN,QAAM,mBAAmB,eAAe;AAAA,IAAO,CAAC,YAC9C,kBAAkB,IAAI,QAAQ,OAAO,YAAY,CAAC;AAAA,EACpD;AAEA,MAAI,iBAAiB,WAAW,GAAG;AACjC;AAAA,EACF;AAEA,QAAM,UAAU,iBACb,IAAI,CAAC,YAAY,GAAG,QAAQ,MAAM,KAAK,QAAQ,MAAM,EAAE,EACvD,KAAK,IAAI;AAEZ,QAAM,IAAI,MAAM,mDAAmD,OAAO,EAAE;AAC9E;AAEA,SAAS,gBACP,UACA,gBACS;AACT,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAEA,SAAO,UAAU,YAAY,EAAE,SAAS,cAAc,KAAK;AAC7D;AAEA,SAAS,uBACP,OACA,UACA,OACA,OACS;AACT,QAAM,YAAY,aAAa,MAAM,WAAW,SAAS,QAAQ;AAEjE,MAAI,SAAS,YAAY,OAAO;AAC9B,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,YAAY,OAAO;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAOA,SAAS,wBACP,QACA,aAC+B;AAC/B,MAAI,CAAC,eAAe,YAAY,WAAW,GAAG;AAC5C,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,IAAI;AAAA,IAC1B,OACG,IAAI,CAAC,UAAU,MAAM,OAAO,YAAY,CAAC,EACzC,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC;AAAA,EACtD;AAEA,SAAO,YAAY,IAAI,CAAC,WAAW;AAAA,IACjC;AAAA,IACA,MAAM,gBAAgB,IAAI,KAAK,IAAI,UAAU;AAAA,EAC/C,EAAE;AACJ;AAEA,SAAS,aACP,OACA,YACS;AACT,MAAI,CAAC,cAAc,WAAW,WAAW,GAAG;AAC1C,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,MAAM,YAAY;AAE1C,SAAO,WAAW;AAAA,IAAK,CAAC,SACtB,KAAK,SAAS,UAAU,oBAAoB,KAAK,QAAQ,gBAAgB,SAAS,KAAK,KAAK;AAAA,EAC9F;AACF;AAUA,SAAS,mBAAmB,QAAsB,aAAiD;AACjG,QAAM,mBAAmB,wBAAwB,QAAQ,WAAW;AAEpE,SAAO,OAAO,OAAO,CAAC,UAAU,aAAa,MAAM,OAAO,gBAAgB,CAAC;AAC7E;AAuBO,SAAS,0BACd,cACA,SACc;AACd,QAAM,gCAA8C,CAAC;AAErD,aAAW,UAAU,cAAc;AACjC,eAAW,SAAS,OAAO,QAAQ;AACjC,UAAI,CAAC,gBAAgB,MAAM,UAAU,QAAQ,cAAc,GAAG;AAC5D;AAAA,MACF;AAEA,UAAI,CAAC,uBAAuB,OAAO,QAAQ,UAAU,QAAQ,OAAO,QAAQ,KAAK,GAAG;AAClF;AAAA,MACF;AAEA,oCAA8B,KAAK,KAAK;AAAA,IAC1C;AAAA,EACF;AAEA,SAAO,mBAAmB,+BAA+B,QAAQ,WAAW;AAC9E;;;AGzVA,IAAM,cAAc;AAEpB,SAAS,uBAAuB,QAAgB,UAAsC;AACpF,MAAI,CAAC,YAAY,UAAU,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,SAAQ,SAAS,cAAe;AAClC;AAEO,SAAS,0BAA0B,OAAmB,SAA+B;AAC1F,QAAM,mBAAmB,QAAQ,oBAAoB;AAErD,QAAM,YAAY,uBAAuB,MAAM,aAAa,QAAQ,aAAa;AACjF,QAAM,aAAa,uBAAuB,MAAM,cAAc,QAAQ,cAAc;AACpF,QAAM,gBAAgB,uBAAuB,MAAM,iBAAiB,QAAQ,iBAAiB;AAC7F,QAAM,iBAAiB,uBAAuB,MAAM,kBAAkB,QAAQ,kBAAkB;AAEhG,QAAM,gBACJ,qBAAqB,aACjB,uBAAuB,MAAM,iBAAiB,QAAQ,iBAAiB,IACvE;AAEN,SAAO,YAAY,aAAa,gBAAgB,iBAAiB;AACnE;AAEO,SAAS,oBAAoB,OAAmB,eAA0C;AAC/F,QAAM,4BACJ,MAAM,aAAa,cAAc,MAAM,YAAY,KAAK,MAAM,UAAU;AAE1E,MAAI,MAAM,aAAa,cAAc,MAAM,YAAY,UAAa,CAAC,2BAA2B;AAC9F,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,MAAM,OAAO;AAChB,WAAO,EAAE,GAAG,OAAO,UAAU,YAAY;AAAA,EAC3C;AAEA,QAAM,UAAU,cAAc,WAAW,MAAM,KAAK;AAEpD,MAAI,CAAC,SAAS;AACZ,QAAI,2BAA2B;AAC7B,aAAO;AAAA,IACT;AAEA,WAAO,EAAE,GAAG,OAAO,UAAU,YAAY;AAAA,EAC3C;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,0BAA0B,OAAO,OAAO;AAAA,IACjD,UAAU;AAAA,EACZ;AACF;AAEO,SAAS,qBACd,QACA,eACc;AACd,SAAO,OAAO,IAAI,CAAC,UAAU,oBAAoB,OAAO,aAAa,CAAC;AACxE;;;AC/DA,SAAS,SAAAC,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AAC3C,OAAOC,YAAU;;;ACDjB;AAAA,EACE,SAAW;AAAA,IACT,MAAQ;AAAA,IACR,aAAa;AAAA,IACb,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,wBAAwB;AAAA,IACxB,sBAAsB;AAAA,IAEtB,uBAAuB;AAAA,IAEvB,gBAAgB;AAAA,IAChB,8BAA8B;AAAA,IAC9B,4BAA4B;AAAA,IAC5B,iCAAiC;AAAA,IAEjC,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IAErB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,+BAA+B;AAAA,IAC/B,+BAA+B;AAAA,EACjC;AAAA,EACA,OAAS;AAAA,IACP,uBAAuB;AAAA,EACzB;AAAA,EACA,qCAAuC;AAAA,IACrC,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACF;;;AD9BA,IAAMC,eAAc;AACpB,IAAMC,wBAAuB,KAAK,KAAK,KAAK;AAC5C,IAAMC,4BAA2B;AACjC,IAAMC,6BAA4B;AAClC,IAAMC,gCAA+B;AAE9B,IAAM,8BACX;AAgCF,IAAM,6BAAN,cAAyC,MAAM;AAAA,EACtC,YAAY,SAAiB;AAClC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAASC,uBAAsB,QAAyB;AACtD,SAAO,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,EAAE,SAAS,MAAM;AAC5D;AAEA,SAASC,yBAAwB,OAAyB;AACxD,MAAI,iBAAiB,4BAA4B;AAC/C,WAAO;AAAA,EACT;AAEA,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,gBAAgB;AAChE,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,WAAW;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,wDAAwD,KAAK,MAAM,OAAO;AACnF;AAEA,eAAeC,OAAM,SAAgC;AACnD,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,eAAW,SAAS,OAAO;AAAA,EAC7B,CAAC;AACH;AAEA,SAAS,aAAa,OAAuB;AAC3C,SAAO,MAAM,KAAK,EAAE,YAAY;AAClC;AAEA,SAAS,qBAAqB,SAAkD;AAC9E,QAAM,wBAAwB,oBAAI,IAAoB;AACtD,QAAM,qCAAqC,oBAAI,IAAoB;AACnE,QAAM,sCAAsC,oBAAI,IAAoB;AAEpE,QAAM,gBAAgB,SAAS,QAAQ,OAAO;AAE9C,MAAI,eAAe;AACjB,eAAW,CAAC,OAAO,cAAc,KAAK,OAAO,QAAQ,aAAa,GAAG;AACnE,UAAI,OAAO,mBAAmB,UAAU;AACtC;AAAA,MACF;AAEA,YAAM,kBAAkB,aAAa,KAAK;AAC1C,YAAM,2BAA2B,aAAa,cAAc;AAE5D,4BAAsB,IAAI,iBAAiB,wBAAwB;AACnE,yCAAmC;AAAA,QACjC,qBAAqB,eAAe;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,yBAAyB,SAAS,QAAQ,mCAAmC;AAEnF,MAAI,wBAAwB;AAC1B,eAAW,CAAC,gBAAgB,mBAAmB,KAAK,OAAO,QAAQ,sBAAsB,GAAG;AAC1F,UAAI,OAAO,wBAAwB,UAAU;AAC3C;AAAA,MACF;AAEA,0CAAoC;AAAA,QAClC,aAAa,cAAc;AAAA,QAC3B,aAAa,mBAAmB;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,kBAAkB,qBAAqB,yBAAsB;AAEnE,SAASC,qBAAoB,OAAoC;AAC/D,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,MAAM,KAAK,MAAM,IAAI;AACvB,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,OAAO,KAAK;AAEhC,QAAI,CAAC,OAAO,SAAS,WAAW,KAAK,cAAc,GAAG;AACpD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,sBAAsB,iBAAoE;AACjG,QAAM,gBACJA,qBAAoB,gBAAgB,oBAAoB,KACxDA,qBAAoB,gBAAgB,6BAA6B;AACnE,QAAM,iBACJA,qBAAoB,gBAAgB,qBAAqB,KACzDA,qBAAoB,gBAAgB,8BAA8B;AAEpE,MAAI,kBAAkB,UAAa,mBAAmB,QAAW;AAC/D,WAAO;AAAA,EACT;AAEA,QAAM,oBACJA,qBAAoB,gBAAgB,2BAA2B,KAC/DA,qBAAoB,gBAAgB,oCAAoC;AAC1E,QAAM,qBAAqBA,qBAAoB,gBAAgB,+BAA+B;AAC9F,QAAM,oBAAoBA,qBAAoB,gBAAgB,+BAA+B;AAE7F,QAAM,eAA6B;AAAA,IACjC,eAAe,gBAAgBR;AAAA,IAC/B,gBAAgB,iBAAiBA;AAAA,EACnC;AAEA,MAAI,sBAAsB,QAAW;AACnC,iBAAa,oBAAoB,oBAAoBA;AAAA,EACvD;AAEA,MAAI,uBAAuB,QAAW;AACpC,iBAAa,qBAAqB,qBAAqBA;AAAA,EACzD;AAEA,MAAI,sBAAsB,QAAW;AACnC,iBAAa,oBAAoB,oBAAoBA;AACrD,iBAAa,mBAAmB;AAAA,EAClC;AAEA,SAAO;AACT;AAEA,SAAS,+BAA+B,SAA6C;AACnF,QAAM,gBAAgB,SAAS,OAAO;AAEtC,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,QAAM,oBAAoB,oBAAI,IAA0B;AAExD,aAAW,CAAC,WAAW,eAAe,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxE,UAAM,qBAAqB,SAAS,eAAe;AAEnD,QAAI,CAAC,oBAAoB;AACvB;AAAA,IACF;AAEA,UAAM,yBAAyB,sBAAsB,kBAAkB;AAEvE,QAAI,CAAC,wBAAwB;AAC3B;AAAA,IACF;AAEA,sBAAkB,IAAI,aAAa,SAAS,GAAG,sBAAsB;AAAA,EACvE;AAEA,MAAI,kBAAkB,SAAS,GAAG;AAChC,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC5F;AAEA,SAAO;AACT;AAEO,SAAS,oCAA4C;AAC1D,SAAOS,OAAK,KAAK,oBAAoB,GAAG,qBAAqB,4BAA4B;AAC3F;AAEA,SAAS,oBAAoB,OAAuB;AAClD,QAAM,aAAa,MAAM,YAAY,GAAG;AAExC,MAAI,eAAe,IAAI;AACrB,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,MAAM,aAAa,CAAC;AACnC;AAEA,SAAS,qBAAqB,OAAuB;AACnD,SAAO,MAAM,QAAQ,eAAe,EAAE;AACxC;AAEA,SAAS,mBAAmB,WAAmB,WAA4B;AACzE,MAAI,CAAC,UAAU,WAAW,SAAS,GAAG;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,WAAW,UAAU,QAAQ;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,UAAU,UAAU,MAAM;AAChD,SAAO,kBAAkB,OAAO,kBAAkB,OAAO,kBAAkB;AAC7E;AAEA,SAAS,qBAAqB,OAAyB;AACrD,SAAO,MAAM,MAAM,OAAO,KAAK,CAAC;AAClC;AAEA,SAAS,+BAA+B,MAAc,OAAwB;AAC5E,QAAM,aAAa,qBAAqB,IAAI;AAC5C,QAAM,cAAc,qBAAqB,KAAK;AAE9C,MAAI,WAAW,WAAW,KAAK,YAAY,WAAW,GAAG;AACvD,WAAO;AAAA,EACT;AAEA,MACE,WAAW,WAAW,YAAY,UAClC,WAAW,MAAM,CAAC,OAAO,UAAU,UAAU,YAAY,KAAK,CAAC,GAC/D;AACA,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,WAAW,KAAK,YAAY,SAAS,KAAK,YAAY,KAAK,EAAE,MAAM,WAAW,CAAC,GAAG;AAC/F,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,WAAW,KAAK,WAAW,SAAS,KAAK,WAAW,KAAK,EAAE,MAAM,YAAY,CAAC,GAAG;AAC/F,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAc,OAAuB;AAChE,QAAM,aAAa,KAAK;AACxB,QAAM,cAAc,MAAM;AAE1B,QAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,aAAa,EAAE,GAAG,CAAC,GAAG,aAAa;AACrE,WAAO,MAAM,KAAK,EAAE,QAAQ,cAAc,EAAE,GAAG,CAACC,IAAG,gBAAgB;AACjE,UAAI,aAAa,GAAG;AAClB,eAAO;AAAA,MACT;AAEA,UAAI,gBAAgB,GAAG;AACrB,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AAED,WAAS,WAAW,GAAG,YAAY,YAAY,YAAY,GAAG;AAC5D,aAAS,cAAc,GAAG,eAAe,aAAa,eAAe,GAAG;AACtE,YAAM,mBAAmB,KAAK,WAAW,CAAC,MAAM,MAAM,cAAc,CAAC,IAAI,IAAI;AAE7E,aAAO,QAAQ,EAAE,WAAW,IAAI,KAAK;AAAA,QACnC,OAAO,WAAW,CAAC,EAAE,WAAW,IAAI;AAAA,QACpC,OAAO,QAAQ,EAAE,cAAc,CAAC,IAAI;AAAA,QACpC,OAAO,WAAW,CAAC,EAAE,cAAc,CAAC,IAAI;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,UAAU,EAAE,WAAW;AACvC;AAEO,IAAM,wBAAN,MAAqD;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,iBAAiB,oBAAI,IAA0B;AAAA,EAC/C,qBAAqB,oBAAI,IAAoB;AAAA,EAE9C,YAAY,UAAwC,CAAC,GAAG;AAC7D,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,gBAAgB,QAAQ,iBAAiB,kCAAkC;AAChF,SAAK,aAAa,QAAQ,cAAcT;AACxC,SAAK,iBAAiB,QAAQ,kBAAkBC;AAChD,SAAK,kBACH,OAAO,SAAS,QAAQ,eAAe,MAAM,QAAQ,mBAAmB,MAAM,IAC1E,KAAK,MAAM,QAAQ,mBAAmBC,0BAAyB,IAC/DA;AACN,SAAK,oBACH,OAAO,SAAS,QAAQ,iBAAiB,MAAM,QAAQ,qBAAqB,KAAK,IAC7E,KAAK,MAAM,QAAQ,qBAAqBC,6BAA4B,IACpEA;AACN,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,MAAM,QAAQ,OAAO,KAAK;AAC/B,SAAK,QAAQ,QAAQ,SAASG;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,OAAyB;AACpC,UAAM,cAAc,MAAM,KAAK,cAAc,EAAE,YAAY,MAAM,CAAC;AAElE,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,SAAS;AAChB,YAAM,mBAAmB,MAAM,KAAK,cAAc,EAAE,YAAY,KAAK,CAAC;AAEtE,UAAI,CAAC,kBAAkB;AACrB,cAAM,IAAI,MAAM,yEAAyE;AAAA,MAC3F;AAEA,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,KAAK,eAAe;AAC1B,aAAO;AAAA,IACT,QAAQ;AACN,YAAM,mBAAmB,MAAM,KAAK,cAAc,EAAE,YAAY,KAAK,CAAC;AAEtE,UAAI,CAAC,kBAAkB;AACrB,cAAM,IAAI,MAAM,sDAAsD;AAAA,MACxE;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEO,kBAAkB,OAAuB;AAC9C,UAAM,kBAAkB,aAAa,KAAK;AAC1C,UAAM,cAAc,KAAK,mBAAmB,IAAI,eAAe;AAE/D,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,KAAK,wBAAwB,eAAe;AAEhE,QAAI,aAAa;AACf,WAAK,mBAAmB,IAAI,iBAAiB,WAAW;AACxD,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,KAAK,wBAAwB,eAAe;AAEhE,QAAI,aAAa;AACf,WAAK,mBAAmB,IAAI,iBAAiB,WAAW;AACxD,aAAO;AAAA,IACT;AAEA,UAAM,wBAAwB,KAAK,kCAAkC,eAAe;AAEpF,QAAI,uBAAuB;AACzB,WAAK,mBAAmB,IAAI,iBAAiB,qBAAqB;AAClE,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,KAAK,wBAAwB,eAAe;AAEhE,QAAI,aAAa;AACf,WAAK,mBAAmB,IAAI,iBAAiB,WAAW;AACxD,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,KAAK,uBAAuB,eAAe;AAC9D,UAAM,gBAAgB,cAAc;AACpC,SAAK,mBAAmB,IAAI,iBAAiB,aAAa;AAE1D,WAAO;AAAA,EACT;AAAA,EAEO,WAAW,OAAyC;AACzD,UAAM,gBAAgB,KAAK,kBAAkB,KAAK;AAClD,WAAO,KAAK,eAAe,IAAI,aAAa;AAAA,EAC9C;AAAA,EAEQ,wBAAwB,iBAA6C;AAC3E,UAAM,iBAAiB,KAAK,0BAA0B,eAAe;AAErE,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,IACT;AAEA,UAAM,sBACJ,gBAAgB,oCAAoC,IAAI,cAAc;AAExE,QAAI,uBAAuB,KAAK,eAAe,IAAI,mBAAmB,GAAG;AACvE,aAAO;AAAA,IACT;AAEA,UAAM,uBAAuB,KAAK,wBAAwB,cAAc;AAExE,QAAI,sBAAsB;AACxB,aAAO;AAAA,IACT;AAEA,UAAM,iCAAiC,KAAK,kCAAkC,cAAc;AAE5F,QAAI,gCAAgC;AAClC,aAAO;AAAA,IACT;AAEA,UAAM,uBAAuB,KAAK,wBAAwB,cAAc;AAExE,QAAI,sBAAsB;AACxB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,uBAAuB,cAAc;AAAA,EACnD;AAAA,EAEQ,0BAA0B,iBAA6C;AAC7E,UAAM,gBAAgB,oBAAoB,eAAe;AAEzD,UAAM,uBACJ,gBAAgB,sBAAsB,IAAI,eAAe,KACzD,gBAAgB,sBAAsB,IAAI,aAAa;AAEzD,QAAI,sBAAsB;AACxB,aAAO;AAAA,IACT;AAEA,UAAM,qBAAqB,qBAAqB,eAAe;AAC/D,UAAM,6BAA6B,qBAAqB,aAAa;AAErE,WACE,gBAAgB,mCAAmC,IAAI,kBAAkB,KACzE,gBAAgB,mCAAmC,IAAI,0BAA0B;AAAA,EAErF;AAAA,EAEQ,wBAAwB,iBAA6C;AAC3E,QAAI,KAAK,eAAe,IAAI,eAAe,GAAG;AAC5C,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,oBAAoB,eAAe;AAEzD,QAAI,KAAK,eAAe,IAAI,aAAa,GAAG;AAC1C,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,kCAAkC,iBAA6C;AACrF,UAAM,aAAa,CAAC,iBAAiB,oBAAoB,eAAe,CAAC;AAEzE,eAAW,aAAa,YAAY;AAClC,UAAI;AAEJ,iBAAW,aAAa,KAAK,eAAe,KAAK,GAAG;AAClD,cAAM,0BACJ,UAAU,SAAS,IAAI,SAAS,EAAE,KAAK,UAAU,SAAS,IAAI,SAAS,EAAE;AAE3E,YAAI,CAAC,yBAAyB;AAC5B;AAAA,QACF;AAEA,YACE,CAAC,aACD,UAAU,SAAS,UAAU,UAC5B,UAAU,WAAW,UAAU,UAAU,mBAAmB,WAAW,SAAS,IAAI,GACrF;AACA,sBAAY;AAAA,QACd;AAAA,MACF;AAEA,UAAI,WAAW;AACb,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,iBAA6C;AAC3E,UAAM,aAAa,CAAC,iBAAiB,oBAAoB,eAAe,CAAC;AAEzE,eAAW,aAAa,YAAY;AAClC,UAAI;AAEJ,iBAAW,aAAa,KAAK,eAAe,KAAK,GAAG;AAClD,YAAI,CAAC,mBAAmB,WAAW,SAAS,GAAG;AAC7C;AAAA,QACF;AAEA,YACE,CAAC,aACD,UAAU,SAAS,UAAU,UAC5B,UAAU,WAAW,UAAU,UAAU,mBAAmB,WAAW,SAAS,IAAI,GACrF;AACA,sBAAY;AAAA,QACd;AAAA,MACF;AAEA,UAAI,WAAW;AACb,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB,iBAA6C;AAC1E,UAAM,gBAAgB,oBAAoB,eAAe;AACzD,UAAM,cAAc,qBAAqB,aAAa;AAEtD,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AAEA,QAAI;AAEJ,eAAW,aAAa,KAAK,eAAe,KAAK,GAAG;AAClD,UAAI,CAAC,+BAA+B,eAAe,SAAS,GAAG;AAC7D;AAAA,MACF;AAEA,YAAM,iBAAiB,qBAAqB,SAAS;AAErD,UAAI,CAAC,gBAAgB;AACnB;AAAA,MACF;AAEA,YAAM,WAAW,oBAAoB,aAAa,cAAc;AAEhE,UAAI,CAAC,aAAa,WAAW,UAAU,UAAU;AAC/C,oBAAY,EAAE,WAAW,SAAS;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,SAAS,GAAG,CAAC;AAEpE,QAAI,UAAU,WAAW,aAAa;AACpC,aAAO;AAAA,IACT;AAEA,WAAO,UAAU;AAAA,EACnB;AAAA,EAEA,MAAc,6BAAgD;AAC5D,UAAM,WAAW,MAAM,KAAK,UAAU,KAAK,WAAW;AAAA,MACpD,QAAQ,YAAY,QAAQ,KAAK,cAAc;AAAA,IACjD,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,UAAIF,uBAAsB,SAAS,MAAM,GAAG;AAC1C,cAAM,IAAI;AAAA,UACR,mDAAmD,SAAS,MAAM;AAAA,QACpE;AAAA,MACF;AAEA,YAAM,IAAI,MAAM,yCAAyC,SAAS,MAAM,EAAE;AAAA,IAC5E;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,sCAAyD;AACrE,UAAM,cAAc,KAAK,kBAAkB;AAE3C,aAAS,eAAe,GAAG,eAAe,aAAa,gBAAgB,GAAG;AACxE,UAAI;AACF,eAAO,MAAM,KAAK,2BAA2B;AAAA,MAC/C,SAAS,OAAO;AACd,cAAM,cAAcC,yBAAwB,KAAK,KAAK,eAAe,cAAc;AAEnF,YAAI,CAAC,aAAa;AAChB,gBAAM;AAAA,QACR;AAAA,MACF;AAEA,YAAM,eAAe,KAAK,oBAAoB,KAAK;AACnD,YAAM,KAAK,MAAM,YAAY;AAAA,IAC/B;AAEA,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAAA,EAEA,MAAc,iBAAgC;AAC5C,UAAM,WAAW,MAAM,KAAK,oCAAoC;AAChE,UAAM,UAAW,MAAM,SAAS,KAAK;AACrC,UAAM,oBAAoB,+BAA+B,OAAO;AAEhE,SAAK,iBAAiB;AACtB,SAAK,mBAAmB,MAAM;AAE9B,QAAI;AACF,YAAM,KAAK,WAAW;AAAA,IACxB,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,SAAoD;AAC9E,UAAM,mBAAmB,MAAM,KAAK,iBAAiB;AAErD,QAAI,CAAC,kBAAkB;AACrB,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,cAAc,KAAK,WAAW;AACjD,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,KAAK,IAAI;AAC9B,UAAM,UACJ,iBAAiB,YAAY,gBAC7B,eAAe,iBAAiB,YAAY,KAAK;AAEnD,QAAI,WAAW,CAAC,QAAQ,YAAY;AAClC,aAAO;AAAA,IACT;AAEA,SAAK,iBAAiB,IAAI;AAAA,MACxB,OAAO,QAAQ,iBAAiB,cAAc,EAAE,IAAI,CAAC,CAAC,WAAW,OAAO,MAAM;AAAA,QAC5E,aAAa,SAAS;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH;AACA,SAAK,mBAAmB,MAAM;AAE9B,WAAO,KAAK,eAAe,OAAO;AAAA,EACpC;AAAA,EAEQ,uBAAuB,YAA+C;AAC5E,UAAM,gBAAgB,SAAS,UAAU;AAEzC,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgBE,qBAAoB,cAAc,aAAa;AACrE,UAAM,iBAAiBA,qBAAoB,cAAc,cAAc;AAEvE,QAAI,kBAAkB,UAAa,mBAAmB,QAAW;AAC/D,aAAO;AAAA,IACT;AAEA,UAAM,eAA6B;AAAA,MACjC;AAAA,MACA;AAAA,IACF;AAEA,UAAM,oBAAoBA,qBAAoB,cAAc,iBAAiB;AAE7E,QAAI,sBAAsB,QAAW;AACnC,mBAAa,oBAAoB;AAAA,IACnC;AAEA,UAAM,qBAAqBA,qBAAoB,cAAc,kBAAkB;AAE/E,QAAI,uBAAuB,QAAW;AACpC,mBAAa,qBAAqB;AAAA,IACpC;AAEA,UAAM,oBAAoBA,qBAAoB,cAAc,iBAAiB;AAE7E,QAAI,sBAAsB,QAAW;AACnC,mBAAa,oBAAoB;AACjC,mBAAa,mBAAmB;AAAA,IAClC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,mBAA6D;AACzE,QAAI;AAEJ,QAAI;AACF,gBAAU,MAAMG,UAAS,KAAK,eAAe,MAAM;AAAA,IACrD,QAAQ;AACN,aAAO;AAAA,IACT;AAEA,QAAI;AAEJ,QAAI;AACF,sBAAgB,KAAK,MAAM,OAAO;AAAA,IACpC,QAAQ;AACN,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,SAAS,aAAa;AAE5C,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,YAAYH,qBAAoB,cAAc,SAAS;AAC7D,UAAM,YACJ,OAAO,cAAc,cAAc,WAAW,cAAc,YAAY;AAC1E,UAAM,uBAAuB,SAAS,cAAc,cAAc;AAElE,QAAI,cAAc,UAAa,CAAC,aAAa,CAAC,sBAAsB;AAClE,aAAO;AAAA,IACT;AAEA,UAAM,iBAA+C,CAAC;AAEtD,eAAW,CAAC,WAAW,UAAU,KAAK,OAAO,QAAQ,oBAAoB,GAAG;AAC1E,YAAM,UAAU,KAAK,uBAAuB,UAAU;AAEtD,UAAI,CAAC,SAAS;AACZ;AAAA,MACF;AAEA,qBAAe,SAAS,IAAI;AAAA,IAC9B;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,aAA4B;AACxC,UAAM,gBAAgBC,OAAK,QAAQ,KAAK,aAAa;AACrD,UAAMG,OAAM,eAAe,EAAE,WAAW,KAAK,CAAC;AAE9C,UAAM,UAA+B;AAAA,MACnC,WAAW,KAAK,IAAI;AAAA,MACpB,WAAW,KAAK;AAAA,MAChB,gBAAgB,OAAO,YAAY,KAAK,eAAe,QAAQ,CAAC;AAAA,IAClE;AAEA,UAAMC,WAAU,KAAK,eAAe,KAAK,UAAU,OAAO,GAAG,MAAM;AAAA,EACrE;AACF;;;AErxBA,eAAsB,qBACpB,SACA,eAC4B;AAC5B,QAAM,wBAAwB,IAAI,sBAAsB;AAAA,IACtD,WAAW,QAAQ;AAAA,IACnB,SAAS,QAAQ;AAAA,IACjB,YAAY,cAAc;AAAA,IAC1B,gBAAgB,cAAc;AAAA,EAChC,CAAC;AAED,MAAI;AACF,UAAM,YAAY,MAAM,sBAAsB,KAAK;AAEnD,QAAI,QAAQ,gBAAgB;AAC1B,aAAO,EAAE,QAAQ,uBAAuB,QAAQ,gBAAgB;AAAA,IAClE;AAEA,WAAO,EAAE,QAAQ,uBAAuB,QAAQ,YAAY,UAAU,UAAU;AAAA,EAClF,SAAS,OAAO;AACd,QAAI,QAAQ,gBAAgB;AAC1B,YAAM,IAAI,MAAM,kEAAkE;AAAA,QAChF,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAEpE,QAAI,QAAQ,YAAY;AACtB,YAAM,IAAI,MAAM,8CAA8C,MAAM,IAAI;AAAA,QACtE,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,IAAI,MAAM,mCAAmC,MAAM,IAAI,EAAE,OAAO,MAAM,CAAC;AAAA,EAC/E;AACF;AAEO,SAAS,wBAAwB,OAA4B;AAClE,MAAI,CAAC,MAAM,OAAO;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,eAAe,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,aAAa,cAAc,MAAM,YAAY,UAAa,MAAM,YAAY;AAC3F;AAEO,SAAS,wBAAwB,QAA+B;AACrE,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,KAAK,CAAC,UAAU,wBAAwB,KAAK,CAAC;AAC9D;AAOA,eAAsB,+BACpB,QACA,SACA,gBAA6C,+BAA+B,GAC5E,oBAA2C,sBAK1C;AACD,MAAI,gBAAoC;AAExC,MAAI,CAAC,wBAAwB,MAAM,GAAG;AACpC,WAAO;AAAA,MACL,cAAc;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AAEJ,MAAI;AACF,oBAAgB,MAAM,kBAAkB,SAAS,aAAa;AAAA,EAChE,SAAS,OAAO;AACd,QAAI,CAAC,QAAQ,uBAAuB;AAClC,YAAM;AAAA,IACR;AAEA,UAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACpE,UAAM,iBAAiB,OAAO,KAAK,EAAE,WAAW,gBAAgB,IAC5D,SACA,+DAA+D,MAAM;AAEzE,WAAO;AAAA,MACL,cAAc;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,kBAAgB,cAAc;AAE9B,SAAO;AAAA,IACL,cAAc,qBAAqB,QAAQ,cAAc,MAAM;AAAA,IAC/D;AAAA,EACF;AACF;;;AClGA,SAAS,yBACP,SACA,sBACsB;AACtB,MAAI,QAAQ,eAAe,sBAAsB;AAC/C,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,YAAY;AAAA,EACd;AACF;AAEA,eAAsB,eACpB,aACA,SACA,OAA2B,CAAC,GACF;AAC1B,QAAM,mBAAmB,0BAA0B,OAAO;AAE1D,QAAM,2BAA2B,KAAK,2BAA2B;AACjE,QAAM,2BACJ,KAAK,kCAAkC;AACzC,QAAM,eAAe,KAAK,kBAAkB;AAC5C,QAAM,oBAAoB,KAAK,wBAAwB;AACvD,QAAM,sBAAsB,KAAK,4BAA4B;AAE7D,QAAM,uBAAuB,yBAAyB;AACtD,QAAM,uBAAuB,yBAAyB;AACtD,QAAM,WAAW,aAAa,OAAO;AACrC,QAAM,kBAAkB,yBAAyB,UAAU,iBAAiB,YAAY;AAExF,QAAM,EAAE,wBAAwB,eAAe,IAAI,MAAM;AAAA,IACvD;AAAA,IACA,qBAAqB;AAAA,IACrB;AAAA,MACE,YAAY;AAAA,QACV,SAAS,qBAAqB;AAAA,QAC9B,OAAO,qBAAqB;AAAA,QAC5B,YAAY,qBAAqB;AAAA,QACjC,UAAU,qBAAqB;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,gCAA8B,gBAAgB,iBAAiB,iBAAiB;AAEhF,QAAM,iBAAiB,0BAA0B,wBAAwB;AAAA,IACvE,UAAU,iBAAiB;AAAA,IAC3B,OAAO,QAAQ;AAAA,IACf,OAAO,QAAQ;AAAA,IACf,gBAAgB,iBAAiB;AAAA,IACjC,aAAa,iBAAiB;AAAA,EAChC,CAAC;AAED,QAAM,iBAAiB,yBAAyB,SAAS,iBAAiB,UAAU;AAEpF,QAAM,EAAE,cAAc,eAAe,eAAe,IAAI,MAAM;AAAA,IAC5D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,OAAO,eAAe,cAAc;AAAA,IACxC;AAAA,IACA,UAAU,iBAAiB;AAAA,IAC3B,aAAa,gBAAgB,IAAI,CAAC,YAAY,QAAQ,EAAE;AAAA,EAC1D,CAAC;AAED,QAAM,cAAc,sBAAsB;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB,oBAAoB;AAAA,IACxC,UAAU,iBAAiB;AAAA,EAC7B,CAAC;AAED,SAAO,wBAAwB,cAAc,MAAM,WAAW;AAChE;;;ACxFA,SAAS,wBAAwB,OAA+C;AAC9E,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAEpD,SAAO,OAAO;AAAA,IAAK,CAAC,UAClB,MACG,MAAM,GAAG,EACT,IAAI,CAAC,cAAc,UAAU,KAAK,CAAC,EACnC,KAAK,CAAC,cAAc,UAAU,SAAS,CAAC;AAAA,EAC7C;AACF;AAEA,SAAS,wBAAwB,UAAuC;AACtE,SAAO,QAAQ,UAAU,KAAK,CAAC;AACjC;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,SAAO,QAAQ,OAAO,KAAK,CAAC;AAC9B;AAEA,SAAS,iBAAiB,SAAuD;AAC/E,QAAM,gBAA0B,CAAC;AAEjC,MAAI,oBAAoB,QAAQ,KAAK,GAAG;AACtC,kBAAc,KAAK,UAAU;AAAA,EAC/B;AAEA,MAAI,oBAAoB,QAAQ,QAAQ,GAAG;AACzC,kBAAc,KAAK,aAAa;AAAA,EAClC;AAEA,MAAI,oBAAoB,QAAQ,SAAS,GAAG;AAC1C,kBAAc,KAAK,cAAc;AAAA,EACnC;AAEA,MAAI,oBAAoB,QAAQ,QAAQ,GAAG;AACzC,kBAAc,KAAK,aAAa;AAAA,EAClC;AAEA,MAAI,oBAAoB,QAAQ,UAAU,GAAG;AAC3C,kBAAc,KAAK,eAAe;AAAA,EACpC;AAEA,MAAI,wBAAwB,QAAQ,SAAS,GAAG;AAC9C,kBAAc,KAAK,cAAc;AAAA,EACnC;AAEA,MAAI,wBAAwB,QAAQ,MAAM,GAAG;AAC3C,kBAAc,KAAK,UAAU;AAAA,EAC/B;AAEA,MAAI,wBAAwB,QAAQ,QAAQ,GAAG;AAC7C,kBAAc,KAAK,YAAY;AAAA,EACjC;AAEA,MAAI,wBAAwB,QAAQ,KAAK,GAAG;AAC1C,kBAAc,KAAK,SAAS;AAAA,EAC9B;AAEA,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,kBAAkB,cAAc,KAAK,IAAI,CAAC;AACnD;AAEA,SAAS,mCAAmC,OAA4B;AACtE,SAAO,MAAM,cAAc,KAAM,MAAM,YAAY,UAAa,MAAM,UAAU;AAClF;AAEA,eAAsB,oBACpB,aACA,SACA,OAAgC,CAAC,GACF;AAC/B,QAAM,aAAa,KAAK,kBAAkB;AAC1C,QAAM,kBAAkB,KAAK,sBAAsB;AACnD,QAAMC,mBAAkB,KAAK,mBAAmB;AAChD,QAAM,UAAU,QAAQ,SAAS,KAAK;AAEtC,MAAI,QAAQ,YAAY,UAAa,CAAC,SAAS;AAC7C,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AAEA,QAAM,YAAY,MAAM,WAAW,aAAa,OAAO;AACvD,QAAM,cAAc,MAAM;AAAA,IACxB,UAAU;AAAA,IACV,WAAW,QAAQ,IAAI;AAAA,IACvBA;AAAA,EACF;AACA,QAAM,0BAA0B,YAAY,cAAc;AAAA,IAAO,CAAC,UAChE,mCAAmC,KAAK;AAAA,EAC1C;AACA,QAAM,kBAAkB,IAAI;AAAA,IAC1B,wBAAwB;AAAA,MAAI,CAAC,UAC3B,aAAa,MAAM,WAAW,SAAS,UAAU,YAAY,QAAQ;AAAA,IACvE;AAAA,EACF;AACA,QAAM,cAAc,MAAM,gBAAgB;AAAA,IACxC;AAAA,IACA;AAAA,IACA,UAAU,UAAU,YAAY;AAAA,IAChC,OAAO,QAAQ;AAAA,IACf,OAAO,QAAQ;AAAA,IACf,qBAAqB,QAAQ;AAAA,IAC7B;AAAA,EACF,CAAC;AACD,QAAM,sBAAsB,eAAe,yBAAyB;AAAA,IAClE;AAAA,IACA,UAAU,UAAU,YAAY;AAAA,EAClC,CAAC;AAED,QAAM,OAAO,oBAAoB;AAAA,IAC/B,WAAW;AAAA,IACX,gBAAgB,YAAY;AAAA,EAC9B,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,aAAa;AAAA,MACX,OAAO,UAAU;AAAA,MACjB,SAAS,YAAY,YAAY;AAAA,MACjC,qBAAqB,YAAY,YAAY;AAAA,MAC7C,gBAAgB,YAAY,YAAY;AAAA,MACxC,eAAe,YAAY,YAAY;AAAA,MACvC,iBAAiB,YAAY,YAAY;AAAA,MACzC,wBAAwB,YAAY;AAAA,MACpC,yBAAyB,YAAY;AAAA,MACrC,6BAA6B,YAAY;AAAA,MACzC,WAAW,iBAAiB,OAAO;AAAA,IACrC;AAAA,EACF;AACF;;;AC1JA,OAAO,QAAQ;AAIf,IAAM,QAAkC;AAAA,EACtC,MAAM,GAAG,KAAK,QAAG;AAAA,EACjB,MAAM,GAAG,OAAO,QAAG;AAAA,EACnB,KAAK,GAAG,KAAK,QAAG;AAClB;AAEA,SAAS,cAAc,OAAiB,SAAyB;AAC/D,QAAM,OAAO,MAAM,KAAK;AACxB,SAAO,GAAG,IAAI,IAAI,OAAO;AAC3B;AAEO,IAAM,SAAS;AAAA,EACpB,MAAM,CAAC,YAA0B;AAC/B,YAAQ,MAAM,cAAc,QAAQ,OAAO,CAAC;AAAA,EAC9C;AAAA,EACA,MAAM,CAAC,YAA0B;AAC/B,YAAQ,MAAM,cAAc,QAAQ,OAAO,CAAC;AAAA,EAC9C;AAAA,EACA,KAAK,CAAC,YAA0B;AAC9B,YAAQ,MAAM,cAAc,OAAO,OAAO,CAAC;AAAA,EAC7C;AACF;;;ACpBO,SAAS,gBACd,aACA,oBAAuC,QACjC;AACN,QAAM,gBAAgB,YAAY,aAAa;AAAA,IAC7C,CAAC,KAAK,YAAY,MAAM,QAAQ;AAAA,IAChC;AAAA,EACF;AACA,QAAM,cAAc,YAAY,aAAa;AAAA,IAC3C,CAAC,KAAK,YAAY,MAAM,QAAQ;AAAA,IAChC;AAAA,EACF;AAEA,MAAI,gBAAgB,GAAG;AACrB,sBAAkB,KAAK,SAAS,aAAa,yBAAyB,WAAW,WAAW;AAE5F,eAAW,WAAW,YAAY,cAAc;AAC9C,YAAM,cAAc,QAAQ,iBAAiB,IAAI,UAAU;AAC3D,wBAAkB;AAAA,QAChB,KAAK,QAAQ,MAAM,KAAK,QAAQ,UAAU,aAAa,QAAQ,YAAY,IAAI,WAAW;AAAA,MAC5F;AAAA,IACF;AAAA,EACF,OAAO;AACL,sBAAkB,KAAK,mBAAmB;AAAA,EAC5C;AAEA,MAAI,YAAY,eAAe,SAAS,GAAG;AACzC,UAAM,cAAc,YAAY,eAAe,WAAW,IAAI,WAAW;AACzE,sBAAkB,KAAK,mBAAmB,YAAY,eAAe,MAAM,IAAI,WAAW,EAAE;AAE5F,eAAW,WAAW,YAAY,gBAAgB;AAChD,wBAAkB,IAAI,KAAK,QAAQ,MAAM,KAAK,QAAQ,MAAM,EAAE;AAAA,IAChE;AAAA,EACF;AAEA,QAAM,mBAAmB,YAAY,YAAY;AAAA,IAC/C,CAAC,KAAK,qBAAqB,MAAM,iBAAiB;AAAA,IAClD;AAAA,EACF;AAEA,MAAI,mBAAmB,GAAG;AACxB,UAAM,WAAW,qBAAqB,IAAI,QAAQ;AAClD,sBAAkB,KAAK,WAAW,gBAAgB,cAAc,QAAQ,EAAE;AAE1E,eAAW,oBAAoB,YAAY,aAAa;AACtD,YAAM,gBAAgB,iBAAiB,SACnC,OAAO,CAAC,eAAe,WAAW,QAAQ,CAAC,EAC5C,IAAI,CAAC,eAAe,GAAG,WAAW,MAAM,KAAK,WAAW,KAAK,EAAE,EAC/D,KAAK,IAAI;AAEZ,wBAAkB;AAAA,QAChB,gBACI,KAAK,iBAAiB,MAAM,KAAK,iBAAiB,WAAW,aAAa,aAAa,MACvF,KAAK,iBAAiB,MAAM,KAAK,iBAAiB,WAAW;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,YAAY,eAAe;AAAA,IACjC,KAAK;AACH,wBAAkB,KAAK,qCAAqC;AAC5D;AAAA,IACF,KAAK;AACH,wBAAkB,KAAK,2BAA2B;AAClD;AAAA,IACF,KAAK;AACH,wBAAkB,KAAK,8BAA8B;AACrD;AAAA,IACF,KAAK;AACH;AAAA,EACJ;AAEA,MAAI,YAAY,gBAAgB;AAC9B,sBAAkB,KAAK,YAAY,cAAc;AAAA,EACnD;AACF;;;ACzEO,SAAS,oBACd,oBACA,mBACM;AACN,QAAM,sBAAsB,sBAAsB,kBAAkB;AAEpE,MAAI,oBAAoB,WAAW,GAAG;AACpC;AAAA,EACF;AAEA,QAAM,CAAC,YAAY,GAAG,WAAW,IAAI;AAErC,MAAI,YAAY;AACd,sBAAkB,KAAK,UAAU;AAAA,EACnC;AAEA,aAAW,cAAc,aAAa;AACpC,sBAAkB,IAAI,UAAU;AAAA,EAClC;AACF;;;AC1BA,IAAM,oBAAoB,IAAI,OAAO,OAAO,uBAAuB,IAAI;AACvE,IAAM,uBAAuB;AAC7B,IAAM,8BAA8B;AACpC,IAAM,2BAA2B;AACjC,IAAM,2BAA2B;AACjC,IAAM,oBAAoB,IAAI,KAAK,UAAU,MAAM,EAAE,aAAa,WAAW,CAAC;AAO9E,SAAS,oBAAoB,OAAuB;AAClD,SAAO,MAAM,QAAQ,WAAW,IAAI;AACtC;AAEO,SAAS,kBAAkB,QAAmD;AACnF,MAAI,OAAO,UAAU,MAAM;AACzB,WAAO;AAAA,EACT;AAEA,MACE,OAAO,OAAO,YAAY,YAC1B,CAAC,OAAO,SAAS,OAAO,OAAO,KAC/B,OAAO,WAAW,GAClB;AACA,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,MAAM,OAAO,OAAO;AAClC;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,MAAM,WAAW,mBAAmB,EAAE;AAC/C;AAEA,SAAS,mBAAmB,WAA4B;AACtD,SAAO,aAAa,MAAS,aAAa,OAAQ,aAAa;AACjE;AAEA,SAAS,qBAAqB,WAA4B;AACxD,SACE,cAAc,QACd,cAAc,QACd,cAAc,QACd,cAAc,SACb,aAAa,SAAU,aAAa;AAEzC;AAIA,IAAM,2BAA2B;AAAA,EAC/B,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,OAAQ,KAAM;AAAA,EACf,CAAC,QAAS,MAAO;AAAA,EACjB,CAAC,QAAS,MAAO;AAAA,EACjB,CAAC,QAAS,MAAO;AACnB;AAEA,IAAM,+BAA+B,oBAAI,IAAY,CAAC,KAAM,CAAC;AAE7D,SAAS,qBAAqB,WAA4B;AACxD,MAAI,OAAO,MAAM,SAAS,KAAK,6BAA6B,IAAI,SAAS,GAAG;AAC1E,WAAO;AAAA,EACT;AAEA,aAAW,CAAC,OAAO,GAAG,KAAK,0BAA0B;AACnD,QAAI,aAAa,SAAS,aAAa,KAAK;AAC1C,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,sBAAsB,WAA2B;AACxD,QAAM,YAAY,UAAU,YAAY,CAAC;AAEzC,MAAI,cAAc,QAAW;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,mBAAmB,SAAS,KAAK,qBAAqB,SAAS,GAAG;AACpE,WAAO;AAAA,EACT;AAEA,MAAI,qBAAqB,KAAK,SAAS,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,MAAI,qBAAqB,SAAS,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,OAAyB;AACjD,SAAO,MAAM,KAAK,kBAAkB,QAAQ,KAAK,GAAG,CAAC,YAAY,QAAQ,OAAO;AAClF;AAEA,SAAS,gBAAgB,UAA2B;AAClD,MAAI,yBAAyB,KAAK,QAAQ,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,MAAI,yBAAyB,KAAK,QAAQ,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,SAAS,QAAQ,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,SAAS,QAAQ,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,SAAO,SAAS,SAAS,QAAQ,KAAK,4BAA4B,KAAK,QAAQ;AACjF;AAEA,SAAS,qBAAqB,UAA0B;AACtD,MAAI,gBAAgB,QAAQ,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ;AAEZ,aAAW,aAAa,UAAU;AAChC,YAAQ,KAAK,IAAI,OAAO,sBAAsB,SAAS,CAAC;AAAA,EAC1D;AAEA,SAAO;AACT;AAEO,SAAS,aAAa,OAAuB;AAClD,MAAI,QAAQ;AAEZ,aAAW,YAAY,iBAAiB,UAAU,KAAK,CAAC,GAAG;AACzD,aAAS,qBAAqB,QAAQ;AAAA,EACxC;AAEA,SAAO;AACT;AAEO,SAAS,eAAe,OAAyB;AACtD,SAAO,oBAAoB,KAAK,EAAE,MAAM,IAAI;AAC9C;AAEA,SAAS,oBAAoB,OAAe,UAA0B;AACpE,MAAI,YAAY,GAAG;AACjB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ;AACZ,MAAI,YAAY;AAEhB,aAAW,YAAY,iBAAiB,KAAK,GAAG;AAC9C,UAAM,gBAAgB,qBAAqB,QAAQ;AAEnD,QAAI,QAAQ,gBAAgB,UAAU;AACpC;AAAA,IACF;AAEA,aAAS;AACT,iBAAa,SAAS;AAAA,EACxB;AAEA,SAAO,MAAM,MAAM,GAAG,SAAS;AACjC;AAEA,SAAS,iBAAiB,OAAuB;AAC/C,aAAW,YAAY,iBAAiB,KAAK,GAAG;AAC9C,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,MAAc,OAAyB;AAC5D,MAAI,aAAa,IAAI,KAAK,OAAO;AAC/B,WAAO,CAAC,IAAI;AAAA,EACd;AAEA,QAAM,eAAyB,CAAC;AAChC,MAAI,YAAY;AAEhB,SAAO,aAAa,SAAS,IAAI,OAAO;AACtC,UAAM,QAAQ,oBAAoB,WAAW,QAAQ,CAAC;AACtD,UAAM,aAAa,MAAM,YAAY,GAAG;AAExC,QAAI,aAAa,GAAG;AAClB,mBAAa,KAAK,UAAU,MAAM,GAAG,UAAU,CAAC;AAChD,kBAAY,UAAU,MAAM,aAAa,CAAC;AAC1C;AAAA,IACF;AAEA,UAAM,QAAQ,oBAAoB,WAAW,KAAK;AAElD,QAAI,MAAM,SAAS,GAAG;AACpB,mBAAa,KAAK,KAAK;AACvB,kBAAY,UAAU,MAAM,MAAM,MAAM;AACxC;AAAA,IACF;AAEA,UAAM,iBAAiB,iBAAiB,SAAS;AAEjD,iBAAa,KAAK,cAAc;AAChC,gBAAY,UAAU,MAAM,eAAe,MAAM;AAAA,EACnD;AAEA,eAAa,KAAK,SAAS;AAE3B,SAAO;AACT;AAEO,SAAS,gBACd,MACA,SACY;AACZ,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,IAAI,WAAW,8CAA8C;AAAA,EACrE;AAEA,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,aAAa,CAAC,GAAG,GAAG;AAC1B,UAAM,OAAO,WAAW,QAAQ,WAAW,KAAK;AAChD,UAAM,eAAe,eAAe,IAAI,EAAE,QAAQ,CAAC,SAAS,cAAc,MAAM,QAAQ,KAAK,CAAC;AAE9F,eAAW,QAAQ,WAAW,IAAI,aAAa,KAAK,IAAI;AAExD,WAAO;AAAA,EACT,CAAC;AACH;;;AC9OA,SAAS,8BACP,cACA,aACoB;AACpB,QAAM,kBAAkB,kBAAkB,WAAW;AAErD,MAAI,oBAAoB,QAAW;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,aAAa,QAAQ,EAAE,MAAM,IAAI;AAClD,QAAM,uBAAuB;AAC7B,QAAM,aAAa,SAAS,OAAO,CAAC,SAAS,qBAAqB,KAAK,IAAI,CAAC;AAE5E,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,WAAW;AAAA,IAC9B,CAAC,UAAU,SAAS,KAAK,IAAI,UAAU,aAAa,IAAI,CAAC;AAAA,IACzD;AAAA,EACF;AAEA,MAAI,gBAAgB,iBAAiB;AACnC,WAAO;AAAA,EACT;AAEA,SAAO,eAAe;AACxB;AAEO,SAAS,6BACd,cACA,MACA,cAAqC,QAAQ,QACvC;AACN,QAAM,kBAAkB,8BAA8B,cAAc,WAAW;AAE/E,MAAI,oBAAoB,QAAW;AACjC;AAAA,MACE,0CAA0C,eAAe;AAAA,IAC3D;AAAA,EACF;AACF;;;AChDA,SAAS,qBAAqB;;;ACA9B,OAAOC,SAAQ;AAQf,SAAS,YAAY,SAAyB;AAC5C,SAAO,aAAa,OAAO,IAAI;AACjC;AAEA,SAAS,YAAY,OAAe,MAAc,QAAgB,OAAuB;AACvF,SAAO,OAAO,OAAO,OAAO,QAAQ,CAAC,IAAI;AAC3C;AAEA,SAAS,QAAQ,SAAiB,OAAuB;AACvD,QAAM,UAAU,QAAQ,IAAI,aAAa,OAAO;AAChD,QAAM,UAAU,KAAK,MAAM,UAAU,CAAC;AACtC,QAAM,WAAW,UAAU;AAC3B,SAAO,WAAM,IAAI,OAAO,OAAO,IAAI,UAAU,IAAI,OAAO,QAAQ,IAAI;AACtE;AAEO,SAAS,mBAAmB,SAAsC;AACvE,QAAM,EAAE,OAAO,WAAW,KAAK,IAAI;AACnC,QAAM,WAAW,YAAY,KAAK;AAElC,QAAM,QAAkB,CAAC;AAEzB,QAAM,YAAY,YAAY,UAAU,UAAK,UAAK,QAAG;AACrD,QAAM,KAAK,WAAWC,IAAG,KAAK,SAAS,IAAI,SAAS;AAEpD,QAAM,YAAY,QAAQ,OAAO,QAAQ;AACzC,QAAM,KAAK,WAAWA,IAAG,MAAM,SAAS,IAAI,SAAS;AAErD,QAAM,eAAe,YAAY,UAAU,UAAK,UAAK,QAAG;AACxD,QAAM,KAAK,WAAWA,IAAG,KAAK,YAAY,IAAI,YAAY;AAE1D,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACrCO,IAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,mBAAmB,IAAI,KAAK,aAAa,OAAO;AACtD,IAAM,mBAAmB,IAAI,KAAK,aAAa,SAAS;AAAA,EACtD,uBAAuB;AAAA,EACvB,uBAAuB;AACzB,CAAC;AACD,IAAM,eAAe,IAAI,KAAK,aAAa,SAAS;AAAA,EAClD,OAAO;AAAA,EACP,UAAU;AAAA,EACV,uBAAuB;AAAA,EACvB,uBAAuB;AACzB,CAAC;AACD,IAAM,mBAAmB,IAAI,KAAK,aAAa,SAAS;AAAA,EACtD,OAAO;AAAA,EACP,UAAU;AAAA,EACV,uBAAuB;AAAA,EACvB,uBAAuB;AACzB,CAAC;AAED,SAAS,cAAc,OAAuB;AAC5C,SAAO,iBAAiB,OAAO,KAAK;AACtC;AAEA,SAAS,UAAU,OAA2B,UAAqC,CAAC,GAAW;AAC7F,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,aAAa,OAAO,KAAK;AAC3C,SAAO,QAAQ,cAAc,IAAI,SAAS,KAAK;AACjD;AAEA,SAAS,cAAc,OAA2B,UAAqC,CAAC,GAAW;AACjG,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,iBAAiB,OAAO,KAAK;AAC/C,SAAO,QAAQ,cAAc,IAAI,SAAS,KAAK;AACjD;AAEA,SAAS,cAAc,OAA2B,UAAqC,CAAC,GAAW;AACjG,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,iBAAiB,OAAO,KAAK;AAC/C,SAAO,QAAQ,cAAc,IAAI,SAAS,KAAK;AACjD;AAEO,SAAS,uBAAuB,MAAmC;AACxE,SAAO,KAAK,IAAI,CAAC,QAAQ;AAAA,IACvB,IAAI;AAAA,IACJ,cAAc,IAAI,WAAW;AAAA,IAC7B,cAAc,IAAI,UAAU;AAAA,IAC5B,cAAc,IAAI,YAAY;AAAA,IAC9B,cAAc,IAAI,YAAY;AAAA,IAC9B,cAAc,IAAI,WAAW;AAAA,IAC7B,cAAc,IAAI,YAAY;AAAA,IAC9B,cAAc,IAAI,eAAe;AAAA,IACjC,cAAc,IAAI,eAAe;AAAA,IACjC,cAAc,IAAI,gBAAgB;AAAA,IAClC,cAAc,IAAI,WAAW;AAAA,IAC7B,UAAU,IAAI,SAAS,EAAE,aAAa,IAAI,eAAe,CAAC;AAAA,IAC1D,cAAc,IAAI,cAAc,EAAE,aAAa,IAAI,eAAe,CAAC;AAAA,IACnE,cAAc,IAAI,sBAAsB,EAAE,aAAa,IAAI,eAAe,CAAC;AAAA,IAC3E,cAAc,IAAI,eAAe;AAAA,IACjC,cAAc,IAAI,uBAAuB;AAAA,IACzC,cAAc,IAAI,eAAe,EAAE,aAAa,IAAI,eAAe,CAAC;AAAA,EACtE,CAAC;AACH;;;AC3FA,OAAOC,SAAQ;;;ACAf,OAAOC,SAAQ;AAiBR,IAAM,8BAAoD;AAAA,EAC/D,MAAMA,IAAG;AAAA,EACT,SAASA,IAAG;AAAA,EACZ,MAAMA,IAAG;AAAA,EACT,QAAQA,IAAG;AAAA,EACX,OAAOA,IAAG;AAAA,EACV,OAAOA,IAAG;AAAA,EACV,MAAMA,IAAG;AAAA,EACT,KAAKA,IAAG;AACV;AAEA,IAAM,oBAAgC,CAAC,SAAS;AAEhD,SAAS,eAAe,MAAc,QAA4B;AAChE,SAAO,KACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAU,KAAK,WAAW,IAAI,KAAK,OAAO,IAAI,CAAE,EACrD,KAAK,IAAI;AACd;AAIA,IAAM,sBAAsB,oBAAI,IAA+B;AAAA,EAC7D,CAAC,MAAM,CAAC,YAAY,QAAQ,IAAI;AAAA,EAChC,CAAC,SAAS,CAAC,YAAY,QAAQ,OAAO;AAAA,EACtC,CAAC,YAAY,CAAC,YAAY,QAAQ,IAAI;AACxC,CAAC;AAEM,SAAS,oBACd,QACA,UAAgC,6BACpB;AACZ,QAAM,cAAc,oBAAoB,IAAI,MAAM;AAElD,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,SAAO,YAAY,OAAO;AAC5B;AAIA,IAAM,uBAA8E;AAAA,EAClF,eAAe,CAAC,OAAO,YAAY;AACjC,UAAM,cAAc,CAAC,GAAG,KAAK;AAC7B,UAAM,kBAAkB,YAAY,SAAS;AAE7C,gBAAY,eAAe,IAAI,eAAe,YAAY,eAAe,GAAG,QAAQ,MAAM;AAE1F,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB,CAAC,OAAO,YACvB,MAAM,IAAI,CAAC,MAAM,cAAc;AAC7B,QAAI,cAAc,GAAG;AACnB,aAAO,eAAe,MAAM,CAAC,SAAS,QAAQ,KAAK,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC1E;AAEA,WAAO,eAAe,MAAM,QAAQ,GAAG;AAAA,EACzC,CAAC;AAAA,EACH,aAAa,CAAC,OAAO,YACnB,MAAM,IAAI,CAAC,MAAM,cAAc;AAC7B,QAAI,cAAc,GAAG;AACnB,aAAO,eAAe,MAAM,CAAC,SAAS,QAAQ,KAAK,QAAQ,MAAM,IAAI,CAAC,CAAC;AAAA,IACzE;AAEA,QAAI,cAAc,GAAG;AACnB,aAAO,eAAe,MAAM,CAAC,SAAS,QAAQ,KAAK,QAAQ,MAAM,IAAI,CAAC,CAAC;AAAA,IACzE;AAEA,WAAO,eAAe,MAAM,QAAQ,IAAI;AAAA,EAC1C,CAAC;AACL;AAEO,SAAS,kBACd,SACA,OACA,UAAgC,6BACtB;AACV,SAAO,qBAAqB,OAAO,EAAE,OAAO,OAAO;AACrD;AAEA,SAAS,mBACP,OACA,SACA,cACU;AACV,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO,CAAC,GAAG,KAAK;AAAA,EAClB;AAEA,QAAM,cAAc,CAAC,GAAG,KAAK;AAE7B,cAAY,CAAC,IAAI,eAAe,YAAY,CAAC,GAAG,QAAQ,KAAK;AAC7D,cAAY,CAAC,IAAI,eAAe,YAAY,CAAC,GAAG,YAAY;AAE5D,SAAO;AACT;AAEO,SAAS,sBACd,UACA,MACA,SAIY;AACZ,MAAI,CAAC,QAAQ,UAAU;AACrB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,QAAQ,WAAW;AAEnC,SAAO,KAAK,IAAI,CAAC,KAAK,UAAU;AAC9B,UAAM,eACJ,IAAI,YAAY,kBACZ,oBAAoB,OAAO,IAAI,MAAM,GAAG,OAAO,IAC/C;AACN,UAAM,kBAAkB,mBAAmB,SAAS,KAAK,GAAG,SAAS,YAAY;AAEjF,WAAO,kBAAkB,IAAI,SAAS,iBAAiB,OAAO;AAAA,EAChE,CAAC;AACH;;;ACvIO,IAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAMC,oBAAmB,IAAI,KAAK,aAAa,OAAO;AACtD,IAAMC,gBAAe,IAAI,KAAK,aAAa,SAAS;AAAA,EAClD,OAAO;AAAA,EACP,UAAU;AAAA,EACV,uBAAuB;AAAA,EACvB,uBAAuB;AACzB,CAAC;AAED,SAAS,aAAa,KAA6B;AACjD,MAAI,IAAI,YAAY,eAAe;AACjC,WAAO;AAAA,EACT;AAEA,SAAO,IAAI;AACb;AAEA,SAAS,iBAAiB,OAAmC;AAC3D,SAAOD,kBAAiB,OAAO,SAAS,CAAC;AAC3C;AAEA,SAASE,WAAU,OAA2B,UAAoC,CAAC,GAAW;AAC5F,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,eAAeD,cAAa,OAAO,KAAK;AAC9C,SAAO,QAAQ,aAAa,IAAI,YAAY,KAAK;AACnD;AAEA,SAAS,gBAAgB,KAA+B;AACtD,MAAI,IAAI,eAAe,SAAS,GAAG;AACjC,WAAO,IAAI,eAAe,IAAI,CAAC,eAAe,UAAK,WAAW,KAAK,EAAE;AAAA,EACvE;AAEA,SAAO,IAAI,OAAO,IAAI,CAAC,UAAU,UAAK,KAAK,EAAE;AAC/C;AAEA,SAAS,aAAa,KAAqB,QAAkC;AAC3E,QAAM,aAAa,gBAAgB,GAAG;AAEtC,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,uBAAuB,IAAI,eAAe,SAAS,GAAG;AACnE,WAAO,CAAC,GAAG,YAAY,cAAS,EAAE,KAAK,IAAI;AAAA,EAC7C;AAEA,SAAO,WAAW,KAAK,IAAI;AAC7B;AAEA,SAAS,kBACP,KACA,UACA,WACA,QACQ;AACR,MAAI,WAAW,uBAAuB,IAAI,eAAe,WAAW,GAAG;AACrE,WAAO,UAAU,SAAS,GAAG,CAAC;AAAA,EAChC;AAEA,QAAM,QAAQ,IAAI,eAAe,IAAI,CAAC,eAAe,UAAU,SAAS,UAAU,CAAC,CAAC;AAEpF,MAAI,IAAI,eAAe,SAAS,GAAG;AACjC,UAAM,KAAK,UAAU,SAAS,GAAG,CAAC,CAAC;AAAA,EACrC;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,sBAAsB,KAAqB,QAAkC;AACpF,MAAI,WAAW,uBAAuB,IAAI,eAAe,WAAW,GAAG;AACrE,WAAOC,WAAU,IAAI,SAAS,EAAE,YAAY,IAAI,eAAe,CAAC;AAAA,EAClE;AAEA,QAAM,QAAQ,IAAI,eAAe;AAAA,IAAI,CAAC,eACpCA,WAAU,WAAW,SAAS,EAAE,YAAY,WAAW,eAAe,CAAC;AAAA,EACzE;AAEA,MAAI,IAAI,eAAe,SAAS,GAAG;AACjC,UAAM,KAAKA,WAAU,IAAI,SAAS,EAAE,YAAY,IAAI,eAAe,CAAC,CAAC;AAAA,EACvE;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,kBACd,MACA,UAAyC,CAAC,GAC9B;AACZ,QAAM,SAAS,QAAQ,UAAU;AAEjC,SAAO,KAAK,IAAI,CAAC,QAAQ;AAAA,IACvB,IAAI;AAAA,IACJ,aAAa,GAAG;AAAA,IAChB,aAAa,KAAK,MAAM;AAAA,IACxB,kBAAkB,KAAK,CAAC,UAAU,MAAM,aAAa,kBAAkB,MAAM;AAAA,IAC7E,kBAAkB,KAAK,CAAC,UAAU,MAAM,cAAc,kBAAkB,MAAM;AAAA,IAC9E,kBAAkB,KAAK,CAAC,UAAU,MAAM,iBAAiB,kBAAkB,MAAM;AAAA,IACjF,kBAAkB,KAAK,CAAC,UAAU,MAAM,iBAAiB,kBAAkB,MAAM;AAAA,IACjF,kBAAkB,KAAK,CAAC,UAAU,MAAM,kBAAkB,kBAAkB,MAAM;AAAA,IAClF,kBAAkB,KAAK,CAAC,UAAU,MAAM,aAAa,kBAAkB,MAAM;AAAA,IAC7E,sBAAsB,KAAK,MAAM;AAAA,EACnC,CAAC;AACH;;;ACxFA,SAAS,mBAAmB,aAAqBC,oBAA2C;AAC1F,MAAI,eAAeA,oBAAmB;AACpC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,qBACP,aACA,aACAA,oBACwB;AACxB,MAAI,gBAAgBA,oBAAmB;AACrC,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,sBAAsB,QAAQ;AACvD;AAEA,SAAS,cAAc,OAAe,OAAeC,YAAmC;AACtF,QAAM,UAAU,KAAK,IAAI,GAAG,QAAQ,aAAa,KAAK,CAAC;AAEvD,MAAIA,eAAc,SAAS;AACzB,WAAO,GAAG,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK;AAAA,EACvC;AAEA,SAAO,GAAG,KAAK,GAAG,IAAI,OAAO,OAAO,CAAC;AACvC;AAEA,SAAS,aACP,OACA,WACA,mBACU;AACV,QAAM,mBAAmB,YAAY,MAAM;AAE3C,MAAI,oBAAoB,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,sBAAsB,OAAO;AAC/B,WAAO,CAAC,GAAG,OAAO,GAAG,MAAM,KAAK,EAAE,QAAQ,iBAAiB,GAAG,MAAM,EAAE,CAAC;AAAA,EACzE;AAEA,QAAM,aAAa,KAAK,MAAM,mBAAmB,CAAC;AAClD,QAAM,gBAAgB,mBAAmB;AAEzC,SAAO;AAAA,IACL,GAAG,MAAM,KAAK,EAAE,QAAQ,WAAW,GAAG,MAAM,EAAE;AAAA,IAC9C,GAAG;AAAA,IACH,GAAG,MAAM,KAAK,EAAE,QAAQ,cAAc,GAAG,MAAM,EAAE;AAAA,EACnD;AACF;AAEA,SAAS,qBACP,KACA,SAKU;AACV,QAAM,YAAY,IAAI,IAAI,CAAC,SAAS,eAAe,IAAI,CAAC;AACxD,QAAM,YAAY,UAAU,OAAO,CAAC,KAAK,UAAU,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG,CAAC;AAEjF,QAAM,uBAAuB,UAAU,IAAI,CAAC,OAAO,gBAAgB;AACjE,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AACA,UAAM,eAAe,aAAa,OAAO,WAAW,iBAAiB;AACrE,UAAM,sBAAsB,mBAAmB,aAAa,QAAQ,iBAAiB;AAErF,WAAO,aAAa;AAAA,MAAI,CAAC,SACvB,cAAc,MAAM,QAAQ,OAAO,WAAW,GAAG,mBAAmB;AAAA,IACtE;AAAA,EACF,CAAC;AAED,SAAO,MAAM,KAAK,EAAE,QAAQ,UAAU,GAAG,CAAC,GAAG,cAAc;AACzD,UAAM,YAAY,qBAAqB,IAAI,CAAC,gBAAgB,YAAY,SAAS,CAAC;AAClF,WAAO,UAAK,UAAU,KAAK,UAAK,CAAC;AAAA,EACnC,CAAC;AACH;AAEA,SAAS,gBAAgB,QAAkB,OAA4B;AACrE,QAAM,WAAW,OAAO,IAAI,CAAC,UAAU,SAAI,OAAO,QAAQ,CAAC,CAAC;AAC5D,SAAO,GAAG,MAAM,IAAI,GAAG,SAAS,KAAK,MAAM,IAAI,CAAC,GAAG,MAAM,KAAK;AAChE;AAEA,SAAS,wBAAwB,OAAe,WAAsC;AACpF,MAAI,QAAQ,KAAK,SAAS,UAAU,SAAS,GAAG;AAC9C,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,UAAU,KAAK;AACnC,QAAM,UAAU,UAAU,QAAQ,CAAC;AAEnC,SACE,YAAY,YAAY,qBACxB,QAAQ,YAAY,iBACpB,YAAY,cAAc,QAAQ;AAEtC;AAEA,SAAS,iBAAiB,SAA0B;AAClD,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEA,SAAS,mBAAmB,WAAqC;AAC/D,MAAI,cAAc,OAAO;AACvB,WAAO,CAAC,GAAG,SAAS;AAAA,EACtB;AAEA,SAAO,CAAC,GAAG,SAAS;AACtB;AAEA,SAAS,iBAAiB,MAAsB,OAA+B;AAC7E,QAAM,CAAC,iBAAiB,aAAa,IAAI,mBAAmB,KAAK,SAAS;AAC1E,QAAM,CAAC,kBAAkB,cAAc,IAAI,mBAAmB,MAAM,SAAS;AAE7E,MAAI,oBAAoB,kBAAkB;AACxC,WAAO,kBAAkB;AAAA,EAC3B;AAEA,MAAI,kBAAkB,gBAAgB;AACpC,WAAO,gBAAgB,iBAAiB,KAAK;AAAA,EAC/C;AAEA,SAAO,iBAAiB,KAAK,OAAO,IAAI,iBAAiB,MAAM,OAAO;AACxE;AAEA,SAAS,oBAAoB,KAA2B,aAA+B;AACrF,QAAM,gBAAgB,OAAO,CAAC;AAE9B,MAAI,cAAc,UAAU,aAAa;AACvC,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG,MAAM,KAAK,EAAE,QAAQ,cAAc,cAAc,OAAO,GAAG,MAAM,EAAE;AAAA,EACxE;AACF;AAEA,SAAS,qBACP,MACA,oBACQ;AACR,SAAO,KAAK;AAAA,IACV,CAAC,gBAAgB,QAAQ,KAAK,IAAI,gBAAgB,IAAI,MAAM;AAAA,IAC5D;AAAA,EACF;AACF;AAEA,SAAS,6BAA6B,SAKb;AACvB,QAAM,sBACJ,QAAQ,UAAU,WAAW,QAAQ,SAAS,UAC9C,QAAQ,UAAU,WAAW,QAAQ,gBAAgB;AAEvD,MAAI,CAAC,qBAAqB;AACxB,WAAO,QAAQ,UAAU,IAAI,CAAC,UAAU,WAAW;AAAA,MACjD;AAAA,MACA,SAAS,oBAAoB,QAAQ,SAAS,KAAK,GAAG,QAAQ,WAAW;AAAA,MACzE,gBAAgB,oBAAoB,QAAQ,gBAAgB,KAAK,GAAG,QAAQ,WAAW;AAAA,MACvF,eAAe;AAAA,IACjB,EAAE;AAAA,EACJ;AAEA,SAAO,QAAQ,UACZ,IAAI,CAAC,UAAU,WAAW;AAAA,IACzB;AAAA,IACA,SAAS,oBAAoB,QAAQ,SAAS,KAAK,GAAG,QAAQ,WAAW;AAAA,IACzE,gBAAgB,oBAAoB,QAAQ,gBAAgB,KAAK,GAAG,QAAQ,WAAW;AAAA,IACvF,eAAe;AAAA,EACjB,EAAE,EACD,KAAK,CAAC,MAAM,UAAU;AACrB,UAAM,aAAa,iBAAiB,KAAK,UAAU,MAAM,QAAQ;AAEjE,QAAI,eAAe,GAAG;AACpB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,gBAAgB,MAAM;AAAA,EACpC,CAAC;AACL;AAEA,SAAS,oBACP,aACA,SACU;AACV,QAAM,cAAc,YAAY;AAAA,IAC9B,CAAC,gBAAgB,QAAQ,KAAK,IAAI,gBAAgB,IAAI,MAAM;AAAA,IAC5D;AAAA,EACF;AACA,QAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,MAAM,CAAC;AAE1D,aAAW,OAAO,aAAa;AAC7B,aAAS,cAAc,GAAG,cAAc,aAAa,eAAe,GAAG;AACrE,iBAAW,QAAQ,eAAe,IAAI,WAAW,KAAK,EAAE,GAAG;AACzD,eAAO,WAAW,IAAI,KAAK,IAAI,OAAO,WAAW,GAAG,aAAa,IAAI,CAAC;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ,iBAAiB,IAAI,QAAQ;AAE5C,SAAO;AACT;AAEO,SAAS,mBAAmB,SAA4C;AAC7E,QAAM,kBAAkB,qBAAqB,QAAQ,UAAU,QAAQ,YAAY,MAAM;AACzF,QAAM,qBAAqB;AAAA,IACzB,QAAQ;AAAA,IACR,QAAQ,mBAAmB;AAAA,EAC7B;AACA,QAAM,oBAAoB,KAAK,IAAI,iBAAiB,kBAAkB;AACtE,QAAM,wBAAwB,oBAAoB,CAAC,GAAG,QAAQ,WAAW,GAAG,iBAAiB;AAC7F,QAAM,+BAA+B;AAAA,IACnC,CAAC,GAAG,QAAQ,kBAAkB;AAAA,IAC9B;AAAA,EACF;AACA,QAAM,2BAA2B,6BAA6B;AAAA,IAC5D,WAAW,QAAQ;AAAA,IACnB,UAAU,QAAQ;AAAA,IAClB,iBAAiB,QAAQ;AAAA,IACzB,aAAa;AAAA,EACf,CAAC;AACD,QAAM,qBAAqB,yBAAyB,IAAI,CAAC,QAAQ,IAAI,OAAO;AAC5E,QAAM,4BAA4B,yBAAyB,IAAI,CAAC,QAAQ,IAAI,cAAc;AAC1F,QAAM,sBAAsB,yBAAyB,IAAI,CAAC,QAAQ,IAAI,QAAQ;AAC9E,QAAM,cAAc,CAAC,8BAA8B,GAAG,yBAAyB;AAC/E,QAAM,SAAS,oBAAoB,aAAa;AAAA,IAC9C,mBAAmB,QAAQ;AAAA,IAC3B,mBAAmB,QAAQ;AAAA,EAC7B,CAAC;AACD,QAAM,gBAA0B,CAAC;AAEjC,gBAAc;AAAA,IACZ,gBAAgB,QAAQ;AAAA,MACtB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,gBAAc;AAAA,IACZ,GAAG,qBAAqB,uBAAuB;AAAA,MAC7C;AAAA,MACA,aAAa;AAAA,MACb,mBAAmB,QAAQ;AAAA,IAC7B,CAAC;AAAA,EACH;AACA,gBAAc;AAAA,IACZ,gBAAgB,QAAQ;AAAA,MACtB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,qBAAmB,QAAQ,CAAC,KAAK,aAAa;AAC5C,kBAAc;AAAA,MACZ,GAAG,qBAAqB,KAAK;AAAA,QAC3B;AAAA,QACA,aAAa,QAAQ;AAAA,QACrB,mBAAmB,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACH;AAEA,QACE,WAAW,mBAAmB,SAAS,KACvC,wBAAwB,UAAU,mBAAmB,GACrD;AACA,oBAAc;AAAA,QACZ,gBAAgB,QAAQ;AAAA,UACtB,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,gBAAc;AAAA,IACZ,gBAAgB,QAAQ;AAAA,MACtB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO,GAAG,cAAc,KAAK,IAAI,CAAC;AAAA;AACpC;;;AH1UA,IAAM,oBAAoB;AAC1B,IAAM,2BAA2B;AACjC,IAAM,2BAA2B;AAQ1B,SAAS,0BAAmC;AACjD,MAAI,QAAQ,IAAI,aAAa,QAAW;AACtC,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,IAAI,gBAAgB,QAAW;AACzC,WAAO,QAAQ,IAAI,gBAAgB;AAAA,EACrC;AAEA,QAAM,cAAe,QAAQ,OAA8B;AAC3D,SAAO,gBAAgB;AACzB;AAEA,SAAS,eAAe,UAA6B;AACnD,QAAM,cAAc,MAAM,KAAK,iBAAiB;AAEhD,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,SAAO,YAAY,IAAI,CAAC,WAAWC,IAAG,KAAKA,IAAG,MAAM,MAAM,CAAC,CAAC;AAC9D;AAEA,SAAS,qBAAqB,OAAiC;AAC7D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ;AACxE;AAEA,SAAS,qBAAqB,UAAkD;AAC9E,MAAI,qBAAqB,QAAQ,GAAG;AAClC,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AAEA,SAAO,kBAAkB,QAAQ,MAAgD;AACnF;AAEA,SAAS,kBAAkB,aAA6B;AACtD,SAAO,YACJ,QAAQ,EACR,MAAM,IAAI,EACV,OAAO,CAAC,UAAU,SAAS,KAAK,IAAI,UAAU,aAAa,IAAI,CAAC,GAAG,CAAC;AACzE;AAEA,SAAS,2BACP,MACA,aACA,UACA,mBACQ;AACR,QAAM,oBAAoB,kBAAkB,MAAM,EAAE,QAAQ,YAAY,CAAC;AACzE,QAAM,kBAAkB,gBAAgB,mBAAmB;AAAA,IACzD,aAAa;AAAA,IACb,OAAO;AAAA,EACT,CAAC;AACD,QAAM,WAAW,sBAAsB,iBAAiB,MAAM,EAAE,SAAS,CAAC;AAE1E,SAAO,mBAAmB;AAAA,IACxB,aAAa,eAAe,QAAQ;AAAA,IACpC;AAAA,IACA,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEO,SAAS,oBACd,MACA,UAAiC,CAAC,GAC1B;AACR,QAAM,WAAW,QAAQ,YAAY,wBAAwB;AAC7D,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,2BAA2B,qBAAqB,QAAQ,aAAa;AAC3E,QAAM,gBAAgB,qBAAqB,QAAQ,aAAa;AAChE,MAAI,oBAAoB;AACxB,MAAI,gBAAgB,2BAA2B,MAAM,aAAa,UAAU,iBAAiB;AAE7F,MAAI,kBAAkB,QAAW;AAC/B,QAAI,qBAAqB,kBAAkB,aAAa;AAExD,WAAO,qBAAqB,iBAAiB,oBAAoB,0BAA0B;AACzF,YAAM,kBAAkB,qBAAqB;AAC7C,YAAM,wBAAwB,KAAK;AAAA,QACjC;AAAA,QACA,oBAAoB;AAAA,MACtB;AAEA,UAAI,0BAA0B,mBAAmB;AAC/C;AAAA,MACF;AAEA,0BAAoB;AACpB,sBAAgB,2BAA2B,MAAM,aAAa,UAAU,iBAAiB;AACzF,2BAAqB,kBAAkB,aAAa;AAAA,IACtD;AAEA,QAAI,4BAA4B,qBAAqB,eAAe;AAClE,YAAM,IAAI;AAAA,QACR,8BAA8B,aAAa,gDAAgD,kBAAkB;AAAA,MAC/G;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AHzGA,SAAS,eAAe,aAAwC;AAC9D,UAAQ,aAAa;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEA,SAAS,eAAe,KAAoC;AAC1D,MAAI,IAAI,YAAY,eAAe;AACjC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ,CAAC;AAAA,MACT,gBAAgB,CAAC;AAAA,MACjB,aAAa,IAAI;AAAA,MACjB,cAAc,IAAI;AAAA,MAClB,iBAAiB,IAAI;AAAA,MACrB,iBAAiB,IAAI;AAAA,MACrB,kBAAkB,IAAI;AAAA,MACtB,aAAa,IAAI;AAAA,MACjB,SAAS,IAAI;AAAA,MACb,gBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW,IAAI;AAAA,IACf,QAAQ;AAAA,IACR,QAAQ,CAAC;AAAA,IACT,gBAAgB,CAAC;AAAA,IACjB,aAAa,IAAI;AAAA,IACjB,cAAc,IAAI;AAAA,IAClB,iBAAiB,IAAI;AAAA,IACrB,iBAAiB,IAAI;AAAA,IACrB,kBAAkB,IAAI;AAAA,IACtB,aAAa,IAAI;AAAA,IACjB,SAAS,IAAI;AAAA,IACb,gBAAgB,IAAI;AAAA,EACtB;AACF;AAEA,SAAS,8BAA8B,MAA+B;AACpE,QAAM,WAAW,uBAAuB,IAAI;AAC5C,QAAM,gBAAgB,KAAK,IAAI,CAAC,QAAQ,eAAe,GAAG,CAAC;AAC3D,QAAM,oBAAoB,KAAK;AAAA,IAC7B,uBAAuB,CAAC,EAAE;AAAA,IAC1B,GAAG,KAAK,IAAI,CAAC,QAAQ,IAAI,UAAU,MAAM;AAAA,EAC3C;AAEA,SAAO,mBAAmB;AAAA,IACxB,aAAa;AAAA,IACb;AAAA,IACA,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,aAAa;AAAA,IACb,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,EACrB,CAAC;AACH;AAEA,SAAS,mBAAmB,OAAuB;AACjD,SAAO,MAAM,QAAQ,WAAW,MAAM;AACxC;AAEA,SAAS,8BAA8B,MAA+B;AACpE,QAAM,WAAW,uBAAuB,IAAI,EAAE;AAAA,IAAI,CAAC,QACjD,IAAI,IAAI,CAAC,SAAS,mBAAmB,IAAI,CAAC;AAAA,EAC5C;AACA,QAAM,YAAY,CAAC,MAAM,KAAK,sBAAsB,GAAG,GAAG,QAAQ;AAClE,QAAMC,aAAY,uBAAuB,IAAI,CAAC,GAAG,UAAW,UAAU,IAAI,MAAM,GAAI;AAKpF,SAAO,cAAc,WAAW;AAAA,IAC9B,OAAOA;AAAA,EACT,CAAC;AACH;AAEA,SAAS,+BACP,gBACA,SACQ;AACR,QAAM,cAAwB,CAAC;AAC/B,QAAM,WAAW,QAAQ,YAAY,wBAAwB;AAE7D,cAAY;AAAA,IACV,mBAAmB;AAAA,MACjB,OAAO,eAAe,QAAQ,WAAW;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,cAAY,KAAK,EAAE;AACnB,cAAY,KAAK,8BAA8B,eAAe,IAAI,CAAC;AAEnE,SAAO,YAAY,KAAK,IAAI;AAC9B;AAEO,SAAS,uBACd,gBACA,QACA,SACQ;AACR,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,KAAK,UAAU,eAAe,MAAM,MAAM,CAAC;AAAA,IACpD,KAAK;AACH,aAAO,8BAA8B,eAAe,IAAI;AAAA,IAC1D,KAAK;AACH,aAAO,+BAA+B,gBAAgB,OAAO;AAAA,EACjE;AACF;;;AOvHA,SAAS,4BAA4B,SAAyC;AAC5E,MAAI,QAAQ,YAAY,QAAQ,MAAM;AACpC,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AACF;AAEA,SAAS,oBAAoB,SAA2D;AACtF,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,UAAU;AACpB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,wBACb,aACA,SACmC;AACnC,8BAA4B,OAAO;AAEnC,QAAM,iBAAiB,MAAM,oBAAoB,aAAa,OAAO;AACrE,QAAM,SAAS,oBAAoB,OAAO;AAE1C,SAAO;AAAA,IACL;AAAA,IACA,aAAa,eAAe;AAAA,IAC5B,QAAQ,uBAAuB,gBAAgB,QAAQ;AAAA,MACrD;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAUA,eAAsB,oBACpB,aACA,SACe;AACf,QAAM,iBAAiB,MAAM,wBAAwB,aAAa,OAAO;AAEzE,kBAAgB,eAAe,YAAY,OAAO,MAAM;AACxD,sBAAoB,eAAe,YAAY,MAAM,oBAAoB,MAAM;AAE/E,QAAM,iBAAiB,eAAe,YAAY,sBAC9C,4BACA;AACJ,SAAO;AAAA,IACL,iBAAiB,cAAc,MAAM,eAAe,YAAY,cAAc,gBAAgB,eAAe,YAAY,aAAa,KAAK,eAAe,YAAY,eAAe,WAAW,eAAe,YAAY,OAAO;AAAA,EACpO;AACA,SAAO;AAAA,IACL,iCAAiC,eAAe,YAAY,sBAAsB,aAAa,eAAe,YAAY,uBAAuB,cAAc,eAAe,YAAY,2BAA2B;AAAA,EACvN;AAEA,MAAI,eAAe,YAAY,WAAW;AACxC,WAAO,KAAK,eAAe,YAAY,SAAS;AAAA,EAClD;AAEA,MAAI,eAAe,WAAW,YAAY;AACxC,iCAA6B,eAAe,QAAQ,CAAC,YAAY;AAC/D,aAAO,KAAK,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,UAAQ,IAAI,eAAe,MAAM;AACnC;;;AC5FA,SAAS,iBAAAC,sBAAqB;AAK9B,IAAM,YAA2B,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAMlF,SAASC,oBAAmB,OAAuB;AACjD,SAAO,MAAM,QAAQ,WAAW,MAAM;AACxC;AAEO,SAAS,oBACd,MACA,UAAiC,CAAC,GAC1B;AACR,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,WAAW,kBAAkB,MAAM,EAAE,QAAQ,YAAY,CAAC,EAAE;AAAA,IAAI,CAAC,QACrE,IAAI,IAAI,CAAC,SAASA,oBAAmB,IAAI,CAAC;AAAA,EAC5C;AACA,QAAM,YAAY,CAAC,MAAM,KAAK,iBAAiB,GAAG,GAAG,QAAQ;AAE7D,SAAOC,eAAc,WAAW;AAAA,IAC9B,OAAO;AAAA,EACT,CAAC;AACH;;;ACbA,SAASC,gBAAe,aAAwC;AAC9D,UAAQ,aAAa;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEA,SAAS,0BACP,WACA,SACQ;AACR,QAAM,cAAwB,CAAC;AAC/B,QAAM,WAAW,QAAQ,YAAY,wBAAwB;AAC7D,QAAM,cAAc,QAAQ,eAAe;AAE3C,cAAY;AAAA,IACV,mBAAmB;AAAA,MACjB,OAAOA,gBAAe,QAAQ,WAAW;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,cAAY,KAAK,EAAE;AACnB,cAAY,KAAK,oBAAoB,UAAU,MAAM,EAAE,UAAU,YAAY,CAAC,CAAC;AAE/E,SAAO,YAAY,KAAK,IAAI;AAC9B;AAEO,SAAS,kBACd,WACA,QACA,SACQ;AACR,QAAM,cAAc,QAAQ,eAAe;AAE3C,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,KAAK,UAAU,UAAU,MAAM,MAAM,CAAC;AAAA,IAC/C,KAAK;AACH,aAAO,oBAAoB,UAAU,MAAM,EAAE,YAAY,CAAC;AAAA,IAC5D,KAAK;AACH,aAAO,0BAA0B,WAAW,OAAO;AAAA,EACvD;AACF;;;AC9CA,SAASC,6BAA4B,SAAqC;AACxE,MAAI,QAAQ,YAAY,QAAQ,MAAM;AACpC,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AACF;AAEA,SAASC,qBAAoB,SAAkD;AAC7E,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,UAAU;AACpB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,mBAAmB,SAAiD;AAC3E,SAAO,QAAQ,kBAAkB,sBAAsB;AACzD;AAEA,eAAe,mBACb,aACA,SAC8B;AAC9B,EAAAD,6BAA4B,OAAO;AAEnC,QAAM,YAAY,MAAM,eAAe,aAAa,OAAO;AAC3D,QAAM,SAASC,qBAAoB,OAAO;AAE1C,SAAO;AAAA,IACL;AAAA,IACA,aAAa,UAAU;AAAA,IACvB,QAAQ,kBAAkB,WAAW,QAAQ;AAAA,MAC3C;AAAA,MACA,aAAa,mBAAmB,OAAO;AAAA,IACzC,CAAC;AAAA,EACH;AACF;AAUA,eAAsB,eACpB,aACA,SACe;AACf,QAAM,iBAAiB,MAAM,mBAAmB,aAAa,OAAO;AACpE,kBAAgB,eAAe,aAAa,MAAM;AAClD,sBAAoB,eAAe,YAAY,oBAAoB,MAAM;AAEzE,MAAI,eAAe,WAAW,YAAY;AACxC,iCAA6B,eAAe,QAAQ,CAAC,YAAY;AAC/D,aAAO,KAAK,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,UAAQ,IAAI,eAAe,MAAM;AACnC;;;AvDpEA,IAAM,kBAAkB,KAAK,eAAe,EAAE,gBAAgB,EAAE,YAAY;AAE5E,SAAS,sBAAsB,OAAe,UAA8B;AAC1E,SAAO,CAAC,GAAG,UAAU,KAAK;AAC5B;AAEA,SAAS,wBAAkC;AACzC,SAAO,oBAAoB;AAC7B;AAEA,SAAS,uBAAuB,oBAA+C;AAC7E,SAAO,mBAAmB,KAAK,IAAI;AACrC;AAEA,SAAS,iBACP,SACA,UAAgD,CAAC,GACxC;AACT,QAAM,qBAAqB,sBAAsB;AACjD,QAAM,sBAAsB,uBAAuB,kBAAkB;AACrE,QAAM,0BAA0B,IAAI,mBAAmB,MAAM,MAAM,mBAAmB;AACtF,QAAM,yBAAyB,QAAQ,0BAA0B;AAEjE,QAAM,oBAAoB,QACvB,OAAO,mBAAmB,gCAAgC,EAC1D,OAAO,sBAAsB,mCAAmC,EAChE,OAAO,uBAAuB,2BAA2B,EACzD,OAAO,sBAAsB,kCAAkC,EAC/D,OAAO,wBAAwB,4BAA4B,EAC3D;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC;AAAA,IACC;AAAA,IACA,yEAAyE,uBAAuB;AAAA,IAChG;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,wBAAwB,6BAA6B,EAC5D,OAAO,wBAAwB,2BAA2B,EAC1D,OAAO,qBAAqB,0BAA0B,eAAe,EACrE,OAAO,qBAAqB,6CAA6C,EACzE;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,uBAAuB,qCAAqC,EACnE,OAAO,qBAAqB,oDAAoD,EAChF;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,cAAc,iCAAiC,EACtD,OAAO,UAAU,uBAAuB;AAE3C,MAAI,CAAC,wBAAwB;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO,kBAAkB;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,aAAwC;AAClE,UAAQ,aAAa;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEA,SAAS,cAAc,aAAyC;AAC9D,QAAM,UAAU,IAAI,QAAQ,WAAW;AAEvC,mBAAiB,OAAO,EACrB,YAAY,mBAAmB,WAAW,CAAC,EAC3C,OAAO,OAAO,YAAkC;AAC/C,UAAM,eAAe,aAAa,OAAO;AAAA,EAC3C,CAAC;AAEH,SAAO;AACT;AAEA,SAAS,yBAAyB,OAAkC;AAClE,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAE5C,MAAI,eAAe,WAAW,eAAe,YAAY,eAAe,WAAW;AACjF,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,wBAAwB,KAAK,2CAA2C;AAC1F;AAEA,SAAS,0BAAmC;AAC1C,QAAM,UAAU,IAAI,QAAQ,YAAY;AAExC,mBAAiB,SAAS,EAAE,wBAAwB,MAAM,CAAC,EACxD,SAAS,iBAAiB,yCAAyC,wBAAwB,EAC3F,OAAO,qBAAqB,4CAA4C,EACxE,OAAO,2BAA2B,8CAA8C,EAChF,YAAY,6EAA6E,EACzF,OAAO,OAAO,aAAgC,YAAsC;AACnF,UAAM,oBAAoB,aAAa,OAAO;AAAA,EAChD,CAAC;AAEH,SAAO;AACT;AAEA,SAAS,kBAA0B;AACjC,QAAM,qBAAqB,sBAAsB;AACjD,QAAM,sBAAsB,uBAAuB,kBAAkB;AAErE,SAAO;AAAA,IACL;AAAA,IACA,sBAAsB,mBAAmB,MAAM,MAAM,mBAAmB;AAAA,IACxE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEO,SAAS,UAAU,UAA4B,CAAC,GAAY;AACjE,QAAM,UAAU,IAAI,QAAQ;AAE5B,UACG,KAAK,WAAW,EAChB,YAAY,gBAAgB,CAAC,EAC7B,QAAQ,QAAQ,WAAW,OAAO,EAClC,mBAAmB,EACnB,WAAW,cAAc,OAAO,CAAC,EACjC,WAAW,cAAc,QAAQ,CAAC,EAClC,WAAW,cAAc,SAAS,CAAC,EACnC,WAAW,wBAAwB,CAAC;AAEvC,SAAO;AACT;;;AwDxKA,SAAS,iBAAAC,sBAAqB;AAS9B,IAAM,uBAAuB;AAC7B,IAAM,0BAA0B;AAEhC,IAAM,+BAA+B,CAAC,mBAAmB,oBAAoB;AAI7E,SAAS,kBAAkB,WAAiD;AAC1E,QAAM,cAAc,SAAS,SAAS;AAEtC,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,QAAMC,eAAc,OAAO,YAAY,SAAS,WAAW,YAAY,KAAK,KAAK,IAAI;AACrF,QAAMC,kBACJ,OAAO,YAAY,YAAY,WAAW,YAAY,QAAQ,KAAK,IAAI;AAEzE,MAAI,CAACD,gBAAe,CAACC,iBAAgB;AACnC,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,aAAAD;AAAA,IACA,gBAAAC;AAAA,EACF;AACF;AAEO,SAAS,uBACd,UACA,wBAA2C,8BAC1B;AACjB,aAAW,iBAAiB,uBAAuB;AACjD,QAAI;AACF,YAAM,WAAW,kBAAkB,SAAS,aAAa,CAAC;AAE1D,UAAI,UAAU;AACZ,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa;AAAA,IACb,gBAAgB;AAAA,EAClB;AACF;AAEO,SAAS,iCAAkD;AAChE,QAAMC,WAAUC,eAAc,YAAY,GAAG;AAC7C,SAAO,uBAAuB,CAAC,kBAAkBD,SAAQ,aAAa,CAAC;AACzE;;;ACvDA,IAAM,EAAE,aAAa,eAAe,IAAI,+BAA+B;AACvE,IAAM,sBAAsB,+BAA+B;AAE3D,IAAM,MAAM,UAAU,EAAE,SAAS,eAAe,CAAC;AAEjD,IAAI;AACF,QAAM,eAAe,MAAM,+BAA+B;AAAA,IACxD;AAAA,IACA,gBAAgB;AAAA,IAChB,YAAY,oBAAoB;AAAA,IAChC,gBAAgB,oBAAoB;AAAA,EACtC,CAAC;AAED,MAAI,CAAC,aAAa,mBAAmB;AACnC,YAAQ,WAAW,aAAa,YAAY;AAAA,EAC9C,OAAO;AACL,UAAM,IAAI,WAAW,QAAQ,IAAI;AAAA,EACnC;AACF,SAAS,OAAO;AACd,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAQ,MAAM,OAAO;AACrB,UAAQ,WAAW;AACrB;","names":["path","path","packageName","os","path","path","path","createInterface","createInterface","path","os","payload","readFile","os","path","defaultSessionsDir","path","os","readFile","readFile","os","path","path","os","readFile","normalizeTimestamp","os","path","require","UNIX_SECONDS_ABS_CUTOFF","normalizeTimestampCandidate","resolveRepoRoot","hasUsageSignal","isBlankText","sleep","os","path","defaultSessionsDir","path","os","UNIX_SECONDS_ABS_CUTOFF","normalizeTimestampCandidate","resolveTimestamp","toFiniteNumber","getFallbackSessionId","USD_PRECISION_SCALE","addUsd","hasUsageSignal","spawn","createInterface","path","stat","path","getNodeErrorCode","stat","spawn","createInterface","access","constants","path","resolveRepoRoot","resolvedRoot","stat","mkdir","readFile","writeFile","path","toNonNegativeNumber","stat","path","mkdir","writeFile","readFile","stat","mkdir","readFile","writeFile","path","ONE_MILLION","DEFAULT_CACHE_TTL_MS","DEFAULT_FETCH_TIMEOUT_MS","DEFAULT_FETCH_RETRY_COUNT","DEFAULT_FETCH_RETRY_DELAY_MS","isRetryableHttpStatus","isRetryableFetchFailure","sleep","toNonNegativeNumber","path","_","readFile","mkdir","writeFile","resolveRepoRoot","pc","pc","pc","pc","integerFormatter","usdFormatter","formatUsd","modelsColumnIndex","alignment","pc","alignment","markdownTable","toMarkdownSafeCell","markdownTable","getReportTitle","validateOutputFormatOptions","resolveReportFormat","createRequire","packageName","packageVersion","require","createRequire"]}
|
|
1
|
+
{"version":3,"sources":["../src/config/runtime-overrides.ts","../src/update/update-cache-repository.ts","../src/utils/as-record.ts","../src/utils/cache-root-dir.ts","../src/utils/compare-by-code-point.ts","../src/update/version-utils.ts","../src/update/update-install-runner.ts","../src/update/update-notifier.ts","../src/cli/create-cli.ts","../src/sources/codex/codex-source-adapter.ts","../src/domain/normalization.ts","../src/domain/provider-normalization.ts","../src/domain/usage-event.ts","../src/utils/discover-files.ts","../src/utils/discover-jsonl-files.ts","../src/utils/fs-helpers.ts","../src/utils/read-jsonl-objects.ts","../src/sources/parsing-utils.ts","../src/sources/droid/droid-source-adapter.ts","../src/sources/parse-diagnostics.ts","../src/sources/gemini/gemini-source-adapter.ts","../src/sources/opencode/opencode-db-path-resolver.ts","../src/sources/opencode/node-sqlite-loader.ts","../src/sources/opencode/sqlite-warning-suppression.ts","../src/sources/opencode/opencode-row-parser.ts","../src/sources/opencode/opencode-sqlite-errors.ts","../src/sources/opencode/opencode-retry-policy.ts","../src/sources/opencode/opencode-sqlite-query.ts","../src/sources/opencode/opencode-source-adapter.ts","../src/sources/pi/pi-source-adapter.ts","../src/sources/create-default-adapters.ts","../src/utils/time-buckets.ts","../src/aggregate/aggregate-usage.ts","../src/efficiency/efficiency-row.ts","../src/efficiency/aggregate-efficiency.ts","../src/efficiency/git-outcome-collector.ts","../src/efficiency/repo-attribution.ts","../src/cli/build-usage-data-diagnostics.ts","../src/config/env-var-display.ts","../src/cli/build-usage-data-inputs.ts","../src/cli/build-usage-data-parsing.ts","../src/cli/normalize-skipped-row-reasons.ts","../src/cli/parse-file-cache.ts","../src/pricing/cost-engine.ts","../src/pricing/litellm-pricing-fetcher.ts","../src/pricing/litellm-model-map.json","../src/cli/build-usage-data-pricing.ts","../src/cli/build-usage-event-dataset.ts","../src/cli/build-usage-data.ts","../src/cli/build-efficiency-data.ts","../src/utils/logger.ts","../src/cli/emit-diagnostics.ts","../src/cli/emit-env-var-overrides.ts","../src/render/table-text-layout.ts","../src/cli/terminal-overflow-warning.ts","../src/render/render-efficiency-report.ts","../src/render/report-header.ts","../src/render/efficiency-row-cells.ts","../src/render/terminal-table.ts","../src/render/terminal-style-policy.ts","../src/render/row-cells.ts","../src/render/unicode-table.ts","../src/cli/run-efficiency-report.ts","../src/render/render-optimize-report.ts","../src/optimize/aggregate-counterfactual.ts","../src/cli/build-optimize-data.ts","../src/cli/run-optimize-report.ts","../src/render/markdown-table.ts","../src/render/render-usage-report.ts","../src/cli/run-usage-report.ts","../src/cli/package-metadata.ts","../src/cli/index.ts"],"sourcesContent":["const MINUTE_MS = 60_000;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nconst UPDATE_CACHE_TTL_DEFAULT_MS = HOUR_MS;\nconst UPDATE_FETCH_TIMEOUT_DEFAULT_MS = 1_000;\nconst PRICING_CACHE_TTL_DEFAULT_MS = DAY_MS;\nconst PRICING_FETCH_TIMEOUT_DEFAULT_MS = 4_000;\nconst PARSE_MAX_PARALLEL_DEFAULT = 8;\nconst PARSE_CACHE_ENABLED_DEFAULT = true;\nconst PARSE_CACHE_TTL_DEFAULT_MS = 7 * DAY_MS;\nconst PARSE_CACHE_MAX_ENTRIES_DEFAULT = 2_000;\nconst PARSE_CACHE_MAX_BYTES_DEFAULT = 32 * 1024 * 1024;\n\nfunction resolveBoundedEnvInteger(\n envValue: string | undefined,\n defaults: {\n fallback: number;\n min: number;\n max: number;\n },\n): number {\n if (envValue === undefined) {\n return defaults.fallback;\n }\n\n const trimmedValue = envValue.trim();\n\n if (trimmedValue.length === 0) {\n return defaults.fallback;\n }\n\n if (!/^[+-]?\\d+$/u.test(trimmedValue)) {\n return defaults.fallback;\n }\n\n const parsedValue = Number.parseInt(trimmedValue, 10);\n\n if (parsedValue < defaults.min) {\n return defaults.min;\n }\n\n if (parsedValue > defaults.max) {\n return defaults.max;\n }\n\n return parsedValue;\n}\n\nfunction resolveEnvBoolean(envValue: string | undefined, fallback: boolean): boolean {\n if (envValue === undefined) {\n return fallback;\n }\n\n const normalizedValue = envValue.trim().toLowerCase();\n\n if (normalizedValue.length === 0) {\n return fallback;\n }\n\n if (['1', 'true', 'yes', 'on'].includes(normalizedValue)) {\n return true;\n }\n\n if (['0', 'false', 'no', 'off'].includes(normalizedValue)) {\n return false;\n }\n\n return fallback;\n}\n\nexport type UpdateNotifierRuntimeConfig = {\n cacheTtlMs: number;\n fetchTimeoutMs: number;\n};\n\nexport type PricingFetcherRuntimeConfig = {\n cacheTtlMs: number;\n fetchTimeoutMs: number;\n};\n\nexport type ParsingRuntimeConfig = {\n maxParallelFileParsing: number;\n parseCacheEnabled: boolean;\n parseCacheTtlMs: number;\n parseCacheMaxEntries: number;\n parseCacheMaxBytes: number;\n};\n\nexport function getUpdateNotifierRuntimeConfig(\n env: NodeJS.ProcessEnv = process.env,\n): UpdateNotifierRuntimeConfig {\n return {\n cacheTtlMs: resolveBoundedEnvInteger(env.LLM_USAGE_UPDATE_CACHE_TTL_MS, {\n fallback: UPDATE_CACHE_TTL_DEFAULT_MS,\n min: 0,\n max: 30 * DAY_MS,\n }),\n fetchTimeoutMs: resolveBoundedEnvInteger(env.LLM_USAGE_UPDATE_FETCH_TIMEOUT_MS, {\n fallback: UPDATE_FETCH_TIMEOUT_DEFAULT_MS,\n min: 200,\n max: 30_000,\n }),\n };\n}\n\nexport function getPricingFetcherRuntimeConfig(\n env: NodeJS.ProcessEnv = process.env,\n): PricingFetcherRuntimeConfig {\n return {\n cacheTtlMs: resolveBoundedEnvInteger(env.LLM_USAGE_PRICING_CACHE_TTL_MS, {\n fallback: PRICING_CACHE_TTL_DEFAULT_MS,\n min: MINUTE_MS,\n max: 30 * DAY_MS,\n }),\n fetchTimeoutMs: resolveBoundedEnvInteger(env.LLM_USAGE_PRICING_FETCH_TIMEOUT_MS, {\n fallback: PRICING_FETCH_TIMEOUT_DEFAULT_MS,\n min: 200,\n max: 30_000,\n }),\n };\n}\n\nexport function getParsingRuntimeConfig(\n env: NodeJS.ProcessEnv = process.env,\n): ParsingRuntimeConfig {\n return {\n maxParallelFileParsing: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_MAX_PARALLEL, {\n fallback: PARSE_MAX_PARALLEL_DEFAULT,\n min: 1,\n max: 64,\n }),\n parseCacheEnabled: resolveEnvBoolean(\n env.LLM_USAGE_PARSE_CACHE_ENABLED,\n PARSE_CACHE_ENABLED_DEFAULT,\n ),\n parseCacheTtlMs: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_CACHE_TTL_MS, {\n fallback: PARSE_CACHE_TTL_DEFAULT_MS,\n min: HOUR_MS,\n max: 30 * DAY_MS,\n }),\n parseCacheMaxEntries: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_CACHE_MAX_ENTRIES, {\n fallback: PARSE_CACHE_MAX_ENTRIES_DEFAULT,\n min: 100,\n max: 20_000,\n }),\n parseCacheMaxBytes: resolveBoundedEnvInteger(env.LLM_USAGE_PARSE_CACHE_MAX_BYTES, {\n fallback: PARSE_CACHE_MAX_BYTES_DEFAULT,\n min: 1024 * 1024,\n max: 512 * 1024 * 1024,\n }),\n };\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { asRecord } from '../utils/as-record.js';\nimport { getUserCacheRootDir } from '../utils/cache-root-dir.js';\nimport { parseVersion } from './version-utils.js';\n\nconst DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000;\nconst DEFAULT_FETCH_TIMEOUT_MS = 1000;\nconst DEFAULT_FETCH_RETRY_COUNT = 2;\nconst DEFAULT_FETCH_RETRY_DELAY_MS = 200;\n\nexport const UPDATE_CHECK_CACHE_SCOPE_ENV_VAR = 'LLM_USAGE_UPDATE_CACHE_SCOPE';\nexport const UPDATE_CHECK_CACHE_SESSION_KEY_ENV_VAR = 'LLM_USAGE_UPDATE_CACHE_SESSION_KEY';\n\nexport type UpdateCheckCachePayload = {\n checkedAt: number;\n latestVersion: string;\n};\n\nexport type ResolveLatestVersionOptions = {\n packageName: string;\n cacheFilePath?: string;\n cacheTtlMs?: number;\n fetchTimeoutMs?: number;\n fetchRetryCount?: number;\n fetchRetryDelayMs?: number;\n fetchImpl?: typeof fetch;\n now?: () => number;\n sleep?: (delayMs: number) => Promise<void>;\n};\n\nclass RetryableFetchError extends Error {\n public constructor(message: string) {\n super(message);\n this.name = 'RetryableFetchError';\n }\n}\n\nfunction isRetryableHttpStatus(status: number): boolean {\n return [408, 425, 429, 500, 502, 503, 504].includes(status);\n}\n\nfunction isRetryableFetchFailure(error: unknown): boolean {\n if (error instanceof RetryableFetchError) {\n return true;\n }\n\n if (!(error instanceof Error)) {\n return false;\n }\n\n if (error.name === 'AbortError' || error.name === 'TimeoutError') {\n return true;\n }\n\n if (error instanceof TypeError) {\n return true;\n }\n\n return /timeout|timed out|network|econn|enotfound|eai_again/iu.test(error.message);\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n}\n\nexport function getDefaultUpdateCheckCachePath(): string {\n return path.join(getUserCacheRootDir(), 'llm-usage-metrics', 'update-check.json');\n}\n\nfunction sanitizeCachePathFragment(value: string): string {\n return value.replace(/[^A-Za-z0-9._-]/gu, '_');\n}\n\nfunction toCacheSessionKey(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const trimmedValue = value.trim();\n\n if (!trimmedValue) {\n return undefined;\n }\n\n const sanitizedValue = sanitizeCachePathFragment(trimmedValue);\n return sanitizedValue || undefined;\n}\n\nexport function getSessionScopedCachePath(\n baseCacheFilePath: string,\n env: NodeJS.ProcessEnv,\n options: { parentPid?: number } = {},\n): string {\n const cacheScope = env[UPDATE_CHECK_CACHE_SCOPE_ENV_VAR]?.trim().toLowerCase();\n\n if (cacheScope !== 'session') {\n return baseCacheFilePath;\n }\n\n const parentPid = options.parentPid ?? process.ppid;\n const sessionKey =\n toCacheSessionKey(env[UPDATE_CHECK_CACHE_SESSION_KEY_ENV_VAR]) ?? `ppid-${parentPid}`;\n\n const parsedPath = path.parse(baseCacheFilePath);\n return path.join(parsedPath.dir, `${parsedPath.name}.${sessionKey}${parsedPath.ext}`);\n}\n\nfunction toNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value !== 'number') {\n return undefined;\n }\n\n if (!Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return value;\n}\n\nfunction isValidVersion(value: string): boolean {\n return parseVersion(value) !== undefined;\n}\n\nexport function isCacheFresh(\n payload: Pick<UpdateCheckCachePayload, 'checkedAt'>,\n cacheTtlMs: number,\n now: () => number,\n): boolean {\n const nowTimestamp = now();\n\n if (payload.checkedAt > nowTimestamp) {\n return false;\n }\n\n return nowTimestamp - payload.checkedAt <= cacheTtlMs;\n}\n\nexport async function readUpdateCheckCachePayload(\n cacheFilePath: string,\n): Promise<UpdateCheckCachePayload | undefined> {\n let content: string;\n\n try {\n content = await readFile(cacheFilePath, 'utf8');\n } catch {\n return undefined;\n }\n\n let parsedContent: unknown;\n\n try {\n parsedContent = JSON.parse(content);\n } catch {\n return undefined;\n }\n\n const record = asRecord(parsedContent);\n\n if (!record) {\n return undefined;\n }\n\n const checkedAt = toNonNegativeNumber(record.checkedAt);\n const latestVersion = typeof record.latestVersion === 'string' ? record.latestVersion.trim() : '';\n\n if (checkedAt === undefined || !latestVersion || !isValidVersion(latestVersion)) {\n return undefined;\n }\n\n return {\n checkedAt,\n latestVersion,\n };\n}\n\nexport async function writeUpdateCheckCachePayload(\n cacheFilePath: string,\n payload: UpdateCheckCachePayload,\n): Promise<void> {\n await mkdir(path.dirname(cacheFilePath), { recursive: true });\n await writeFile(cacheFilePath, JSON.stringify(payload), 'utf8');\n}\n\nasync function fetchLatestVersion(\n packageName: string,\n fetchImpl: typeof fetch,\n fetchTimeoutMs: number,\n): Promise<string | undefined> {\n const response = await fetchImpl(\n `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`,\n {\n signal: AbortSignal.timeout(fetchTimeoutMs),\n },\n );\n\n if (!response.ok) {\n if (isRetryableHttpStatus(response.status)) {\n throw new RetryableFetchError(\n `Retryable update-check response status: HTTP ${response.status}`,\n );\n }\n\n return undefined;\n }\n\n let payload: unknown;\n\n try {\n payload = (await response.json()) as unknown;\n } catch {\n return undefined;\n }\n\n const payloadRecord = asRecord(payload);\n\n if (!payloadRecord) {\n return undefined;\n }\n\n const version = typeof payloadRecord.version === 'string' ? payloadRecord.version.trim() : '';\n\n if (!version || !isValidVersion(version)) {\n return undefined;\n }\n\n return version;\n}\n\nasync function fetchLatestVersionWithRetry(\n packageName: string,\n fetchImpl: typeof fetch,\n fetchTimeoutMs: number,\n fetchRetryCount: number,\n fetchRetryDelayMs: number,\n sleepFn: (delayMs: number) => Promise<void>,\n): Promise<string | undefined> {\n const safeRetryCount =\n Number.isFinite(fetchRetryCount) && fetchRetryCount >= 0\n ? Math.trunc(fetchRetryCount)\n : DEFAULT_FETCH_RETRY_COUNT;\n const safeRetryDelayMs =\n Number.isFinite(fetchRetryDelayMs) && fetchRetryDelayMs > 0\n ? Math.trunc(fetchRetryDelayMs)\n : DEFAULT_FETCH_RETRY_DELAY_MS;\n const maxAttempts = safeRetryCount + 1;\n\n for (let attemptIndex = 0; attemptIndex < maxAttempts; attemptIndex += 1) {\n try {\n return await fetchLatestVersion(packageName, fetchImpl, fetchTimeoutMs);\n } catch (error) {\n const shouldRetry = isRetryableFetchFailure(error) && attemptIndex < maxAttempts - 1;\n\n if (!shouldRetry) {\n throw error;\n }\n }\n\n const backoffDelay = safeRetryDelayMs * 2 ** attemptIndex;\n await sleepFn(backoffDelay);\n }\n\n return undefined;\n}\n\nexport async function resolveLatestVersion(\n options: ResolveLatestVersionOptions,\n): Promise<string | undefined> {\n const cacheFilePath = options.cacheFilePath ?? getDefaultUpdateCheckCachePath();\n const cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n const fetchTimeoutMs = options.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;\n const fetchRetryCount = options.fetchRetryCount ?? DEFAULT_FETCH_RETRY_COUNT;\n const fetchRetryDelayMs = options.fetchRetryDelayMs ?? DEFAULT_FETCH_RETRY_DELAY_MS;\n const fetchImpl = options.fetchImpl ?? fetch;\n const now = options.now ?? Date.now;\n const sleepFn = options.sleep ?? sleep;\n\n const cachePayload = await readUpdateCheckCachePayload(cacheFilePath);\n\n if (cachePayload && isCacheFresh(cachePayload, cacheTtlMs, now)) {\n return cachePayload.latestVersion;\n }\n\n try {\n const latestVersion = await fetchLatestVersionWithRetry(\n options.packageName,\n fetchImpl,\n fetchTimeoutMs,\n fetchRetryCount,\n fetchRetryDelayMs,\n sleepFn,\n );\n\n if (!latestVersion) {\n return cachePayload?.latestVersion;\n }\n\n try {\n await writeUpdateCheckCachePayload(cacheFilePath, {\n checkedAt: now(),\n latestVersion,\n });\n } catch {\n // Cache writes are best-effort.\n }\n\n return latestVersion;\n } catch {\n return cachePayload?.latestVersion;\n }\n}\n","function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n\n return value;\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nexport function getUserCacheRootDir(\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n homedir: string = os.homedir(),\n): string {\n const xdgCacheDir = env.XDG_CACHE_HOME;\n\n if (xdgCacheDir) {\n return xdgCacheDir;\n }\n\n if (platform === 'win32') {\n const localAppData = env.LOCALAPPDATA;\n\n if (localAppData) {\n return localAppData;\n }\n }\n\n return path.join(homedir, '.cache');\n}\n","export function compareByCodePoint(left: string, right: string): number {\n if (left === right) {\n return 0;\n }\n\n const leftIterator = left[Symbol.iterator]();\n const rightIterator = right[Symbol.iterator]();\n\n for (;;) {\n const leftStep = leftIterator.next();\n const rightStep = rightIterator.next();\n\n if (leftStep.done && rightStep.done) {\n return 0;\n }\n\n if (leftStep.done) {\n return -1;\n }\n\n if (rightStep.done) {\n return 1;\n }\n\n const leftCodePoint = leftStep.value.codePointAt(0) ?? 0;\n const rightCodePoint = rightStep.value.codePointAt(0) ?? 0;\n\n if (leftCodePoint !== rightCodePoint) {\n return leftCodePoint < rightCodePoint ? -1 : 1;\n }\n }\n}\n","import { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\nexport type ParsedVersion = {\n major: number;\n minor: number;\n patch: number;\n prerelease: string[];\n};\n\nexport function parseVersion(value: string): ParsedVersion | undefined {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/u.exec(\n value.trim(),\n );\n\n if (!match) {\n return undefined;\n }\n\n const major = Number(match[1]);\n const minor = Number(match[2]);\n const patch = Number(match[3]);\n\n if (![major, minor, patch].every((part) => Number.isSafeInteger(part))) {\n return undefined;\n }\n\n const prerelease = match[4] ? match[4].split('.') : [];\n\n return {\n major,\n minor,\n patch,\n prerelease,\n };\n}\n\nfunction isNumericIdentifier(value: string): boolean {\n return /^\\d+$/u.test(value);\n}\n\nfunction comparePrereleaseIdentifiers(left: string, right: string): number {\n const leftIsNumeric = isNumericIdentifier(left);\n const rightIsNumeric = isNumericIdentifier(right);\n\n if (leftIsNumeric && rightIsNumeric) {\n return Number(left) - Number(right);\n }\n\n if (leftIsNumeric && !rightIsNumeric) {\n return -1;\n }\n\n if (!leftIsNumeric && rightIsNumeric) {\n return 1;\n }\n\n return compareByCodePoint(left, right);\n}\n\nfunction isPrerelease(version: string): boolean {\n const parsed = parseVersion(version);\n return Boolean(parsed && parsed.prerelease.length > 0);\n}\n\nexport function compareVersions(left: string, right: string): number {\n const parsedLeft = parseVersion(left);\n const parsedRight = parseVersion(right);\n\n if (!parsedLeft || !parsedRight) {\n return 0;\n }\n\n if (parsedLeft.major !== parsedRight.major) {\n return parsedLeft.major - parsedRight.major;\n }\n\n if (parsedLeft.minor !== parsedRight.minor) {\n return parsedLeft.minor - parsedRight.minor;\n }\n\n if (parsedLeft.patch !== parsedRight.patch) {\n return parsedLeft.patch - parsedRight.patch;\n }\n\n const leftPrerelease = parsedLeft.prerelease;\n const rightPrerelease = parsedRight.prerelease;\n\n if (leftPrerelease.length === 0 && rightPrerelease.length === 0) {\n return 0;\n }\n\n if (leftPrerelease.length === 0) {\n return 1;\n }\n\n if (rightPrerelease.length === 0) {\n return -1;\n }\n\n const comparableLength = Math.min(leftPrerelease.length, rightPrerelease.length);\n\n for (let index = 0; index < comparableLength; index += 1) {\n const comparison = comparePrereleaseIdentifiers(leftPrerelease[index], rightPrerelease[index]);\n\n if (comparison !== 0) {\n return comparison;\n }\n }\n\n return leftPrerelease.length - rightPrerelease.length;\n}\n\nexport function shouldOfferUpdate(currentVersion: string, latestVersion: string): boolean {\n if (isPrerelease(latestVersion) && !isPrerelease(currentVersion)) {\n return false;\n }\n\n return compareVersions(latestVersion, currentVersion) > 0;\n}\n","import { spawn } from 'node:child_process';\nimport { createInterface } from 'node:readline/promises';\n\ntype CommandRunnerOptions = {\n env?: NodeJS.ProcessEnv;\n stdio?: 'inherit';\n};\n\nexport type CommandRunner = (\n command: string,\n args: string[],\n options?: CommandRunnerOptions,\n) => Promise<number>;\n\nexport type ConfirmInstall = (prompt: string) => Promise<boolean>;\nexport type Notify = (message: string) => void;\n\nexport type UpdateInstallRestartResult = {\n continueExecution: boolean;\n exitCode?: number;\n};\n\nexport type RunInteractiveInstallAndRestartOptions = {\n packageName: string;\n updateMessage: string;\n env: NodeJS.ProcessEnv;\n argv: string[];\n execPath?: string;\n skipUpdateCheckEnvVar: string;\n confirmInstall?: ConfirmInstall;\n runCommand?: CommandRunner;\n notify?: Notify;\n};\n\nexport function isInteractiveSession(options: {\n env: NodeJS.ProcessEnv;\n stdinIsTTY: boolean;\n stdoutIsTTY: boolean;\n}): boolean {\n const ciValue = options.env.CI;\n const normalizedCiValue = ciValue?.trim().toLowerCase();\n const ciEnabled =\n normalizedCiValue !== undefined &&\n normalizedCiValue.length > 0 &&\n !['0', 'false', 'no', 'off'].includes(normalizedCiValue);\n\n return options.stdinIsTTY && options.stdoutIsTTY && !ciEnabled;\n}\n\nexport async function defaultConfirmInstall(prompt: string): Promise<boolean> {\n const readline = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n try {\n const answer = await readline.question(prompt);\n return ['y', 'yes'].includes(answer.trim().toLowerCase());\n } finally {\n readline.close();\n }\n}\n\nexport async function runCommandWithSpawn(\n command: string,\n args: string[],\n options: CommandRunnerOptions = {},\n): Promise<number> {\n return await new Promise<number>((resolve, reject) => {\n const child = spawn(command, args, {\n env: options.env,\n stdio: options.stdio ?? 'inherit',\n });\n\n child.once('error', (error) => {\n reject(error);\n });\n\n child.once('close', (exitCode) => {\n resolve(exitCode ?? 1);\n });\n });\n}\n\nexport function defaultNotify(message: string): void {\n console.error(message);\n}\n\nexport async function runInteractiveInstallAndRestart(\n options: RunInteractiveInstallAndRestartOptions,\n): Promise<UpdateInstallRestartResult> {\n const confirmInstall = options.confirmInstall ?? defaultConfirmInstall;\n const installAccepted = await confirmInstall(`${options.updateMessage} Install now? [y/N] `);\n\n if (!installAccepted) {\n return { continueExecution: true };\n }\n\n const runCommand = options.runCommand ?? runCommandWithSpawn;\n const notify = options.notify ?? defaultNotify;\n const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';\n const installExitCode = await runCommand(\n npmCommand,\n ['install', '-g', `${options.packageName}@latest`],\n {\n env: options.env,\n stdio: 'inherit',\n },\n );\n\n if (installExitCode !== 0) {\n notify(`Failed to install ${options.packageName}@latest (exit code ${installExitCode}).`);\n return { continueExecution: true };\n }\n\n const restartArgs = options.argv.slice(1);\n const restartEnv: NodeJS.ProcessEnv = {\n ...options.env,\n [options.skipUpdateCheckEnvVar]: '1',\n };\n\n const restartExitCode = await runCommand(options.execPath ?? process.execPath, restartArgs, {\n env: restartEnv,\n stdio: 'inherit',\n });\n\n return {\n continueExecution: false,\n exitCode: restartExitCode,\n };\n}\n","import {\n getDefaultUpdateCheckCachePath,\n getSessionScopedCachePath,\n resolveLatestVersion,\n type ResolveLatestVersionOptions,\n} from './update-cache-repository.js';\nimport {\n isInteractiveSession,\n runInteractiveInstallAndRestart,\n type CommandRunner,\n type ConfirmInstall,\n type Notify,\n} from './update-install-runner.js';\nimport { shouldOfferUpdate } from './version-utils.js';\n\nexport {\n UPDATE_CHECK_CACHE_SCOPE_ENV_VAR,\n UPDATE_CHECK_CACHE_SESSION_KEY_ENV_VAR,\n getDefaultUpdateCheckCachePath,\n getSessionScopedCachePath,\n isCacheFresh,\n readUpdateCheckCachePayload,\n resolveLatestVersion,\n writeUpdateCheckCachePayload,\n type ResolveLatestVersionOptions,\n type UpdateCheckCachePayload,\n} from './update-cache-repository.js';\nexport {\n compareVersions,\n parseVersion,\n shouldOfferUpdate,\n type ParsedVersion,\n} from './version-utils.js';\nexport {\n defaultConfirmInstall,\n defaultNotify,\n isInteractiveSession,\n runCommandWithSpawn,\n runInteractiveInstallAndRestart,\n type CommandRunner,\n type ConfirmInstall,\n type Notify,\n type RunInteractiveInstallAndRestartOptions,\n type UpdateInstallRestartResult,\n} from './update-install-runner.js';\n\nexport const UPDATE_CHECK_SKIP_ENV_VAR = 'LLM_USAGE_SKIP_UPDATE_CHECK';\n\nexport type UpdateNotifierOptions = {\n packageName: string;\n currentVersion: string;\n cacheFilePath?: string;\n cacheTtlMs?: number;\n fetchTimeoutMs?: number;\n fetchImpl?: typeof fetch;\n now?: () => number;\n env?: NodeJS.ProcessEnv;\n argv?: string[];\n execPath?: string;\n stdinIsTTY?: boolean;\n stdoutIsTTY?: boolean;\n confirmInstall?: ConfirmInstall;\n runCommand?: CommandRunner;\n notify?: Notify;\n};\n\nexport type UpdateNotifierResult = {\n continueExecution: boolean;\n exitCode?: number;\n};\n\nfunction isTruthyEnvFlag(value: string | undefined): boolean {\n if (value === undefined) {\n return false;\n }\n\n const normalizedValue = value.trim().toLowerCase();\n\n if (normalizedValue.length === 0) {\n return false;\n }\n\n return ['1', 'true', 'yes', 'on'].includes(normalizedValue);\n}\n\nexport function shouldSkipUpdateCheckForArgv(argv: string[]): boolean {\n const executableArgs = argv.slice(2);\n const commandNames = new Set([\n 'daily',\n 'weekly',\n 'monthly',\n 'efficiency',\n 'optimize',\n 'help',\n 'version',\n ]);\n\n if (executableArgs.length === 0) {\n return false;\n }\n\n if (executableArgs.some((arg) => ['-h', '--help', '-V', '--version'].includes(arg))) {\n return true;\n }\n\n const firstRecognizedCommand = executableArgs.find((arg) => commandNames.has(arg));\n\n return firstRecognizedCommand === 'help' || firstRecognizedCommand === 'version';\n}\n\nexport function isLikelyNpxExecution(argv: string[], env: NodeJS.ProcessEnv): boolean {\n const executablePath = argv[1] ?? '';\n\n if (/[\\\\/]_npx[\\\\/]/u.test(executablePath)) {\n return true;\n }\n\n const npmExecPath = env.npm_execpath ?? '';\n\n if (/npx(?:-cli)?\\.js$/u.test(npmExecPath) || /[\\\\/]npx[\\\\/]/u.test(npmExecPath)) {\n return true;\n }\n\n const npmCommand = env.npm_command ?? '';\n\n return npmCommand === 'exec' || npmCommand === 'npx';\n}\n\nexport function isLikelySourceExecution(argv: string[]): boolean {\n const executablePath = argv[1] ?? '';\n return /\\.[cm]?tsx?$/iu.test(executablePath);\n}\n\nfunction toResolveLatestVersionOptions(\n options: UpdateNotifierOptions,\n env: NodeJS.ProcessEnv,\n): ResolveLatestVersionOptions {\n const baseCacheFilePath = options.cacheFilePath ?? getDefaultUpdateCheckCachePath();\n const scopedCacheFilePath = getSessionScopedCachePath(baseCacheFilePath, env);\n\n return {\n packageName: options.packageName,\n cacheFilePath: scopedCacheFilePath,\n cacheTtlMs: options.cacheTtlMs,\n fetchTimeoutMs: options.fetchTimeoutMs,\n fetchImpl: options.fetchImpl,\n now: options.now,\n };\n}\n\nexport async function checkForUpdatesAndMaybeRestart(\n options: UpdateNotifierOptions,\n): Promise<UpdateNotifierResult> {\n const env = options.env ?? process.env;\n const argv = options.argv ?? process.argv;\n\n if (isTruthyEnvFlag(env[UPDATE_CHECK_SKIP_ENV_VAR])) {\n return { continueExecution: true };\n }\n\n if (shouldSkipUpdateCheckForArgv(argv)) {\n return { continueExecution: true };\n }\n\n if (isLikelyNpxExecution(argv, env)) {\n return { continueExecution: true };\n }\n\n if (isLikelySourceExecution(argv)) {\n return { continueExecution: true };\n }\n\n try {\n const latestVersion = await resolveLatestVersion(toResolveLatestVersionOptions(options, env));\n\n if (!latestVersion || !shouldOfferUpdate(options.currentVersion, latestVersion)) {\n return { continueExecution: true };\n }\n\n const updateMessage = `Update available for ${options.packageName}: ${options.currentVersion} → ${latestVersion}.`;\n const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY;\n const stdoutIsTTY = options.stdoutIsTTY ?? process.stdout.isTTY;\n\n if (!isInteractiveSession({ env, stdinIsTTY, stdoutIsTTY })) {\n (options.notify ?? console.error)(\n `${updateMessage} Run \"npm install -g ${options.packageName}@latest\" to update.`,\n );\n return { continueExecution: true };\n }\n\n return await runInteractiveInstallAndRestart({\n packageName: options.packageName,\n updateMessage,\n env,\n argv,\n execPath: options.execPath,\n skipUpdateCheckEnvVar: UPDATE_CHECK_SKIP_ENV_VAR,\n confirmInstall: options.confirmInstall,\n runCommand: options.runCommand,\n notify: options.notify,\n });\n } catch {\n return { continueExecution: true };\n }\n}\n","import { Command } from 'commander';\n\nimport { getDefaultSourceIds } from '../sources/create-default-adapters.js';\nimport { runEfficiencyReport } from './run-efficiency-report.js';\nimport { runOptimizeReport } from './run-optimize-report.js';\nimport { runUsageReport } from './run-usage-report.js';\nimport type {\n EfficiencyCommandOptions,\n OptimizeCommandOptions,\n ReportCommandOptions,\n} from './usage-data-contracts.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\n\nexport type CreateCliOptions = {\n version?: string;\n};\n\nconst defaultTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';\n\nfunction collectRepeatedOption(value: string, previous: string[]): string[] {\n return [...previous, value];\n}\n\nfunction getSupportedSourceIds(): string[] {\n return getDefaultSourceIds();\n}\n\nfunction getAllowedSourcesLabel(supportedSourceIds: readonly string[]): string {\n return supportedSourceIds.join(', ');\n}\n\nfunction addSharedOptions(\n command: Command,\n options: { includePerModelColumns?: boolean } = {},\n): Command {\n const supportedSourceIds = getSupportedSourceIds();\n const allowedSourcesLabel = getAllowedSourcesLabel(supportedSourceIds);\n const supportedSourcesSummary = `(${supportedSourceIds.length}): ${allowedSourcesLabel}`;\n const includePerModelColumns = options.includePerModelColumns ?? true;\n\n const configuredCommand = command\n .option('--pi-dir <path>', 'Path to .pi sessions directory')\n .option('--codex-dir <path>', 'Path to .codex sessions directory')\n .option('--gemini-dir <path>', 'Path to .gemini directory')\n .option('--droid-dir <path>', 'Path to Droid sessions directory')\n .option('--opencode-db <path>', 'Path to OpenCode SQLite DB')\n .option(\n '--source-dir <source-id=path>',\n 'Override source directory for directory-backed sources (repeatable)',\n collectRepeatedOption,\n [],\n )\n .option(\n '--source <name>',\n `Filter by source id (repeatable or comma-separated, supported sources ${supportedSourcesSummary})`,\n collectRepeatedOption,\n [],\n )\n .option('--since <YYYY-MM-DD>', 'Inclusive start date filter')\n .option('--until <YYYY-MM-DD>', 'Inclusive end date filter')\n .option('--timezone <iana>', 'Timezone for bucketing', defaultTimezone)\n .option(\n '--provider <name>',\n 'Billing-provider filter (substring match, optional; e.g. openai, anthropic, google)',\n )\n .option(\n '--model <name>',\n 'Filter by model (repeatable/comma-separated; exact when exact match exists after source/provider/date filters, otherwise substring)',\n collectRepeatedOption,\n [],\n )\n .option('--pricing-url <url>', 'Override LiteLLM pricing source URL')\n .option('--pricing-offline', 'Use cached LiteLLM pricing only (no network fetch)')\n .option(\n '--ignore-pricing-failures',\n 'Continue without estimated costs when pricing cannot be loaded',\n )\n .option('--markdown', 'Render output as markdown table')\n .option('--json', 'Render output as JSON');\n\n if (!includePerModelColumns) {\n return configuredCommand;\n }\n\n return configuredCommand.option(\n '--per-model-columns',\n 'Render per-model metrics as multiline aligned table columns (terminal/markdown)',\n );\n}\n\nfunction commandDescription(granularity: ReportGranularity): string {\n switch (granularity) {\n case 'daily':\n return 'Show daily usage report';\n case 'weekly':\n return 'Show weekly usage report (week starts Monday)';\n case 'monthly':\n return 'Show monthly usage report';\n }\n}\n\nfunction createCommand(granularity: ReportGranularity): Command {\n const command = new Command(granularity);\n\n addSharedOptions(command)\n .description(commandDescription(granularity))\n .action(async (options: ReportCommandOptions) => {\n await runUsageReport(granularity, options);\n });\n\n return command;\n}\n\nfunction parseGranularityArgument(value: string): ReportGranularity {\n const normalized = value.trim().toLowerCase();\n\n if (normalized === 'daily' || normalized === 'weekly' || normalized === 'monthly') {\n return normalized;\n }\n\n throw new Error(`Invalid granularity: ${value}. Expected one of: daily, weekly, monthly`);\n}\n\nfunction createEfficiencyCommand(): Command {\n const command = new Command('efficiency');\n\n addSharedOptions(command, { includePerModelColumns: false })\n .argument('<granularity>', 'Granularity: daily | weekly | monthly', parseGranularityArgument)\n .option('--repo-dir <path>', 'Path to repository for Git outcome metrics')\n .option('--include-merge-commits', 'Include merge commits in Git outcome metrics')\n .description('Show efficiency report by correlating usage metrics with local Git outcomes')\n .action(async (granularity: ReportGranularity, options: EfficiencyCommandOptions) => {\n await runEfficiencyReport(granularity, options);\n });\n\n return command;\n}\n\nfunction createOptimizeCommand(): Command {\n const command = new Command('optimize');\n\n addSharedOptions(command, { includePerModelColumns: false })\n .argument('<granularity>', 'Granularity: daily | weekly | monthly', parseGranularityArgument)\n .option(\n '--candidate-model <name>',\n 'Candidate model for counterfactual pricing (repeatable or comma-separated)',\n collectRepeatedOption,\n [],\n )\n .option('--top <n>', 'Show only the top N cheapest candidates (positive integer)')\n .description('Show counterfactual pricing report for candidate model(s)')\n .action(async (granularity: ReportGranularity, options: OptimizeCommandOptions) => {\n await runOptimizeReport(granularity, options);\n });\n\n return command;\n}\n\nfunction rootDescription(): string {\n const supportedSourceIds = getSupportedSourceIds();\n const allowedSourcesLabel = getAllowedSourcesLabel(supportedSourceIds);\n\n return [\n 'Aggregate local LLM usage metrics from supported local session sources',\n `Supported sources (${supportedSourceIds.length}): ${allowedSourcesLabel}`,\n '',\n 'Run `llm-usage <command> --help` to see command options (e.g. --json, --source).',\n '',\n 'Examples:',\n ' $ llm-usage daily',\n ' $ llm-usage daily --help',\n ' $ llm-usage weekly --timezone Europe/Paris',\n ' $ llm-usage monthly --since 2026-01-01 --until 2026-01-31 --source pi,codex --json',\n ' $ llm-usage monthly --source opencode --opencode-db /path/to/opencode.db --json',\n ' $ llm-usage monthly --model claude --per-model-columns',\n ' $ llm-usage daily --source-dir pi=/tmp/pi-sessions --source-dir gemini=/tmp/.gemini --source-dir droid=/tmp/droid-sessions',\n ' $ llm-usage daily --pi-dir /tmp/pi-sessions --gemini-dir /tmp/.gemini --droid-dir /tmp/droid-sessions',\n ' $ llm-usage efficiency weekly --repo-dir /path/to/repo --json',\n ' $ llm-usage optimize monthly --provider openai --candidate-model gpt-4.1 --candidate-model gpt-5-codex --json',\n ' $ npx --yes llm-usage-metrics@latest daily',\n ].join('\\n');\n}\n\nexport function createCli(options: CreateCliOptions = {}): Command {\n const program = new Command();\n\n program\n .name('llm-usage')\n .description(rootDescription())\n .version(options.version ?? '0.0.0')\n .showHelpAfterError()\n .addCommand(createCommand('daily'))\n .addCommand(createCommand('weekly'))\n .addCommand(createCommand('monthly'))\n .addCommand(createEfficiencyCommand())\n .addCommand(createOptimizeCommand());\n\n return program;\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { normalizeNonNegativeInteger } from '../../domain/normalization.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverJsonlFiles } from '../../utils/discover-jsonl-files.js';\nimport { pathStat } from '../../utils/fs-helpers.js';\nimport { readJsonlObjects } from '../../utils/read-jsonl-objects.js';\nimport { asTrimmedText, isBlankText, toNumberLike } from '../parsing-utils.js';\nimport type { SourceAdapter } from '../source-adapter.js';\n\nconst defaultSessionsDir = path.join(os.homedir(), '.codex', 'sessions');\n\nexport const LEGACY_CODEX_MODEL_FALLBACK = 'legacy-codex-unknown';\n\ntype CodexUsage = {\n inputTokens: number;\n cacheReadTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n totalTokens: number;\n};\n\ntype CodexSessionState = {\n sessionId: string;\n repoRoot?: string;\n provider?: string;\n model?: string;\n previousTotalUsage?: CodexUsage;\n};\n\nexport type CodexSourceAdapterOptions = {\n sessionsDir?: string;\n requireSessionsDir?: boolean;\n};\n\nconst SESSION_META_LINE_PATTERN = /\"type\"\\s*:\\s*\"session_meta\"/u;\nconst TURN_CONTEXT_LINE_PATTERN = /\"type\"\\s*:\\s*\"turn_context\"/u;\nconst EVENT_MSG_LINE_PATTERN = /\"type\"\\s*:\\s*\"event_msg\"/u;\nconst TOKEN_COUNT_LINE_PATTERN = /\"type\"\\s*:\\s*\"token_count\"/u;\n\nfunction shouldParseCodexJsonlLine(lineText: string): boolean {\n if (SESSION_META_LINE_PATTERN.test(lineText) || TURN_CONTEXT_LINE_PATTERN.test(lineText)) {\n return true;\n }\n\n return EVENT_MSG_LINE_PATTERN.test(lineText) && TOKEN_COUNT_LINE_PATTERN.test(lineText);\n}\n\nfunction toUsage(value: unknown): CodexUsage | undefined {\n const usage = asRecord(value);\n\n if (!usage) {\n return undefined;\n }\n\n const rawInputTokens = normalizeNonNegativeInteger(toNumberLike(usage.input_tokens));\n const cacheReadTokens = normalizeNonNegativeInteger(toNumberLike(usage.cached_input_tokens));\n const outputTokens = normalizeNonNegativeInteger(toNumberLike(usage.output_tokens));\n\n const inputTokens = Math.max(0, rawInputTokens - cacheReadTokens);\n\n return {\n // Codex input_tokens includes cached_input_tokens. We store net input separately\n // to avoid double counting input + cache read in reports and estimated pricing.\n inputTokens,\n cacheReadTokens,\n outputTokens,\n reasoningTokens: normalizeNonNegativeInteger(toNumberLike(usage.reasoning_output_tokens)),\n // Match ccusage semantics: billable total excludes reasoning breakdown.\n totalTokens: inputTokens + outputTokens + cacheReadTokens,\n };\n}\n\nfunction subtractUsage(current: CodexUsage, previous: CodexUsage): CodexUsage {\n return {\n inputTokens: Math.max(0, current.inputTokens - previous.inputTokens),\n cacheReadTokens: Math.max(0, current.cacheReadTokens - previous.cacheReadTokens),\n outputTokens: Math.max(0, current.outputTokens - previous.outputTokens),\n reasoningTokens: Math.max(0, current.reasoningTokens - previous.reasoningTokens),\n totalTokens: Math.max(0, current.totalTokens - previous.totalTokens),\n };\n}\n\nfunction addUsage(left: CodexUsage, right: CodexUsage): CodexUsage {\n return {\n inputTokens: left.inputTokens + right.inputTokens,\n cacheReadTokens: left.cacheReadTokens + right.cacheReadTokens,\n outputTokens: left.outputTokens + right.outputTokens,\n reasoningTokens: left.reasoningTokens + right.reasoningTokens,\n totalTokens: left.totalTokens + right.totalTokens,\n };\n}\n\nfunction hasUsageSignal(usage: CodexUsage): boolean {\n return (\n usage.inputTokens > 0 ||\n usage.cacheReadTokens > 0 ||\n usage.outputTokens > 0 ||\n usage.reasoningTokens > 0 ||\n usage.totalTokens > 0\n );\n}\n\nfunction deriveDeltaUsage(\n info: Record<string, unknown>,\n previousTotalUsage: CodexUsage | undefined,\n): { deltaUsage?: CodexUsage; latestTotalUsage?: CodexUsage } {\n const totalUsage = toUsage(info.total_token_usage);\n const lastUsage = toUsage(info.last_token_usage);\n\n if (lastUsage) {\n return { deltaUsage: lastUsage, latestTotalUsage: totalUsage };\n }\n\n if (!totalUsage) {\n return {};\n }\n\n const deltaUsage = previousTotalUsage\n ? subtractUsage(totalUsage, previousTotalUsage)\n : totalUsage;\n\n return { deltaUsage, latestTotalUsage: totalUsage };\n}\n\nfunction getFallbackSessionId(filePath: string): string {\n return path.basename(filePath, '.jsonl');\n}\n\nfunction resolveRepoRootFromPayload(\n payload: Record<string, unknown> | undefined,\n): string | undefined {\n if (!payload) {\n return undefined;\n }\n\n return (\n asTrimmedText(payload.cwd) ??\n asTrimmedText(payload.repo_root) ??\n asTrimmedText(payload.repoRoot) ??\n asTrimmedText(payload.project_root) ??\n asTrimmedText(payload.projectRoot)\n );\n}\n\nexport class CodexSourceAdapter implements SourceAdapter {\n public readonly id = 'codex' as const;\n\n private readonly sessionsDir: string;\n private readonly requireSessionsDir: boolean;\n\n public constructor(options: CodexSourceAdapterOptions = {}) {\n this.sessionsDir = options.sessionsDir ?? defaultSessionsDir;\n this.requireSessionsDir = options.requireSessionsDir ?? false;\n }\n\n public async discoverFiles(): Promise<string[]> {\n if (isBlankText(this.sessionsDir)) {\n throw new Error('Codex sessions directory must be a non-empty path');\n }\n\n const normalizedSessionsDir = this.sessionsDir.trim();\n\n if (this.requireSessionsDir) {\n const sessionsDirStats = await pathStat(normalizedSessionsDir);\n\n if (!sessionsDirStats) {\n throw new Error(\n `Codex sessions directory is missing or unreadable: ${normalizedSessionsDir}`,\n );\n }\n\n if (!sessionsDirStats.isDirectory()) {\n throw new Error(`Codex sessions directory is not a directory: ${normalizedSessionsDir}`);\n }\n }\n\n return discoverJsonlFiles(normalizedSessionsDir);\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const events: UsageEvent[] = [];\n\n const state: CodexSessionState = {\n sessionId: getFallbackSessionId(filePath),\n provider: 'openai',\n };\n\n for await (const line of readJsonlObjects(filePath, {\n shouldParseLine: shouldParseCodexJsonlLine,\n })) {\n if (line.type === 'session_meta') {\n const payload = asRecord(line.payload);\n state.sessionId = asTrimmedText(payload?.id) ?? state.sessionId;\n state.provider = asTrimmedText(payload?.model_provider) ?? state.provider;\n state.repoRoot = resolveRepoRootFromPayload(payload) ?? state.repoRoot;\n continue;\n }\n\n if (line.type === 'turn_context') {\n const payload = asRecord(line.payload);\n state.model = asTrimmedText(payload?.model) ?? state.model;\n state.repoRoot = resolveRepoRootFromPayload(payload) ?? state.repoRoot;\n continue;\n }\n\n if (line.type !== 'event_msg') {\n continue;\n }\n\n const payload = asRecord(line.payload);\n\n if (payload?.type !== 'token_count') {\n continue;\n }\n\n const info = asRecord(payload.info);\n\n if (!info) {\n continue;\n }\n\n const { deltaUsage, latestTotalUsage } = deriveDeltaUsage(info, state.previousTotalUsage);\n\n if (!deltaUsage || !hasUsageSignal(deltaUsage)) {\n state.previousTotalUsage = latestTotalUsage ?? state.previousTotalUsage;\n continue;\n }\n\n const timestamp = asTrimmedText(line.timestamp);\n\n if (!timestamp) {\n state.previousTotalUsage = latestTotalUsage ?? state.previousTotalUsage;\n continue;\n }\n\n const model = state.model ?? LEGACY_CODEX_MODEL_FALLBACK;\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId: state.sessionId,\n timestamp,\n repoRoot: state.repoRoot,\n provider: state.provider,\n model,\n inputTokens: deltaUsage.inputTokens,\n outputTokens: deltaUsage.outputTokens,\n reasoningTokens: deltaUsage.reasoningTokens,\n cacheReadTokens: deltaUsage.cacheReadTokens,\n cacheWriteTokens: 0,\n totalTokens: deltaUsage.totalTokens,\n costMode: 'estimated',\n }),\n );\n } catch {\n // no-op: malformed lines are ignored by design\n }\n\n if (latestTotalUsage) {\n state.previousTotalUsage = latestTotalUsage;\n } else if (state.previousTotalUsage) {\n state.previousTotalUsage = addUsage(state.previousTotalUsage, deltaUsage);\n } else {\n state.previousTotalUsage = deltaUsage;\n }\n }\n\n return events;\n }\n}\n\nexport function getDefaultCodexSessionsDir(): string {\n return defaultSessionsDir;\n}\n","import { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\nexport type NumberLike = number | string | null | undefined;\n\nexport function normalizeNonNegativeInteger(value: NumberLike): number {\n if (value === null || value === undefined) {\n return 0;\n }\n\n const parsed = typeof value === 'number' ? value : Number(value);\n\n if (!Number.isFinite(parsed)) {\n return 0;\n }\n\n return Math.max(0, Math.trunc(parsed));\n}\n\nexport function normalizeUsdCost(value: NumberLike): number | undefined {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n if (typeof value === 'string' && value.trim() === '') {\n return undefined;\n }\n\n const parsed = typeof value === 'number' ? value : Number(value);\n\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n\n return Math.max(0, parsed);\n}\n\nexport function normalizeTimestamp(value: string | Date): string {\n const date = value instanceof Date ? value : new Date(value);\n\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid timestamp: ${String(value)}`);\n }\n\n return date.toISOString();\n}\n\nexport function normalizeModelList(models: Iterable<string | null | undefined>): string[] {\n const deduplicated = new Set<string>();\n\n for (const model of models) {\n if (!model) {\n continue;\n }\n\n const normalized = model.trim();\n\n if (!normalized) {\n continue;\n }\n\n deduplicated.add(normalized);\n }\n\n return [...deduplicated].sort(compareByCodePoint);\n}\n","const billingProviderAliases = new Map<string, string>([\n ['openai-codex', 'openai'],\n ['github-copilot', 'github'],\n]);\n\nconst billingProviderPrefixAliases: Array<[prefix: string, billingProvider: string]> = [\n ['openai-', 'openai'],\n ['openai/', 'openai'],\n];\n\nexport function normalizeProviderToBillingEntity(provider: string | undefined): string | undefined {\n if (!provider) {\n return undefined;\n }\n\n const normalizedProvider = provider.trim().toLowerCase();\n\n if (normalizedProvider.length === 0) {\n return undefined;\n }\n\n const aliasedProvider = billingProviderAliases.get(normalizedProvider);\n\n if (aliasedProvider) {\n return aliasedProvider;\n }\n\n for (const [prefix, billingProvider] of billingProviderPrefixAliases) {\n if (normalizedProvider.startsWith(prefix)) {\n return billingProvider;\n }\n }\n\n return normalizedProvider;\n}\n","import {\n normalizeNonNegativeInteger,\n normalizeTimestamp,\n normalizeUsdCost,\n type NumberLike,\n} from './normalization.js';\nimport { normalizeProviderToBillingEntity } from './provider-normalization.js';\n\nexport type SourceId = 'pi' | 'codex' | (string & {});\n\nexport type CostMode = 'explicit' | 'estimated';\n\nexport type UsageEvent = {\n source: SourceId;\n sessionId: string;\n timestamp: string;\n repoRoot?: string;\n provider?: string;\n model?: string;\n\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n totalTokens: number;\n\n costUsd?: number;\n costMode: CostMode;\n};\n\nexport type UsageEventInput = {\n source: SourceId;\n sessionId: string;\n timestamp: string | Date;\n repoRoot?: string;\n provider?: string;\n model?: string;\n\n inputTokens?: NumberLike;\n outputTokens?: NumberLike;\n reasoningTokens?: NumberLike;\n cacheReadTokens?: NumberLike;\n cacheWriteTokens?: NumberLike;\n totalTokens?: NumberLike;\n\n costUsd?: NumberLike;\n costMode?: CostMode;\n};\n\nexport function normalizeSourceId(value: unknown): SourceId | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized || undefined;\n}\n\nfunction requireText(value: string, fieldName: string): string {\n const normalized = value.trim();\n\n if (!normalized) {\n throw new Error(`UsageEvent ${fieldName} must be a non-empty string`);\n }\n\n return normalized;\n}\n\nfunction normalizeOptionalText(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized || undefined;\n}\n\nfunction normalizeOptionalProvider(value: string | undefined): string | undefined {\n return normalizeProviderToBillingEntity(value);\n}\n\nfunction normalizeOptionalPath(value: string | undefined): string | undefined {\n return normalizeOptionalText(value);\n}\n\nfunction normalizeOptionalModel(value: string | undefined): string | undefined {\n const normalized = normalizeOptionalText(value);\n\n if (!normalized) {\n return undefined;\n }\n\n return normalized.toLowerCase();\n}\n\nfunction resolveCostMode(costMode: CostMode | undefined, costUsd: number | undefined): CostMode {\n if (costMode === 'explicit' && costUsd === undefined) {\n throw new Error('UsageEvent with costMode \"explicit\" requires costUsd');\n }\n\n if (costMode) {\n return costMode;\n }\n\n return costUsd === undefined ? 'estimated' : 'explicit';\n}\n\nexport function createUsageEvent(input: UsageEventInput): UsageEvent {\n const source = normalizeSourceId(input.source);\n\n if (!source) {\n throw new Error('UsageEvent source must be a non-empty string');\n }\n\n const inputTokens = normalizeNonNegativeInteger(input.inputTokens);\n const outputTokens = normalizeNonNegativeInteger(input.outputTokens);\n const reasoningTokens = normalizeNonNegativeInteger(input.reasoningTokens);\n const cacheReadTokens = normalizeNonNegativeInteger(input.cacheReadTokens);\n const cacheWriteTokens = normalizeNonNegativeInteger(input.cacheWriteTokens);\n const declaredTotalTokens = normalizeNonNegativeInteger(input.totalTokens);\n const componentTotalTokens =\n inputTokens + outputTokens + reasoningTokens + cacheReadTokens + cacheWriteTokens;\n const totalTokens = declaredTotalTokens > 0 ? declaredTotalTokens : componentTotalTokens;\n\n const costUsd = normalizeUsdCost(input.costUsd);\n const costMode = resolveCostMode(input.costMode, costUsd);\n\n return {\n source,\n sessionId: requireText(input.sessionId, 'sessionId'),\n timestamp: normalizeTimestamp(input.timestamp),\n repoRoot: normalizeOptionalPath(input.repoRoot),\n provider: normalizeOptionalProvider(input.provider),\n model: normalizeOptionalModel(input.model),\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costUsd,\n costMode,\n };\n}\n","import { readdir } from 'node:fs/promises';\nimport type { Dirent } from 'node:fs';\nimport path from 'node:path';\n\nimport { asRecord } from './as-record.js';\nimport { compareByCodePoint } from './compare-by-code-point.js';\n\nexport type DiscoverFilesOptions = {\n /** File extension to match (e.g., '.json', '.settings.json'). Case-insensitive. */\n extension: string;\n /** Whether to recurse into subdirectories. Default: true */\n recursive?: boolean;\n /** Skip permission errors (EACCES/EPERM) instead of throwing. Default: true */\n allowPermissionSkip?: boolean;\n /** Sort files by path for deterministic ordering. Default: true */\n sort?: boolean;\n};\n\nfunction getNodeErrorCode(error: unknown): string | undefined {\n const record = asRecord(error);\n return typeof record?.code === 'string' ? record.code : undefined;\n}\n\nfunction isSkippableDirectoryReadError(error: unknown): boolean {\n const code = getNodeErrorCode(error);\n return code === 'EACCES' || code === 'EPERM';\n}\n\nfunction matchesExtension(fileName: string, extension: string): boolean {\n const lowerFileName = fileName.toLowerCase();\n const lowerExtension = extension.toLowerCase();\n return lowerFileName.endsWith(lowerExtension);\n}\n\nfunction normalizeExtension(extension: string): string {\n const normalized = extension.trim();\n\n if (!normalized) {\n throw new Error('discoverFiles extension must be a non-empty string');\n }\n\n if (!normalized.startsWith('.')) {\n throw new Error('discoverFiles extension must start with \".\"');\n }\n\n return normalized;\n}\n\nasync function walkDirectory(\n rootDir: string,\n acc: string[],\n options: Required<DiscoverFilesOptions>,\n): Promise<void> {\n let entries: Dirent[];\n\n try {\n entries = await readdir(rootDir, { withFileTypes: true, encoding: 'utf8' });\n } catch (error) {\n if (getNodeErrorCode(error) === 'ENOENT') {\n return;\n }\n\n if (options.allowPermissionSkip && isSkippableDirectoryReadError(error)) {\n return;\n }\n\n throw error;\n }\n\n if (options.sort) {\n entries.sort((left, right) => compareByCodePoint(left.name, right.name));\n }\n\n for (const entry of entries) {\n const entryPath = path.join(rootDir, entry.name);\n\n if (entry.isDirectory() && options.recursive) {\n await walkDirectory(entryPath, acc, options);\n continue;\n }\n\n if (entry.isFile() && matchesExtension(entry.name, options.extension)) {\n acc.push(entryPath);\n }\n }\n}\n\n/**\n * Recursively discover files matching the given extension.\n * Returns empty array if rootDir doesn't exist.\n * Skips permission errors by default.\n */\nexport async function discoverFiles(\n rootDir: string,\n options: DiscoverFilesOptions,\n): Promise<string[]> {\n const files: string[] = [];\n const resolvedOptions: Required<DiscoverFilesOptions> = {\n extension: normalizeExtension(options.extension),\n recursive: options.recursive ?? true,\n allowPermissionSkip: options.allowPermissionSkip ?? true,\n sort: options.sort ?? true,\n };\n\n await walkDirectory(rootDir, files, resolvedOptions);\n\n return files;\n}\n","import { discoverFiles } from './discover-files.js';\n\n/**\n * Recursively discover .jsonl files in a directory.\n * Returns empty array if rootDir doesn't exist.\n * Skips permission errors in subdirectories (EACCES/EPERM).\n */\nexport async function discoverJsonlFiles(rootDir: string): Promise<string[]> {\n return discoverFiles(rootDir, { extension: '.jsonl' });\n}\n","import type { Stats } from 'node:fs';\nimport { access, constants, stat } from 'node:fs/promises';\n\nexport async function pathExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function pathReadable(filePath: string): Promise<boolean> {\n try {\n await access(filePath, constants.R_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function pathIsDirectory(filePath: string): Promise<boolean> {\n try {\n return (await stat(filePath)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function pathIsFile(filePath: string): Promise<boolean> {\n try {\n return (await stat(filePath)).isFile();\n } catch {\n return false;\n }\n}\n\nexport async function pathStat(filePath: string): Promise<Stats | undefined> {\n try {\n return await stat(filePath);\n } catch {\n return undefined;\n }\n}\n","import { createReadStream } from 'node:fs';\nimport { createInterface } from 'node:readline';\n\nimport { asRecord } from './as-record.js';\n\nexport async function* readJsonlObjects(\n filePath: string,\n options: { shouldParseLine?: (lineText: string) => boolean } = {},\n): AsyncGenerator<Record<string, unknown>, void, undefined> {\n const stream = createReadStream(filePath, {\n encoding: 'utf8',\n });\n const lineReader = createInterface({\n input: stream,\n crlfDelay: Infinity,\n });\n\n let isFirstLine = true;\n\n try {\n for await (const rawLine of lineReader) {\n const normalizedLine = isFirstLine ? rawLine.replace(/^\\uFEFF/u, '') : rawLine;\n isFirstLine = false;\n\n const lineText = normalizedLine.trim();\n\n if (!lineText) {\n continue;\n }\n\n if (options.shouldParseLine && !options.shouldParseLine(lineText)) {\n continue;\n }\n\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(lineText);\n } catch {\n continue;\n }\n\n const parsedObject = asRecord(parsed);\n\n if (!parsedObject) {\n continue;\n }\n\n yield parsedObject;\n }\n } finally {\n lineReader.close();\n stream.destroy();\n }\n}\n","import type { NumberLike } from '../domain/normalization.js';\n\nexport function asTrimmedText(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized || undefined;\n}\n\nexport function isBlankText(value: string): boolean {\n return value.trim().length === 0;\n}\n\nexport function toNumberLike(value: unknown): NumberLike {\n if (\n value === null ||\n value === undefined ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n return value;\n }\n\n return undefined;\n}\n","import { readFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { normalizeNonNegativeInteger } from '../../domain/normalization.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverFiles } from '../../utils/discover-files.js';\nimport { pathIsDirectory, pathReadable } from '../../utils/fs-helpers.js';\nimport { readJsonlObjects } from '../../utils/read-jsonl-objects.js';\nimport { asTrimmedText, isBlankText, toNumberLike } from '../parsing-utils.js';\nimport { incrementSkippedReason, toParseDiagnostics } from '../parse-diagnostics.js';\nimport type { SourceAdapter, SourceParseFileDiagnostics } from '../source-adapter.js';\n\nconst defaultSessionsDir = path.join(os.homedir(), '.factory', 'sessions');\n\nexport type DroidSourceAdapterOptions = {\n sessionsDir?: string;\n requireSessionsDir?: boolean;\n};\n\nconst DROID_SESSION_START_LINE_PATTERN = /\"type\"\\s*:\\s*\"session_start\"/u;\nconst DROID_MESSAGE_LINE_PATTERN = /\"type\"\\s*:\\s*\"message\"/u;\n\nfunction shouldParseDroidJsonlLine(lineText: string): boolean {\n return (\n DROID_SESSION_START_LINE_PATTERN.test(lineText) || DROID_MESSAGE_LINE_PATTERN.test(lineText)\n );\n}\n\nconst UNIX_SECONDS_ABS_CUTOFF = 10_000_000_000;\n\nfunction normalizeTimestampCandidate(candidate: unknown): string | undefined {\n let date: Date | undefined;\n\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n const timestampMs =\n Math.abs(candidate) <= UNIX_SECONDS_ABS_CUTOFF ? candidate * 1000 : candidate;\n date = new Date(timestampMs);\n } else {\n const normalizedText = asTrimmedText(candidate);\n\n if (!normalizedText) {\n return undefined;\n }\n\n date = new Date(normalizedText);\n }\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n}\n\nfunction getSettingsSessionId(filePath: string): string {\n return path.basename(filePath, '.settings.json');\n}\n\nfunction getSiblingJsonlPath(settingsPath: string): string {\n return path.join(path.dirname(settingsPath), `${getSettingsSessionId(settingsPath)}.jsonl`);\n}\n\nfunction isSessionStartRecord(line: Record<string, unknown>): boolean {\n return asTrimmedText(line.type) === 'session_start';\n}\n\nfunction isMessageRecord(line: Record<string, unknown>): boolean {\n return asTrimmedText(line.type) === 'message';\n}\n\nfunction resolveRepoRootFromSessionStart(line: Record<string, unknown>): string | undefined {\n const payload = asRecord(line.session_start);\n return asTrimmedText(payload?.cwd);\n}\n\nexport class DroidSourceAdapter implements SourceAdapter {\n public readonly id = 'droid' as const;\n\n private readonly sessionsDir: string;\n private readonly requireSessionsDir: boolean;\n\n public constructor(options: DroidSourceAdapterOptions = {}) {\n this.sessionsDir = options.sessionsDir ?? defaultSessionsDir;\n this.requireSessionsDir = options.requireSessionsDir ?? false;\n }\n\n private getNormalizedSessionsDir(): string {\n if (isBlankText(this.sessionsDir)) {\n throw new Error('Droid sessions directory must be a non-empty path');\n }\n\n return this.sessionsDir.trim();\n }\n\n public async discoverFiles(): Promise<string[]> {\n const normalizedDir = this.getNormalizedSessionsDir();\n\n if (this.requireSessionsDir && !(await pathReadable(normalizedDir))) {\n throw new Error(`Droid sessions directory is missing or unreadable: ${normalizedDir}`);\n }\n\n if (this.requireSessionsDir && !(await pathIsDirectory(normalizedDir))) {\n throw new Error(`Droid sessions directory is not a directory: ${normalizedDir}`);\n }\n\n return discoverFiles(normalizedDir, { extension: '.settings.json' });\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const { events } = await this.parseFileWithDiagnostics(filePath);\n return events;\n }\n\n public async parseFileWithDiagnostics(filePath: string): Promise<SourceParseFileDiagnostics> {\n const events: UsageEvent[] = [];\n let skippedRows = 0;\n const skippedRowReasons = new Map<string, number>();\n\n let settingsJson: unknown;\n\n try {\n const content = await readFile(filePath, 'utf8');\n settingsJson = JSON.parse(content) as unknown;\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'json_parse_error');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const settings = asRecord(settingsJson);\n\n if (!settings) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_settings_data');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const tokenUsage = asRecord(settings.tokenUsage);\n\n if (!tokenUsage) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'no_token_usage');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const inputTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.inputTokens));\n const outputTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.outputTokens));\n const reasoningTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.thinkingTokens));\n const cacheReadTokens = normalizeNonNegativeInteger(toNumberLike(tokenUsage.cacheReadTokens));\n const cacheWriteTokens = normalizeNonNegativeInteger(\n toNumberLike(tokenUsage.cacheCreationTokens),\n );\n const billableTokens = inputTokens + outputTokens + cacheReadTokens + cacheWriteTokens;\n\n if (billableTokens === 0) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'no_token_usage');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const provider = asTrimmedText(settings.providerLock);\n const model = asTrimmedText(settings.model);\n const totalTokens = billableTokens;\n\n const primaryTimestamp = normalizeTimestampCandidate(settings.providerLockTimestamp);\n const hasValidPrimaryTimestamp = Boolean(primaryTimestamp);\n\n const jsonlPath = getSiblingJsonlPath(filePath);\n\n let repoRoot: string | undefined;\n let fallbackMessageTimestamp: string | undefined;\n\n try {\n for await (const line of readJsonlObjects(jsonlPath, {\n shouldParseLine: shouldParseDroidJsonlLine,\n })) {\n if (!repoRoot && isSessionStartRecord(line)) {\n repoRoot = resolveRepoRootFromSessionStart(line) ?? repoRoot;\n\n if (hasValidPrimaryTimestamp) {\n break;\n }\n\n continue;\n }\n\n if (!hasValidPrimaryTimestamp && isMessageRecord(line)) {\n fallbackMessageTimestamp = normalizeTimestampCandidate(line.timestamp);\n\n if (fallbackMessageTimestamp) {\n break;\n }\n }\n }\n } catch {\n // fail-open: JSONL enrichment is optional\n }\n\n const timestamp = primaryTimestamp ?? fallbackMessageTimestamp;\n\n if (!timestamp) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_timestamp');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId: getSettingsSessionId(filePath),\n timestamp,\n repoRoot,\n provider,\n model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costMode: 'estimated',\n }),\n );\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'event_creation_failed');\n }\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n}\n\nexport function getDefaultDroidSessionsDir(): string {\n return defaultSessionsDir;\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport type { SourceParseFileDiagnostics, SourceSkippedRowReasonStat } from './source-adapter.js';\n\nexport function incrementSkippedReason(reasons: Map<string, number>, reason: string): void {\n const current = reasons.get(reason) ?? 0;\n reasons.set(reason, current + 1);\n}\n\nexport function toSkippedRowReasonStats(\n reasons: Map<string, number>,\n): SourceSkippedRowReasonStat[] {\n return [...reasons.entries()]\n .map(([reason, count]) => ({ reason, count }))\n .sort((left, right) => compareByCodePoint(left.reason, right.reason));\n}\n\nexport function toParseDiagnostics<Event extends UsageEvent>(\n events: Event[],\n skippedRows: number,\n skippedRowReasons: Map<string, number>,\n): SourceParseFileDiagnostics<Event> {\n return {\n events,\n skippedRows,\n skippedRowReasons: toSkippedRowReasonStats(skippedRowReasons),\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverFiles } from '../../utils/discover-files.js';\nimport { pathIsDirectory, pathReadable } from '../../utils/fs-helpers.js';\nimport { asTrimmedText, isBlankText } from '../parsing-utils.js';\nimport { incrementSkippedReason, toParseDiagnostics } from '../parse-diagnostics.js';\nimport type { SourceAdapter, SourceParseFileDiagnostics } from '../source-adapter.js';\n\nconst defaultGeminiDir = path.join(os.homedir(), '.gemini');\n\nexport type GeminiSourceAdapterOptions = {\n geminiDir?: string;\n requireGeminiDir?: boolean;\n};\n\nfunction parseProjectsJson(data: unknown): Map<string, string> {\n const mapping = new Map<string, string>();\n const record = asRecord(data);\n\n if (!record) {\n return mapping;\n }\n\n const projects = asRecord(record.projects);\n\n if (!projects) {\n return mapping;\n }\n\n for (const [key, value] of Object.entries(projects)) {\n const projectEntry = asRecord(value);\n const absolutePath = asTrimmedText(projectEntry?.absolutePath);\n\n if (absolutePath) {\n mapping.set(key, absolutePath);\n }\n }\n\n return mapping;\n}\n\nasync function loadProjectsJson(geminiDir: string): Promise<Map<string, string>> {\n const projectsPath = path.join(geminiDir, 'projects.json');\n\n try {\n const content = await readFile(projectsPath, 'utf8');\n const parsed = JSON.parse(content) as unknown;\n\n return parseProjectsJson(parsed);\n } catch {\n return new Map();\n }\n}\n\nasync function discoverSessionFiles(geminiDir: string): Promise<string[]> {\n const tmpDir = path.join(geminiDir, 'tmp');\n const allSessionFiles: string[] = [];\n const discoveredFiles = await discoverFiles(tmpDir, { extension: '.json' });\n\n for (const filePath of discoveredFiles) {\n const parentDir = path.basename(path.dirname(filePath));\n\n if (parentDir.toLowerCase() === 'chats') {\n allSessionFiles.push(filePath);\n }\n }\n\n return allSessionFiles;\n}\n\nfunction resolveRepoRoot(\n filePath: string,\n sessionData: Record<string, unknown>,\n projectMapping: Map<string, string>,\n): string | undefined {\n const projectHash = asTrimmedText(sessionData.projectHash);\n\n if (projectHash) {\n const mappedRoot = projectMapping.get(projectHash);\n\n if (mappedRoot) {\n return mappedRoot;\n }\n }\n\n const chatsDir = path.dirname(filePath);\n const projectDir = path.dirname(chatsDir);\n const projectIdentifier = path.basename(projectDir);\n\n return projectMapping.get(projectIdentifier);\n}\n\nfunction toFiniteNumber(value: unknown): number | undefined {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : undefined;\n }\n\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const trimmed = value.trim();\n\n if (!trimmed) {\n return undefined;\n }\n\n const parsed = Number(trimmed);\n\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n\n return parsed;\n}\n\nfunction extractTokenUsage(tokens: Record<string, unknown> | undefined): {\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n totalTokens: number;\n} | null {\n if (!tokens) {\n return null;\n }\n\n const input = Math.max(0, toFiniteNumber(tokens.input) ?? 0);\n const tool = Math.max(0, toFiniteNumber(tokens.tool) ?? 0);\n const output = Math.max(0, toFiniteNumber(tokens.output) ?? 0);\n const thoughts = Math.max(0, toFiniteNumber(tokens.thoughts) ?? 0);\n const cached = Math.max(0, toFiniteNumber(tokens.cached) ?? 0);\n\n const inputTokens = input + tool;\n const outputTokens = output;\n const reasoningTokens = thoughts;\n const cacheReadTokens = cached;\n\n const declaredTotal = Math.max(0, toFiniteNumber(tokens.total) ?? 0);\n const componentTotal = inputTokens + outputTokens + reasoningTokens + cacheReadTokens;\n const totalTokens = declaredTotal > 0 ? declaredTotal : componentTotal;\n\n if (inputTokens === 0 && outputTokens === 0 && reasoningTokens === 0 && cached === 0) {\n return null;\n }\n\n return {\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n totalTokens,\n };\n}\n\n// diagnostics helpers live in ../parse-diagnostics.ts\n\nfunction normalizeTimestamp(candidate: unknown): string | undefined {\n if (typeof candidate !== 'string' || isBlankText(candidate)) {\n return undefined;\n }\n\n const date = new Date(candidate.trim());\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n}\n\nexport class GeminiSourceAdapter implements SourceAdapter {\n public readonly id = 'gemini' as const;\n\n private readonly geminiDir: string;\n private readonly requireGeminiDir: boolean;\n private projectMapping: Map<string, string> | null = null;\n\n public constructor(options: GeminiSourceAdapterOptions = {}) {\n this.geminiDir = options.geminiDir ?? defaultGeminiDir;\n this.requireGeminiDir = options.requireGeminiDir ?? false;\n }\n\n private getNormalizedGeminiDir(): string {\n if (isBlankText(this.geminiDir)) {\n throw new Error('Gemini directory must be a non-empty path');\n }\n\n return this.geminiDir.trim();\n }\n\n private async getProjectMapping(normalizedGeminiDir: string): Promise<Map<string, string>> {\n if (this.projectMapping) {\n return this.projectMapping;\n }\n\n this.projectMapping = await loadProjectsJson(normalizedGeminiDir);\n return this.projectMapping;\n }\n\n private async getProjectMappingForParse(): Promise<Map<string, string>> {\n if (this.projectMapping) {\n return this.projectMapping;\n }\n\n if (isBlankText(this.geminiDir)) {\n return new Map();\n }\n\n this.projectMapping = await loadProjectsJson(this.geminiDir.trim());\n return this.projectMapping;\n }\n\n public async discoverFiles(): Promise<string[]> {\n const normalizedDir = this.getNormalizedGeminiDir();\n\n if (this.requireGeminiDir && !(await pathReadable(normalizedDir))) {\n throw new Error(`Gemini directory is missing or unreadable: ${normalizedDir}`);\n }\n\n if (this.requireGeminiDir && !(await pathIsDirectory(normalizedDir))) {\n throw new Error(`Gemini directory is not a directory: ${normalizedDir}`);\n }\n\n await this.getProjectMapping(normalizedDir);\n\n return discoverSessionFiles(normalizedDir);\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const { events } = await this.parseFileWithDiagnostics(filePath);\n\n return events;\n }\n\n public async parseFileWithDiagnostics(filePath: string): Promise<SourceParseFileDiagnostics> {\n const events: UsageEvent[] = [];\n let skippedRows = 0;\n const skippedRowReasons = new Map<string, number>();\n\n let sessionData: unknown;\n\n try {\n const content = await readFile(filePath, 'utf8');\n sessionData = JSON.parse(content) as unknown;\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'json_parse_error');\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const sessionDataRecord = asRecord(sessionData);\n\n if (!sessionDataRecord) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_session_data');\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const sessionId =\n asTrimmedText(sessionDataRecord.sessionId) ?? path.basename(filePath, '.json');\n\n const projectMapping = await this.getProjectMappingForParse();\n const repoRoot = resolveRepoRoot(filePath, sessionDataRecord, projectMapping);\n\n if (!Array.isArray(sessionDataRecord.messages)) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_messages_array');\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n\n const messages = sessionDataRecord.messages;\n\n for (const rawMessage of messages) {\n const message = asRecord(rawMessage);\n\n if (!message) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_message');\n\n continue;\n }\n\n if (message.type !== 'gemini') {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'non_gemini_message');\n\n continue;\n }\n\n const tokens = extractTokenUsage(asRecord(message.tokens));\n\n if (!tokens) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'no_token_usage');\n\n continue;\n }\n\n const timestamp = normalizeTimestamp(message.timestamp);\n\n if (!timestamp) {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'invalid_timestamp');\n\n continue;\n }\n\n const model = asTrimmedText(message.model);\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId,\n timestamp,\n repoRoot,\n provider: 'google',\n model,\n ...tokens,\n costMode: 'estimated',\n }),\n );\n } catch {\n skippedRows++;\n incrementSkippedReason(skippedRowReasons, 'event_creation_failed');\n }\n }\n\n return toParseDiagnostics(events, skippedRows, skippedRowReasons);\n }\n}\n\nexport function getDefaultGeminiDir(): string {\n return defaultGeminiDir;\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nexport type OpenCodeDbPathResolverOptions = {\n platform?: NodeJS.Platform;\n homeDir?: string;\n env?: NodeJS.ProcessEnv;\n};\n\nfunction deduplicate(paths: string[]): string[] {\n return [...new Set(paths)];\n}\n\nfunction getLinuxLikeCandidates(homeDir: string, env: NodeJS.ProcessEnv): string[] {\n const xdgDataHome = env.XDG_DATA_HOME ?? path.join(homeDir, '.local', 'share');\n\n return [\n path.join(xdgDataHome, 'opencode', 'opencode.db'),\n path.join(xdgDataHome, 'opencode', 'db.sqlite'),\n path.join(homeDir, '.opencode', 'opencode.db'),\n path.join(homeDir, '.opencode', 'db.sqlite'),\n ];\n}\n\nfunction getMacOsCandidates(homeDir: string): string[] {\n const appSupportDir = path.join(homeDir, 'Library', 'Application Support');\n\n return [\n path.join(appSupportDir, 'opencode', 'opencode.db'),\n path.join(appSupportDir, 'opencode', 'db.sqlite'),\n path.join(homeDir, '.opencode', 'opencode.db'),\n path.join(homeDir, '.opencode', 'db.sqlite'),\n ];\n}\n\nfunction getWindowsCandidates(homeDir: string, env: NodeJS.ProcessEnv): string[] {\n const roamingBase =\n env.APPDATA ??\n env.LOCALAPPDATA ??\n (env.USERPROFILE ? path.join(env.USERPROFILE, 'AppData', 'Roaming') : undefined);\n\n const roamingCandidates = roamingBase\n ? [\n path.join(roamingBase, 'opencode', 'opencode.db'),\n path.join(roamingBase, 'opencode', 'db.sqlite'),\n ]\n : [];\n\n return [\n ...roamingCandidates,\n path.join(homeDir, '.opencode', 'opencode.db'),\n path.join(homeDir, '.opencode', 'db.sqlite'),\n ];\n}\n\nexport function getDefaultOpenCodeDbPathCandidates(\n options: OpenCodeDbPathResolverOptions = {},\n): string[] {\n const platform = options.platform ?? process.platform;\n const homeDir = options.homeDir ?? os.homedir();\n const env = options.env ?? process.env;\n\n switch (platform) {\n case 'win32':\n return deduplicate(getWindowsCandidates(homeDir, env));\n case 'darwin':\n return deduplicate(getMacOsCandidates(homeDir));\n default:\n return deduplicate(getLinuxLikeCandidates(homeDir, env));\n }\n}\n","import { createRequire } from 'node:module';\n\nimport { asRecord } from '../../utils/as-record.js';\nimport { withSuppressedSqliteExperimentalWarning } from './sqlite-warning-suppression.js';\n\nexport type SqliteModule = {\n DatabaseSync: new (\n filePath: string,\n options?: {\n readOnly?: boolean;\n timeout?: number;\n },\n ) => {\n prepare: (sql: string) => {\n all: (...anonymousParameters: unknown[]) => Record<string, unknown>[];\n iterate?: (...anonymousParameters: unknown[]) => IterableIterator<Record<string, unknown>>;\n };\n close: () => void;\n };\n};\n\ntype RequireFn = (moduleId: string) => unknown;\n\nconst require = createRequire(import.meta.url);\n\nfunction isSqliteModule(value: unknown): value is SqliteModule {\n const moduleRecord = asRecord(value);\n return typeof moduleRecord?.DatabaseSync === 'function';\n}\n\nexport function loadNodeSqliteModuleFromRequire(requireFn: RequireFn): SqliteModule {\n try {\n const moduleValue = withSuppressedSqliteExperimentalWarning(() => requireFn('node:sqlite'));\n\n if (!isSqliteModule(moduleValue)) {\n throw new Error('node:sqlite loaded but did not expose a DatabaseSync constructor.');\n }\n\n return moduleValue;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(\n `OpenCode source requires Node.js 24+ runtime with node:sqlite support: ${reason}`,\n { cause: error },\n );\n }\n}\n\nexport async function loadNodeSqliteModule(): Promise<SqliteModule> {\n return loadNodeSqliteModuleFromRequire(require);\n}\n","const sqliteExperimentalWarningText =\n 'SQLite is an experimental feature and might change at any time';\n\nexport function isSqliteExperimentalWarning(\n warning: unknown,\n warningType: string | undefined,\n): boolean {\n const message =\n warning instanceof Error ? warning.message : typeof warning === 'string' ? warning : '';\n const derivedType =\n warningType ??\n (warning instanceof Error ? warning.name : typeof warning === 'string' ? '' : '');\n\n return derivedType === 'ExperimentalWarning' && message.includes(sqliteExperimentalWarningText);\n}\n\nexport function withSuppressedSqliteExperimentalWarning<T>(load: () => T): T {\n const originalEmitWarning = process.emitWarning.bind(process);\n const patchedEmitWarning = ((warning: unknown, ...args: unknown[]): void => {\n const firstArgument = args[0];\n const warningType =\n typeof firstArgument === 'string'\n ? firstArgument\n : typeof firstArgument === 'object' &&\n firstArgument !== null &&\n 'type' in firstArgument &&\n typeof firstArgument.type === 'string'\n ? firstArgument.type\n : undefined;\n\n if (isSqliteExperimentalWarning(warning, warningType)) {\n return;\n }\n\n Reflect.apply(originalEmitWarning, process, [warning, ...args]);\n }) as typeof process.emitWarning;\n\n process.emitWarning = patchedEmitWarning;\n\n try {\n return load();\n } finally {\n process.emitWarning = originalEmitWarning;\n }\n}\n","import { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport { compareByCodePoint } from '../../utils/compare-by-code-point.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { asTrimmedText, toNumberLike } from '../parsing-utils.js';\nimport type { SourceParseFileDiagnostics } from '../source-adapter.js';\nimport type { OpenCodeSqliteRow } from './opencode-sqlite-query.js';\n\nconst UNIX_SECONDS_ABS_CUTOFF = 10_000_000_000;\n\ntype SkippedRowReason =\n | 'missing_data_json'\n | 'invalid_data_json'\n | 'missing_timestamp'\n | 'missing_session_id'\n | 'missing_usage_signal'\n | 'invalid_usage_event';\n\nfunction normalizeTimestampCandidate(candidate: unknown): string | undefined {\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n const timestampMs =\n Math.abs(candidate) <= UNIX_SECONDS_ABS_CUTOFF ? candidate * 1000 : candidate;\n const date = new Date(timestampMs);\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n }\n\n if (typeof candidate === 'string') {\n const trimmed = candidate.trim();\n\n if (!trimmed) {\n return undefined;\n }\n\n const numericTimestamp = Number(trimmed);\n\n if (Number.isFinite(numericTimestamp)) {\n return normalizeTimestampCandidate(numericTimestamp);\n }\n\n const date = new Date(trimmed);\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n }\n\n return undefined;\n}\n\nfunction resolveTimestamp(\n rowTimestamp: unknown,\n messagePayload: Record<string, unknown>,\n): string | undefined {\n const timestampCandidates = [\n rowTimestamp,\n messagePayload.timestamp,\n messagePayload.timeCreated,\n messagePayload.time_created,\n ];\n\n for (const candidate of timestampCandidates) {\n const resolved = normalizeTimestampCandidate(candidate);\n\n if (resolved) {\n return resolved;\n }\n }\n\n return undefined;\n}\n\nfunction parseNonNegativeNumber(value: unknown): number | undefined {\n const parsed = toNumberLike(value);\n\n if (parsed === undefined || parsed === null) {\n return undefined;\n }\n\n if (typeof parsed === 'string' && parsed.trim() === '') {\n return undefined;\n }\n\n const numberValue = typeof parsed === 'number' ? parsed : Number(parsed);\n\n if (!Number.isFinite(numberValue) || numberValue < 0) {\n return undefined;\n }\n\n return numberValue;\n}\n\nfunction normalizeSessionIdCandidate(value: unknown): string | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return String(value);\n }\n\n return asTrimmedText(value);\n}\n\nfunction resolveRepoRoot(messagePayload: Record<string, unknown>): string | undefined {\n const pathPayload = asRecord(messagePayload.path);\n\n return (\n asTrimmedText(pathPayload?.root) ??\n asTrimmedText(pathPayload?.cwd) ??\n asTrimmedText(messagePayload.cwd) ??\n asTrimmedText(messagePayload.repo_root) ??\n asTrimmedText(messagePayload.repoRoot) ??\n asTrimmedText(messagePayload.project_root) ??\n asTrimmedText(messagePayload.projectRoot)\n );\n}\n\nfunction hasUsageSignal(usageFields: Array<unknown>, explicitCost: number | undefined): boolean {\n if (explicitCost !== undefined) {\n return true;\n }\n\n return usageFields.some((value) => {\n const parsed = parseNonNegativeNumber(value);\n return parsed !== undefined && parsed > 0;\n });\n}\n\nexport function parseOpenCodeMessageRows(\n rows: Iterable<OpenCodeSqliteRow>,\n sourceId: UsageEvent['source'],\n): SourceParseFileDiagnostics {\n const events: UsageEvent[] = [];\n let skippedRows = 0;\n const skippedRowReasons = new Map<SkippedRowReason, number>();\n\n const recordSkippedRow = (reason: SkippedRowReason): void => {\n skippedRows += 1;\n skippedRowReasons.set(reason, (skippedRowReasons.get(reason) ?? 0) + 1);\n };\n\n for (const row of rows) {\n const dataJson = asTrimmedText(row.data_json);\n\n if (!dataJson) {\n recordSkippedRow('missing_data_json');\n continue;\n }\n\n let payload: Record<string, unknown>;\n\n try {\n const parsedPayload = asRecord(JSON.parse(dataJson));\n\n if (!parsedPayload) {\n recordSkippedRow('invalid_data_json');\n continue;\n }\n\n payload = parsedPayload;\n } catch {\n recordSkippedRow('invalid_data_json');\n continue;\n }\n\n const role = asTrimmedText(payload.role) ?? asTrimmedText(payload.type);\n\n if (role?.toLowerCase() !== 'assistant') {\n continue;\n }\n\n const timestamp = resolveTimestamp(row.row_time, payload);\n\n if (!timestamp) {\n recordSkippedRow('missing_timestamp');\n continue;\n }\n\n const sessionId =\n normalizeSessionIdCandidate(row.row_session_id) ??\n normalizeSessionIdCandidate(payload.sessionID) ??\n normalizeSessionIdCandidate(payload.sessionId) ??\n normalizeSessionIdCandidate(payload.session_id) ??\n normalizeSessionIdCandidate(row.row_id);\n\n if (!sessionId) {\n recordSkippedRow('missing_session_id');\n continue;\n }\n\n const provider = asTrimmedText(payload.providerID) ?? asTrimmedText(payload.provider);\n const model = asTrimmedText(payload.modelID) ?? asTrimmedText(payload.model);\n const repoRoot = resolveRepoRoot(payload);\n const tokens = asRecord(payload.tokens);\n const tokenCache = asRecord(tokens?.cache);\n const inputTokens = toNumberLike(tokens?.input);\n const outputTokens = toNumberLike(tokens?.output);\n const reasoningTokens = toNumberLike(tokens?.reasoning);\n const cacheReadTokens = toNumberLike(tokenCache?.read);\n const cacheWriteTokens = toNumberLike(tokenCache?.write);\n const totalTokens = toNumberLike(tokens?.total);\n const explicitCost = parseNonNegativeNumber(payload.cost);\n\n if (\n !hasUsageSignal(\n [\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n ],\n explicitCost,\n )\n ) {\n recordSkippedRow('missing_usage_signal');\n continue;\n }\n\n try {\n events.push(\n createUsageEvent({\n source: sourceId,\n sessionId,\n timestamp,\n repoRoot,\n provider,\n model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costUsd: explicitCost,\n costMode: explicitCost === undefined ? 'estimated' : 'explicit',\n }),\n );\n } catch {\n recordSkippedRow('invalid_usage_event');\n }\n }\n\n return {\n events,\n skippedRows,\n skippedRowReasons: [...skippedRowReasons.entries()]\n .map(([reason, count]) => ({ reason, count }))\n .sort((left, right) => compareByCodePoint(left.reason, right.reason)),\n };\n}\n","import { asRecord } from '../../utils/as-record.js';\nimport { asTrimmedText } from '../parsing-utils.js';\n\nexport function isBusyOrLockedSqliteError(error: unknown): boolean {\n const asError = asRecord(error);\n const code = asTrimmedText(asError?.code);\n const message = error instanceof Error ? error.message : String(error);\n const busySignal = /SQLITE_BUSY|SQLITE_LOCKED|database is locked|database table is locked/u;\n\n return (\n code === 'SQLITE_BUSY' ||\n code === 'SQLITE_LOCKED' ||\n code === 'ERR_SQLITE_BUSY' ||\n busySignal.test(message)\n );\n}\n\nexport function formatSqliteError(error: unknown): string {\n if (!(error instanceof Error)) {\n return String(error);\n }\n\n const errorRecord = asRecord(error);\n const code = asTrimmedText(errorRecord?.code);\n\n if (!code) {\n return error.message;\n }\n\n return `${code}: ${error.message}`;\n}\n","import { formatSqliteError, isBusyOrLockedSqliteError } from './opencode-sqlite-errors.js';\n\nexport type SleepFn = (delayMs: number) => Promise<void>;\n\nexport async function runWithBusyRetries<T>(\n operation: () => Promise<T>,\n options: {\n dbPath: string;\n maxBusyRetries: number;\n busyRetryDelayMs: number;\n sleep: SleepFn;\n },\n): Promise<T> {\n for (let attempt = 0; attempt <= options.maxBusyRetries; attempt += 1) {\n try {\n return await operation();\n } catch (error) {\n const isBusy = isBusyOrLockedSqliteError(error);\n\n if (isBusy && attempt < options.maxBusyRetries) {\n await options.sleep(options.busyRetryDelayMs * (attempt + 1));\n continue;\n }\n\n if (isBusy) {\n throw new Error(\n `OpenCode DB is busy/locked: ${options.dbPath}. Retries exhausted after ${options.maxBusyRetries + 1} attempt(s). Close active OpenCode processes and retry.`,\n { cause: error },\n );\n }\n\n throw new Error(\n `Could not read OpenCode DB at ${options.dbPath}: ${formatSqliteError(error)}`,\n { cause: error },\n );\n }\n }\n\n throw new Error('Unexpected OpenCode retry state: loop exhausted without result');\n}\n","import { asTrimmedText } from '../parsing-utils.js';\n\nexport type OpenCodeSqliteRow = Record<string, unknown>;\n\ntype OpenCodeSqliteDatabase = {\n prepare: (sql: string) => {\n all: (...anonymousParameters: unknown[]) => OpenCodeSqliteRow[];\n iterate?: (...anonymousParameters: unknown[]) => IterableIterator<OpenCodeSqliteRow>;\n };\n};\n\ntype MessageQueryColumns = {\n idColumn: string;\n timestampColumn: string;\n dataColumn: string;\n sessionIdColumn: string | undefined;\n};\n\nfunction shouldFallbackToNonJsonExtractQuery(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return /no such function:\\s*json_(?:extract|valid)|malformed JSON/iu.test(message);\n}\n\nfunction escapeIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction resolveIdentifierCaseInsensitive(\n identifiers: readonly string[],\n candidates: readonly string[],\n): string | undefined {\n for (const candidate of candidates) {\n const normalizedCandidate = candidate.toLowerCase();\n const matchedIdentifier = identifiers.find(\n (identifier) => identifier.toLowerCase() === normalizedCandidate,\n );\n\n if (matchedIdentifier) {\n return matchedIdentifier;\n }\n }\n\n return undefined;\n}\n\nfunction resolveRequiredMessageColumns(messageColumns: readonly string[]): MessageQueryColumns {\n const dataColumn = resolveIdentifierCaseInsensitive(messageColumns, ['data']);\n\n if (!dataColumn) {\n throw new Error(\n 'OpenCode schema drift: \"message.data\" column not found. Inspect schema with `opencode db` commands.',\n );\n }\n\n const idColumn = resolveIdentifierCaseInsensitive(messageColumns, ['id', 'message_id']);\n const timestampColumn = resolveIdentifierCaseInsensitive(messageColumns, [\n 'time_created',\n 'created_at',\n 'timestamp',\n ]);\n const sessionIdColumn = resolveIdentifierCaseInsensitive(messageColumns, [\n 'session_id',\n 'sessionid',\n ]);\n\n if (!idColumn || !timestampColumn) {\n throw new Error(\n 'OpenCode schema drift: required message id/timestamp columns are unavailable. Inspect schema with `opencode db` commands.',\n );\n }\n\n return {\n idColumn,\n timestampColumn,\n dataColumn,\n sessionIdColumn,\n };\n}\n\nfunction createPrimaryQuery(tableName: string, columns: MessageQueryColumns): string {\n const rowSessionId = columns.sessionIdColumn\n ? `${escapeIdentifier(columns.sessionIdColumn)} AS row_session_id`\n : 'NULL AS row_session_id';\n\n return [\n 'SELECT',\n ` ${escapeIdentifier(columns.idColumn)} AS row_id,`,\n ` ${escapeIdentifier(columns.timestampColumn)} AS row_time,`,\n ` ${rowSessionId},`,\n ` ${escapeIdentifier(columns.dataColumn)} AS data_json`,\n `FROM ${escapeIdentifier(tableName)}`,\n [\n 'WHERE CASE',\n ` WHEN json_valid(${escapeIdentifier(columns.dataColumn)}) = 1`,\n ` THEN lower(trim(coalesce(json_extract(${escapeIdentifier(columns.dataColumn)}, '$.role'), json_extract(${escapeIdentifier(columns.dataColumn)}, '$.type'))))`,\n \" ELSE 'assistant'\",\n \"END = 'assistant'\",\n ].join('\\n'),\n `ORDER BY ${escapeIdentifier(columns.timestampColumn)} ASC, ${escapeIdentifier(columns.idColumn)} ASC`,\n ].join('\\n');\n}\n\nfunction createFallbackQuery(tableName: string, columns: MessageQueryColumns): string {\n const rowSessionId = columns.sessionIdColumn\n ? `${escapeIdentifier(columns.sessionIdColumn)} AS row_session_id`\n : 'NULL AS row_session_id';\n\n return [\n 'SELECT',\n ` ${escapeIdentifier(columns.idColumn)} AS row_id,`,\n ` ${escapeIdentifier(columns.timestampColumn)} AS row_time,`,\n ` ${rowSessionId},`,\n ` ${escapeIdentifier(columns.dataColumn)} AS data_json`,\n `FROM ${escapeIdentifier(tableName)}`,\n `ORDER BY ${escapeIdentifier(columns.timestampColumn)} ASC, ${escapeIdentifier(columns.idColumn)} ASC`,\n ].join('\\n');\n}\n\nfunction resolveMessageTableName(database: OpenCodeSqliteDatabase): string {\n const tablesResult = database\n .prepare(\"SELECT name FROM sqlite_master WHERE type = 'table'\")\n .all()\n .map((row) => asTrimmedText(row.name))\n .filter((value): value is string => Boolean(value));\n const messageTableName = resolveIdentifierCaseInsensitive(tablesResult, ['message']);\n\n if (!messageTableName) {\n throw new Error(\n 'OpenCode schema drift: required \"message\" table not found. Inspect schema with `opencode db` commands.',\n );\n }\n\n return messageTableName;\n}\n\nfunction resolveMessageQueryColumns(\n database: OpenCodeSqliteDatabase,\n messageTableName: string,\n): MessageQueryColumns {\n const escapedMessageTableName = messageTableName.replaceAll(\"'\", \"''\");\n const messageColumns = database\n .prepare(`PRAGMA table_info('${escapedMessageTableName}')`)\n .all()\n .map((row) => asTrimmedText(row.name))\n .filter((value): value is string => Boolean(value));\n\n return resolveRequiredMessageColumns(messageColumns);\n}\n\nfunction executeQueryRows(\n database: OpenCodeSqliteDatabase,\n query: string,\n): Iterable<OpenCodeSqliteRow> {\n const statement = database.prepare(query);\n\n if (statement.iterate) {\n const iterator = statement.iterate();\n const firstResult = iterator.next();\n\n return (function* iterRows(): IterableIterator<OpenCodeSqliteRow> {\n if (!firstResult.done) {\n yield firstResult.value;\n }\n\n yield* iterator;\n })();\n }\n\n return statement.all();\n}\n\nexport function queryOpenCodeMessageRows(\n database: OpenCodeSqliteDatabase,\n): Iterable<OpenCodeSqliteRow> {\n const messageTableName = resolveMessageTableName(database);\n const columns = resolveMessageQueryColumns(database, messageTableName);\n const primaryQuery = createPrimaryQuery(messageTableName, columns);\n\n try {\n return executeQueryRows(database, primaryQuery);\n } catch (error) {\n if (!shouldFallbackToNonJsonExtractQuery(error)) {\n throw error;\n }\n\n return executeQueryRows(database, createFallbackQuery(messageTableName, columns));\n }\n}\n","import type { UsageEvent } from '../../domain/usage-event.js';\nimport { pathExists, pathIsFile, pathReadable } from '../../utils/fs-helpers.js';\nimport type { SourceAdapter, SourceParseFileDiagnostics } from '../source-adapter.js';\nimport { getDefaultOpenCodeDbPathCandidates } from './opencode-db-path-resolver.js';\nimport { loadNodeSqliteModule, type SqliteModule } from './node-sqlite-loader.js';\nimport { parseOpenCodeMessageRows } from './opencode-row-parser.js';\nimport { runWithBusyRetries, type SleepFn } from './opencode-retry-policy.js';\nimport { queryOpenCodeMessageRows } from './opencode-sqlite-query.js';\n\nconst DEFAULT_BUSY_RETRY_COUNT = 2;\nconst DEFAULT_BUSY_RETRY_DELAY_MS = 50;\n\ntype PathPredicate = (filePath: string) => Promise<boolean>;\n\nexport type OpenCodeSourceAdapterOptions = {\n dbPath?: string;\n resolveDefaultDbPaths?: () => string[];\n pathExists?: PathPredicate;\n pathReadable?: PathPredicate;\n pathIsFile?: PathPredicate;\n loadSqliteModule?: () => Promise<SqliteModule>;\n maxBusyRetries?: number;\n busyRetryDelayMs?: number;\n sleep?: SleepFn;\n};\n\nfunction isBlankText(value: string): boolean {\n return value.trim().length === 0;\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n}\n\nexport class OpenCodeSourceAdapter implements SourceAdapter {\n public readonly id = 'opencode' as const;\n\n private readonly explicitDbPath?: string;\n private readonly resolveDefaultDbPaths: () => string[];\n private readonly pathExists: PathPredicate;\n private readonly pathReadable: PathPredicate;\n private readonly pathIsFile: PathPredicate;\n private readonly loadSqliteModule: () => Promise<SqliteModule>;\n private readonly maxBusyRetries: number;\n private readonly busyRetryDelayMs: number;\n private readonly sleep: SleepFn;\n\n public constructor(options: OpenCodeSourceAdapterOptions = {}) {\n this.explicitDbPath = options.dbPath;\n this.resolveDefaultDbPaths =\n options.resolveDefaultDbPaths ?? getDefaultOpenCodeDbPathCandidates;\n this.pathExists = options.pathExists ?? pathExists;\n this.pathReadable = options.pathReadable ?? pathReadable;\n this.pathIsFile = options.pathIsFile ?? pathIsFile;\n this.loadSqliteModule = options.loadSqliteModule ?? loadNodeSqliteModule;\n this.maxBusyRetries = Math.max(0, options.maxBusyRetries ?? DEFAULT_BUSY_RETRY_COUNT);\n this.busyRetryDelayMs = Math.max(1, options.busyRetryDelayMs ?? DEFAULT_BUSY_RETRY_DELAY_MS);\n this.sleep = options.sleep ?? sleep;\n }\n\n public async discoverFiles(): Promise<string[]> {\n if (this.explicitDbPath !== undefined) {\n if (isBlankText(this.explicitDbPath)) {\n throw new Error('--opencode-db must be a non-empty path');\n }\n\n const explicitDbPath = this.explicitDbPath.trim();\n const readable = await this.pathReadable(explicitDbPath);\n\n if (!readable) {\n throw new Error(`OpenCode DB path is missing or unreadable: ${explicitDbPath}`);\n }\n\n if ((await this.pathExists(explicitDbPath)) && !(await this.pathIsFile(explicitDbPath))) {\n throw new Error(`OpenCode DB path is not a file: ${explicitDbPath}`);\n }\n\n return [explicitDbPath];\n }\n\n let firstUnreadableCandidatePath: string | undefined;\n\n for (const candidatePath of this.resolveDefaultDbPaths()) {\n if (await this.pathReadable(candidatePath)) {\n if ((await this.pathExists(candidatePath)) && !(await this.pathIsFile(candidatePath))) {\n throw new Error(`OpenCode DB path is not a file: ${candidatePath}`);\n }\n\n return [candidatePath];\n }\n\n if (!firstUnreadableCandidatePath && (await this.pathExists(candidatePath))) {\n firstUnreadableCandidatePath = candidatePath;\n }\n }\n\n if (firstUnreadableCandidatePath) {\n throw new Error(`OpenCode DB path is unreadable: ${firstUnreadableCandidatePath}`);\n }\n\n return [];\n }\n\n public async parseFile(dbPath: string): Promise<UsageEvent[]> {\n const parseDiagnostics = await this.parseFileWithDiagnostics(dbPath);\n return parseDiagnostics.events;\n }\n\n public async parseFileWithDiagnostics(dbPath: string): Promise<SourceParseFileDiagnostics> {\n if (isBlankText(dbPath)) {\n throw new Error('OpenCode DB path must be a non-empty path');\n }\n\n const normalizedDbPath = dbPath.trim();\n const readable = await this.pathReadable(normalizedDbPath);\n\n if (!readable) {\n throw new Error(`OpenCode DB path is unreadable: ${normalizedDbPath}`);\n }\n\n if ((await this.pathExists(normalizedDbPath)) && !(await this.pathIsFile(normalizedDbPath))) {\n throw new Error(`OpenCode DB path is not a file: ${normalizedDbPath}`);\n }\n\n return runWithBusyRetries(() => this.parseFileOnce(normalizedDbPath), {\n dbPath: normalizedDbPath,\n maxBusyRetries: this.maxBusyRetries,\n busyRetryDelayMs: this.busyRetryDelayMs,\n sleep: this.sleep,\n });\n }\n\n private async parseFileOnce(dbPath: string): Promise<SourceParseFileDiagnostics> {\n const sqlite = await this.loadSqliteModule();\n const database = new sqlite.DatabaseSync(dbPath, { readOnly: true, timeout: 0 });\n\n try {\n const messageRows = queryOpenCodeMessageRows(database);\n return parseOpenCodeMessageRows(messageRows, this.id);\n } finally {\n database.close();\n }\n }\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nimport { createUsageEvent } from '../../domain/usage-event.js';\nimport type { UsageEvent } from '../../domain/usage-event.js';\nimport type { NumberLike } from '../../domain/normalization.js';\nimport { asRecord } from '../../utils/as-record.js';\nimport { discoverJsonlFiles } from '../../utils/discover-jsonl-files.js';\nimport { pathIsDirectory, pathReadable } from '../../utils/fs-helpers.js';\nimport { readJsonlObjects } from '../../utils/read-jsonl-objects.js';\nimport { asTrimmedText, isBlankText, toNumberLike } from '../parsing-utils.js';\nimport type { SourceAdapter } from '../source-adapter.js';\n\nconst defaultSessionsDir = path.join(os.homedir(), '.pi', 'agent', 'sessions');\n\ntype ProviderFilter = (provider: string | undefined) => boolean;\n\ntype PiSessionState = {\n sessionId?: string;\n sessionTimestamp?: string;\n repoRoot?: string;\n provider?: string;\n model?: string;\n};\n\ntype PiUsageExtract = {\n inputTokens?: NumberLike;\n outputTokens?: NumberLike;\n reasoningTokens?: NumberLike;\n cacheReadTokens?: NumberLike;\n cacheWriteTokens?: NumberLike;\n totalTokens?: NumberLike;\n costUsd?: NumberLike;\n};\n\nexport type PiSourceAdapterOptions = {\n sessionsDir?: string;\n providerFilter?: ProviderFilter;\n requireSessionsDir?: boolean;\n};\n\nconst PI_MESSAGE_LINE_PATTERN = /\"type\"\\s*:\\s*\"message\"/u;\nconst PI_SESSION_LINE_PATTERN = /\"type\"\\s*:\\s*\"session\"/u;\nconst PI_MODEL_CHANGE_LINE_PATTERN = /\"type\"\\s*:\\s*\"model_change\"/u;\n\nfunction shouldParsePiJsonlLine(lineText: string): boolean {\n return (\n PI_MESSAGE_LINE_PATTERN.test(lineText) ||\n PI_SESSION_LINE_PATTERN.test(lineText) ||\n PI_MODEL_CHANGE_LINE_PATTERN.test(lineText)\n );\n}\n\nconst allowAllProviders: ProviderFilter = () => true;\n\nconst UNIX_SECONDS_ABS_CUTOFF = 10_000_000_000;\n\nfunction normalizeTimestampCandidate(candidate: unknown): string | undefined {\n let date: Date | undefined;\n\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n const timestampMs =\n Math.abs(candidate) <= UNIX_SECONDS_ABS_CUTOFF ? candidate * 1000 : candidate;\n date = new Date(timestampMs);\n } else {\n const normalizedText = asTrimmedText(candidate);\n\n if (!normalizedText) {\n return undefined;\n }\n\n date = new Date(normalizedText);\n }\n\n if (Number.isNaN(date.getTime())) {\n return undefined;\n }\n\n return date.toISOString();\n}\n\nfunction resolveTimestamp(\n line: Record<string, unknown>,\n message: Record<string, unknown> | undefined,\n state: PiSessionState,\n): string | undefined {\n const candidates = [line.timestamp, message?.timestamp, state.sessionTimestamp];\n\n for (const candidate of candidates) {\n const normalizedTimestamp = normalizeTimestampCandidate(candidate);\n\n if (normalizedTimestamp) {\n return normalizedTimestamp;\n }\n }\n\n return undefined;\n}\n\nfunction extractUsageFromRecord(usage: Record<string, unknown>): PiUsageExtract | undefined {\n const cost = asRecord(usage.cost);\n\n const extracted: PiUsageExtract = {\n inputTokens: toNumberLike(usage.input),\n outputTokens: toNumberLike(usage.output),\n reasoningTokens: toNumberLike(\n usage.reasoning ?? usage.reasoningTokens ?? usage.reasoningOutput ?? usage.outputReasoning,\n ),\n cacheReadTokens: toNumberLike(usage.cacheRead),\n cacheWriteTokens: toNumberLike(usage.cacheWrite),\n totalTokens: toNumberLike(usage.totalTokens),\n costUsd: toNumberLike(cost?.total),\n };\n\n const toFiniteNumber = (value: NumberLike | undefined): number | undefined => {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n if (typeof value === 'string' && value.trim().length === 0) {\n return undefined;\n }\n\n const parsed = typeof value === 'number' ? value : Number(value);\n\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n\n return parsed;\n };\n\n const usageCandidates = [\n extracted.inputTokens,\n extracted.outputTokens,\n extracted.reasoningTokens,\n extracted.cacheReadTokens,\n extracted.cacheWriteTokens,\n extracted.totalTokens,\n ];\n const hasPositiveUsageSignal = usageCandidates.some((value) => {\n const parsed = toFiniteNumber(value);\n return parsed !== undefined && parsed > 0;\n });\n const explicitCost = toFiniteNumber(extracted.costUsd);\n const hasPositiveCostSignal = explicitCost !== undefined && explicitCost > 0;\n\n return hasPositiveUsageSignal || hasPositiveCostSignal ? extracted : undefined;\n}\n\nfunction extractUsage(line: Record<string, unknown>, message: Record<string, unknown> | undefined) {\n const lineUsage = asRecord(line.usage);\n const messageUsage = asRecord(message?.usage);\n\n if (lineUsage) {\n const extractedLineUsage = extractUsageFromRecord(lineUsage);\n\n if (extractedLineUsage) {\n return extractedLineUsage;\n }\n }\n\n if (!messageUsage) {\n return undefined;\n }\n\n return extractUsageFromRecord(messageUsage);\n}\n\nfunction getFallbackSessionId(filePath: string): string {\n return path.basename(filePath, '.jsonl');\n}\n\nfunction resolveRepoRootFromRecord(\n record: Record<string, unknown> | undefined,\n): string | undefined {\n if (!record) {\n return undefined;\n }\n\n const pathRecord = asRecord(record.path);\n\n return (\n asTrimmedText(pathRecord?.root) ??\n asTrimmedText(pathRecord?.cwd) ??\n asTrimmedText(record.cwd) ??\n asTrimmedText(record.repo_root) ??\n asTrimmedText(record.repoRoot) ??\n asTrimmedText(record.project_root) ??\n asTrimmedText(record.projectRoot)\n );\n}\n\nexport class PiSourceAdapter implements SourceAdapter {\n public readonly id = 'pi' as const;\n\n private readonly sessionsDir: string;\n private readonly providerFilter: ProviderFilter;\n private readonly requireSessionsDir: boolean;\n\n public constructor(options: PiSourceAdapterOptions = {}) {\n this.sessionsDir = options.sessionsDir ?? defaultSessionsDir;\n this.providerFilter = options.providerFilter ?? allowAllProviders;\n this.requireSessionsDir = options.requireSessionsDir ?? false;\n }\n\n public async discoverFiles(): Promise<string[]> {\n if (isBlankText(this.sessionsDir)) {\n throw new Error('PI sessions directory must be a non-empty path');\n }\n\n const normalizedSessionsDir = this.sessionsDir.trim();\n\n if (this.requireSessionsDir && !(await pathReadable(normalizedSessionsDir))) {\n throw new Error(`PI sessions directory is missing or unreadable: ${normalizedSessionsDir}`);\n }\n\n if (this.requireSessionsDir && !(await pathIsDirectory(normalizedSessionsDir))) {\n throw new Error(`PI sessions directory is not a directory: ${normalizedSessionsDir}`);\n }\n\n return discoverJsonlFiles(normalizedSessionsDir);\n }\n\n public async parseFile(filePath: string): Promise<UsageEvent[]> {\n const events: UsageEvent[] = [];\n const state: PiSessionState = { sessionId: getFallbackSessionId(filePath) };\n\n for await (const line of readJsonlObjects(filePath, {\n shouldParseLine: shouldParsePiJsonlLine,\n })) {\n if (line.type === 'session') {\n state.sessionId = asTrimmedText(line.id) ?? state.sessionId;\n state.sessionTimestamp = asTrimmedText(line.timestamp) ?? state.sessionTimestamp;\n state.repoRoot = resolveRepoRootFromRecord(line) ?? state.repoRoot;\n continue;\n }\n\n if (line.type === 'model_change') {\n state.provider = asTrimmedText(line.provider) ?? state.provider;\n state.model = asTrimmedText(line.modelId) ?? asTrimmedText(line.model) ?? state.model;\n state.repoRoot = resolveRepoRootFromRecord(line) ?? state.repoRoot;\n continue;\n }\n\n if (line.type !== 'message') {\n continue;\n }\n\n const message = asRecord(line.message);\n const usage = extractUsage(line, message);\n\n if (!usage) {\n continue;\n }\n\n const provider =\n asTrimmedText(line.provider) ?? asTrimmedText(message?.provider) ?? state.provider;\n\n if (!this.providerFilter(provider)) {\n continue;\n }\n\n const timestamp = resolveTimestamp(line, message, state);\n\n if (!timestamp || !state.sessionId) {\n continue;\n }\n\n const model =\n asTrimmedText(line.model) ??\n asTrimmedText(line.modelId) ??\n asTrimmedText(message?.model) ??\n state.model;\n const repoRoot =\n resolveRepoRootFromRecord(line) ?? resolveRepoRootFromRecord(message) ?? state.repoRoot;\n\n try {\n events.push(\n createUsageEvent({\n source: this.id,\n sessionId: state.sessionId,\n timestamp,\n repoRoot,\n provider,\n model,\n ...usage,\n }),\n );\n } catch {\n continue;\n }\n }\n\n return events;\n }\n}\n\nexport function getDefaultPiSessionsDir(): string {\n return defaultSessionsDir;\n}\n","import { CodexSourceAdapter } from './codex/codex-source-adapter.js';\nimport { DroidSourceAdapter } from './droid/droid-source-adapter.js';\nimport { GeminiSourceAdapter } from './gemini/gemini-source-adapter.js';\nimport { OpenCodeSourceAdapter } from './opencode/opencode-source-adapter.js';\nimport { PiSourceAdapter } from './pi/pi-source-adapter.js';\nimport type { SourceAdapter } from './source-adapter.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\ntype SourceRegistration = {\n id: string;\n sourceDirOverride: { kind: 'directory' } | { kind: 'unsupported'; flag: string };\n create: (\n options: CreateDefaultAdaptersOptions,\n sourceDirectoryOverrides: ReadonlyMap<string, string>,\n ) => SourceAdapter;\n};\n\nexport type CreateDefaultAdaptersOptions = {\n piDir?: string;\n codexDir?: string;\n geminiDir?: string;\n droidDir?: string;\n opencodeDb?: string;\n sourceDir?: string[];\n};\n\nfunction parseSourceDirectoryOverrides(entries: string[] | undefined): Map<string, string> {\n const overrides = new Map<string, string>();\n\n if (!entries || entries.length === 0) {\n return overrides;\n }\n\n for (const entry of entries) {\n const separatorIndex = entry.indexOf('=');\n\n if (separatorIndex <= 0 || separatorIndex >= entry.length - 1) {\n throw new Error('--source-dir must use format <source-id>=<path>');\n }\n\n const sourceId = entry.slice(0, separatorIndex).trim().toLowerCase();\n const directoryPath = entry.slice(separatorIndex + 1).trim();\n\n if (!sourceId || !directoryPath) {\n throw new Error('--source-dir must use non-empty <source-id>=<path> values');\n }\n\n if (overrides.has(sourceId)) {\n throw new Error(`Duplicate --source-dir source id: ${sourceId}`);\n }\n\n overrides.set(sourceId, directoryPath);\n }\n\n return overrides;\n}\n\nconst sourceRegistrations: readonly SourceRegistration[] = [\n {\n id: 'pi',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig('pi', options.piDir, sourceDirectoryOverrides);\n\n return new PiSourceAdapter({\n sessionsDir: directoryConfig.path,\n requireSessionsDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'codex',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig(\n 'codex',\n options.codexDir,\n sourceDirectoryOverrides,\n );\n\n return new CodexSourceAdapter({\n sessionsDir: directoryConfig.path,\n requireSessionsDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'gemini',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig(\n 'gemini',\n options.geminiDir,\n sourceDirectoryOverrides,\n );\n\n return new GeminiSourceAdapter({\n geminiDir: directoryConfig.path,\n requireGeminiDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'droid',\n sourceDirOverride: { kind: 'directory' },\n create: (options, sourceDirectoryOverrides) => {\n const directoryConfig = resolveDirectoryConfig(\n 'droid',\n options.droidDir,\n sourceDirectoryOverrides,\n );\n\n return new DroidSourceAdapter({\n sessionsDir: directoryConfig.path,\n requireSessionsDir: directoryConfig.requireExistingPath,\n });\n },\n },\n {\n id: 'opencode',\n sourceDirOverride: { kind: 'unsupported', flag: '--opencode-db' },\n create: (options) =>\n new OpenCodeSourceAdapter({\n dbPath: options.opencodeDb,\n }),\n },\n];\n\nconst sourceDirUnsupportedFlags = new Map(\n sourceRegistrations\n .filter(\n (\n source,\n ): source is SourceRegistration & {\n sourceDirOverride: { kind: 'unsupported'; flag: string };\n } => source.sourceDirOverride.kind === 'unsupported',\n )\n .map((source) => [source.id, source.sourceDirOverride.flag]),\n);\n\nconst sourceDirSupportedIds = new Set(\n sourceRegistrations\n .filter(\n (source): source is SourceRegistration & { sourceDirOverride: { kind: 'directory' } } =>\n source.sourceDirOverride.kind === 'directory',\n )\n .map((source) => source.id),\n);\n\nfunction validateSourceDirectoryOverrideIds(\n sourceDirectoryOverrides: ReadonlyMap<string, string>,\n): void {\n const nonDirectorySourceOverrides = [...sourceDirectoryOverrides.keys()].filter((sourceId) =>\n sourceDirUnsupportedFlags.has(sourceId),\n );\n\n if (nonDirectorySourceOverrides.length > 0) {\n const sourceId = nonDirectorySourceOverrides[0];\n const flag = sourceDirUnsupportedFlags.get(sourceId);\n\n throw new Error(`--source-dir does not support \"${sourceId}\". Use ${flag} instead.`);\n }\n\n const unknownSourceIds = [...sourceDirectoryOverrides.keys()].filter(\n (sourceId) => !sourceDirSupportedIds.has(sourceId),\n );\n\n if (unknownSourceIds.length === 0) {\n return;\n }\n\n const allowedSourceIds = [...sourceDirSupportedIds].sort(compareByCodePoint);\n\n throw new Error(\n `Unknown --source-dir source id(s): ${unknownSourceIds.join(', ')}. Allowed values: ${allowedSourceIds.join(', ')}`,\n );\n}\n\nfunction validateOpencodeOverride(opencodeDb: string | undefined): void {\n if (opencodeDb === undefined) {\n return;\n }\n\n if (opencodeDb.trim().length === 0) {\n throw new Error('--opencode-db must be a non-empty path');\n }\n}\n\nfunction validateDirectoryOverride(\n optionName: '--pi-dir' | '--codex-dir' | '--gemini-dir' | '--droid-dir',\n value: string | undefined,\n): void {\n if (value === undefined) {\n return;\n }\n\n if (value.trim().length === 0) {\n throw new Error(`${optionName} must be a non-empty path`);\n }\n}\n\nfunction resolveDirectoryConfig(\n sourceId: string,\n explicitDirectory: string | undefined,\n sourceDirectoryOverrides: ReadonlyMap<string, string>,\n): {\n path: string | undefined;\n requireExistingPath: boolean;\n} {\n if (explicitDirectory !== undefined) {\n return {\n path: explicitDirectory,\n requireExistingPath: true,\n };\n }\n\n const sourceDirOverride = sourceDirectoryOverrides.get(sourceId);\n\n if (sourceDirOverride !== undefined) {\n return {\n path: sourceDirOverride,\n requireExistingPath: true,\n };\n }\n\n return {\n path: undefined,\n requireExistingPath: false,\n };\n}\n\nexport function getDefaultSourceIds(): string[] {\n return sourceRegistrations.map((source) => source.id);\n}\n\nexport function createDefaultAdapters(options: CreateDefaultAdaptersOptions): SourceAdapter[] {\n validateOpencodeOverride(options.opencodeDb);\n validateDirectoryOverride('--pi-dir', options.piDir);\n validateDirectoryOverride('--codex-dir', options.codexDir);\n validateDirectoryOverride('--gemini-dir', options.geminiDir);\n validateDirectoryOverride('--droid-dir', options.droidDir);\n\n const sourceDirectoryOverrides = parseSourceDirectoryOverrides(options.sourceDir);\n validateSourceDirectoryOverrideIds(sourceDirectoryOverrides);\n\n return sourceRegistrations.map((source) => source.create(options, sourceDirectoryOverrides));\n}\n","export type ReportGranularity = 'daily' | 'weekly' | 'monthly';\n\ntype LocalDateParts = {\n year: number;\n month: number;\n day: number;\n};\n\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\n\nfunction getDateFormatter(timezone: string): Intl.DateTimeFormat {\n const cachedFormatter = formatterCache.get(timezone);\n\n if (cachedFormatter) {\n return cachedFormatter;\n }\n\n const formatter = new Intl.DateTimeFormat('en-CA', {\n timeZone: timezone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n });\n formatterCache.set(timezone, formatter);\n return formatter;\n}\n\nfunction extractLocalDateParts(timestampIso: string, timezone: string): LocalDateParts {\n const date = new Date(timestampIso);\n\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid event timestamp: ${timestampIso}`);\n }\n\n const formatter = getDateFormatter(timezone);\n const parts = formatter.formatToParts(date);\n\n const year = Number(parts.find((part) => part.type === 'year')?.value);\n const month = Number(parts.find((part) => part.type === 'month')?.value);\n const day = Number(parts.find((part) => part.type === 'day')?.value);\n\n if (!year || !month || !day) {\n throw new Error(`Could not resolve local date parts for timestamp: ${timestampIso}`);\n }\n\n return { year, month, day };\n}\n\nfunction createUtcDate(localDate: LocalDateParts): Date {\n return new Date(Date.UTC(localDate.year, localDate.month - 1, localDate.day));\n}\n\nfunction addDays(date: Date, days: number): Date {\n return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);\n}\n\nfunction toIsoDayOfWeek(date: Date): number {\n const utcDay = date.getUTCDay();\n return utcDay === 0 ? 7 : utcDay;\n}\n\nfunction getIsoWeekParts(localDate: LocalDateParts): { weekYear: number; weekNumber: number } {\n const localUtcDate = createUtcDate(localDate);\n const isoDay = toIsoDayOfWeek(localUtcDate);\n\n const currentWeekMonday = addDays(localUtcDate, -(isoDay - 1));\n const currentWeekThursday = addDays(localUtcDate, 4 - isoDay);\n const weekYear = currentWeekThursday.getUTCFullYear();\n\n const jan4 = new Date(Date.UTC(weekYear, 0, 4));\n const jan4IsoDay = toIsoDayOfWeek(jan4);\n const firstWeekMonday = addDays(jan4, -(jan4IsoDay - 1));\n\n const diffMs = currentWeekMonday.getTime() - firstWeekMonday.getTime();\n const weekNumber = Math.floor(diffMs / (7 * 24 * 60 * 60 * 1000)) + 1;\n\n return { weekYear, weekNumber };\n}\n\nexport function getPeriodKey(\n timestampIso: string,\n granularity: ReportGranularity,\n timezone: string,\n): string {\n const localDate = extractLocalDateParts(timestampIso, timezone);\n\n if (granularity === 'daily') {\n return `${localDate.year}-${String(localDate.month).padStart(2, '0')}-${String(localDate.day).padStart(2, '0')}`;\n }\n\n if (granularity === 'monthly') {\n return `${localDate.year}-${String(localDate.month).padStart(2, '0')}`;\n }\n\n const isoWeek = getIsoWeekParts(localDate);\n return `${isoWeek.weekYear}-W${String(isoWeek.weekNumber).padStart(2, '0')}`;\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport type {\n GrandTotalRow,\n ModelUsageBreakdown,\n PeriodCombinedRow,\n PeriodSourceRow,\n UsageReportRow,\n UsageTotals,\n} from '../domain/usage-report-row.js';\nimport { normalizeModelList } from '../domain/normalization.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport { getPeriodKey, type ReportGranularity } from '../utils/time-buckets.js';\n\nexport type AggregateUsageOptions = {\n granularity: ReportGranularity;\n timezone: string;\n sourceOrder?: string[];\n};\n\ntype RowAccumulator = {\n totals: UsageTotals;\n modelTotals: Map<string, UsageTotals>;\n};\n\nconst USD_PRECISION_SCALE = 1_000_000_000_000;\n\nfunction addUsd(left: number, right: number): number {\n return Math.round((left + right) * USD_PRECISION_SCALE) / USD_PRECISION_SCALE;\n}\n\nfunction createEmptyTotals(): UsageTotals {\n return {\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n totalTokens: 0,\n };\n}\n\nfunction createRowAccumulator(): RowAccumulator {\n return {\n totals: createEmptyTotals(),\n modelTotals: new Map<string, UsageTotals>(),\n };\n}\n\nfunction addEventToTotals(target: UsageTotals, event: UsageEvent): void {\n target.inputTokens += event.inputTokens;\n target.outputTokens += event.outputTokens;\n target.reasoningTokens += event.reasoningTokens;\n target.cacheReadTokens += event.cacheReadTokens;\n target.cacheWriteTokens += event.cacheWriteTokens;\n target.totalTokens += event.totalTokens;\n\n if (event.costUsd === undefined) {\n target.costIncomplete = true;\n return;\n }\n\n target.costUsd = addUsd(target.costUsd ?? 0, event.costUsd);\n}\n\nfunction normalizeModelKey(model: string | undefined): string | undefined {\n if (!model) {\n return undefined;\n }\n\n const normalized = model.trim().toLowerCase();\n return normalized || undefined;\n}\n\nfunction addEventToAccumulator(accumulator: RowAccumulator, event: UsageEvent): void {\n addEventToTotals(accumulator.totals, event);\n\n const normalizedModel = normalizeModelKey(event.model);\n\n if (!normalizedModel) {\n return;\n }\n\n const existingTotals = accumulator.modelTotals.get(normalizedModel) ?? createEmptyTotals();\n addEventToTotals(existingTotals, event);\n accumulator.modelTotals.set(normalizedModel, existingTotals);\n}\n\nfunction addTotals(target: UsageTotals, source: UsageTotals): void {\n target.inputTokens += source.inputTokens;\n target.outputTokens += source.outputTokens;\n target.reasoningTokens += source.reasoningTokens;\n target.cacheReadTokens += source.cacheReadTokens;\n target.cacheWriteTokens += source.cacheWriteTokens;\n target.totalTokens += source.totalTokens;\n\n if (source.costUsd !== undefined) {\n target.costUsd = addUsd(target.costUsd ?? 0, source.costUsd);\n }\n\n if (source.costIncomplete) {\n target.costIncomplete = true;\n }\n}\n\nfunction mergeModelTotals(\n targetModelTotals: Map<string, UsageTotals>,\n sourceModelTotals: ReadonlyMap<string, UsageTotals>,\n): void {\n for (const [model, sourceTotals] of sourceModelTotals) {\n const targetTotals = targetModelTotals.get(model) ?? createEmptyTotals();\n addTotals(targetTotals, sourceTotals);\n targetModelTotals.set(model, targetTotals);\n }\n}\n\nfunction toModelUsageBreakdown(\n modelTotals: ReadonlyMap<string, UsageTotals>,\n): ModelUsageBreakdown[] {\n const sortedModels = normalizeModelList(modelTotals.keys());\n\n return sortedModels.map((model) => {\n const totals = modelTotals.get(model) ?? createEmptyTotals();\n\n return {\n model,\n ...totals,\n };\n });\n}\n\nfunction sourceSortComparator(\n left: string,\n right: string,\n sourceWeightMap: ReadonlyMap<string, number>,\n): number {\n const leftWeight = sourceWeightMap.get(left) ?? Number.MAX_SAFE_INTEGER;\n const rightWeight = sourceWeightMap.get(right) ?? Number.MAX_SAFE_INTEGER;\n\n if (leftWeight !== rightWeight) {\n return leftWeight - rightWeight;\n }\n\n return compareByCodePoint(left, right);\n}\n\nexport function aggregateUsage(\n events: UsageEvent[],\n options: AggregateUsageOptions,\n): UsageReportRow[] {\n const sourceWeightMap = new Map<string, number>();\n\n for (const [index, source] of (options.sourceOrder ?? []).entries()) {\n sourceWeightMap.set(source, index);\n }\n\n const periodMap = new Map<string, Map<string, RowAccumulator>>();\n\n for (const event of events) {\n const periodKey = getPeriodKey(event.timestamp, options.granularity, options.timezone);\n const periodSources = periodMap.get(periodKey) ?? new Map<string, RowAccumulator>();\n periodMap.set(periodKey, periodSources);\n\n const rowAccumulator = periodSources.get(event.source) ?? createRowAccumulator();\n periodSources.set(event.source, rowAccumulator);\n\n addEventToAccumulator(rowAccumulator, event);\n }\n\n const sortedPeriodKeys = [...periodMap.keys()].sort(compareByCodePoint);\n const rows: UsageReportRow[] = [];\n const grandTotals = createEmptyTotals();\n const grandModelTotals = new Map<string, UsageTotals>();\n\n for (const periodKey of sortedPeriodKeys) {\n const sourceMap = periodMap.get(periodKey);\n\n if (!sourceMap) {\n continue;\n }\n\n const periodCombinedTotals = createEmptyTotals();\n const periodCombinedModelTotals = new Map<string, UsageTotals>();\n\n const sortedSources = [...sourceMap.keys()].sort((left, right) =>\n sourceSortComparator(left, right, sourceWeightMap),\n );\n\n for (const source of sortedSources) {\n const accumulator = sourceMap.get(source);\n\n if (!accumulator) {\n continue;\n }\n\n const sourceRow: PeriodSourceRow = {\n rowType: 'period_source',\n periodKey,\n source,\n models: normalizeModelList(accumulator.modelTotals.keys()),\n modelBreakdown: toModelUsageBreakdown(accumulator.modelTotals),\n ...accumulator.totals,\n };\n\n rows.push(sourceRow);\n\n addTotals(periodCombinedTotals, accumulator.totals);\n addTotals(grandTotals, accumulator.totals);\n mergeModelTotals(periodCombinedModelTotals, accumulator.modelTotals);\n mergeModelTotals(grandModelTotals, accumulator.modelTotals);\n }\n\n if (sortedSources.length > 1) {\n const combinedRow: PeriodCombinedRow = {\n rowType: 'period_combined',\n periodKey,\n source: 'combined',\n models: normalizeModelList(periodCombinedModelTotals.keys()),\n modelBreakdown: toModelUsageBreakdown(periodCombinedModelTotals),\n ...periodCombinedTotals,\n };\n\n rows.push(combinedRow);\n }\n }\n\n const finalizedGrandTotals =\n events.length === 0 && grandTotals.costUsd === undefined && grandTotals.costIncomplete !== true\n ? { ...grandTotals, costUsd: 0 }\n : grandTotals;\n\n const grandTotalRow: GrandTotalRow = {\n rowType: 'grand_total',\n periodKey: 'ALL',\n source: 'combined',\n models: normalizeModelList(grandModelTotals.keys()),\n modelBreakdown: toModelUsageBreakdown(grandModelTotals),\n ...finalizedGrandTotals,\n };\n\n rows.push(grandTotalRow);\n\n return rows;\n}\n","export type EfficiencyUsageTotals = {\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n totalTokens: number;\n costUsd?: number;\n costIncomplete?: boolean;\n};\n\nexport type EfficiencyOutcomeTotals = {\n commitCount: number;\n linesAdded: number;\n linesDeleted: number;\n linesChanged: number;\n};\n\nexport type EfficiencyDerivedMetrics = {\n usdPerCommit?: number;\n usdPer1kLinesChanged?: number;\n tokensPerCommit?: number;\n nonCacheTokensPerCommit?: number;\n commitsPerUsd?: number;\n};\n\nexport type EfficiencyPeriodRow = EfficiencyUsageTotals &\n EfficiencyOutcomeTotals &\n EfficiencyDerivedMetrics & {\n rowType: 'period';\n periodKey: string;\n };\n\nexport type EfficiencyGrandTotalRow = EfficiencyUsageTotals &\n EfficiencyOutcomeTotals &\n EfficiencyDerivedMetrics & {\n rowType: 'grand_total';\n periodKey: 'ALL';\n };\n\nexport type EfficiencyRow = EfficiencyPeriodRow | EfficiencyGrandTotalRow;\n\nexport function createEmptyEfficiencyUsageTotals(): EfficiencyUsageTotals {\n return {\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n totalTokens: 0,\n costUsd: 0,\n };\n}\n\nexport function createEmptyEfficiencyOutcomeTotals(): EfficiencyOutcomeTotals {\n return {\n commitCount: 0,\n linesAdded: 0,\n linesDeleted: 0,\n linesChanged: 0,\n };\n}\n","import type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport {\n createEmptyEfficiencyOutcomeTotals,\n createEmptyEfficiencyUsageTotals,\n type EfficiencyDerivedMetrics,\n type EfficiencyOutcomeTotals,\n type EfficiencyRow,\n type EfficiencyUsageTotals,\n} from './efficiency-row.js';\n\nconst USD_PRECISION_SCALE = 1_000_000_000_000;\n\nexport type AggregateEfficiencyOptions = {\n usageRows: UsageReportRow[];\n periodOutcomes: ReadonlyMap<string, EfficiencyOutcomeTotals>;\n};\n\nfunction addUsd(left: number, right: number): number {\n return Math.round((left + right) * USD_PRECISION_SCALE) / USD_PRECISION_SCALE;\n}\n\nfunction toUsageTotals(row: UsageReportRow): EfficiencyUsageTotals {\n return {\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n costUsd: row.costUsd,\n costIncomplete: row.costIncomplete,\n };\n}\n\nfunction buildUsageTotalsByPeriod(usageRows: UsageReportRow[]): Map<string, EfficiencyUsageTotals> {\n const combinedByPeriod = new Map<string, EfficiencyUsageTotals>();\n const sourceByPeriod = new Map<string, EfficiencyUsageTotals>();\n\n for (const row of usageRows) {\n if (row.rowType === 'grand_total') {\n continue;\n }\n\n if (row.rowType === 'period_combined') {\n combinedByPeriod.set(row.periodKey, toUsageTotals(row));\n continue;\n }\n\n const existingSourceTotals =\n sourceByPeriod.get(row.periodKey) ?? createEmptyEfficiencyUsageTotals();\n sourceByPeriod.set(row.periodKey, addUsageTotals(existingSourceTotals, toUsageTotals(row)));\n }\n\n const periodKeys = new Set<string>([...combinedByPeriod.keys(), ...sourceByPeriod.keys()]);\n const usageTotalsByPeriod = new Map<string, EfficiencyUsageTotals>();\n\n for (const periodKey of periodKeys) {\n usageTotalsByPeriod.set(\n periodKey,\n combinedByPeriod.get(periodKey) ??\n sourceByPeriod.get(periodKey) ??\n createEmptyEfficiencyUsageTotals(),\n );\n }\n\n return usageTotalsByPeriod;\n}\n\nfunction addOutcomeTotals(\n left: EfficiencyOutcomeTotals,\n right: EfficiencyOutcomeTotals,\n): EfficiencyOutcomeTotals {\n return {\n commitCount: left.commitCount + right.commitCount,\n linesAdded: left.linesAdded + right.linesAdded,\n linesDeleted: left.linesDeleted + right.linesDeleted,\n linesChanged: left.linesChanged + right.linesChanged,\n };\n}\n\nfunction addUsageTotals(\n left: EfficiencyUsageTotals,\n right: EfficiencyUsageTotals,\n): EfficiencyUsageTotals {\n const hasUnknownCost =\n (left.costIncomplete === true && left.costUsd === undefined) ||\n (right.costIncomplete === true && right.costUsd === undefined);\n const isNeutralZeroCost = (value: EfficiencyUsageTotals): boolean =>\n value.totalTokens === 0 && value.costUsd === 0 && value.costIncomplete !== true;\n const leftKnownCost =\n left.costUsd !== undefined && !isNeutralZeroCost(left) ? left.costUsd : undefined;\n const rightKnownCost =\n right.costUsd !== undefined && !isNeutralZeroCost(right) ? right.costUsd : undefined;\n\n let costUsd =\n leftKnownCost !== undefined && rightKnownCost !== undefined\n ? addUsd(leftKnownCost, rightKnownCost)\n : (leftKnownCost ?? rightKnownCost);\n\n if (hasUnknownCost && (costUsd === undefined || costUsd === 0)) {\n costUsd = undefined;\n }\n\n return {\n inputTokens: left.inputTokens + right.inputTokens,\n outputTokens: left.outputTokens + right.outputTokens,\n reasoningTokens: left.reasoningTokens + right.reasoningTokens,\n cacheReadTokens: left.cacheReadTokens + right.cacheReadTokens,\n cacheWriteTokens: left.cacheWriteTokens + right.cacheWriteTokens,\n totalTokens: left.totalTokens + right.totalTokens,\n costUsd,\n costIncomplete: left.costIncomplete || right.costIncomplete ? true : undefined,\n };\n}\n\nfunction computeDerivedMetrics(\n usage: EfficiencyUsageTotals,\n outcomes: EfficiencyOutcomeTotals,\n): EfficiencyDerivedMetrics {\n const costUsd = usage.costUsd;\n const nonCacheTotalTokens = usage.inputTokens + usage.outputTokens + usage.reasoningTokens;\n\n return {\n usdPerCommit:\n costUsd !== undefined && outcomes.commitCount > 0\n ? costUsd / outcomes.commitCount\n : undefined,\n usdPer1kLinesChanged:\n costUsd !== undefined && outcomes.linesChanged > 0\n ? costUsd / (outcomes.linesChanged / 1_000)\n : undefined,\n tokensPerCommit:\n outcomes.commitCount > 0 ? usage.totalTokens / outcomes.commitCount : undefined,\n nonCacheTokensPerCommit:\n outcomes.commitCount > 0 ? nonCacheTotalTokens / outcomes.commitCount : undefined,\n commitsPerUsd:\n costUsd !== undefined && costUsd > 0 ? outcomes.commitCount / costUsd : undefined,\n };\n}\n\nexport function aggregateEfficiency(options: AggregateEfficiencyOptions): EfficiencyRow[] {\n const usageTotalsByPeriod = buildUsageTotalsByPeriod(options.usageRows);\n const periodKeys = [\n ...new Set([...usageTotalsByPeriod.keys(), ...options.periodOutcomes.keys()]),\n ].sort(compareByCodePoint);\n\n const rows: EfficiencyRow[] = [];\n let totalUsage = createEmptyEfficiencyUsageTotals();\n let totalOutcomes = createEmptyEfficiencyOutcomeTotals();\n\n for (const periodKey of periodKeys) {\n const usageTotals = usageTotalsByPeriod.get(periodKey) ?? createEmptyEfficiencyUsageTotals();\n const outcomeTotals =\n options.periodOutcomes.get(periodKey) ?? createEmptyEfficiencyOutcomeTotals();\n const hasUsageRow = usageTotalsByPeriod.has(periodKey);\n const hasUsageSignal =\n hasUsageRow &&\n (usageTotals.totalTokens > 0 ||\n usageTotals.costUsd !== undefined ||\n usageTotals.costIncomplete === true);\n\n if (outcomeTotals.commitCount === 0 || !hasUsageSignal) {\n continue;\n }\n\n const derived = computeDerivedMetrics(usageTotals, outcomeTotals);\n\n rows.push({\n rowType: 'period',\n periodKey,\n ...usageTotals,\n ...outcomeTotals,\n ...derived,\n });\n\n totalUsage = addUsageTotals(totalUsage, usageTotals);\n totalOutcomes = addOutcomeTotals(totalOutcomes, outcomeTotals);\n }\n\n const finalizedTotalUsage =\n totalUsage.costUsd === undefined &&\n totalUsage.costIncomplete !== true &&\n totalUsage.totalTokens === 0\n ? { ...totalUsage, costUsd: 0 }\n : totalUsage;\n\n rows.push({\n rowType: 'grand_total',\n periodKey: 'ALL',\n ...finalizedTotalUsage,\n ...totalOutcomes,\n ...computeDerivedMetrics(finalizedTotalUsage, totalOutcomes),\n });\n\n return rows;\n}\n","import { spawn } from 'node:child_process';\nimport { createInterface } from 'node:readline';\nimport path from 'node:path';\nimport { stat } from 'node:fs/promises';\n\nimport { getPeriodKey, type ReportGranularity } from '../utils/time-buckets.js';\nimport {\n createEmptyEfficiencyOutcomeTotals,\n type EfficiencyOutcomeTotals,\n} from './efficiency-row.js';\n\nconst GIT_COMMIT_MARKER = '\\u001f';\nconst SHORTSTAT_PATTERN =\n /(\\d+)\\s+files?\\s+changed(?:,\\s+(\\d+)\\s+insertions?\\(\\+\\))?(?:,\\s+(\\d+)\\s+deletions?\\(-\\))?/u;\n\nexport type GitOutcomeCollectorOptions = {\n repoDir?: string;\n granularity: ReportGranularity;\n timezone: string;\n since?: string;\n until?: string;\n includeMergeCommits?: boolean;\n activeUsageDays?: ReadonlySet<string>;\n};\n\nexport type GitOutcomeEvent = {\n sha: string;\n timestamp: string;\n linesAdded: number;\n linesDeleted: number;\n linesChanged: number;\n};\n\nexport type GitOutcomeCollectionDiagnostics = {\n repoDir: string;\n includeMergeCommits: boolean;\n commitsCollected: number;\n linesAdded: number;\n linesDeleted: number;\n};\n\nexport type GitOutcomeCollectionResult = {\n periodOutcomes: Map<string, EfficiencyOutcomeTotals>;\n totalOutcomes: EfficiencyOutcomeTotals;\n diagnostics: GitOutcomeCollectionDiagnostics;\n};\n\ntype MutableGitOutcomeEvent = {\n sha: string;\n timestampSeconds: number;\n authorEmail: string;\n linesAdded: number;\n linesDeleted: number;\n};\n\ntype GitCommandResult = {\n lines: string[];\n stderr: string;\n exitCode: number;\n};\n\nexport type GitOutcomeCollectorDeps = {\n runGitCommand?: (repoDir: string, args: string[]) => Promise<GitCommandResult>;\n};\n\nfunction shiftDate(value: string, days: number): string {\n const date = new Date(`${value}T00:00:00.000Z`);\n\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid date value: ${value}`);\n }\n\n date.setUTCDate(date.getUTCDate() + days);\n return date.toISOString().slice(0, 10);\n}\n\nfunction escapeGitRegexLiteral(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&');\n}\n\nfunction resolveGitCommandFailureReason(result: GitCommandResult): string {\n return result.stderr.trim() || `git exited with code ${result.exitCode}`;\n}\n\nfunction resolveRepoDir(repoDir: string | undefined): string {\n if (repoDir === undefined) {\n return path.resolve(process.cwd());\n }\n\n const normalizedRepoDir = repoDir.trim();\n\n if (!normalizedRepoDir) {\n throw new Error('--repo-dir must be a non-empty path');\n }\n\n return path.resolve(normalizedRepoDir);\n}\n\nfunction getNodeErrorCode(error: unknown): string | undefined {\n if (typeof error !== 'object' || error === null || !('code' in error)) {\n return undefined;\n }\n\n const record = error as { code?: unknown };\n return typeof record.code === 'string' ? record.code : undefined;\n}\n\nasync function assertRepoDirReadable(repoDir: string): Promise<void> {\n let directoryStats: Awaited<ReturnType<typeof stat>>;\n\n try {\n directoryStats = await stat(repoDir);\n } catch (error) {\n const code = getNodeErrorCode(error);\n\n if (code === 'ENOENT') {\n throw new Error(`Repository path does not exist: ${repoDir}`, { cause: error });\n }\n\n if (code === 'EACCES' || code === 'EPERM') {\n throw new Error(`Repository path is unreadable: ${repoDir}`, { cause: error });\n }\n\n throw error;\n }\n\n if (!directoryStats.isDirectory()) {\n throw new Error(`Repository path is not a directory: ${repoDir}`);\n }\n}\n\nasync function assertGitRepository(\n repoDir: string,\n runCommand: (repoDir: string, args: string[]) => Promise<GitCommandResult>,\n): Promise<void> {\n const gitRepoResult = await runCommand(repoDir, ['rev-parse', '--is-inside-work-tree']);\n\n if (gitRepoResult.exitCode === 0) {\n return;\n }\n\n throw new Error(`Repository is not a git repository: ${repoDir}`);\n}\n\nfunction isNoCommitHistoryFailure(result: GitCommandResult): boolean {\n if (result.exitCode !== 128) {\n return false;\n }\n\n const reason = result.stderr.toLowerCase();\n\n return (\n reason.includes('does not have any commits yet') ||\n reason.includes('needed a single revision') ||\n reason.includes('unknown revision or path not in the working tree') ||\n reason.includes(\"bad revision 'head'\")\n );\n}\n\nfunction createEmptyOutcomeCollection(\n repoDir: string,\n includeMergeCommits: boolean,\n): GitOutcomeCollectionResult {\n return {\n periodOutcomes: new Map(),\n totalOutcomes: createEmptyEfficiencyOutcomeTotals(),\n diagnostics: {\n repoDir,\n includeMergeCommits,\n commitsCollected: 0,\n linesAdded: 0,\n linesDeleted: 0,\n },\n };\n}\n\nfunction isMissingGitUserEmailError(error: unknown): boolean {\n return error instanceof Error && error.message.startsWith('Git user.email is not configured for');\n}\n\nfunction resolveConfiguredEmailFromLines(lines: string[]): string | undefined {\n return lines.map((line) => line.trim()).find((line) => line.length > 0);\n}\n\nfunction resolveEmailFromGitAuthorIdent(lines: string[]): string | undefined {\n const identLine = lines.map((line) => line.trim()).find((line) => line.length > 0);\n\n if (!identLine) {\n return undefined;\n }\n\n const emailMatch = /<([^>]+)>/u.exec(identLine);\n const email = emailMatch?.[1]?.trim();\n\n return email && email.length > 0 ? email : undefined;\n}\n\nasync function resolveConfiguredAuthorEmail(\n repoDir: string,\n runCommand: (repoDir: string, args: string[]) => Promise<GitCommandResult>,\n): Promise<string> {\n const configLookupAttempts: string[][] = [\n ['config', '--get', 'user.email'],\n ['config', '--global', '--get', 'user.email'],\n ];\n\n for (const args of configLookupAttempts) {\n const configResult = await runCommand(repoDir, args);\n\n if (configResult.exitCode === 0) {\n const configuredEmail = resolveConfiguredEmailFromLines(configResult.lines);\n\n if (configuredEmail) {\n return configuredEmail;\n }\n\n continue;\n }\n\n if (configResult.exitCode !== 1) {\n const reason = resolveGitCommandFailureReason(configResult);\n throw new Error(`Failed to resolve git user.email from ${repoDir}: ${reason}`);\n }\n }\n\n const gitAuthorIdentResult = await runCommand(repoDir, ['var', 'GIT_AUTHOR_IDENT']);\n\n if (gitAuthorIdentResult.exitCode === 0) {\n const authorIdentEmail = resolveEmailFromGitAuthorIdent(gitAuthorIdentResult.lines);\n\n if (authorIdentEmail) {\n return authorIdentEmail;\n }\n }\n\n throw new Error(\n `Git user.email is not configured for ${repoDir}. Run: git -C ${repoDir} config user.email \"you@example.com\"`,\n );\n}\n\nfunction toIsoTimestamp(timestampSeconds: number): string {\n const timestamp = new Date(timestampSeconds * 1000);\n\n if (Number.isNaN(timestamp.getTime())) {\n throw new Error(`Invalid git commit timestamp: ${timestampSeconds}`);\n }\n\n return timestamp.toISOString();\n}\n\nfunction parseShortstatLine(\n line: string,\n): { linesAdded: number; linesDeleted: number } | undefined {\n const shortstatMatch = SHORTSTAT_PATTERN.exec(line.trim());\n\n if (!shortstatMatch) {\n return undefined;\n }\n\n const linesAddedRaw = shortstatMatch[2];\n const linesDeletedRaw = shortstatMatch[3];\n\n return {\n linesAdded: linesAddedRaw ? Number.parseInt(linesAddedRaw, 10) : 0,\n linesDeleted: linesDeletedRaw ? Number.parseInt(linesDeletedRaw, 10) : 0,\n };\n}\n\nfunction finalizeCurrentEvent(\n currentEvent: MutableGitOutcomeEvent | undefined,\n events: GitOutcomeEvent[],\n authorEmail: string | undefined,\n): void {\n if (!currentEvent) {\n return;\n }\n\n if (\n authorEmail &&\n currentEvent.authorEmail.trim().toLowerCase() !== authorEmail.trim().toLowerCase()\n ) {\n return;\n }\n\n const timestamp = toIsoTimestamp(currentEvent.timestampSeconds);\n\n events.push({\n sha: currentEvent.sha,\n timestamp,\n linesAdded: currentEvent.linesAdded,\n linesDeleted: currentEvent.linesDeleted,\n linesChanged: currentEvent.linesAdded + currentEvent.linesDeleted,\n });\n}\n\nexport function parseGitLogShortstatLines(\n lines: Iterable<string>,\n authorEmail?: string,\n): GitOutcomeEvent[] {\n const events: GitOutcomeEvent[] = [];\n let currentEvent: MutableGitOutcomeEvent | undefined;\n\n for (const line of lines) {\n if (line.startsWith(GIT_COMMIT_MARKER)) {\n const commitParts = line.slice(1).split(GIT_COMMIT_MARKER);\n const timestampPart = commitParts[0];\n const shaPart = commitParts[1];\n const authorPart = commitParts[2];\n\n if (\n commitParts.length !== 3 ||\n !/^\\d+$/u.test(timestampPart) ||\n !/^[0-9a-f]{7,64}$/iu.test(shaPart) ||\n authorPart.trim().length === 0\n ) {\n throw new Error(`Malformed git commit boundary line: ${line}`);\n }\n\n finalizeCurrentEvent(currentEvent, events, authorEmail);\n currentEvent = {\n timestampSeconds: Number.parseInt(timestampPart, 10),\n sha: shaPart,\n authorEmail: authorPart,\n linesAdded: 0,\n linesDeleted: 0,\n };\n continue;\n }\n\n if (!currentEvent) {\n continue;\n }\n\n const shortstat = parseShortstatLine(line);\n\n if (!shortstat) {\n continue;\n }\n\n currentEvent.linesAdded += shortstat.linesAdded;\n currentEvent.linesDeleted += shortstat.linesDeleted;\n }\n\n finalizeCurrentEvent(currentEvent, events, authorEmail);\n return events;\n}\n\nasync function runGitCommand(repoDir: string, args: string[]): Promise<GitCommandResult> {\n return await new Promise<GitCommandResult>((resolve, reject) => {\n const child = spawn('git', args, {\n cwd: repoDir,\n env: {\n ...process.env,\n LC_ALL: 'C',\n LANG: 'C',\n },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n const lines: string[] = [];\n let stderr = '';\n\n const stdoutReader = createInterface({ input: child.stdout });\n const stdoutPromise = (async () => {\n for await (const line of stdoutReader) {\n lines.push(line);\n }\n })();\n\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n stderr += chunk;\n });\n\n child.once('error', (error) => {\n reject(error);\n });\n\n child.once('close', (exitCode) => {\n void stdoutPromise\n .then(() => {\n resolve({\n lines,\n stderr,\n exitCode: exitCode ?? 1,\n });\n })\n .catch((error: unknown) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n });\n}\n\nfunction filterEventsByDateRange(\n events: GitOutcomeEvent[],\n timezone: string,\n since: string | undefined,\n until: string | undefined,\n): GitOutcomeEvent[] {\n const normalizedSince = since ? shiftDate(since, 0) : undefined;\n const normalizedUntil = until ? shiftDate(until, 0) : undefined;\n\n return events.filter((event) => {\n const eventDate = getPeriodKey(event.timestamp, 'daily', timezone);\n\n if (normalizedSince && eventDate < normalizedSince) {\n return false;\n }\n\n if (normalizedUntil && eventDate > normalizedUntil) {\n return false;\n }\n\n return true;\n });\n}\n\nfunction filterEventsByActiveUsageDays(\n events: GitOutcomeEvent[],\n timezone: string,\n activeUsageDays: ReadonlySet<string> | undefined,\n): GitOutcomeEvent[] {\n if (activeUsageDays === undefined) {\n return events;\n }\n\n if (activeUsageDays.size === 0) {\n return [];\n }\n\n return events.filter((event) =>\n activeUsageDays.has(getPeriodKey(event.timestamp, 'daily', timezone)),\n );\n}\n\nfunction aggregatePeriodOutcomes(\n events: GitOutcomeEvent[],\n granularity: ReportGranularity,\n timezone: string,\n): {\n periodOutcomes: Map<string, EfficiencyOutcomeTotals>;\n totalOutcomes: EfficiencyOutcomeTotals;\n} {\n const periodOutcomes = new Map<string, EfficiencyOutcomeTotals>();\n const totalOutcomes = createEmptyEfficiencyOutcomeTotals();\n\n for (const event of events) {\n const periodKey = getPeriodKey(event.timestamp, granularity, timezone);\n const periodTotals = periodOutcomes.get(periodKey) ?? createEmptyEfficiencyOutcomeTotals();\n\n periodTotals.commitCount += 1;\n periodTotals.linesAdded += event.linesAdded;\n periodTotals.linesDeleted += event.linesDeleted;\n periodTotals.linesChanged += event.linesChanged;\n\n periodOutcomes.set(periodKey, periodTotals);\n\n totalOutcomes.commitCount += 1;\n totalOutcomes.linesAdded += event.linesAdded;\n totalOutcomes.linesDeleted += event.linesDeleted;\n totalOutcomes.linesChanged += event.linesChanged;\n }\n\n return {\n periodOutcomes,\n totalOutcomes,\n };\n}\n\nfunction buildGitLogArgs(options: {\n since?: string;\n until?: string;\n includeMergeCommits: boolean;\n authorEmail: string;\n}): string[] {\n const args = [\n 'log',\n `--pretty=format:${GIT_COMMIT_MARKER}%ct${GIT_COMMIT_MARKER}%H${GIT_COMMIT_MARKER}%ae`,\n '--shortstat',\n '--regexp-ignore-case',\n `--author=<${escapeGitRegexLiteral(options.authorEmail)}>`,\n ];\n\n if (!options.includeMergeCommits) {\n args.push('--no-merges');\n }\n\n if (options.since) {\n args.push(`--since=${shiftDate(options.since, -1)}T00:00:00Z`);\n }\n\n if (options.until) {\n args.push(`--until=${shiftDate(options.until, 1)}T23:59:59Z`);\n }\n\n return args;\n}\n\nfunction resolveGitLogDateWindow(options: {\n since?: string;\n until?: string;\n activeUsageDays?: ReadonlySet<string>;\n}): {\n since?: string;\n until?: string;\n} {\n if (!options.activeUsageDays || options.activeUsageDays.size === 0) {\n return {\n since: options.since,\n until: options.until,\n };\n }\n\n let earliestUsageDay: string | undefined;\n let latestUsageDay: string | undefined;\n\n for (const usageDay of options.activeUsageDays) {\n if (!earliestUsageDay || usageDay < earliestUsageDay) {\n earliestUsageDay = usageDay;\n }\n\n if (!latestUsageDay || usageDay > latestUsageDay) {\n latestUsageDay = usageDay;\n }\n }\n\n return {\n since: options.since ?? earliestUsageDay,\n until: options.until ?? latestUsageDay,\n };\n}\n\nexport async function collectGitOutcomes(\n options: GitOutcomeCollectorOptions,\n deps: GitOutcomeCollectorDeps = {},\n): Promise<GitOutcomeCollectionResult> {\n const repoDir = resolveRepoDir(options.repoDir);\n const includeMergeCommits = options.includeMergeCommits ?? false;\n const runCommand = deps.runGitCommand ?? runGitCommand;\n\n if (options.activeUsageDays?.size === 0) {\n return createEmptyOutcomeCollection(repoDir, includeMergeCommits);\n }\n\n if (!deps.runGitCommand) {\n await assertRepoDirReadable(repoDir);\n await assertGitRepository(repoDir, runCommand);\n }\n\n let authorEmail: string;\n\n try {\n authorEmail = await resolveConfiguredAuthorEmail(repoDir, runCommand);\n } catch (error) {\n if (!isMissingGitUserEmailError(error)) {\n throw error;\n }\n\n const headResult = await runCommand(repoDir, ['rev-parse', '--verify', 'HEAD']);\n\n if (isNoCommitHistoryFailure(headResult)) {\n return createEmptyOutcomeCollection(repoDir, includeMergeCommits);\n }\n\n throw error;\n }\n\n const gitLogDateWindow = resolveGitLogDateWindow({\n since: options.since,\n until: options.until,\n activeUsageDays: options.activeUsageDays,\n });\n\n const gitResult = await runCommand(\n repoDir,\n buildGitLogArgs({\n since: gitLogDateWindow.since,\n until: gitLogDateWindow.until,\n includeMergeCommits,\n authorEmail,\n }),\n );\n\n if (gitResult.exitCode !== 0) {\n if (isNoCommitHistoryFailure(gitResult)) {\n return createEmptyOutcomeCollection(repoDir, includeMergeCommits);\n }\n\n const reason = resolveGitCommandFailureReason(gitResult);\n throw new Error(`Failed to collect git outcomes from ${repoDir}: ${reason}`);\n }\n\n const allEvents = parseGitLogShortstatLines(gitResult.lines, authorEmail);\n const filteredEvents = filterEventsByDateRange(\n allEvents,\n options.timezone,\n options.since,\n options.until,\n );\n const usageAttributedEvents = filterEventsByActiveUsageDays(\n filteredEvents,\n options.timezone,\n options.activeUsageDays,\n );\n const { periodOutcomes, totalOutcomes } = aggregatePeriodOutcomes(\n usageAttributedEvents,\n options.granularity,\n options.timezone,\n );\n\n return {\n periodOutcomes,\n totalOutcomes,\n diagnostics: {\n repoDir,\n includeMergeCommits,\n commitsCollected: totalOutcomes.commitCount,\n linesAdded: totalOutcomes.linesAdded,\n linesDeleted: totalOutcomes.linesDeleted,\n },\n };\n}\n","import { access, constants, realpath } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { UsageEvent } from '../domain/usage-event.js';\n\nexport type RepoAttributionResult = {\n matchedEvents: UsageEvent[];\n matchedEventCount: number;\n excludedEventCount: number;\n unattributedEventCount: number;\n};\n\nexport type RepoRootResolver = (pathHint: string) => Promise<string | undefined>;\n\nasync function hasGitMarker(directoryPath: string): Promise<boolean> {\n try {\n await access(path.join(directoryPath, '.git'), constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction normalizeComparablePath(value: string): string {\n const normalizedPath = path.normalize(path.resolve(value));\n return process.platform === 'win32' ? normalizedPath.toLowerCase() : normalizedPath;\n}\n\nasync function resolveComparablePath(value: string): Promise<string> {\n const resolvedPath = path.resolve(value);\n\n try {\n return normalizeComparablePath(await realpath(resolvedPath));\n } catch {\n return normalizeComparablePath(resolvedPath);\n }\n}\n\nexport async function resolveRepoRootFromPathHint(pathHint: string): Promise<string | undefined> {\n const trimmedPath = pathHint.trim();\n\n if (!trimmedPath) {\n return undefined;\n }\n\n let currentPath = path.resolve(trimmedPath);\n\n for (;;) {\n if (await hasGitMarker(currentPath)) {\n return currentPath;\n }\n\n const parentPath = path.dirname(currentPath);\n\n if (parentPath === currentPath) {\n return undefined;\n }\n\n currentPath = parentPath;\n }\n}\n\nexport async function attributeUsageEventsToRepo(\n events: UsageEvent[],\n repoDir: string,\n resolveRepoRoot: RepoRootResolver = resolveRepoRootFromPathHint,\n): Promise<RepoAttributionResult> {\n const resolvedTargetRepoRoot = await resolveRepoRoot(repoDir).catch(() => undefined);\n const targetRepoPath = await resolveComparablePath(resolvedTargetRepoRoot ?? repoDir);\n const rootCache = new Map<\n string,\n Promise<{ resolvedRoot: string; comparableRoot: string } | undefined>\n >();\n const matchedEvents: UsageEvent[] = [];\n let excludedEventCount = 0;\n let unattributedEventCount = 0;\n\n for (const event of events) {\n if (!event.repoRoot) {\n unattributedEventCount += 1;\n continue;\n }\n const eventRepoRoot = event.repoRoot;\n\n const cachedRootPromise =\n rootCache.get(eventRepoRoot) ??\n (async () => {\n const resolvedRoot = await resolveRepoRoot(eventRepoRoot).catch(() => undefined);\n\n if (!resolvedRoot) {\n return undefined;\n }\n\n return {\n resolvedRoot,\n comparableRoot: await resolveComparablePath(resolvedRoot),\n };\n })();\n rootCache.set(eventRepoRoot, cachedRootPromise);\n const resolvedRoot = await cachedRootPromise;\n\n if (!resolvedRoot) {\n unattributedEventCount += 1;\n continue;\n }\n\n if (resolvedRoot.comparableRoot !== targetRepoPath) {\n excludedEventCount += 1;\n continue;\n }\n\n matchedEvents.push({\n ...event,\n repoRoot: resolvedRoot.resolvedRoot,\n });\n }\n\n return {\n matchedEvents,\n matchedEventCount: matchedEvents.length,\n excludedEventCount,\n unattributedEventCount,\n };\n}\n","import type { UsageReportRow } from '../domain/usage-report-row.js';\nimport type { SourceAdapter } from '../sources/source-adapter.js';\n\nimport type { AdapterParseResult } from './build-usage-data-parsing.js';\nimport type {\n UsageDataResult,\n UsageDiagnostics,\n UsagePricingOrigin,\n UsageSourceFailure,\n} from './usage-data-contracts.js';\n\ntype BuildUsageDiagnosticsParams = {\n adaptersToParse: SourceAdapter[];\n successfulParseResults: AdapterParseResult[];\n sourceFailures: UsageSourceFailure[];\n pricingOrigin: UsagePricingOrigin;\n pricingWarning?: string;\n activeEnvOverrides: UsageDiagnostics['activeEnvOverrides'];\n timezone: string;\n};\n\nexport function buildUsageDiagnostics(params: BuildUsageDiagnosticsParams): UsageDiagnostics {\n const parseResultBySource = new Map(\n params.successfulParseResults.map((result) => [result.source.toLowerCase(), result]),\n );\n\n const sessionStats = params.adaptersToParse.map((adapter) => {\n const parseResult = parseResultBySource.get(adapter.id.toLowerCase());\n\n return {\n source: adapter.id,\n filesFound: parseResult?.filesFound ?? 0,\n eventsParsed: parseResult?.events.length ?? 0,\n };\n });\n\n const skippedRows = params.successfulParseResults\n .filter((result) => result.skippedRows > 0)\n .map((result) => ({\n source: result.source,\n skippedRows: result.skippedRows,\n reasons: result.skippedRowReasons,\n }));\n\n return {\n sessionStats,\n sourceFailures: params.sourceFailures,\n skippedRows,\n pricingOrigin: params.pricingOrigin,\n pricingWarning: params.pricingWarning,\n activeEnvOverrides: params.activeEnvOverrides,\n timezone: params.timezone,\n };\n}\n\nexport function assembleUsageDataResult(\n events: UsageDataResult['events'],\n rows: UsageReportRow[],\n diagnostics: UsageDiagnostics,\n): UsageDataResult {\n return {\n events,\n rows,\n diagnostics,\n };\n}\n","export type EnvVarOverride = {\n name: string;\n value: string;\n description: string;\n};\n\nconst ENV_VARS_TO_DISPLAY: Array<{ name: string; description: string }> = [\n { name: 'LLM_USAGE_SKIP_UPDATE_CHECK', description: 'skip startup update check' },\n {\n name: 'LLM_USAGE_UPDATE_CACHE_SCOPE',\n description: 'update-check cache scope (global/session)',\n },\n { name: 'LLM_USAGE_UPDATE_CACHE_SESSION_KEY', description: 'update-check session cache key' },\n { name: 'LLM_USAGE_UPDATE_CACHE_TTL_MS', description: 'update-check cache TTL' },\n { name: 'LLM_USAGE_UPDATE_FETCH_TIMEOUT_MS', description: 'update-check fetch timeout' },\n { name: 'LLM_USAGE_PRICING_CACHE_TTL_MS', description: 'pricing cache TTL' },\n { name: 'LLM_USAGE_PRICING_FETCH_TIMEOUT_MS', description: 'pricing fetch timeout' },\n { name: 'LLM_USAGE_PARSE_MAX_PARALLEL', description: 'max parallel file parsing' },\n { name: 'LLM_USAGE_PARSE_CACHE_ENABLED', description: 'enable file parse cache' },\n { name: 'LLM_USAGE_PARSE_CACHE_TTL_MS', description: 'file parse cache TTL' },\n { name: 'LLM_USAGE_PARSE_CACHE_MAX_ENTRIES', description: 'file parse cache max entries' },\n { name: 'LLM_USAGE_PARSE_CACHE_MAX_BYTES', description: 'file parse cache max bytes' },\n];\n\nexport function getActiveEnvVarOverrides(): EnvVarOverride[] {\n const overrides: EnvVarOverride[] = [];\n\n for (const { name, description } of ENV_VARS_TO_DISPLAY) {\n const value = process.env[name];\n if (value !== undefined && value !== '') {\n overrides.push({ name, value, description });\n }\n }\n\n return overrides;\n}\n\nexport function formatEnvVarOverrides(overrides: EnvVarOverride[]): string[] {\n if (overrides.length === 0) {\n return [];\n }\n\n const lines: string[] = [];\n lines.push('Active environment overrides:');\n\n for (const { name, value, description } of overrides) {\n lines.push(` ${name}=${value} (${description})`);\n }\n\n return lines;\n}\n","import type { SourceAdapter } from '../sources/source-adapter.js';\nimport { normalizeProviderToBillingEntity } from '../domain/provider-normalization.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\n\nimport type { ReportCommandOptions } from './usage-data-contracts.js';\n\nexport type NormalizedBuildUsageInputs = {\n timezone: string;\n providerFilter: string | undefined;\n sourceFilter: Set<string> | undefined;\n modelFilter: string[] | undefined;\n explicitSourceIds: Set<string>;\n pricingUrl: string | undefined;\n};\n\nexport function validateDateInput(value: string, flagName: '--since' | '--until'): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/u.test(value)) {\n throw new Error(`${flagName} must use format YYYY-MM-DD`);\n }\n\n const parsed = new Date(`${value}T00:00:00.000Z`);\n\n if (Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== value) {\n throw new Error(`${flagName} has an invalid calendar date`);\n }\n}\n\nexport function validateTimezone(timezone: string): void {\n const normalizedTimezone = timezone.trim();\n\n try {\n new Intl.DateTimeFormat('en-US', { timeZone: normalizedTimezone }).format(new Date());\n } catch {\n throw new Error(`Invalid timezone: ${normalizedTimezone}`);\n }\n}\n\nexport function normalizeProviderFilter(provider: string | undefined): string | undefined {\n return normalizeProviderToBillingEntity(provider);\n}\n\nexport function normalizeSourceFilter(\n source: string | string[] | undefined,\n): Set<string> | undefined {\n if (!source || (Array.isArray(source) && source.length === 0)) {\n return undefined;\n }\n\n const sourceCandidates = Array.isArray(source) ? source : [source];\n const normalizedSources = sourceCandidates\n .flatMap((candidate) => candidate.split(','))\n .map((candidate) => candidate.trim().toLowerCase())\n .filter((candidate) => candidate.length > 0);\n\n if (normalizedSources.length === 0) {\n throw new Error('--source must contain at least one non-empty source id');\n }\n\n return new Set(normalizedSources);\n}\n\nexport function normalizeModelFilter(model: string | string[] | undefined): string[] | undefined {\n if (!model || (Array.isArray(model) && model.length === 0)) {\n return undefined;\n }\n\n const modelCandidates = Array.isArray(model) ? model : [model];\n const normalizedModels = modelCandidates\n .flatMap((candidate) => candidate.split(','))\n .map((candidate) => candidate.trim().toLowerCase())\n .filter((candidate) => candidate.length > 0);\n\n if (normalizedModels.length === 0) {\n throw new Error('--model must contain at least one non-empty model filter');\n }\n\n return [...new Set(normalizedModels)];\n}\n\nexport function validateSourceFilterValues(\n sourceFilter: Set<string> | undefined,\n availableSourceIds: ReadonlySet<string>,\n): void {\n if (!sourceFilter) {\n return;\n }\n\n const unknownSources = [...sourceFilter].filter((source) => !availableSourceIds.has(source));\n\n if (unknownSources.length === 0) {\n return;\n }\n\n const allowedSources = [...availableSourceIds].sort(compareByCodePoint);\n\n throw new Error(\n `Unknown --source value(s): ${unknownSources.join(', ')}. Allowed values: ${allowedSources.join(', ')}`,\n );\n}\n\nexport function validatePricingUrl(pricingUrl: string | undefined): string | undefined {\n if (pricingUrl === undefined) {\n return undefined;\n }\n\n const normalizedPricingUrl = pricingUrl.trim();\n\n if (normalizedPricingUrl.length === 0) {\n throw new Error('--pricing-url must be a valid http(s) URL');\n }\n\n try {\n const parsedUrl = new URL(normalizedPricingUrl);\n\n if (!['http:', 'https:'].includes(parsedUrl.protocol)) {\n throw new Error('Unsupported protocol');\n }\n } catch {\n throw new Error('--pricing-url must be a valid http(s) URL');\n }\n\n return normalizedPricingUrl;\n}\n\nexport function validateBuildOptions(options: ReportCommandOptions): {\n normalizedPricingUrl: string | undefined;\n} {\n if (options.since) {\n validateDateInput(options.since, '--since');\n }\n\n if (options.until) {\n validateDateInput(options.until, '--until');\n }\n\n if (options.since && options.until && options.since > options.until) {\n throw new Error('--since must be less than or equal to --until');\n }\n\n return {\n normalizedPricingUrl: validatePricingUrl(options.pricingUrl),\n };\n}\n\nfunction parseSourceDirOverrideIds(sourceDirEntries: string[] | undefined): Set<string> {\n const overrideIds = new Set<string>();\n\n if (!sourceDirEntries || sourceDirEntries.length === 0) {\n return overrideIds;\n }\n\n for (const entry of sourceDirEntries) {\n const separatorIndex = entry.indexOf('=');\n\n if (separatorIndex <= 0) {\n continue;\n }\n\n const sourceId = entry.slice(0, separatorIndex).trim().toLowerCase();\n\n if (sourceId.length > 0) {\n overrideIds.add(sourceId);\n }\n }\n\n return overrideIds;\n}\n\nexport function resolveExplicitSourceIds(\n options: ReportCommandOptions,\n sourceFilter: Set<string> | undefined,\n): Set<string> {\n const explicitSourceIds = new Set<string>();\n\n if (sourceFilter) {\n for (const sourceId of sourceFilter) {\n explicitSourceIds.add(sourceId);\n }\n }\n\n for (const sourceId of parseSourceDirOverrideIds(options.sourceDir)) {\n explicitSourceIds.add(sourceId);\n }\n\n if (options.piDir) {\n explicitSourceIds.add('pi');\n }\n\n if (options.codexDir) {\n explicitSourceIds.add('codex');\n }\n\n if (options.geminiDir) {\n explicitSourceIds.add('gemini');\n }\n\n if (options.droidDir) {\n explicitSourceIds.add('droid');\n }\n\n if (options.opencodeDb) {\n explicitSourceIds.add('opencode');\n }\n\n return explicitSourceIds;\n}\n\nfunction detectDefaultTimezone(): string {\n const detectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n if (typeof detectedTimezone === 'string') {\n const trimmedDetectedTimezone = detectedTimezone.trim();\n\n if (trimmedDetectedTimezone.length > 0) {\n return trimmedDetectedTimezone;\n }\n }\n\n return 'UTC';\n}\n\nexport function normalizeBuildUsageInputs(\n options: ReportCommandOptions,\n): NormalizedBuildUsageInputs {\n const { normalizedPricingUrl } = validateBuildOptions(options);\n\n const timezone =\n options.timezone !== undefined ? options.timezone.trim() : detectDefaultTimezone();\n validateTimezone(timezone);\n\n const providerFilter = normalizeProviderFilter(options.provider);\n const sourceFilter = normalizeSourceFilter(options.source);\n const modelFilter = normalizeModelFilter(options.model);\n const explicitSourceIds = resolveExplicitSourceIds(options, sourceFilter);\n\n return {\n timezone,\n providerFilter,\n sourceFilter,\n modelFilter,\n explicitSourceIds,\n pricingUrl: normalizedPricingUrl,\n };\n}\n\nexport function selectAdaptersForParsing(\n adapters: SourceAdapter[],\n sourceFilter: Set<string> | undefined,\n): SourceAdapter[] {\n const availableSourceIds = new Set(adapters.map((adapter) => adapter.id.toLowerCase()));\n validateSourceFilterValues(sourceFilter, availableSourceIds);\n\n return sourceFilter\n ? adapters.filter((adapter) => sourceFilter.has(adapter.id.toLowerCase()))\n : adapters;\n}\n","import { stat } from 'node:fs/promises';\n\nimport type { UsageEvent } from '../domain/usage-event.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport type {\n SourceAdapter,\n SourceParseFileDiagnostics,\n SourceSkippedRowReasonStat,\n} from '../sources/source-adapter.js';\nimport { normalizeSkippedRowReasons } from './normalize-skipped-row-reasons.js';\nimport { getPeriodKey } from '../utils/time-buckets.js';\nimport {\n getDefaultParseFileCachePath,\n getSourceShardedParseFileCachePath,\n ParseFileCache,\n} from './parse-file-cache.js';\n\nimport type { UsageSourceFailure } from './usage-data-contracts.js';\n\nexport type AdapterParseResult = {\n source: string;\n events: UsageEvent[];\n filesFound: number;\n skippedRows: number;\n skippedRowReasons: SourceSkippedRowReasonStat[];\n};\n\nexport type ParsedAdaptersResult = {\n successfulParseResults: AdapterParseResult[];\n sourceFailures: UsageSourceFailure[];\n};\n\nexport type ParseCacheRuntimeConfig = {\n enabled: boolean;\n ttlMs: number;\n maxEntries: number;\n maxBytes: number;\n};\n\nexport type ParseSelectedAdaptersOptions = {\n parseCache?: ParseCacheRuntimeConfig;\n parseCacheFilePath?: string;\n now?: () => number;\n};\n\nfunction getDefaultParseFileDiagnostics(events: UsageEvent[]): SourceParseFileDiagnostics {\n return { events, skippedRows: 0, skippedRowReasons: [] };\n}\n\nfunction normalizeSkippedRowsCount(value: unknown): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return 0;\n }\n\n return Math.max(0, Math.trunc(value));\n}\n\nexport async function parseAdapterEvents(\n adapter: SourceAdapter,\n maxParallelFileParsing: number,\n parseFileCache?: ParseFileCache,\n): Promise<AdapterParseResult> {\n const files = await adapter.discoverFiles();\n\n if (files.length === 0) {\n return {\n source: adapter.id,\n events: [],\n filesFound: 0,\n skippedRows: 0,\n skippedRowReasons: [],\n };\n }\n\n const safeMaxParallelFileParsing =\n Number.isFinite(maxParallelFileParsing) && maxParallelFileParsing > 0\n ? Math.max(1, Math.floor(maxParallelFileParsing))\n : 1;\n const parsedByFile: UsageEvent[][] = Array.from({ length: files.length }, () => []);\n const skippedRowsByFile: number[] = Array.from({ length: files.length }, () => 0);\n const skippedRowReasons = new Map<string, number>();\n const workerCount = Math.min(safeMaxParallelFileParsing, files.length);\n let nextFileIndex = 0;\n\n const workers = Array.from({ length: workerCount }, async () => {\n while (nextFileIndex < files.length) {\n const fileIndex = nextFileIndex;\n nextFileIndex += 1;\n\n const filePath = files[fileIndex];\n let fileFingerprint:\n | {\n size: number;\n mtimeMs: number;\n }\n | undefined;\n let parseFileDiagnostics: SourceParseFileDiagnostics | undefined;\n\n if (parseFileCache) {\n try {\n const fileStat = await stat(filePath);\n fileFingerprint = {\n size: fileStat.size,\n mtimeMs: fileStat.mtimeMs,\n };\n parseFileDiagnostics = parseFileCache.get(adapter.id, filePath, fileFingerprint);\n } catch {\n // Some adapters may return virtual/non-file identifiers. In that case, bypass cache.\n }\n }\n\n if (!parseFileDiagnostics) {\n parseFileDiagnostics = adapter.parseFileWithDiagnostics\n ? await adapter.parseFileWithDiagnostics(filePath)\n : getDefaultParseFileDiagnostics(await adapter.parseFile(filePath));\n if (parseFileCache && fileFingerprint) {\n parseFileCache.set(adapter.id, filePath, fileFingerprint, parseFileDiagnostics);\n }\n }\n\n parsedByFile[fileIndex] = parseFileDiagnostics.events;\n skippedRowsByFile[fileIndex] = normalizeSkippedRowsCount(parseFileDiagnostics.skippedRows);\n for (const reasonStat of normalizeSkippedRowReasons(parseFileDiagnostics.skippedRowReasons)) {\n skippedRowReasons.set(\n reasonStat.reason,\n (skippedRowReasons.get(reasonStat.reason) ?? 0) + reasonStat.count,\n );\n }\n }\n });\n\n await Promise.all(workers);\n\n return {\n source: adapter.id,\n events: parsedByFile.flat(),\n filesFound: files.length,\n skippedRows: skippedRowsByFile.reduce((sum, skippedRowsCount) => sum + skippedRowsCount, 0),\n skippedRowReasons: [...skippedRowReasons.entries()]\n .map(([reason, count]) => ({ reason, count }))\n .sort((left, right) => compareByCodePoint(left.reason, right.reason)),\n };\n}\n\nfunction getErrorReason(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n return String(error);\n}\n\nexport async function parseSelectedAdapters(\n adaptersToParse: SourceAdapter[],\n maxParallelFileParsing: number,\n options: ParseSelectedAdaptersOptions = {},\n): Promise<ParsedAdaptersResult> {\n const parseCacheBySource = new Map<string, ParseFileCache>();\n\n if (options.parseCache?.enabled) {\n const parseCacheLimits = {\n ttlMs: options.parseCache.ttlMs,\n maxEntries: options.parseCache.maxEntries,\n maxBytes: options.parseCache.maxBytes,\n };\n const cacheFilePath = options.parseCacheFilePath ?? getDefaultParseFileCachePath();\n\n await Promise.all(\n adaptersToParse.map(async (adapter) => {\n const sourceId = adapter.id.toLowerCase();\n\n if (parseCacheBySource.has(sourceId)) {\n return;\n }\n\n parseCacheBySource.set(\n sourceId,\n await ParseFileCache.load({\n cacheFilePath: getSourceShardedParseFileCachePath(cacheFilePath, sourceId),\n limits: parseCacheLimits,\n now: options.now,\n }),\n );\n }),\n );\n }\n\n const parseResults = await Promise.allSettled(\n adaptersToParse.map((adapter) =>\n parseAdapterEvents(\n adapter,\n maxParallelFileParsing,\n parseCacheBySource.get(adapter.id.toLowerCase()),\n ),\n ),\n );\n\n if (parseCacheBySource.size > 0) {\n await Promise.allSettled(\n [...parseCacheBySource.values()].map(async (parseCache) => parseCache.persist()),\n );\n }\n\n const sourceFailures: UsageSourceFailure[] = [];\n const successfulParseResults: AdapterParseResult[] = [];\n\n for (const [index, parseResult] of parseResults.entries()) {\n const source = adaptersToParse[index].id;\n\n if (parseResult.status === 'fulfilled') {\n successfulParseResults.push(parseResult.value);\n continue;\n }\n\n sourceFailures.push({ source, reason: getErrorReason(parseResult.reason) });\n }\n\n return {\n successfulParseResults,\n sourceFailures,\n };\n}\n\nexport function throwOnExplicitSourceFailures(\n sourceFailures: UsageSourceFailure[],\n explicitSourceIds: ReadonlySet<string>,\n): void {\n const explicitFailures = sourceFailures.filter((failure) =>\n explicitSourceIds.has(failure.source.toLowerCase()),\n );\n\n if (explicitFailures.length === 0) {\n return;\n }\n\n const details = explicitFailures\n .map((failure) => `${failure.source}: ${failure.reason}`)\n .join('; ');\n\n throw new Error(`Failed to parse explicitly requested source(s): ${details}`);\n}\n\nfunction matchesProvider(\n provider: string | undefined,\n providerFilter: string | undefined,\n): boolean {\n if (!providerFilter) {\n return true;\n }\n\n return provider?.toLowerCase().includes(providerFilter) ?? false;\n}\n\nfunction isEventWithinDateRange(\n event: UsageEvent,\n timezone: string,\n since: string | undefined,\n until: string | undefined,\n): boolean {\n const eventDate = getPeriodKey(event.timestamp, 'daily', timezone);\n\n if (since && eventDate < since) {\n return false;\n }\n\n if (until && eventDate > until) {\n return false;\n }\n\n return true;\n}\n\ntype ModelFilterRule = {\n value: string;\n mode: 'exact' | 'substring';\n};\n\nfunction resolveModelFilterRules(\n events: UsageEvent[],\n modelFilter: string[] | undefined,\n): ModelFilterRule[] | undefined {\n if (!modelFilter || modelFilter.length === 0) {\n return undefined;\n }\n\n const availableModels = new Set(\n events\n .map((event) => event.model?.toLowerCase())\n .filter((model): model is string => Boolean(model)),\n );\n\n return modelFilter.map((value) => ({\n value,\n mode: availableModels.has(value) ? 'exact' : 'substring',\n }));\n}\n\nfunction matchesModel(\n model: string | undefined,\n modelRules: ModelFilterRule[] | undefined,\n): boolean {\n if (!modelRules || modelRules.length === 0) {\n return true;\n }\n\n if (!model) {\n return false;\n }\n\n const normalizedModel = model.toLowerCase();\n\n return modelRules.some((rule) =>\n rule.mode === 'exact' ? normalizedModel === rule.value : normalizedModel.includes(rule.value),\n );\n}\n\nexport type UsageEventFilterOptions = {\n timezone: string;\n since?: string;\n until?: string;\n providerFilter?: string;\n modelFilter?: string[];\n};\n\nfunction filterByModelRules(events: UsageEvent[], modelFilter: string[] | undefined): UsageEvent[] {\n const modelFilterRules = resolveModelFilterRules(events, modelFilter);\n\n return events.filter((event) => matchesModel(event.model, modelFilterRules));\n}\n\nexport function filterUsageEvents(\n events: UsageEvent[],\n options: UsageEventFilterOptions,\n): UsageEvent[] {\n const providerAndDateFilteredEvents: UsageEvent[] = [];\n\n for (const event of events) {\n if (!matchesProvider(event.provider, options.providerFilter)) {\n continue;\n }\n\n if (!isEventWithinDateRange(event, options.timezone, options.since, options.until)) {\n continue;\n }\n\n providerAndDateFilteredEvents.push(event);\n }\n\n return filterByModelRules(providerAndDateFilteredEvents, options.modelFilter);\n}\n\nexport function filterParsedAdapterEvents(\n parseResults: AdapterParseResult[],\n options: UsageEventFilterOptions,\n): UsageEvent[] {\n const providerAndDateFilteredEvents: UsageEvent[] = [];\n\n for (const result of parseResults) {\n for (const event of result.events) {\n if (!matchesProvider(event.provider, options.providerFilter)) {\n continue;\n }\n\n if (!isEventWithinDateRange(event, options.timezone, options.since, options.until)) {\n continue;\n }\n\n providerAndDateFilteredEvents.push(event);\n }\n }\n\n return filterByModelRules(providerAndDateFilteredEvents, options.modelFilter);\n}\n","import type { SourceSkippedRowReasonStat } from '../sources/source-adapter.js';\nimport { asRecord } from '../utils/as-record.js';\n\nfunction toPositiveInteger(value: unknown): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {\n return undefined;\n }\n\n return Math.trunc(value);\n}\n\nexport function normalizeSkippedRowReasons(value: unknown): SourceSkippedRowReasonStat[] {\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.flatMap((entry) => {\n const record = asRecord(entry);\n\n if (!record) {\n return [];\n }\n\n const reason = typeof record.reason === 'string' ? record.reason.trim() : '';\n const count = toPositiveInteger(record.count);\n\n if (!reason || count === undefined) {\n return [];\n }\n\n return [{ reason, count }];\n });\n}\n","import { mkdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { normalizeSourceId, type UsageEvent } from '../domain/usage-event.js';\nimport { normalizeProviderToBillingEntity } from '../domain/provider-normalization.js';\nimport type {\n SourceParseFileDiagnostics,\n SourceSkippedRowReasonStat,\n} from '../sources/source-adapter.js';\nimport { normalizeSkippedRowReasons } from './normalize-skipped-row-reasons.js';\nimport { asRecord } from '../utils/as-record.js';\nimport { getUserCacheRootDir } from '../utils/cache-root-dir.js';\n\nconst PARSE_FILE_CACHE_VERSION = 3;\nconst CACHE_KEY_SEPARATOR = '\\u0000';\n\nexport type ParseFileFingerprint = {\n size: number;\n mtimeMs: number;\n};\n\nexport type ParseFileCacheLimits = {\n ttlMs: number;\n maxEntries: number;\n maxBytes: number;\n};\n\ntype ParseFileCacheEntry = {\n source: string;\n filePath: string;\n fingerprint: ParseFileFingerprint;\n cachedAt: number;\n diagnostics: SourceParseFileDiagnostics;\n};\n\ntype ParseFileCachePayload = {\n version: number;\n entries: ParseFileCacheEntry[];\n};\n\nfunction createCacheKey(source: string, filePath: string): string {\n return `${source}${CACHE_KEY_SEPARATOR}${filePath}`;\n}\n\nfunction normalizeCacheSource(source: string): string {\n return normalizeSourceId(source)?.toLowerCase() ?? '';\n}\n\nfunction toNonNegativeInteger(value: unknown): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return Math.trunc(value);\n}\n\nfunction toNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return value;\n}\n\nfunction normalizeCachedTimestamp(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalized = value.trim();\n\n if (!normalized) {\n return undefined;\n }\n\n const timestamp = new Date(normalized);\n\n if (Number.isNaN(timestamp.getTime())) {\n return undefined;\n }\n\n return timestamp.toISOString() === normalized ? normalized : undefined;\n}\n\nfunction normalizeCachedUsageEvent(value: unknown): UsageEvent | undefined {\n const record = asRecord(value);\n\n if (!record) {\n return undefined;\n }\n\n const source = normalizeSourceId(record.source)?.toLowerCase();\n const sessionId = typeof record.sessionId === 'string' ? record.sessionId.trim() : '';\n const timestamp = normalizeCachedTimestamp(record.timestamp);\n const repoRoot = typeof record.repoRoot === 'string' ? record.repoRoot.trim() : '';\n\n if (!source || !sessionId || !timestamp) {\n return undefined;\n }\n\n const costMode =\n record.costMode === 'explicit' || record.costMode === 'estimated' ? record.costMode : undefined;\n\n if (!costMode) {\n return undefined;\n }\n\n const inputTokens = toNonNegativeInteger(record.inputTokens);\n const outputTokens = toNonNegativeInteger(record.outputTokens);\n const reasoningTokens = toNonNegativeInteger(record.reasoningTokens);\n const cacheReadTokens = toNonNegativeInteger(record.cacheReadTokens);\n const cacheWriteTokens = toNonNegativeInteger(record.cacheWriteTokens);\n const totalTokens = toNonNegativeInteger(record.totalTokens);\n\n if (\n inputTokens === undefined ||\n outputTokens === undefined ||\n reasoningTokens === undefined ||\n cacheReadTokens === undefined ||\n cacheWriteTokens === undefined ||\n totalTokens === undefined\n ) {\n return undefined;\n }\n\n const provider = normalizeProviderToBillingEntity(\n typeof record.provider === 'string' ? record.provider : undefined,\n );\n const model = typeof record.model === 'string' ? record.model.trim().toLowerCase() : '';\n const costUsd = toNonNegativeNumber(record.costUsd);\n\n if (costMode === 'explicit' && costUsd === undefined) {\n return undefined;\n }\n\n return {\n source,\n sessionId,\n timestamp,\n repoRoot: repoRoot || undefined,\n provider,\n model: model || undefined,\n inputTokens,\n outputTokens,\n reasoningTokens,\n cacheReadTokens,\n cacheWriteTokens,\n totalTokens,\n costUsd,\n costMode,\n };\n}\n\nfunction cloneUsageEvent(event: UsageEvent): UsageEvent {\n return { ...event };\n}\n\nfunction cloneUsageEvents(events: UsageEvent[]): UsageEvent[] {\n return events.map((event) => cloneUsageEvent(event));\n}\n\nfunction cloneSkippedRowReasons(\n skippedRowReasons: SourceSkippedRowReasonStat[] | undefined,\n): SourceSkippedRowReasonStat[] {\n return (skippedRowReasons ?? []).map((stat) => ({ reason: stat.reason, count: stat.count }));\n}\n\nfunction normalizeCachedEvents(value: unknown): UsageEvent[] | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const normalizedEvents: UsageEvent[] = [];\n\n for (const event of value) {\n const normalizedEvent = normalizeCachedUsageEvent(event);\n\n if (!normalizedEvent) {\n return undefined;\n }\n\n normalizedEvents.push(normalizedEvent);\n }\n\n return normalizedEvents;\n}\n\nfunction normalizeCacheEntry(value: unknown): ParseFileCacheEntry | undefined {\n const record = asRecord(value);\n\n if (!record) {\n return undefined;\n }\n\n const source = normalizeSourceId(record.source)?.toLowerCase() ?? '';\n const filePath = typeof record.filePath === 'string' ? record.filePath.trim() : '';\n const cachedAt = toNonNegativeInteger(record.cachedAt);\n const fingerprint = asRecord(record.fingerprint);\n const diagnostics = asRecord(record.diagnostics);\n const size = toNonNegativeInteger(fingerprint?.size);\n const mtimeMs = toNonNegativeNumber(fingerprint?.mtimeMs);\n const skippedRows = toNonNegativeInteger(diagnostics?.skippedRows) ?? 0;\n const events = normalizeCachedEvents(diagnostics?.events);\n\n if (\n !source ||\n !filePath ||\n size === undefined ||\n mtimeMs === undefined ||\n cachedAt === undefined\n ) {\n return undefined;\n }\n\n if (!events) {\n return undefined;\n }\n\n return {\n source,\n filePath,\n fingerprint: { size, mtimeMs },\n cachedAt,\n diagnostics: {\n events,\n skippedRows,\n skippedRowReasons: normalizeSkippedRowReasons(diagnostics?.skippedRowReasons),\n },\n };\n}\n\nexport function getDefaultParseFileCachePath(): string {\n return path.join(getUserCacheRootDir(), 'llm-usage-metrics', 'parse-file-cache.json');\n}\n\nfunction normalizeCacheShardSource(source: string): string {\n const normalizedSource = normalizeCacheSource(source);\n\n if (!normalizedSource) {\n return 'unknown';\n }\n\n return normalizedSource.replace(/[^a-z0-9._-]/gu, '_');\n}\n\nexport function getSourceShardedParseFileCachePath(cacheFilePath: string, source: string): string {\n const parsedPath = path.parse(cacheFilePath);\n const sourceShard = normalizeCacheShardSource(source);\n\n if (parsedPath.ext.length > 0) {\n return path.join(parsedPath.dir, `${parsedPath.name}.${sourceShard}${parsedPath.ext}`);\n }\n\n return path.join(parsedPath.dir, `${parsedPath.base}.${sourceShard}`);\n}\n\nexport class ParseFileCache {\n private readonly entriesByKey = new Map<string, ParseFileCacheEntry>();\n private dirty = false;\n\n private constructor(\n private readonly cacheFilePath: string,\n private readonly limits: ParseFileCacheLimits,\n private readonly now: () => number,\n ) {}\n\n public static async load(options: {\n cacheFilePath?: string;\n limits: ParseFileCacheLimits;\n now?: () => number;\n }): Promise<ParseFileCache> {\n const cache = new ParseFileCache(\n options.cacheFilePath ?? getDefaultParseFileCachePath(),\n options.limits,\n options.now ?? Date.now,\n );\n await cache.loadFromDisk();\n return cache;\n }\n\n public get(\n source: string,\n filePath: string,\n fingerprint: ParseFileFingerprint,\n ): SourceParseFileDiagnostics | undefined {\n const normalizedSource = normalizeCacheSource(source);\n const cacheKey = createCacheKey(normalizedSource, filePath);\n const entry = this.entriesByKey.get(cacheKey);\n\n if (!entry) {\n return undefined;\n }\n\n if (entry.cachedAt + this.limits.ttlMs < this.now()) {\n this.entriesByKey.delete(cacheKey);\n this.dirty = true;\n return undefined;\n }\n\n if (\n entry.fingerprint.size !== fingerprint.size ||\n entry.fingerprint.mtimeMs !== fingerprint.mtimeMs\n ) {\n this.entriesByKey.delete(cacheKey);\n this.dirty = true;\n return undefined;\n }\n\n return {\n events: cloneUsageEvents(entry.diagnostics.events),\n skippedRows: entry.diagnostics.skippedRows,\n skippedRowReasons: cloneSkippedRowReasons(entry.diagnostics.skippedRowReasons),\n };\n }\n\n public set(\n source: string,\n filePath: string,\n fingerprint: ParseFileFingerprint,\n diagnostics: SourceParseFileDiagnostics,\n ): void {\n const normalizedSource = normalizeCacheSource(source);\n this.entriesByKey.set(createCacheKey(normalizedSource, filePath), {\n source: normalizedSource,\n filePath,\n fingerprint: {\n size: fingerprint.size,\n mtimeMs: fingerprint.mtimeMs,\n },\n cachedAt: this.now(),\n diagnostics: {\n events: cloneUsageEvents(diagnostics.events),\n skippedRows: diagnostics.skippedRows,\n skippedRowReasons: cloneSkippedRowReasons(diagnostics.skippedRowReasons),\n },\n });\n this.dirty = true;\n }\n\n public async persist(): Promise<void> {\n if (!this.dirty) {\n return;\n }\n\n const sortedEntries = [...this.entriesByKey.values()]\n .filter((entry) => entry.cachedAt + this.limits.ttlMs >= this.now())\n .sort((left, right) => right.cachedAt - left.cachedAt);\n\n const keptEntries = sortedEntries.slice(0, this.limits.maxEntries);\n let payloadText = JSON.stringify(this.toPayload(keptEntries));\n\n if (Buffer.byteLength(payloadText, 'utf8') > this.limits.maxBytes) {\n let bestCount = 0;\n let bestPayloadText = JSON.stringify(this.toPayload([]));\n let low = 0;\n let high = keptEntries.length;\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const candidateText = JSON.stringify(this.toPayload(keptEntries.slice(0, mid)));\n\n if (Buffer.byteLength(candidateText, 'utf8') <= this.limits.maxBytes) {\n bestCount = mid;\n bestPayloadText = candidateText;\n low = mid + 1;\n continue;\n }\n\n high = mid - 1;\n }\n\n keptEntries.length = bestCount;\n payloadText = bestPayloadText;\n }\n\n await mkdir(path.dirname(this.cacheFilePath), { recursive: true });\n const temporaryPath = `${this.cacheFilePath}.${process.pid}.${this.now()}.tmp`;\n\n try {\n await writeFile(temporaryPath, payloadText, 'utf8');\n await rename(temporaryPath, this.cacheFilePath);\n this.dirty = false;\n } catch (error) {\n await rm(temporaryPath, { force: true }).catch(() => undefined);\n throw error;\n }\n }\n\n private toPayload(entries: ParseFileCacheEntry[]): ParseFileCachePayload {\n return {\n version: PARSE_FILE_CACHE_VERSION,\n entries: entries.map((entry) => ({\n source: entry.source,\n filePath: entry.filePath,\n fingerprint: entry.fingerprint,\n cachedAt: entry.cachedAt,\n diagnostics: {\n events: entry.diagnostics.events,\n skippedRows: entry.diagnostics.skippedRows,\n skippedRowReasons: cloneSkippedRowReasons(entry.diagnostics.skippedRowReasons),\n },\n })),\n };\n }\n\n private async loadFromDisk(): Promise<void> {\n let cacheFileSizeBytes: number;\n\n try {\n const cacheStat = await stat(this.cacheFilePath);\n cacheFileSizeBytes = cacheStat.size;\n } catch {\n return;\n }\n\n if (cacheFileSizeBytes > this.limits.maxBytes) {\n this.dirty = true;\n return;\n }\n\n let content: string;\n\n try {\n content = await readFile(this.cacheFilePath, 'utf8');\n } catch {\n return;\n }\n\n let parsedPayload: unknown;\n\n try {\n parsedPayload = JSON.parse(content);\n } catch {\n this.dirty = true;\n return;\n }\n\n const payloadRecord = asRecord(parsedPayload);\n\n if (!payloadRecord) {\n this.dirty = true;\n return;\n }\n\n const version = toNonNegativeInteger(payloadRecord.version);\n\n if (version !== PARSE_FILE_CACHE_VERSION) {\n this.dirty = true;\n return;\n }\n\n if (Buffer.byteLength(content, 'utf8') > this.limits.maxBytes) {\n this.dirty = true;\n return;\n }\n\n const entries = Array.isArray(payloadRecord.entries) ? payloadRecord.entries : [];\n\n for (const rawEntry of entries) {\n const normalizedEntry = normalizeCacheEntry(rawEntry);\n\n if (!normalizedEntry) {\n this.dirty = true;\n continue;\n }\n\n if (normalizedEntry.cachedAt + this.limits.ttlMs < this.now()) {\n this.dirty = true;\n continue;\n }\n\n this.entriesByKey.set(\n createCacheKey(normalizedEntry.source, normalizedEntry.filePath),\n normalizedEntry,\n );\n }\n\n if (this.entriesByKey.size > this.limits.maxEntries) {\n this.dirty = true;\n }\n }\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport type { ModelPricing, PricingSource } from './types.js';\n\nconst ONE_MILLION = 1_000_000;\n\nfunction estimateTokenGroupCost(tokens: number, per1MUsd: number | undefined): number {\n if (!per1MUsd || tokens <= 0) {\n return 0;\n }\n\n return (tokens / ONE_MILLION) * per1MUsd;\n}\n\nexport function calculateEstimatedCostUsd(event: UsageEvent, pricing: ModelPricing): number {\n const reasoningBilling = pricing.reasoningBilling ?? 'included-in-output';\n\n const inputCost = estimateTokenGroupCost(event.inputTokens, pricing.inputPer1MUsd);\n const outputCost = estimateTokenGroupCost(event.outputTokens, pricing.outputPer1MUsd);\n const cacheReadCost = estimateTokenGroupCost(event.cacheReadTokens, pricing.cacheReadPer1MUsd);\n const cacheWriteCost = estimateTokenGroupCost(event.cacheWriteTokens, pricing.cacheWritePer1MUsd);\n\n const reasoningCost =\n reasoningBilling === 'separate'\n ? estimateTokenGroupCost(event.reasoningTokens, pricing.reasoningPer1MUsd)\n : 0;\n\n return inputCost + outputCost + cacheReadCost + cacheWriteCost + reasoningCost;\n}\n\nexport function applyPricingToEvent(event: UsageEvent, pricingSource: PricingSource): UsageEvent {\n const shouldRepriceExplicitZero =\n event.costMode === 'explicit' && event.costUsd === 0 && event.model !== undefined;\n\n if (event.costMode === 'explicit' && event.costUsd !== undefined && !shouldRepriceExplicitZero) {\n return event;\n }\n\n if (!event.model) {\n return { ...event, costMode: 'estimated' };\n }\n\n const pricing = pricingSource.getPricing(event.model);\n\n if (!pricing) {\n if (shouldRepriceExplicitZero) {\n return event;\n }\n\n return { ...event, costMode: 'estimated' };\n }\n\n return {\n ...event,\n costUsd: calculateEstimatedCostUsd(event, pricing),\n costMode: 'estimated',\n };\n}\n\nexport function applyPricingToEvents(\n events: UsageEvent[],\n pricingSource: PricingSource,\n): UsageEvent[] {\n return events.map((event) => applyPricingToEvent(event, pricingSource));\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { asRecord } from '../utils/as-record.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport { getUserCacheRootDir } from '../utils/cache-root-dir.js';\nimport litellmModelMapPayload from './litellm-model-map.json' with { type: 'json' };\nimport type { ModelPricing, PricingSource } from './types.js';\n\nconst ONE_MILLION = 1_000_000;\nconst DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst DEFAULT_FETCH_TIMEOUT_MS = 4000;\nconst DEFAULT_FETCH_RETRY_COUNT = 2;\nconst DEFAULT_FETCH_RETRY_DELAY_MS = 200;\n\nexport const DEFAULT_LITELLM_PRICING_URL =\n 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json';\n\ntype LiteLLMCachePayload = {\n fetchedAt: number;\n sourceUrl: string;\n pricingByModel: Record<string, ModelPricing>;\n};\n\nexport type LiteLLMPricingFetcherOptions = {\n sourceUrl?: string;\n cacheFilePath?: string;\n cacheTtlMs?: number;\n fetchTimeoutMs?: number;\n fetchRetryCount?: number;\n fetchRetryDelayMs?: number;\n offline?: boolean;\n fetchImpl?: typeof fetch;\n now?: () => number;\n sleep?: (delayMs: number) => Promise<void>;\n};\n\ntype LiteLLMModelMapPayload = {\n aliases?: unknown;\n preferredPricingKeyByCanonicalModel?: unknown;\n};\n\ntype LiteLLMModelMap = {\n aliasToCanonicalModel: Map<string, string>;\n canonicalizedAliasToCanonicalModel: Map<string, string>;\n preferredPricingKeyByCanonicalModel: Map<string, string>;\n};\n\nclass RetryableLiteLLMFetchError extends Error {\n public constructor(message: string) {\n super(message);\n this.name = 'RetryableLiteLLMFetchError';\n }\n}\n\nfunction isRetryableHttpStatus(status: number): boolean {\n return [408, 425, 429, 500, 502, 503, 504].includes(status);\n}\n\nfunction isRetryableFetchFailure(error: unknown): boolean {\n if (error instanceof RetryableLiteLLMFetchError) {\n return true;\n }\n\n if (!(error instanceof Error)) {\n return false;\n }\n\n if (error.name === 'AbortError' || error.name === 'TimeoutError') {\n return true;\n }\n\n if (error instanceof TypeError) {\n return true;\n }\n\n return /timeout|timed out|network|econn|enotfound|eai_again/iu.test(error.message);\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n}\n\nfunction normalizeKey(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction parseLiteLLMModelMap(payload: LiteLLMModelMapPayload): LiteLLMModelMap {\n const aliasToCanonicalModel = new Map<string, string>();\n const canonicalizedAliasToCanonicalModel = new Map<string, string>();\n const preferredPricingKeyByCanonicalModel = new Map<string, string>();\n\n const aliasesRecord = asRecord(payload.aliases);\n\n if (aliasesRecord) {\n for (const [alias, canonicalModel] of Object.entries(aliasesRecord)) {\n if (typeof canonicalModel !== 'string') {\n continue;\n }\n\n const normalizedAlias = normalizeKey(alias);\n const normalizedCanonicalModel = normalizeKey(canonicalModel);\n\n aliasToCanonicalModel.set(normalizedAlias, normalizedCanonicalModel);\n canonicalizedAliasToCanonicalModel.set(\n canonicalizeForFuzzy(normalizedAlias),\n normalizedCanonicalModel,\n );\n }\n }\n\n const preferredPricingRecord = asRecord(payload.preferredPricingKeyByCanonicalModel);\n\n if (preferredPricingRecord) {\n for (const [canonicalModel, preferredPricingKey] of Object.entries(preferredPricingRecord)) {\n if (typeof preferredPricingKey !== 'string') {\n continue;\n }\n\n preferredPricingKeyByCanonicalModel.set(\n normalizeKey(canonicalModel),\n normalizeKey(preferredPricingKey),\n );\n }\n }\n\n return {\n aliasToCanonicalModel,\n canonicalizedAliasToCanonicalModel,\n preferredPricingKeyByCanonicalModel,\n };\n}\n\nconst litellmModelMap = parseLiteLLMModelMap(litellmModelMapPayload);\n\nfunction toNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value < 0) {\n return undefined;\n }\n\n return value;\n }\n\n if (typeof value === 'string') {\n if (value.trim() === '') {\n return undefined;\n }\n\n const parsedValue = Number(value);\n\n if (!Number.isFinite(parsedValue) || parsedValue < 0) {\n return undefined;\n }\n\n return parsedValue;\n }\n\n return undefined;\n}\n\nfunction normalizeModelPricing(rawModelPricing: Record<string, unknown>): ModelPricing | undefined {\n const inputPerToken =\n toNonNegativeNumber(rawModelPricing.input_cost_per_token) ??\n toNonNegativeNumber(rawModelPricing.input_cost_per_token_priority);\n const outputPerToken =\n toNonNegativeNumber(rawModelPricing.output_cost_per_token) ??\n toNonNegativeNumber(rawModelPricing.output_cost_per_token_priority);\n\n if (inputPerToken === undefined || outputPerToken === undefined) {\n return undefined;\n }\n\n const cacheReadPerToken =\n toNonNegativeNumber(rawModelPricing.cache_read_input_token_cost) ??\n toNonNegativeNumber(rawModelPricing.cache_read_input_token_cost_priority);\n const cacheWritePerToken =\n toNonNegativeNumber(rawModelPricing.cache_creation_input_token_cost) ??\n toNonNegativeNumber(rawModelPricing.cache_creation_input_token_cost_priority);\n const reasoningPerToken = toNonNegativeNumber(rawModelPricing.output_cost_per_reasoning_token);\n\n const modelPricing: ModelPricing = {\n inputPer1MUsd: inputPerToken * ONE_MILLION,\n outputPer1MUsd: outputPerToken * ONE_MILLION,\n };\n\n if (cacheReadPerToken !== undefined) {\n modelPricing.cacheReadPer1MUsd = cacheReadPerToken * ONE_MILLION;\n }\n\n if (cacheWritePerToken !== undefined) {\n modelPricing.cacheWritePer1MUsd = cacheWritePerToken * ONE_MILLION;\n }\n\n if (reasoningPerToken !== undefined) {\n modelPricing.reasoningPer1MUsd = reasoningPerToken * ONE_MILLION;\n modelPricing.reasoningBilling = 'separate';\n }\n\n return modelPricing;\n}\n\nfunction normalizeLitellmPricingPayload(payload: unknown): Map<string, ModelPricing> {\n const payloadRecord = asRecord(payload);\n\n if (!payloadRecord) {\n throw new Error('LiteLLM pricing payload must be a JSON object');\n }\n\n const normalizedPricing = new Map<string, ModelPricing>();\n\n for (const [modelName, rawModelPricing] of Object.entries(payloadRecord)) {\n const modelPricingRecord = asRecord(rawModelPricing);\n\n if (!modelPricingRecord) {\n continue;\n }\n\n const normalizedModelPricing = normalizeModelPricing(modelPricingRecord);\n\n if (!normalizedModelPricing) {\n continue;\n }\n\n normalizedPricing.set(normalizeKey(modelName), normalizedModelPricing);\n }\n\n if (normalizedPricing.size === 0) {\n throw new Error('LiteLLM pricing payload did not contain any usable model pricing entries');\n }\n\n return normalizedPricing;\n}\n\nexport function getDefaultLiteLLMPricingCachePath(): string {\n return path.join(getUserCacheRootDir(), 'llm-usage-metrics', 'litellm-pricing-cache.json');\n}\n\nfunction stripProviderPrefix(model: string): string {\n const slashIndex = model.lastIndexOf('/');\n\n if (slashIndex === -1) {\n return model;\n }\n\n return model.slice(slashIndex + 1);\n}\n\nfunction canonicalizeForFuzzy(value: string): string {\n return value.replace(/[^a-z0-9]/gu, '');\n}\n\nfunction isPrefixModelMatch(candidate: string, modelName: string): boolean {\n if (!candidate.startsWith(modelName)) {\n return false;\n }\n\n if (candidate.length === modelName.length) {\n return true;\n }\n\n const nextCharacter = candidate[modelName.length];\n return nextCharacter === '-' || nextCharacter === ':' || nextCharacter === '@';\n}\n\nfunction extractNumericTokens(value: string): string[] {\n return value.match(/\\d+/gu) ?? [];\n}\n\nfunction areNumericSignaturesCompatible(left: string, right: string): boolean {\n const leftTokens = extractNumericTokens(left);\n const rightTokens = extractNumericTokens(right);\n\n if (leftTokens.length === 0 || rightTokens.length === 0) {\n return true;\n }\n\n if (\n leftTokens.length === rightTokens.length &&\n leftTokens.every((token, index) => token === rightTokens[index])\n ) {\n return true;\n }\n\n if (leftTokens.length === 1 && rightTokens.length > 1 && rightTokens.join('') === leftTokens[0]) {\n return true;\n }\n\n if (rightTokens.length === 1 && leftTokens.length > 1 && leftTokens.join('') === rightTokens[0]) {\n return true;\n }\n\n return false;\n}\n\nfunction levenshteinDistance(left: string, right: string): number {\n const leftLength = left.length;\n const rightLength = right.length;\n\n const matrix = Array.from({ length: leftLength + 1 }, (_, rowIndex) => {\n return Array.from({ length: rightLength + 1 }, (_, columnIndex) => {\n if (rowIndex === 0) {\n return columnIndex;\n }\n\n if (columnIndex === 0) {\n return rowIndex;\n }\n\n return 0;\n });\n });\n\n for (let rowIndex = 1; rowIndex <= leftLength; rowIndex += 1) {\n for (let columnIndex = 1; columnIndex <= rightLength; columnIndex += 1) {\n const substitutionCost = left[rowIndex - 1] === right[columnIndex - 1] ? 0 : 1;\n\n matrix[rowIndex][columnIndex] = Math.min(\n matrix[rowIndex - 1][columnIndex] + 1,\n matrix[rowIndex][columnIndex - 1] + 1,\n matrix[rowIndex - 1][columnIndex - 1] + substitutionCost,\n );\n }\n }\n\n return matrix[leftLength][rightLength];\n}\n\nexport class LiteLLMPricingFetcher implements PricingSource {\n private readonly sourceUrl: string;\n private readonly cacheFilePath: string;\n private readonly cacheTtlMs: number;\n private readonly fetchTimeoutMs: number;\n private readonly fetchRetryCount: number;\n private readonly fetchRetryDelayMs: number;\n private readonly offline: boolean;\n private readonly fetchImpl: typeof fetch;\n private readonly now: () => number;\n private readonly sleep: (delayMs: number) => Promise<void>;\n\n private pricingByModel = new Map<string, ModelPricing>();\n private resolvedAliasCache = new Map<string, string>();\n\n public constructor(options: LiteLLMPricingFetcherOptions = {}) {\n this.sourceUrl = options.sourceUrl ?? DEFAULT_LITELLM_PRICING_URL;\n this.cacheFilePath = options.cacheFilePath ?? getDefaultLiteLLMPricingCachePath();\n this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n this.fetchTimeoutMs = options.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;\n this.fetchRetryCount =\n Number.isFinite(options.fetchRetryCount) && (options.fetchRetryCount ?? 0) >= 0\n ? Math.trunc(options.fetchRetryCount ?? DEFAULT_FETCH_RETRY_COUNT)\n : DEFAULT_FETCH_RETRY_COUNT;\n this.fetchRetryDelayMs =\n Number.isFinite(options.fetchRetryDelayMs) && (options.fetchRetryDelayMs ?? 0) > 0\n ? Math.trunc(options.fetchRetryDelayMs ?? DEFAULT_FETCH_RETRY_DELAY_MS)\n : DEFAULT_FETCH_RETRY_DELAY_MS;\n this.offline = options.offline ?? false;\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.now = options.now ?? Date.now;\n this.sleep = options.sleep ?? sleep;\n }\n\n /**\n * Loads pricing data from cache or remote.\n * @returns Promise<boolean> True if loaded from cache, false if from network\n */\n public async load(): Promise<boolean> {\n const cacheLoaded = await this.loadFromCache({ allowStale: false });\n\n if (cacheLoaded) {\n return true;\n }\n\n if (this.offline) {\n const staleCacheLoaded = await this.loadFromCache({ allowStale: true });\n\n if (!staleCacheLoaded) {\n throw new Error('Offline pricing mode enabled but no cached LiteLLM pricing is available');\n }\n\n return true;\n }\n\n try {\n await this.loadFromRemote();\n return false;\n } catch {\n const staleCacheLoaded = await this.loadFromCache({ allowStale: true });\n\n if (!staleCacheLoaded) {\n throw new Error('Could not load LiteLLM pricing from network or cache');\n }\n\n return true;\n }\n }\n\n public resolveModelAlias(model: string): string {\n const normalizedModel = normalizeKey(model);\n const cachedAlias = this.resolvedAliasCache.get(normalizedModel);\n\n if (cachedAlias) {\n return cachedAlias;\n }\n\n const mappedAlias = this.resolveMappedModelAlias(normalizedModel);\n\n if (mappedAlias) {\n this.resolvedAliasCache.set(normalizedModel, mappedAlias);\n return mappedAlias;\n }\n\n const directMatch = this.resolveDirectModelMatch(normalizedModel);\n\n if (directMatch) {\n this.resolvedAliasCache.set(normalizedModel, directMatch);\n return directMatch;\n }\n\n const providerPrefixedMatch = this.resolveProviderPrefixedModelMatch(normalizedModel);\n\n if (providerPrefixedMatch) {\n this.resolvedAliasCache.set(normalizedModel, providerPrefixedMatch);\n return providerPrefixedMatch;\n }\n\n const prefixMatch = this.resolvePrefixModelMatch(normalizedModel);\n\n if (prefixMatch) {\n this.resolvedAliasCache.set(normalizedModel, prefixMatch);\n return prefixMatch;\n }\n\n const fuzzyMatch = this.resolveFuzzyModelMatch(normalizedModel);\n const resolvedAlias = fuzzyMatch ?? normalizedModel;\n this.resolvedAliasCache.set(normalizedModel, resolvedAlias);\n\n return resolvedAlias;\n }\n\n public getPricing(model: string): ModelPricing | undefined {\n const resolvedModel = this.resolveModelAlias(model);\n return this.pricingByModel.get(resolvedModel);\n }\n\n private resolveMappedModelAlias(normalizedModel: string): string | undefined {\n const canonicalModel = this.resolveCanonicalModelName(normalizedModel);\n\n if (!canonicalModel) {\n return undefined;\n }\n\n const preferredPricingKey =\n litellmModelMap.preferredPricingKeyByCanonicalModel.get(canonicalModel);\n\n if (preferredPricingKey && this.pricingByModel.has(preferredPricingKey)) {\n return preferredPricingKey;\n }\n\n const directCanonicalMatch = this.resolveDirectModelMatch(canonicalModel);\n\n if (directCanonicalMatch) {\n return directCanonicalMatch;\n }\n\n const providerPrefixedCanonicalMatch = this.resolveProviderPrefixedModelMatch(canonicalModel);\n\n if (providerPrefixedCanonicalMatch) {\n return providerPrefixedCanonicalMatch;\n }\n\n const prefixCanonicalMatch = this.resolvePrefixModelMatch(canonicalModel);\n\n if (prefixCanonicalMatch) {\n return prefixCanonicalMatch;\n }\n\n return this.resolveFuzzyModelMatch(canonicalModel);\n }\n\n private resolveCanonicalModelName(normalizedModel: string): string | undefined {\n const strippedModel = stripProviderPrefix(normalizedModel);\n\n const directCanonicalMatch =\n litellmModelMap.aliasToCanonicalModel.get(normalizedModel) ??\n litellmModelMap.aliasToCanonicalModel.get(strippedModel);\n\n if (directCanonicalMatch) {\n return directCanonicalMatch;\n }\n\n const canonicalizedModel = canonicalizeForFuzzy(normalizedModel);\n const canonicalizedStrippedModel = canonicalizeForFuzzy(strippedModel);\n\n return (\n litellmModelMap.canonicalizedAliasToCanonicalModel.get(canonicalizedModel) ??\n litellmModelMap.canonicalizedAliasToCanonicalModel.get(canonicalizedStrippedModel)\n );\n }\n\n private resolveDirectModelMatch(normalizedModel: string): string | undefined {\n if (this.pricingByModel.has(normalizedModel)) {\n return normalizedModel;\n }\n\n const strippedModel = stripProviderPrefix(normalizedModel);\n\n if (this.pricingByModel.has(strippedModel)) {\n return strippedModel;\n }\n\n return undefined;\n }\n\n private resolveProviderPrefixedModelMatch(normalizedModel: string): string | undefined {\n const candidates = [normalizedModel, stripProviderPrefix(normalizedModel)];\n\n for (const candidate of candidates) {\n let bestMatch: string | undefined;\n\n for (const modelName of this.pricingByModel.keys()) {\n const isProviderPrefixedMatch =\n modelName.endsWith(`/${candidate}`) || modelName.endsWith(`.${candidate}`);\n\n if (!isProviderPrefixedMatch) {\n continue;\n }\n\n if (\n !bestMatch ||\n modelName.length < bestMatch.length ||\n (modelName.length === bestMatch.length && compareByCodePoint(modelName, bestMatch) < 0)\n ) {\n bestMatch = modelName;\n }\n }\n\n if (bestMatch) {\n return bestMatch;\n }\n }\n\n return undefined;\n }\n\n private resolvePrefixModelMatch(normalizedModel: string): string | undefined {\n const candidates = [normalizedModel, stripProviderPrefix(normalizedModel)];\n\n for (const candidate of candidates) {\n let bestMatch: string | undefined;\n\n for (const modelName of this.pricingByModel.keys()) {\n if (!isPrefixModelMatch(candidate, modelName)) {\n continue;\n }\n\n if (\n !bestMatch ||\n modelName.length > bestMatch.length ||\n (modelName.length === bestMatch.length && compareByCodePoint(modelName, bestMatch) < 0)\n ) {\n bestMatch = modelName;\n }\n }\n\n if (bestMatch) {\n return bestMatch;\n }\n }\n\n return undefined;\n }\n\n private resolveFuzzyModelMatch(normalizedModel: string): string | undefined {\n const strippedModel = stripProviderPrefix(normalizedModel);\n const fuzzyTarget = canonicalizeForFuzzy(strippedModel);\n\n if (!fuzzyTarget) {\n return undefined;\n }\n\n let bestMatch: { modelName: string; distance: number } | undefined;\n\n for (const modelName of this.pricingByModel.keys()) {\n if (!areNumericSignaturesCompatible(strippedModel, modelName)) {\n continue;\n }\n\n const fuzzyModelName = canonicalizeForFuzzy(modelName);\n\n if (!fuzzyModelName) {\n continue;\n }\n\n const distance = levenshteinDistance(fuzzyTarget, fuzzyModelName);\n\n if (!bestMatch || distance < bestMatch.distance) {\n bestMatch = { modelName, distance };\n }\n }\n\n if (!bestMatch) {\n return undefined;\n }\n\n const maxDistance = Math.max(2, Math.floor(fuzzyTarget.length * 0.2));\n\n if (bestMatch.distance > maxDistance) {\n return undefined;\n }\n\n return bestMatch.modelName;\n }\n\n private async fetchRemotePricingResponse(): Promise<Response> {\n const response = await this.fetchImpl(this.sourceUrl, {\n signal: AbortSignal.timeout(this.fetchTimeoutMs),\n });\n\n if (!response.ok) {\n if (isRetryableHttpStatus(response.status)) {\n throw new RetryableLiteLLMFetchError(\n `Retryable LiteLLM pricing response status: HTTP ${response.status}`,\n );\n }\n\n throw new Error(`Failed to fetch LiteLLM pricing: HTTP ${response.status}`);\n }\n\n return response;\n }\n\n private async fetchRemotePricingResponseWithRetry(): Promise<Response> {\n const maxAttempts = this.fetchRetryCount + 1;\n\n for (let attemptIndex = 0; attemptIndex < maxAttempts; attemptIndex += 1) {\n try {\n return await this.fetchRemotePricingResponse();\n } catch (error) {\n const shouldRetry = isRetryableFetchFailure(error) && attemptIndex < maxAttempts - 1;\n\n if (!shouldRetry) {\n throw error;\n }\n }\n\n const backoffDelay = this.fetchRetryDelayMs * 2 ** attemptIndex;\n await this.sleep(backoffDelay);\n }\n\n throw new Error('Failed to fetch LiteLLM pricing after retries');\n }\n\n private async loadFromRemote(): Promise<void> {\n const response = await this.fetchRemotePricingResponseWithRetry();\n const payload = (await response.json()) as unknown;\n const normalizedPricing = normalizeLitellmPricingPayload(payload);\n\n this.pricingByModel = normalizedPricing;\n this.resolvedAliasCache.clear();\n\n try {\n await this.writeCache();\n } catch {\n // Cache writes are best-effort. A successful remote fetch must still be usable.\n }\n }\n\n private async loadFromCache(options: { allowStale: boolean }): Promise<boolean> {\n const cacheFileContent = await this.readCachePayload();\n\n if (!cacheFileContent) {\n return false;\n }\n\n if (cacheFileContent.sourceUrl !== this.sourceUrl) {\n return false;\n }\n\n const nowTimestamp = this.now();\n const isStale =\n cacheFileContent.fetchedAt > nowTimestamp ||\n nowTimestamp - cacheFileContent.fetchedAt > this.cacheTtlMs;\n\n if (isStale && !options.allowStale) {\n return false;\n }\n\n this.pricingByModel = new Map(\n Object.entries(cacheFileContent.pricingByModel).map(([modelName, pricing]) => [\n normalizeKey(modelName),\n pricing,\n ]),\n );\n this.resolvedAliasCache.clear();\n\n return this.pricingByModel.size > 0;\n }\n\n private normalizeCachedPricing(rawPricing: unknown): ModelPricing | undefined {\n const pricingRecord = asRecord(rawPricing);\n\n if (!pricingRecord) {\n return undefined;\n }\n\n const inputPer1MUsd = toNonNegativeNumber(pricingRecord.inputPer1MUsd);\n const outputPer1MUsd = toNonNegativeNumber(pricingRecord.outputPer1MUsd);\n\n if (inputPer1MUsd === undefined || outputPer1MUsd === undefined) {\n return undefined;\n }\n\n const modelPricing: ModelPricing = {\n inputPer1MUsd,\n outputPer1MUsd,\n };\n\n const cacheReadPer1MUsd = toNonNegativeNumber(pricingRecord.cacheReadPer1MUsd);\n\n if (cacheReadPer1MUsd !== undefined) {\n modelPricing.cacheReadPer1MUsd = cacheReadPer1MUsd;\n }\n\n const cacheWritePer1MUsd = toNonNegativeNumber(pricingRecord.cacheWritePer1MUsd);\n\n if (cacheWritePer1MUsd !== undefined) {\n modelPricing.cacheWritePer1MUsd = cacheWritePer1MUsd;\n }\n\n const reasoningPer1MUsd = toNonNegativeNumber(pricingRecord.reasoningPer1MUsd);\n\n if (reasoningPer1MUsd !== undefined) {\n modelPricing.reasoningPer1MUsd = reasoningPer1MUsd;\n modelPricing.reasoningBilling = 'separate';\n }\n\n return modelPricing;\n }\n\n private async readCachePayload(): Promise<LiteLLMCachePayload | undefined> {\n let content: string;\n\n try {\n content = await readFile(this.cacheFilePath, 'utf8');\n } catch {\n return undefined;\n }\n\n let parsedPayload: unknown;\n\n try {\n parsedPayload = JSON.parse(content);\n } catch {\n return undefined;\n }\n\n const payloadRecord = asRecord(parsedPayload);\n\n if (!payloadRecord) {\n return undefined;\n }\n\n const fetchedAt = toNonNegativeNumber(payloadRecord.fetchedAt);\n const sourceUrl =\n typeof payloadRecord.sourceUrl === 'string' ? payloadRecord.sourceUrl : undefined;\n const pricingByModelRecord = asRecord(payloadRecord.pricingByModel);\n\n if (fetchedAt === undefined || !sourceUrl || !pricingByModelRecord) {\n return undefined;\n }\n\n const pricingByModel: Record<string, ModelPricing> = {};\n\n for (const [modelName, rawPricing] of Object.entries(pricingByModelRecord)) {\n const pricing = this.normalizeCachedPricing(rawPricing);\n\n if (!pricing) {\n continue;\n }\n\n pricingByModel[modelName] = pricing;\n }\n\n return {\n fetchedAt,\n sourceUrl,\n pricingByModel,\n };\n }\n\n private async writeCache(): Promise<void> {\n const directoryPath = path.dirname(this.cacheFilePath);\n await mkdir(directoryPath, { recursive: true });\n\n const payload: LiteLLMCachePayload = {\n fetchedAt: this.now(),\n sourceUrl: this.sourceUrl,\n pricingByModel: Object.fromEntries(this.pricingByModel.entries()),\n };\n\n await writeFile(this.cacheFilePath, JSON.stringify(payload), 'utf8');\n }\n}\n","{\n \"aliases\": {\n \"k2p5\": \"kimi-k2.5\",\n \"kimi-k2p5\": \"kimi-k2.5\",\n \"kimi-k2.5\": \"kimi-k2.5\",\n \"kimi-k2.5-free\": \"kimi-k2.5\",\n \"moonshotai.kimi-k2.5\": \"kimi-k2.5\",\n \"moonshot/kimi-k2.5\": \"kimi-k2.5\",\n\n \"gpt-5.3-codex-spark\": \"gpt-5.3-codex\",\n\n \"gemini-3-pro\": \"gemini-3-pro\",\n \"antigravity-gemini-3-flash\": \"gemini-3-flash\",\n \"antigravity-gemini-3-pro\": \"gemini-3-pro\",\n \"antigravity-gemini-3-pro-high\": \"gemini-3-pro\",\n\n \"minimax-m2.1\": \"minimax-m2.1\",\n \"minimax-m2.1-free\": \"minimax-m2.1\",\n \"minimax-m2.5\": \"minimax-m2.5\",\n \"minimax-m2.5-free\": \"minimax-m2.5\",\n\n \"claude sonnet 4.6\": \"claude-sonnet-4.6\",\n \"claude-sonnet-4.6\": \"claude-sonnet-4.6\",\n \"claude-sonnet-4-6\": \"claude-sonnet-4.6\",\n \"anthropic/claude-sonnet-4.6\": \"claude-sonnet-4.6\",\n \"anthropic.claude-sonnet-4-6\": \"claude-sonnet-4.6\"\n },\n \"notes\": {\n \"gpt-5.3-codex-spark\": \"Alias to gpt-5.3-codex because upstream publishes token pricing on the gpt-5.3-codex key\"\n },\n \"preferredPricingKeyByCanonicalModel\": {\n \"kimi-k2.5\": \"moonshot/kimi-k2.5\",\n \"gpt-5.3-codex\": \"gpt-5.3-codex\",\n \"gemini-3-flash\": \"gemini/gemini-3-flash-preview\",\n \"gemini-3-pro\": \"gemini/gemini-3-pro-preview\",\n \"minimax-m2.1\": \"openrouter/minimax/minimax-m2.1\",\n \"minimax-m2.5\": \"openrouter/minimax/minimax-m2.5\",\n \"claude-sonnet-4.6\": \"anthropic.claude-sonnet-4-6\"\n }\n}\n","import type { UsageEvent } from '../domain/usage-event.js';\nimport {\n getPricingFetcherRuntimeConfig,\n type PricingFetcherRuntimeConfig,\n} from '../config/runtime-overrides.js';\nimport { applyPricingToEvents } from '../pricing/cost-engine.js';\nimport type { PricingSource } from '../pricing/types.js';\nimport { LiteLLMPricingFetcher } from '../pricing/litellm-pricing-fetcher.js';\n\nimport type {\n PricingLoadResult,\n ReportCommandOptions,\n UsagePricingOrigin,\n} from './usage-data-contracts.js';\n\nexport async function resolvePricingSource(\n options: ReportCommandOptions,\n runtimeConfig: PricingFetcherRuntimeConfig,\n): Promise<PricingLoadResult> {\n const litellmPricingFetcher = new LiteLLMPricingFetcher({\n sourceUrl: options.pricingUrl,\n offline: options.pricingOffline,\n cacheTtlMs: runtimeConfig.cacheTtlMs,\n fetchTimeoutMs: runtimeConfig.fetchTimeoutMs,\n });\n\n try {\n const fromCache = await litellmPricingFetcher.load();\n\n if (options.pricingOffline) {\n return { source: litellmPricingFetcher, origin: 'offline-cache' };\n }\n\n return { source: litellmPricingFetcher, origin: fromCache ? 'cache' : 'network' };\n } catch (error) {\n if (options.pricingOffline) {\n throw new Error('Offline pricing mode enabled but cached pricing is unavailable', {\n cause: error,\n });\n }\n\n const reason = error instanceof Error ? error.message : String(error);\n\n if (options.pricingUrl) {\n throw new Error(`Could not load pricing from --pricing-url: ${reason}`, {\n cause: error,\n });\n }\n\n throw new Error(`Could not load LiteLLM pricing: ${reason}`, { cause: error });\n }\n}\n\nexport function eventNeedsPricingLookup(event: UsageEvent): boolean {\n if (!event.model) {\n return false;\n }\n\n if (event.totalTokens <= 0) {\n return false;\n }\n\n return event.costMode !== 'explicit' || event.costUsd === undefined || event.costUsd === 0;\n}\n\nexport function shouldLoadPricingSource(events: UsageEvent[]): boolean {\n if (events.length === 0) {\n return false;\n }\n\n return events.some((event) => eventNeedsPricingLookup(event));\n}\n\nfunction hasAnyBillableTokenBuckets(events: UsageEvent[]): boolean {\n return events.some(\n (event) =>\n event.inputTokens > 0 ||\n event.outputTokens > 0 ||\n event.reasoningTokens > 0 ||\n event.cacheReadTokens > 0 ||\n event.cacheWriteTokens > 0,\n );\n}\n\nexport type PricingLoadMode = 'auto' | 'force';\n\nfunction shouldLoadPricingSourceForMode(\n events: UsageEvent[],\n pricingLoadMode: PricingLoadMode,\n): boolean {\n if (pricingLoadMode === 'force') {\n return hasAnyBillableTokenBuckets(events);\n }\n\n return shouldLoadPricingSource(events);\n}\n\ntype PricingSourceResolver = (\n options: ReportCommandOptions,\n runtimeConfig: PricingFetcherRuntimeConfig,\n) => Promise<PricingLoadResult>;\n\nexport async function resolveAndApplyPricingToEvents(\n events: UsageEvent[],\n options: ReportCommandOptions,\n runtimeConfig: PricingFetcherRuntimeConfig = getPricingFetcherRuntimeConfig(),\n loadPricingSource: PricingSourceResolver = resolvePricingSource,\n pricingLoadMode: PricingLoadMode = 'auto',\n): Promise<{\n pricedEvents: UsageEvent[];\n pricingOrigin: UsagePricingOrigin;\n pricingWarning?: string;\n pricingSource?: PricingSource;\n}> {\n let pricingOrigin: UsagePricingOrigin = 'none';\n\n if (!shouldLoadPricingSourceForMode(events, pricingLoadMode)) {\n return {\n pricedEvents: events,\n pricingOrigin,\n };\n }\n\n let pricingResult: PricingLoadResult;\n\n try {\n pricingResult = await loadPricingSource(options, runtimeConfig);\n } catch (error) {\n if (!options.ignorePricingFailures) {\n throw error;\n }\n\n const reason = error instanceof Error ? error.message : String(error);\n const pricingWarning = reason.trim().startsWith('Could not load')\n ? reason\n : `Could not load pricing; continuing without estimated costs: ${reason}`;\n\n return {\n pricedEvents: events,\n pricingOrigin,\n pricingWarning,\n };\n }\n\n pricingOrigin = pricingResult.origin;\n\n return {\n pricedEvents: applyPricingToEvents(events, pricingResult.source),\n pricingOrigin,\n pricingSource: pricingResult.source,\n };\n}\n","import { getActiveEnvVarOverrides } from '../config/env-var-display.js';\nimport {\n getParsingRuntimeConfig,\n getPricingFetcherRuntimeConfig,\n} from '../config/runtime-overrides.js';\nimport type { UsageEvent } from '../domain/usage-event.js';\nimport { createDefaultAdapters } from '../sources/create-default-adapters.js';\nimport { normalizeBuildUsageInputs, selectAdaptersForParsing } from './build-usage-data-inputs.js';\nimport {\n filterParsedAdapterEvents,\n parseSelectedAdapters,\n throwOnExplicitSourceFailures,\n type AdapterParseResult,\n} from './build-usage-data-parsing.js';\nimport {\n resolveAndApplyPricingToEvents,\n resolvePricingSource,\n type PricingLoadMode,\n} from './build-usage-data-pricing.js';\nimport type {\n BuildUsageDataDeps,\n ReportCommandOptions,\n UsagePricingOrigin,\n UsageSourceFailure,\n} from './usage-data-contracts.js';\nimport type { SourceAdapter } from '../sources/source-adapter.js';\nimport type { EnvVarOverride } from '../config/env-var-display.js';\nimport type { PricingSource } from '../pricing/types.js';\n\nfunction withNormalizedPricingUrl(\n options: ReportCommandOptions,\n normalizedPricingUrl: string | undefined,\n): ReportCommandOptions {\n if (options.pricingUrl === normalizedPricingUrl) {\n return options;\n }\n\n return {\n ...options,\n pricingUrl: normalizedPricingUrl,\n };\n}\n\nexport type UsageEventDataset = {\n options: ReportCommandOptions;\n normalizedInputs: ReturnType<typeof normalizeBuildUsageInputs>;\n adaptersToParse: SourceAdapter[];\n successfulParseResults: AdapterParseResult[];\n sourceFailures: UsageSourceFailure[];\n filteredEvents: UsageEvent[];\n pricingRuntimeConfig: ReturnType<typeof getPricingFetcherRuntimeConfig>;\n readEnvVarOverrides: () => EnvVarOverride[];\n};\n\nexport type UsageEventDatasetPricingResult = {\n pricedEvents: UsageEvent[];\n pricingOrigin: UsagePricingOrigin;\n pricingWarning?: string;\n pricingSource?: PricingSource;\n};\n\nexport async function buildUsageEventDataset(\n options: ReportCommandOptions,\n deps: BuildUsageDataDeps = {},\n): Promise<UsageEventDataset> {\n const normalizedInputs = normalizeBuildUsageInputs(options);\n\n const readParsingRuntimeConfig = deps.getParsingRuntimeConfig ?? getParsingRuntimeConfig;\n const readPricingRuntimeConfig =\n deps.getPricingFetcherRuntimeConfig ?? getPricingFetcherRuntimeConfig;\n const makeAdapters = deps.createAdapters ?? createDefaultAdapters;\n const parsingRuntimeConfig = readParsingRuntimeConfig();\n const pricingRuntimeConfig = readPricingRuntimeConfig();\n\n const adapters = makeAdapters(options);\n const adaptersToParse = selectAdaptersForParsing(adapters, normalizedInputs.sourceFilter);\n\n const { successfulParseResults, sourceFailures } = await parseSelectedAdapters(\n adaptersToParse,\n parsingRuntimeConfig.maxParallelFileParsing,\n {\n parseCache: {\n enabled: parsingRuntimeConfig.parseCacheEnabled,\n ttlMs: parsingRuntimeConfig.parseCacheTtlMs,\n maxEntries: parsingRuntimeConfig.parseCacheMaxEntries,\n maxBytes: parsingRuntimeConfig.parseCacheMaxBytes,\n },\n },\n );\n\n throwOnExplicitSourceFailures(sourceFailures, normalizedInputs.explicitSourceIds);\n\n const filteredEvents = filterParsedAdapterEvents(successfulParseResults, {\n timezone: normalizedInputs.timezone,\n since: options.since,\n until: options.until,\n providerFilter: normalizedInputs.providerFilter,\n modelFilter: normalizedInputs.modelFilter,\n });\n\n return {\n options,\n normalizedInputs,\n adaptersToParse,\n successfulParseResults,\n sourceFailures,\n filteredEvents,\n pricingRuntimeConfig,\n readEnvVarOverrides: deps.getActiveEnvVarOverrides ?? getActiveEnvVarOverrides,\n };\n}\n\nexport async function applyPricingToUsageEventDataset(\n dataset: UsageEventDataset,\n deps: BuildUsageDataDeps = {},\n pricingLoadMode: PricingLoadMode = 'auto',\n): Promise<UsageEventDatasetPricingResult> {\n const loadPricingSource = deps.resolvePricingSource ?? resolvePricingSource;\n const pricingOptions = withNormalizedPricingUrl(\n dataset.options,\n dataset.normalizedInputs.pricingUrl,\n );\n\n return resolveAndApplyPricingToEvents(\n dataset.filteredEvents,\n pricingOptions,\n dataset.pricingRuntimeConfig,\n loadPricingSource,\n pricingLoadMode,\n );\n}\n","import { aggregateUsage } from '../aggregate/aggregate-usage.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { assembleUsageDataResult, buildUsageDiagnostics } from './build-usage-data-diagnostics.js';\nimport {\n applyPricingToUsageEventDataset,\n buildUsageEventDataset,\n} from './build-usage-event-dataset.js';\nimport type {\n BuildUsageDataDeps,\n ReportCommandOptions,\n UsageDataResult,\n} from './usage-data-contracts.js';\n\nexport async function buildUsageData(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n deps: BuildUsageDataDeps = {},\n): Promise<UsageDataResult> {\n const dataset = await buildUsageEventDataset(options, deps);\n const { pricedEvents, pricingOrigin, pricingWarning } = await applyPricingToUsageEventDataset(\n dataset,\n deps,\n 'auto',\n );\n\n const rows = aggregateUsage(pricedEvents, {\n granularity,\n timezone: dataset.normalizedInputs.timezone,\n sourceOrder: dataset.adaptersToParse.map((adapter) => adapter.id),\n });\n\n const diagnostics = buildUsageDiagnostics({\n adaptersToParse: dataset.adaptersToParse,\n successfulParseResults: dataset.successfulParseResults,\n sourceFailures: dataset.sourceFailures,\n pricingOrigin,\n pricingWarning,\n activeEnvOverrides: dataset.readEnvVarOverrides(),\n timezone: dataset.normalizedInputs.timezone,\n });\n\n return assembleUsageDataResult(pricedEvents, rows, diagnostics);\n}\n","import { aggregateUsage } from '../aggregate/aggregate-usage.js';\nimport { aggregateEfficiency } from '../efficiency/aggregate-efficiency.js';\nimport { collectGitOutcomes } from '../efficiency/git-outcome-collector.js';\nimport {\n attributeUsageEventsToRepo,\n resolveRepoRootFromPathHint,\n type RepoRootResolver,\n} from '../efficiency/repo-attribution.js';\nimport type { UsageEvent } from '../domain/usage-event.js';\nimport { getPeriodKey, type ReportGranularity } from '../utils/time-buckets.js';\nimport { buildUsageData } from './build-usage-data.js';\nimport type { EfficiencyCommandOptions, EfficiencyDataResult } from './usage-data-contracts.js';\n\nexport type BuildEfficiencyDataDeps = {\n buildUsageData?: typeof buildUsageData;\n collectGitOutcomes?: typeof collectGitOutcomes;\n resolveRepoRoot?: RepoRootResolver;\n};\n\nfunction hasActiveRepeatedFilter(value: string | string[] | undefined): boolean {\n if (!value) {\n return false;\n }\n\n const values = Array.isArray(value) ? value : [value];\n\n return values.some((entry) =>\n entry\n .split(',')\n .map((candidate) => candidate.trim())\n .some((candidate) => candidate.length > 0),\n );\n}\n\nfunction hasActiveProviderFilter(provider: string | undefined): boolean {\n return Boolean(provider?.trim());\n}\n\nfunction hasActiveTextOption(value: string | undefined): boolean {\n return Boolean(value?.trim());\n}\n\nfunction resolveScopeNote(options: EfficiencyCommandOptions): string | undefined {\n const activeFilters: string[] = [];\n\n if (hasActiveTextOption(options.piDir)) {\n activeFilters.push('--pi-dir');\n }\n\n if (hasActiveTextOption(options.codexDir)) {\n activeFilters.push('--codex-dir');\n }\n\n if (hasActiveTextOption(options.geminiDir)) {\n activeFilters.push('--gemini-dir');\n }\n\n if (hasActiveTextOption(options.droidDir)) {\n activeFilters.push('--droid-dir');\n }\n\n if (hasActiveTextOption(options.opencodeDb)) {\n activeFilters.push('--opencode-db');\n }\n\n if (hasActiveRepeatedFilter(options.sourceDir)) {\n activeFilters.push('--source-dir');\n }\n\n if (hasActiveRepeatedFilter(options.source)) {\n activeFilters.push('--source');\n }\n\n if (hasActiveProviderFilter(options.provider)) {\n activeFilters.push('--provider');\n }\n\n if (hasActiveRepeatedFilter(options.model)) {\n activeFilters.push('--model');\n }\n\n if (activeFilters.length === 0) {\n return undefined;\n }\n\n return `Usage filters (${activeFilters.join(', ')}) affect commit attribution too: only commit days with matching repo-attributed usage events are counted.`;\n}\n\nfunction hasMeaningfulEfficiencyUsageSignal(event: UsageEvent): boolean {\n return event.totalTokens > 0 || (event.costUsd !== undefined && event.costUsd > 0);\n}\n\nexport async function buildEfficiencyData(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n deps: BuildEfficiencyDataDeps = {},\n): Promise<EfficiencyDataResult> {\n const buildUsage = deps.buildUsageData ?? buildUsageData;\n const collectOutcomes = deps.collectGitOutcomes ?? collectGitOutcomes;\n const resolveRepoRoot = deps.resolveRepoRoot ?? resolveRepoRootFromPathHint;\n const repoDir = options.repoDir?.trim();\n\n if (options.repoDir !== undefined && !repoDir) {\n throw new Error('--repo-dir must be a non-empty path');\n }\n\n const usageData = await buildUsage(granularity, options);\n const attribution = await attributeUsageEventsToRepo(\n usageData.events,\n repoDir ?? process.cwd(),\n resolveRepoRoot,\n );\n const matchedEventsWithSignal = attribution.matchedEvents.filter((event) =>\n hasMeaningfulEfficiencyUsageSignal(event),\n );\n const activeUsageDays = new Set(\n matchedEventsWithSignal.map((event) =>\n getPeriodKey(event.timestamp, 'daily', usageData.diagnostics.timezone),\n ),\n );\n const gitOutcomes = await collectOutcomes({\n repoDir,\n granularity,\n timezone: usageData.diagnostics.timezone,\n since: options.since,\n until: options.until,\n includeMergeCommits: options.includeMergeCommits,\n activeUsageDays,\n });\n const repoScopedUsageRows = aggregateUsage(matchedEventsWithSignal, {\n granularity,\n timezone: usageData.diagnostics.timezone,\n });\n\n const rows = aggregateEfficiency({\n usageRows: repoScopedUsageRows,\n periodOutcomes: gitOutcomes.periodOutcomes,\n });\n\n return {\n rows,\n diagnostics: {\n usage: usageData.diagnostics,\n repoDir: gitOutcomes.diagnostics.repoDir,\n includeMergeCommits: gitOutcomes.diagnostics.includeMergeCommits,\n gitCommitCount: gitOutcomes.diagnostics.commitsCollected,\n gitLinesAdded: gitOutcomes.diagnostics.linesAdded,\n gitLinesDeleted: gitOutcomes.diagnostics.linesDeleted,\n repoMatchedUsageEvents: attribution.matchedEventCount,\n repoExcludedUsageEvents: attribution.excludedEventCount,\n repoUnattributedUsageEvents: attribution.unattributedEventCount,\n scopeNote: resolveScopeNote(options),\n },\n };\n}\n","import pc from 'picocolors';\n\ntype LogLevel = 'info' | 'warn' | 'dim';\n\nconst icons: Record<LogLevel, string> = {\n info: pc.blue('ℹ'),\n warn: pc.yellow('⚠'),\n dim: pc.gray('•'),\n};\n\nfunction formatMessage(level: LogLevel, message: string): string {\n const icon = icons[level];\n return `${icon} ${message}`;\n}\n\nexport const logger = {\n info: (message: string): void => {\n console.error(formatMessage('info', message));\n },\n warn: (message: string): void => {\n console.error(formatMessage('warn', message));\n },\n dim: (message: string): void => {\n console.error(formatMessage('dim', message));\n },\n};\n","import type { UsageDiagnostics } from './usage-data-contracts.js';\nimport { logger } from '../utils/logger.js';\n\nexport type DiagnosticsLogger = Pick<typeof logger, 'info' | 'warn' | 'dim'>;\n\nexport function emitDiagnostics(\n diagnostics: UsageDiagnostics,\n diagnosticsLogger: DiagnosticsLogger = logger,\n): void {\n const totalSessions = diagnostics.sessionStats.reduce(\n (sum, current) => sum + current.filesFound,\n 0,\n );\n const totalEvents = diagnostics.sessionStats.reduce(\n (sum, current) => sum + current.eventsParsed,\n 0,\n );\n\n if (totalSessions > 0) {\n diagnosticsLogger.info(`Found ${totalSessions} session file(s) with ${totalEvents} event(s)`);\n\n for (const session of diagnostics.sessionStats) {\n const eventsLabel = session.eventsParsed === 1 ? 'event' : 'events';\n diagnosticsLogger.dim(\n ` ${session.source}: ${session.filesFound} file(s), ${session.eventsParsed} ${eventsLabel}`,\n );\n }\n } else {\n diagnosticsLogger.warn('No sessions found');\n }\n\n if (diagnostics.sourceFailures.length > 0) {\n const sourceLabel = diagnostics.sourceFailures.length === 1 ? 'source' : 'sources';\n diagnosticsLogger.warn(`Failed to parse ${diagnostics.sourceFailures.length} ${sourceLabel}`);\n\n for (const failure of diagnostics.sourceFailures) {\n diagnosticsLogger.dim(` ${failure.source}: ${failure.reason}`);\n }\n }\n\n const totalSkippedRows = diagnostics.skippedRows.reduce(\n (sum, skippedRowsEntry) => sum + skippedRowsEntry.skippedRows,\n 0,\n );\n\n if (totalSkippedRows > 0) {\n const rowLabel = totalSkippedRows === 1 ? 'row' : 'rows';\n diagnosticsLogger.warn(`Skipped ${totalSkippedRows} malformed ${rowLabel}`);\n\n for (const skippedRowsEntry of diagnostics.skippedRows) {\n const reasonSummary = skippedRowsEntry.reasons\n ?.filter((reasonStat) => reasonStat.count > 0)\n .map((reasonStat) => `${reasonStat.reason}: ${reasonStat.count}`)\n .join(', ');\n\n diagnosticsLogger.dim(\n reasonSummary\n ? ` ${skippedRowsEntry.source}: ${skippedRowsEntry.skippedRows} skipped (${reasonSummary})`\n : ` ${skippedRowsEntry.source}: ${skippedRowsEntry.skippedRows} skipped`,\n );\n }\n }\n\n switch (diagnostics.pricingOrigin) {\n case 'offline-cache':\n diagnosticsLogger.info('Using cached pricing (offline mode)');\n break;\n case 'cache':\n diagnosticsLogger.info('Loaded pricing from cache');\n break;\n case 'network':\n diagnosticsLogger.info('Fetched pricing from LiteLLM');\n break;\n case 'none':\n break;\n }\n\n if (diagnostics.pricingWarning) {\n diagnosticsLogger.warn(diagnostics.pricingWarning);\n }\n}\n","import { formatEnvVarOverrides, type EnvVarOverride } from '../config/env-var-display.js';\n\ntype EnvVarOverridesLogger = {\n info: (message: string) => void;\n dim: (message: string) => void;\n};\n\nexport function emitEnvVarOverrides(\n activeEnvOverrides: EnvVarOverride[],\n diagnosticsLogger: EnvVarOverridesLogger,\n): void {\n const envVarOverrideLines = formatEnvVarOverrides(activeEnvOverrides);\n\n if (envVarOverrideLines.length === 0) {\n return;\n }\n\n const [headerLine, ...envVarLines] = envVarOverrideLines;\n\n if (headerLine) {\n diagnosticsLogger.info(headerLine);\n }\n\n for (const envVarLine of envVarLines) {\n diagnosticsLogger.dim(envVarLine);\n }\n}\n","const ansiEscapePattern = new RegExp(String.raw`\\u001B\\[[0-9;]*m`, 'gu');\nconst combiningMarkPattern = /\\p{Mark}/u;\nconst extendedPictographicPattern = /\\p{Extended_Pictographic}/u;\nconst emojiPresentationPattern = /\\p{Emoji_Presentation}/u;\nconst regionalIndicatorPattern = /\\p{Regional_Indicator}/u;\nconst graphemeSegmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });\n\nexport type TerminalColumnsSource = {\n isTTY?: unknown;\n columns?: unknown;\n};\n\nfunction normalizeLineBreaks(value: string): string {\n return value.replace(/\\r\\n?/gu, '\\n');\n}\n\nexport function resolveTtyColumns(source: TerminalColumnsSource): number | undefined {\n if (source.isTTY !== true) {\n return undefined;\n }\n\n if (\n typeof source.columns !== 'number' ||\n !Number.isFinite(source.columns) ||\n source.columns <= 0\n ) {\n return undefined;\n }\n\n return Math.floor(source.columns);\n}\n\nfunction stripAnsi(value: string): string {\n return value.replaceAll(ansiEscapePattern, '');\n}\n\nfunction isControlCodePoint(codePoint: number): boolean {\n return codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f);\n}\n\nfunction isZeroWidthCodePoint(codePoint: number): boolean {\n return (\n codePoint === 0x200b ||\n codePoint === 0x200d ||\n codePoint === 0x2060 ||\n codePoint === 0xfeff ||\n (codePoint >= 0xfe00 && codePoint <= 0xfe0f)\n );\n}\n\n// Adapted from the is-fullwidth-code-point package to preserve table alignment\n// for East Asian wide characters without re-introducing a dependency.\nconst fullWidthCodePointRanges = [\n [0x1100, 0x115f],\n [0x2329, 0x232a],\n [0x2e80, 0x3247],\n [0x3250, 0x4dbf],\n [0x4e00, 0xa4c6],\n [0xa960, 0xa97c],\n [0xac00, 0xd7a3],\n [0xf900, 0xfaff],\n [0xfe10, 0xfe19],\n [0xfe30, 0xfe6b],\n [0xff01, 0xff60],\n [0xffe0, 0xffe6],\n [0x1b000, 0x1b001],\n [0x1f200, 0x1f251],\n [0x20000, 0x3fffd],\n] as const;\n\nconst fullWidthCodePointExclusions = new Set<number>([0x303f]);\n\nfunction isFullWidthCodePoint(codePoint: number): boolean {\n if (Number.isNaN(codePoint) || fullWidthCodePointExclusions.has(codePoint)) {\n return false;\n }\n\n for (const [start, end] of fullWidthCodePointRanges) {\n if (codePoint >= start && codePoint <= end) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction codePointDisplayWidth(character: string): number {\n const codePoint = character.codePointAt(0);\n\n if (codePoint === undefined) {\n return 0;\n }\n\n if (isControlCodePoint(codePoint) || isZeroWidthCodePoint(codePoint)) {\n return 0;\n }\n\n if (combiningMarkPattern.test(character)) {\n return 0;\n }\n\n if (isFullWidthCodePoint(codePoint)) {\n return 2;\n }\n\n return 1;\n}\n\nfunction segmentGraphemes(value: string): string[] {\n return Array.from(graphemeSegmenter.segment(value), (segment) => segment.segment);\n}\n\nfunction isEmojiGrapheme(grapheme: string): boolean {\n if (emojiPresentationPattern.test(grapheme)) {\n return true;\n }\n\n if (regionalIndicatorPattern.test(grapheme)) {\n return true;\n }\n\n if (grapheme.includes('\\u20E3')) {\n return true;\n }\n\n if (grapheme.includes('\\uFE0F')) {\n return true;\n }\n\n return grapheme.includes('\\u200D') && extendedPictographicPattern.test(grapheme);\n}\n\nfunction graphemeDisplayWidth(grapheme: string): number {\n if (isEmojiGrapheme(grapheme)) {\n return 2;\n }\n\n let width = 0;\n\n for (const character of grapheme) {\n width = Math.max(width, codePointDisplayWidth(character));\n }\n\n return width;\n}\n\nexport function visibleWidth(value: string): number {\n let width = 0;\n\n for (const grapheme of segmentGraphemes(stripAnsi(value))) {\n width += graphemeDisplayWidth(grapheme);\n }\n\n return width;\n}\n\nexport function splitCellLines(value: string): string[] {\n return normalizeLineBreaks(value).split('\\n');\n}\n\nfunction sliceByVisibleWidth(value: string, maxWidth: number): string {\n if (maxWidth <= 0) {\n return '';\n }\n\n let width = 0;\n let endOffset = 0;\n\n for (const grapheme of segmentGraphemes(value)) {\n const graphemeWidth = graphemeDisplayWidth(grapheme);\n\n if (width + graphemeWidth > maxWidth) {\n break;\n }\n\n width += graphemeWidth;\n endOffset += grapheme.length;\n }\n\n return value.slice(0, endOffset);\n}\n\nfunction getFirstGrapheme(value: string): string {\n for (const grapheme of segmentGraphemes(value)) {\n return grapheme;\n }\n\n return '';\n}\n\nfunction wrapPlainLine(line: string, width: number): string[] {\n if (visibleWidth(line) <= width) {\n return [line];\n }\n\n const wrappedLines: string[] = [];\n let remaining = line;\n\n while (visibleWidth(remaining) > width) {\n const slice = sliceByVisibleWidth(remaining, width + 1);\n const breakIndex = slice.lastIndexOf(' ');\n\n if (breakIndex > 0) {\n wrappedLines.push(remaining.slice(0, breakIndex));\n remaining = remaining.slice(breakIndex + 1);\n continue;\n }\n\n const chunk = sliceByVisibleWidth(remaining, width);\n\n if (chunk.length > 0) {\n wrappedLines.push(chunk);\n remaining = remaining.slice(chunk.length);\n continue;\n }\n\n const firstCharacter = getFirstGrapheme(remaining);\n\n wrappedLines.push(firstCharacter);\n remaining = remaining.slice(firstCharacter.length);\n }\n\n wrappedLines.push(remaining);\n\n return wrappedLines;\n}\n\nexport function wrapTableColumn(\n rows: string[][],\n options: { columnIndex: number; width: number },\n): string[][] {\n if (options.width <= 0) {\n throw new RangeError('wrapTableColumn width must be greater than 0');\n }\n\n return rows.map((row) => {\n const wrappedRow = [...row];\n const cell = wrappedRow[options.columnIndex] ?? '';\n const wrappedLines = splitCellLines(cell).flatMap((line) => wrapPlainLine(line, options.width));\n\n wrappedRow[options.columnIndex] = wrappedLines.join('\\n');\n\n return wrappedRow;\n });\n}\n","import {\n resolveTtyColumns,\n type TerminalColumnsSource,\n visibleWidth,\n} from '../render/table-text-layout.js';\n\nfunction detectTerminalOverflowColumns(\n reportOutput: string,\n stdoutState: TerminalColumnsSource,\n): number | undefined {\n const terminalColumns = resolveTtyColumns(stdoutState);\n\n if (terminalColumns === undefined) {\n return undefined;\n }\n\n const allLines = reportOutput.trimEnd().split('\\n');\n const tableLikeLinePattern = /[│╭╮╰╯├┼┬┴┌┐└┘]|^\\s*\\|.*\\|\\s*$/u;\n const tableLines = allLines.filter((line) => tableLikeLinePattern.test(line));\n\n if (tableLines.length === 0) {\n return undefined;\n }\n\n const maxLineWidth = tableLines.reduce(\n (maxWidth, line) => Math.max(maxWidth, visibleWidth(line)),\n 0,\n );\n\n if (maxLineWidth <= terminalColumns) {\n return undefined;\n }\n\n return maxLineWidth - terminalColumns;\n}\n\nexport function warnIfTerminalTableOverflows(\n reportOutput: string,\n warn: (message: string) => void,\n stdoutState: TerminalColumnsSource = process.stdout as TerminalColumnsSource,\n): void {\n const overflowColumns = detectTerminalOverflowColumns(reportOutput, stdoutState);\n\n if (overflowColumns !== undefined) {\n warn(\n `Report table is wider than terminal by ${overflowColumns} column(s). Use fullscreen/maximized terminal for better readability.`,\n );\n }\n}\n","import { markdownTable } from 'markdown-table';\nimport pc from 'picocolors';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\nimport type { EfficiencyDataResult } from '../cli/usage-data-contracts.js';\nimport type { EfficiencyRow } from '../efficiency/efficiency-row.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { renderReportHeader } from './report-header.js';\nimport { efficiencyTableHeaders, toEfficiencyTableCells } from './efficiency-row-cells.js';\nimport {\n resolveTtyColumns,\n splitCellLines,\n visibleWidth,\n wrapTableColumn,\n} from './table-text-layout.js';\nimport { shouldUseColorByDefault } from './terminal-table.js';\nimport { renderUnicodeTable } from './unicode-table.js';\n\nexport type EfficiencyReportFormat = 'terminal' | 'markdown' | 'json';\n\nexport type RenderEfficiencyReportOptions = {\n granularity: ReportGranularity;\n useColor?: boolean;\n};\n\nconst periodColumnIndex = 0;\nconst minimumEfficiencyColumnWidth = 1;\nconst commitsColumnIndex = 1;\nconst linesAddedColumnIndex = 2;\nconst linesDeletedColumnIndex = 3;\nconst linesChangedColumnIndex = 4;\nconst costColumnIndex = 11;\nconst usdPerCommitColumnIndex = 12;\nconst usdPer1kLinesChangedColumnIndex = 13;\nconst commitsPerUsdColumnIndex = 16;\n\ntype FittedEfficiencyTableCells = {\n headerCells: string[];\n bodyRows: string[][];\n widths: number[];\n};\n\nfunction getReportTitle(granularity: ReportGranularity): string {\n switch (granularity) {\n case 'daily':\n return 'Daily Efficiency Report';\n case 'weekly':\n return 'Weekly Efficiency Report';\n case 'monthly':\n return 'Monthly Efficiency Report';\n }\n}\n\nfunction toTableSortRow(row: EfficiencyRow): UsageReportRow {\n if (row.rowType === 'grand_total') {\n return {\n rowType: 'grand_total',\n periodKey: 'ALL',\n source: 'combined',\n models: [],\n modelBreakdown: [],\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n costUsd: row.costUsd,\n costIncomplete: row.costIncomplete,\n };\n }\n\n return {\n rowType: 'period_source',\n periodKey: row.periodKey,\n source: 'combined',\n models: [],\n modelBreakdown: [],\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n costUsd: row.costUsd,\n costIncomplete: row.costIncomplete,\n };\n}\n\nfunction measureRenderedTableWidth(columnWidths: number[]): number {\n if (columnWidths.length === 0) {\n return 0;\n }\n\n return columnWidths.reduce((sum, width) => sum + width, 0) + columnWidths.length * 3 + 1;\n}\n\nfunction computeColumnWidths(\n headerCells: readonly string[],\n bodyRows: readonly string[][],\n): number[] {\n const columnCount = Math.max(\n headerCells.length,\n ...bodyRows.map((row) => row.length),\n efficiencyTableHeaders.length,\n );\n const widths = Array.from({ length: columnCount }, () => 0);\n\n const measureRow = (row: readonly string[]) => {\n for (let columnIndex = 0; columnIndex < columnCount; columnIndex += 1) {\n for (const line of splitCellLines(row[columnIndex] ?? '')) {\n widths[columnIndex] = Math.max(widths[columnIndex], visibleWidth(line));\n }\n }\n };\n\n measureRow(headerCells);\n\n for (const row of bodyRows) {\n measureRow(row);\n }\n\n return widths;\n}\n\nfunction resolveWrappedCells(\n headerCells: readonly string[],\n bodyRows: readonly string[][],\n widths: readonly number[],\n): { wrappedHeaderCells: string[]; wrappedBodyRows: string[][] } {\n let wrappedHeaderCells = [...headerCells];\n let wrappedBodyRows = bodyRows.map((row) => [...row]);\n\n for (let columnIndex = 0; columnIndex < widths.length; columnIndex += 1) {\n const columnWidth = widths[columnIndex] ?? 0;\n\n if (columnWidth <= 0) {\n continue;\n }\n\n wrappedHeaderCells =\n wrapTableColumn([wrappedHeaderCells], {\n columnIndex,\n width: columnWidth,\n })[0] ?? [];\n wrappedBodyRows = wrapTableColumn(wrappedBodyRows, {\n columnIndex,\n width: columnWidth,\n });\n }\n\n return {\n wrappedHeaderCells,\n wrappedBodyRows,\n };\n}\n\nfunction fitTableCellsToTerminal(\n headerCells: readonly string[],\n bodyRows: readonly string[][],\n): FittedEfficiencyTableCells {\n const naturalWidths = computeColumnWidths(headerCells, bodyRows);\n const terminalWidth = resolveTtyColumns(process.stdout as { isTTY?: unknown; columns?: unknown });\n\n if (terminalWidth === undefined || measureRenderedTableWidth(naturalWidths) <= terminalWidth) {\n return {\n headerCells: [...headerCells],\n bodyRows: bodyRows.map((row) => [...row]),\n widths: naturalWidths,\n };\n }\n\n const constrainedWidths = [...naturalWidths];\n let renderedTableWidth = measureRenderedTableWidth(constrainedWidths);\n\n while (\n renderedTableWidth > terminalWidth &&\n constrainedWidths.some((width) => width > minimumEfficiencyColumnWidth)\n ) {\n let widestIndex = -1;\n let widestWidth = -1;\n\n for (let columnIndex = 0; columnIndex < constrainedWidths.length; columnIndex += 1) {\n const columnWidth = constrainedWidths[columnIndex];\n\n if (columnWidth <= minimumEfficiencyColumnWidth || columnWidth <= widestWidth) {\n continue;\n }\n\n widestIndex = columnIndex;\n widestWidth = columnWidth;\n }\n\n if (widestIndex === -1) {\n break;\n }\n\n const overflowColumns = renderedTableWidth - terminalWidth;\n const maxReducibleWidth = widestWidth - minimumEfficiencyColumnWidth;\n const reduction = Math.min(overflowColumns, maxReducibleWidth);\n\n if (reduction <= 0) {\n break;\n }\n\n constrainedWidths[widestIndex] -= reduction;\n renderedTableWidth -= reduction;\n }\n\n const { wrappedHeaderCells, wrappedBodyRows } = resolveWrappedCells(\n headerCells,\n bodyRows,\n constrainedWidths,\n );\n\n return {\n headerCells: wrappedHeaderCells,\n bodyRows: wrappedBodyRows,\n widths: constrainedWidths,\n };\n}\n\nfunction styleDeltaCell(\n value: number,\n formattedValue: string,\n options: { useColor: boolean },\n): string {\n if (!options.useColor) {\n return formattedValue;\n }\n\n if (value > 0) {\n return pc.green(formattedValue);\n }\n\n if (value < 0) {\n return pc.red(formattedValue);\n }\n\n return pc.dim(formattedValue);\n}\n\nfunction styleEfficiencyTerminalRows(\n rows: EfficiencyRow[],\n bodyRows: string[][],\n options: { useColor: boolean },\n): string[][] {\n return bodyRows.map((cells, rowIndex) => {\n if (!options.useColor) {\n return [...cells];\n }\n\n const row = rows[rowIndex];\n const styledCells = [...cells];\n const periodCell = styledCells[periodColumnIndex];\n\n styledCells[periodColumnIndex] =\n row.rowType === 'grand_total' ? pc.bold(pc.cyan(periodCell)) : pc.bold(periodCell);\n styledCells[commitsColumnIndex] = pc.bold(styledCells[commitsColumnIndex]);\n styledCells[linesAddedColumnIndex] = styleDeltaCell(\n row.linesAdded,\n styledCells[linesAddedColumnIndex],\n options,\n );\n styledCells[linesDeletedColumnIndex] = styleDeltaCell(\n row.linesDeleted * -1,\n styledCells[linesDeletedColumnIndex],\n options,\n );\n styledCells[linesChangedColumnIndex] = styleDeltaCell(\n row.linesChanged,\n styledCells[linesChangedColumnIndex],\n options,\n );\n\n const costValue = row.costUsd;\n if (costValue !== undefined && costValue > 0) {\n styledCells[costColumnIndex] = pc.yellow(styledCells[costColumnIndex]);\n }\n\n const usdPerCommitValue = row.usdPerCommit;\n if (usdPerCommitValue !== undefined && usdPerCommitValue > 0) {\n styledCells[usdPerCommitColumnIndex] = pc.yellow(styledCells[usdPerCommitColumnIndex]);\n }\n\n const usdPer1kLinesChangedValue = row.usdPer1kLinesChanged;\n if (usdPer1kLinesChangedValue !== undefined && usdPer1kLinesChangedValue > 0) {\n styledCells[usdPer1kLinesChangedColumnIndex] = pc.yellow(\n styledCells[usdPer1kLinesChangedColumnIndex],\n );\n }\n\n const commitsPerUsdValue = row.commitsPerUsd;\n if (commitsPerUsdValue !== undefined && commitsPerUsdValue > 0) {\n styledCells[commitsPerUsdColumnIndex] = pc.green(styledCells[commitsPerUsdColumnIndex]);\n }\n\n return styledCells;\n });\n}\n\nfunction renderTerminalEfficiencyTable(\n rows: EfficiencyRow[],\n options: { useColor: boolean },\n): string {\n const headerCells = Array.from(efficiencyTableHeaders);\n const bodyRows = styleEfficiencyTerminalRows(rows, toEfficiencyTableCells(rows), options);\n const tableSortRows = rows.map((row) => toTableSortRow(row));\n const fittedCells = fitTableCellsToTerminal(headerCells, bodyRows);\n\n return renderUnicodeTable({\n headerCells: fittedCells.headerCells,\n bodyRows: fittedCells.bodyRows,\n measureHeaderCells: fittedCells.headerCells,\n measureBodyRows: fittedCells.bodyRows,\n usageRows: tableSortRows,\n tableLayout: 'compact',\n modelsColumnIndex: periodColumnIndex,\n modelsColumnWidth:\n fittedCells.widths[periodColumnIndex] ?? efficiencyTableHeaders[periodColumnIndex].length,\n });\n}\n\nfunction toMarkdownSafeCell(value: string): string {\n return value.replace(/\\r?\\n/gu, '<br>');\n}\n\nfunction renderMarkdownEfficiencyTable(rows: EfficiencyRow[]): string {\n const bodyRows = toEfficiencyTableCells(rows).map((row) =>\n row.map((cell) => toMarkdownSafeCell(cell)),\n );\n const tableRows = [Array.from(efficiencyTableHeaders), ...bodyRows];\n const alignment = efficiencyTableHeaders.map((_, index) => (index === 0 ? 'l' : 'r')) as (\n | 'l'\n | 'r'\n )[];\n\n return markdownTable(tableRows, {\n align: alignment,\n });\n}\n\nfunction renderTerminalEfficiencyReport(\n efficiencyData: EfficiencyDataResult,\n options: RenderEfficiencyReportOptions,\n): string {\n const outputLines: string[] = [];\n const useColor = options.useColor ?? shouldUseColorByDefault();\n\n outputLines.push(\n renderReportHeader({\n title: getReportTitle(options.granularity),\n useColor,\n }),\n );\n\n outputLines.push('');\n outputLines.push(renderTerminalEfficiencyTable(efficiencyData.rows, { useColor }));\n\n return outputLines.join('\\n');\n}\n\nexport function renderEfficiencyReport(\n efficiencyData: EfficiencyDataResult,\n format: EfficiencyReportFormat,\n options: RenderEfficiencyReportOptions,\n): string {\n switch (format) {\n case 'json':\n return JSON.stringify(efficiencyData.rows, null, 2);\n case 'markdown':\n return renderMarkdownEfficiencyTable(efficiencyData.rows);\n case 'terminal':\n return renderTerminalEfficiencyReport(efficiencyData, options);\n }\n}\n","import pc from 'picocolors';\nimport { visibleWidth } from './table-text-layout.js';\n\nexport type ReportHeaderOptions = {\n title: string;\n useColor?: boolean;\n};\n\nfunction getBoxWidth(content: string): number {\n return visibleWidth(content) + 4;\n}\n\nfunction drawBoxLine(width: number, left: string, middle: string, right: string): string {\n return left + middle.repeat(width - 2) + right;\n}\n\nfunction padLine(content: string, width: number): string {\n const padding = width - 2 - visibleWidth(content);\n const leftPad = Math.floor(padding / 2);\n const rightPad = padding - leftPad;\n return '│' + ' '.repeat(leftPad) + content + ' '.repeat(rightPad) + '│';\n}\n\nexport function renderReportHeader(options: ReportHeaderOptions): string {\n const { title, useColor = true } = options;\n const boxWidth = getBoxWidth(title);\n\n const lines: string[] = [];\n\n const topBorder = drawBoxLine(boxWidth, '┌', '─', '┐');\n lines.push(useColor ? pc.gray(topBorder) : topBorder);\n\n const titleLine = padLine(title, boxWidth);\n lines.push(useColor ? pc.white(titleLine) : titleLine);\n\n const bottomBorder = drawBoxLine(boxWidth, '└', '─', '┘');\n lines.push(useColor ? pc.gray(bottomBorder) : bottomBorder);\n\n return lines.join('\\n');\n}\n","import type { EfficiencyRow } from '../efficiency/efficiency-row.js';\n\nexport const efficiencyTableHeaders = [\n 'Period',\n 'Commits',\n '+Lines',\n '-Lines',\n 'ΔLines',\n 'Input',\n 'Output',\n 'Reasoning',\n 'Cache Read',\n 'Cache Write',\n 'Total',\n 'Cost',\n '$/Commit',\n '$/1k Lines',\n 'All Tokens/Commit',\n 'Non-Cache/Commit',\n 'Commits/$',\n] as const;\n\nconst integerFormatter = new Intl.NumberFormat('en-US');\nconst decimalFormatter = new Intl.NumberFormat('en-US', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n});\nconst usdFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n});\nconst usdRateFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 4,\n maximumFractionDigits: 4,\n});\n\nfunction formatInteger(value: number): string {\n return integerFormatter.format(value);\n}\n\nfunction formatUsd(value: number | undefined, options: { approximate?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formatted = usdFormatter.format(value);\n return options.approximate ? `~${formatted}` : formatted;\n}\n\nfunction formatUsdRate(value: number | undefined, options: { approximate?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formatted = usdRateFormatter.format(value);\n return options.approximate ? `~${formatted}` : formatted;\n}\n\nfunction formatDecimal(value: number | undefined, options: { approximate?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formatted = decimalFormatter.format(value);\n return options.approximate ? `~${formatted}` : formatted;\n}\n\nexport function toEfficiencyTableCells(rows: EfficiencyRow[]): string[][] {\n return rows.map((row) => [\n row.periodKey,\n formatInteger(row.commitCount),\n formatInteger(row.linesAdded),\n formatInteger(row.linesDeleted),\n formatInteger(row.linesChanged),\n formatInteger(row.inputTokens),\n formatInteger(row.outputTokens),\n formatInteger(row.reasoningTokens),\n formatInteger(row.cacheReadTokens),\n formatInteger(row.cacheWriteTokens),\n formatInteger(row.totalTokens),\n formatUsd(row.costUsd, { approximate: row.costIncomplete }),\n formatUsdRate(row.usdPerCommit, { approximate: row.costIncomplete }),\n formatUsdRate(row.usdPer1kLinesChanged, { approximate: row.costIncomplete }),\n formatDecimal(row.tokensPerCommit),\n formatDecimal(row.nonCacheTokensPerCommit),\n formatDecimal(row.commitsPerUsd, { approximate: row.costIncomplete }),\n ]);\n}\n","import pc from 'picocolors';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { colorizeUsageBodyRows } from './terminal-style-policy.js';\nimport { toUsageTableCells, type UsageTableLayout, usageTableHeaders } from './row-cells.js';\nimport { resolveTtyColumns, visibleWidth, wrapTableColumn } from './table-text-layout.js';\nimport { renderUnicodeTable } from './unicode-table.js';\n\nconst modelsColumnIndex = 2;\nconst defaultModelsColumnWidth = 32;\nconst minimumModelsColumnWidth = 12;\n\ntype TerminalRenderOptions = {\n useColor?: boolean;\n tableLayout?: UsageTableLayout;\n terminalWidth?: number;\n};\n\nexport function shouldUseColorByDefault(): boolean {\n if (process.env.NO_COLOR !== undefined) {\n return false;\n }\n\n if (process.env.FORCE_COLOR !== undefined) {\n return process.env.FORCE_COLOR !== '0';\n }\n\n const stdoutIsTTY = (process.stdout as { isTTY: unknown }).isTTY;\n return stdoutIsTTY === true;\n}\n\nfunction colorizeHeader(useColor: boolean): string[] {\n const headerCells = Array.from(usageTableHeaders);\n\n if (!useColor) {\n return headerCells;\n }\n\n return headerCells.map((header) => pc.bold(pc.white(header)));\n}\n\nfunction isValidTerminalWidth(width: unknown): width is number {\n return typeof width === 'number' && Number.isFinite(width) && width > 0;\n}\n\nfunction resolveTerminalWidth(override: number | undefined): number | undefined {\n if (isValidTerminalWidth(override)) {\n return Math.floor(override);\n }\n\n return resolveTtyColumns(process.stdout as { isTTY?: unknown; columns?: unknown });\n}\n\nfunction measureTableWidth(tableOutput: string): number {\n return tableOutput\n .trimEnd()\n .split('\\n')\n .reduce((maxWidth, line) => Math.max(maxWidth, visibleWidth(line)), 0);\n}\n\nfunction renderTableWithModelsWidth(\n rows: UsageReportRow[],\n tableLayout: UsageTableLayout,\n useColor: boolean,\n modelsColumnWidth: number,\n): string {\n const uncoloredBodyRows = toUsageTableCells(rows, { layout: tableLayout });\n const wrappedBodyRows = wrapTableColumn(uncoloredBodyRows, {\n columnIndex: modelsColumnIndex,\n width: modelsColumnWidth,\n });\n const bodyRows = colorizeUsageBodyRows(wrappedBodyRows, rows, { useColor });\n\n return renderUnicodeTable({\n headerCells: colorizeHeader(useColor),\n bodyRows,\n measureHeaderCells: usageTableHeaders,\n measureBodyRows: wrappedBodyRows,\n usageRows: rows,\n tableLayout,\n modelsColumnIndex,\n modelsColumnWidth,\n });\n}\n\nexport function renderTerminalTable(\n rows: UsageReportRow[],\n options: TerminalRenderOptions = {},\n): string {\n const useColor = options.useColor ?? shouldUseColorByDefault();\n const tableLayout = options.tableLayout ?? 'compact';\n const hasExplicitTerminalWidth = isValidTerminalWidth(options.terminalWidth);\n const terminalWidth = resolveTerminalWidth(options.terminalWidth);\n let modelsColumnWidth = defaultModelsColumnWidth;\n let renderedTable = renderTableWithModelsWidth(rows, tableLayout, useColor, modelsColumnWidth);\n\n if (terminalWidth !== undefined) {\n let renderedTableWidth = measureTableWidth(renderedTable);\n\n while (renderedTableWidth > terminalWidth && modelsColumnWidth > minimumModelsColumnWidth) {\n const overflowColumns = renderedTableWidth - terminalWidth;\n const nextModelsColumnWidth = Math.max(\n minimumModelsColumnWidth,\n modelsColumnWidth - overflowColumns,\n );\n\n if (nextModelsColumnWidth === modelsColumnWidth) {\n break;\n }\n\n modelsColumnWidth = nextModelsColumnWidth;\n renderedTable = renderTableWithModelsWidth(rows, tableLayout, useColor, modelsColumnWidth);\n renderedTableWidth = measureTableWidth(renderedTable);\n }\n\n if (hasExplicitTerminalWidth && renderedTableWidth > terminalWidth) {\n throw new Error(\n `Configured terminal width (${terminalWidth}) is too narrow for table rendering (minimum ${renderedTableWidth}).`,\n );\n }\n }\n\n return renderedTable;\n}\n","import pc from 'picocolors';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\n\nexport type TextStyler = (text: string) => string;\n\nexport type TerminalStylePalette = {\n cyan: TextStyler;\n magenta: TextStyler;\n blue: TextStyler;\n yellow: TextStyler;\n green: TextStyler;\n white: TextStyler;\n bold: TextStyler;\n dim: TextStyler;\n};\n\nexport const defaultTerminalStylePalette: TerminalStylePalette = {\n cyan: pc.cyan,\n magenta: pc.magenta,\n blue: pc.blue,\n yellow: pc.yellow,\n green: pc.green,\n white: pc.white,\n bold: pc.bold,\n dim: pc.dim,\n};\n\nconst passthroughStyler: TextStyler = (text) => text;\n\nfunction styleCellLines(cell: string, styler: TextStyler): string {\n return cell\n .split('\\n')\n .map((line) => (line.length === 0 ? '' : styler(line)))\n .join('\\n');\n}\n\ntype SourceStylePolicy = (palette: TerminalStylePalette) => TextStyler;\n\nconst sourceStylePolicies = new Map<string, SourceStylePolicy>([\n ['pi', (palette) => palette.cyan],\n ['codex', (palette) => palette.magenta],\n ['opencode', (palette) => palette.blue],\n]);\n\nexport function resolveSourceStyler(\n source: string,\n palette: TerminalStylePalette = defaultTerminalStylePalette,\n): TextStyler {\n const stylePolicy = sourceStylePolicies.get(source);\n\n if (!stylePolicy) {\n return passthroughStyler;\n }\n\n return stylePolicy(palette);\n}\n\ntype RowTypeStylePolicy = (cells: string[], palette: TerminalStylePalette) => string[];\n\nconst rowTypeStylePolicies: Record<UsageReportRow['rowType'], RowTypeStylePolicy> = {\n period_source: (cells, palette) => {\n const styledCells = [...cells];\n const costColumnIndex = styledCells.length - 1;\n\n styledCells[costColumnIndex] = styleCellLines(styledCells[costColumnIndex], palette.yellow);\n\n return styledCells;\n },\n period_combined: (cells, palette) =>\n cells.map((cell, cellIndex) => {\n if (cellIndex === 1) {\n return styleCellLines(cell, (line) => palette.bold(palette.yellow(line)));\n }\n\n return styleCellLines(cell, palette.dim);\n }),\n grand_total: (cells, palette) =>\n cells.map((cell, cellIndex) => {\n if (cellIndex === 0) {\n return styleCellLines(cell, (line) => palette.bold(palette.white(line)));\n }\n\n if (cellIndex === 1) {\n return styleCellLines(cell, (line) => palette.bold(palette.green(line)));\n }\n\n return styleCellLines(cell, palette.bold);\n }),\n};\n\nexport function applyRowTypeStyle(\n rowType: UsageReportRow['rowType'],\n cells: string[],\n palette: TerminalStylePalette = defaultTerminalStylePalette,\n): string[] {\n return rowTypeStylePolicies[rowType](cells, palette);\n}\n\nfunction applyBaseCellStyle(\n cells: string[],\n palette: TerminalStylePalette,\n sourceStyler: TextStyler,\n): string[] {\n if (cells.length < 2) {\n return [...cells];\n }\n\n const styledCells = [...cells];\n\n styledCells[0] = styleCellLines(styledCells[0], palette.white);\n styledCells[1] = styleCellLines(styledCells[1], sourceStyler);\n\n return styledCells;\n}\n\nexport function colorizeUsageBodyRows(\n bodyRows: string[][],\n rows: UsageReportRow[],\n options: {\n useColor: boolean;\n palette?: TerminalStylePalette;\n },\n): string[][] {\n if (!options.useColor) {\n return bodyRows;\n }\n\n const palette = options.palette ?? defaultTerminalStylePalette;\n\n return rows.map((row, index) => {\n const sourceStyler =\n row.rowType === 'period_source'\n ? resolveSourceStyler(String(row.source), palette)\n : passthroughStyler;\n const baseStyledCells = applyBaseCellStyle(bodyRows[index], palette, sourceStyler);\n\n return applyRowTypeStyle(row.rowType, baseStyledCells, palette);\n });\n}\n","import type { ModelUsageBreakdown, UsageReportRow } from '../domain/usage-report-row.js';\n\nexport type UsageTableLayout = 'compact' | 'per_model_columns';\n\nexport const usageTableHeaders = [\n 'Period',\n 'Source',\n 'Models',\n 'Input',\n 'Output',\n 'Reasoning',\n 'Cache Read',\n 'Cache Write',\n 'Total',\n 'Cost',\n] as const;\n\nconst integerFormatter = new Intl.NumberFormat('en-US');\nconst usdFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n});\n\nfunction formatSource(row: UsageReportRow): string {\n if (row.rowType === 'grand_total') {\n return 'TOTAL';\n }\n\n return row.source;\n}\n\nfunction formatTokenCount(value: number | undefined): string {\n return integerFormatter.format(value ?? 0);\n}\n\nfunction formatUsd(value: number | undefined, options: { incomplete?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formattedUsd = usdFormatter.format(value);\n return options.incomplete ? `~${formattedUsd}` : formattedUsd;\n}\n\nfunction buildModelLines(row: UsageReportRow): string[] {\n if (row.modelBreakdown.length > 0) {\n return row.modelBreakdown.map((modelUsage) => `• ${modelUsage.model}`);\n }\n\n return row.models.map((model) => `• ${model}`);\n}\n\nfunction formatModels(row: UsageReportRow, layout: UsageTableLayout): string {\n const modelLines = buildModelLines(row);\n\n if (modelLines.length === 0) {\n return '-';\n }\n\n if (layout === 'per_model_columns' && row.modelBreakdown.length > 1) {\n return [...modelLines, 'Σ TOTAL'].join('\\n');\n }\n\n return modelLines.join('\\n');\n}\n\nfunction formatModelMetric(\n row: UsageReportRow,\n selector: (value: ModelUsageBreakdown | UsageReportRow) => number | undefined,\n formatter: (value: number | undefined) => string,\n layout: UsageTableLayout,\n): string {\n if (layout !== 'per_model_columns' || row.modelBreakdown.length === 0) {\n return formatter(selector(row));\n }\n\n const lines = row.modelBreakdown.map((modelUsage) => formatter(selector(modelUsage)));\n\n if (row.modelBreakdown.length > 1) {\n lines.push(formatter(selector(row)));\n }\n\n return lines.join('\\n');\n}\n\nfunction formatModelCostMetric(row: UsageReportRow, layout: UsageTableLayout): string {\n if (layout !== 'per_model_columns' || row.modelBreakdown.length === 0) {\n return formatUsd(row.costUsd, { incomplete: row.costIncomplete });\n }\n\n const lines = row.modelBreakdown.map((modelUsage) =>\n formatUsd(modelUsage.costUsd, { incomplete: modelUsage.costIncomplete }),\n );\n\n if (row.modelBreakdown.length > 1) {\n lines.push(formatUsd(row.costUsd, { incomplete: row.costIncomplete }));\n }\n\n return lines.join('\\n');\n}\n\nexport function toUsageTableCells(\n rows: UsageReportRow[],\n options: { layout?: UsageTableLayout } = {},\n): string[][] {\n const layout = options.layout ?? 'compact';\n\n return rows.map((row) => [\n row.periodKey,\n formatSource(row),\n formatModels(row, layout),\n formatModelMetric(row, (value) => value.inputTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.outputTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.reasoningTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.cacheReadTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.cacheWriteTokens, formatTokenCount, layout),\n formatModelMetric(row, (value) => value.totalTokens, formatTokenCount, layout),\n formatModelCostMetric(row, layout),\n ]);\n}\n","import type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { splitCellLines, visibleWidth } from './table-text-layout.js';\nimport type { UsageTableLayout } from './row-cells.js';\n\ntype TableAlignment = 'left' | 'right';\ntype TableVerticalAlignment = 'top' | 'middle';\n\ntype RenderUnicodeTableOptions = {\n headerCells: readonly string[];\n bodyRows: string[][];\n measureHeaderCells: readonly string[];\n measureBodyRows: string[][];\n usageRows: UsageReportRow[];\n tableLayout: UsageTableLayout;\n modelsColumnIndex: number;\n modelsColumnWidth: number;\n};\n\ntype BorderChars = {\n left: string;\n join: string;\n right: string;\n};\n\ntype RowType = UsageReportRow['rowType'];\n\ntype RenderableUsageRow = {\n usageRow: UsageReportRow;\n bodyRow: string[];\n measureBodyRow: string[];\n originalIndex: number;\n};\n\nfunction getColumnAlignment(columnIndex: number, modelsColumnIndex: number): TableAlignment {\n if (columnIndex <= modelsColumnIndex) {\n return 'left';\n }\n\n return 'right';\n}\n\nfunction getVerticalAlignment(\n columnIndex: number,\n tableLayout: UsageTableLayout,\n modelsColumnIndex: number,\n): TableVerticalAlignment {\n if (columnIndex === modelsColumnIndex) {\n return 'top';\n }\n\n return tableLayout === 'per_model_columns' ? 'top' : 'middle';\n}\n\nfunction alignCellLine(value: string, width: number, alignment: TableAlignment): string {\n const padding = Math.max(0, width - visibleWidth(value));\n\n if (alignment === 'right') {\n return `${' '.repeat(padding)}${value}`;\n }\n\n return `${value}${' '.repeat(padding)}`;\n}\n\nfunction padCellLines(\n lines: string[],\n rowHeight: number,\n verticalAlignment: TableVerticalAlignment,\n): string[] {\n const missingLineCount = rowHeight - lines.length;\n\n if (missingLineCount <= 0) {\n return lines;\n }\n\n if (verticalAlignment === 'top') {\n return [...lines, ...Array.from({ length: missingLineCount }, () => '')];\n }\n\n const topPadding = Math.floor(missingLineCount / 2);\n const bottomPadding = missingLineCount - topPadding;\n\n return [\n ...Array.from({ length: topPadding }, () => ''),\n ...lines,\n ...Array.from({ length: bottomPadding }, () => ''),\n ];\n}\n\nfunction toRenderableRowLines(\n row: readonly string[],\n options: {\n widths: number[];\n tableLayout: UsageTableLayout;\n modelsColumnIndex: number;\n },\n): string[] {\n const cellLines = row.map((cell) => splitCellLines(cell));\n const rowHeight = cellLines.reduce((max, lines) => Math.max(max, lines.length), 1);\n\n const paddedAlignedColumns = cellLines.map((lines, columnIndex) => {\n const verticalAlignment = getVerticalAlignment(\n columnIndex,\n options.tableLayout,\n options.modelsColumnIndex,\n );\n const alignedLines = padCellLines(lines, rowHeight, verticalAlignment);\n const horizontalAlignment = getColumnAlignment(columnIndex, options.modelsColumnIndex);\n\n return alignedLines.map((line) =>\n alignCellLine(line, options.widths[columnIndex], horizontalAlignment),\n );\n });\n\n return Array.from({ length: rowHeight }, (_, lineIndex) => {\n const lineCells = paddedAlignedColumns.map((columnLines) => columnLines[lineIndex]);\n return `│ ${lineCells.join(' │ ')} │`;\n });\n}\n\nfunction buildBorderLine(widths: number[], chars: BorderChars): string {\n const segments = widths.map((width) => '─'.repeat(width + 2));\n return `${chars.left}${segments.join(chars.join)}${chars.right}`;\n}\n\nfunction shouldDrawBodySeparator(index: number, usageRows: UsageReportRow[]): boolean {\n if (index < 0 || index >= usageRows.length - 1) {\n return false;\n }\n\n const previousRow = usageRows[index];\n const nextRow = usageRows[index + 1];\n\n return (\n previousRow.rowType === 'period_combined' ||\n nextRow.rowType === 'grand_total' ||\n previousRow.periodKey !== nextRow.periodKey\n );\n}\n\nfunction getRowTypeWeight(rowType: RowType): number {\n switch (rowType) {\n case 'period_source':\n return 0;\n case 'period_combined':\n return 1;\n case 'grand_total':\n return 2;\n }\n}\n\nfunction getPeriodSortTuple(periodKey: string): [number, string] {\n if (periodKey === 'ALL') {\n return [1, periodKey];\n }\n\n return [0, periodKey];\n}\n\nfunction compareUsageRows(left: UsageReportRow, right: UsageReportRow): number {\n const [leftPeriodGroup, leftPeriodKey] = getPeriodSortTuple(left.periodKey);\n const [rightPeriodGroup, rightPeriodKey] = getPeriodSortTuple(right.periodKey);\n\n if (leftPeriodGroup !== rightPeriodGroup) {\n return leftPeriodGroup - rightPeriodGroup;\n }\n\n if (leftPeriodKey !== rightPeriodKey) {\n return leftPeriodKey < rightPeriodKey ? -1 : 1;\n }\n\n return getRowTypeWeight(left.rowType) - getRowTypeWeight(right.rowType);\n}\n\nfunction padRowToColumnCount(row: string[] | undefined, columnCount: number): string[] {\n const normalizedRow = row ?? [];\n\n if (normalizedRow.length >= columnCount) {\n return normalizedRow;\n }\n\n return [\n ...normalizedRow,\n ...Array.from({ length: columnCount - normalizedRow.length }, () => ''),\n ];\n}\n\nfunction getMaxRowColumnCount(\n rows: readonly (readonly string[])[],\n minimumColumnCount: number,\n): number {\n return rows.reduce(\n (maxColumnCount, row) => Math.max(maxColumnCount, row.length),\n minimumColumnCount,\n );\n}\n\nfunction normalizeRenderableUsageRows(options: {\n usageRows: UsageReportRow[];\n bodyRows: string[][];\n measureBodyRows: string[][];\n columnCount: number;\n}): RenderableUsageRow[] {\n const hasAlignedRowCounts =\n options.usageRows.length === options.bodyRows.length &&\n options.usageRows.length === options.measureBodyRows.length;\n\n if (!hasAlignedRowCounts) {\n return options.usageRows.map((usageRow, index) => ({\n usageRow,\n bodyRow: padRowToColumnCount(options.bodyRows[index], options.columnCount),\n measureBodyRow: padRowToColumnCount(options.measureBodyRows[index], options.columnCount),\n originalIndex: index,\n }));\n }\n\n return options.usageRows\n .map((usageRow, index) => ({\n usageRow,\n bodyRow: padRowToColumnCount(options.bodyRows[index], options.columnCount),\n measureBodyRow: padRowToColumnCount(options.measureBodyRows[index], options.columnCount),\n originalIndex: index,\n }))\n .sort((left, right) => {\n const comparison = compareUsageRows(left.usageRow, right.usageRow);\n\n if (comparison !== 0) {\n return comparison;\n }\n\n return left.originalIndex - right.originalIndex;\n });\n}\n\nfunction computeColumnWidths(\n measureRows: readonly (readonly string[])[],\n options: { modelsColumnIndex: number; modelsColumnWidth: number },\n): number[] {\n const columnCount = measureRows.reduce(\n (maxColumnCount, row) => Math.max(maxColumnCount, row.length),\n 0,\n );\n const widths = Array.from({ length: columnCount }, () => 0);\n\n for (const row of measureRows) {\n for (let columnIndex = 0; columnIndex < columnCount; columnIndex += 1) {\n for (const line of splitCellLines(row[columnIndex] ?? '')) {\n widths[columnIndex] = Math.max(widths[columnIndex], visibleWidth(line));\n }\n }\n }\n\n widths[options.modelsColumnIndex] = options.modelsColumnWidth;\n\n return widths;\n}\n\nexport function renderUnicodeTable(options: RenderUnicodeTableOptions): string {\n const bodyColumnCount = getMaxRowColumnCount(options.bodyRows, options.headerCells.length);\n const measureColumnCount = getMaxRowColumnCount(\n options.measureBodyRows,\n options.measureHeaderCells.length,\n );\n const sharedColumnCount = Math.max(bodyColumnCount, measureColumnCount);\n const normalizedHeaderCells = padRowToColumnCount([...options.headerCells], sharedColumnCount);\n const normalizedMeasureHeaderCells = padRowToColumnCount(\n [...options.measureHeaderCells],\n sharedColumnCount,\n );\n const normalizedRenderableRows = normalizeRenderableUsageRows({\n usageRows: options.usageRows,\n bodyRows: options.bodyRows,\n measureBodyRows: options.measureBodyRows,\n columnCount: sharedColumnCount,\n });\n const normalizedBodyRows = normalizedRenderableRows.map((row) => row.bodyRow);\n const normalizedMeasureBodyRows = normalizedRenderableRows.map((row) => row.measureBodyRow);\n const normalizedUsageRows = normalizedRenderableRows.map((row) => row.usageRow);\n const measureRows = [normalizedMeasureHeaderCells, ...normalizedMeasureBodyRows];\n const widths = computeColumnWidths(measureRows, {\n modelsColumnIndex: options.modelsColumnIndex,\n modelsColumnWidth: options.modelsColumnWidth,\n });\n const renderedLines: string[] = [];\n\n renderedLines.push(\n buildBorderLine(widths, {\n left: '╭',\n join: '┬',\n right: '╮',\n }),\n );\n renderedLines.push(\n ...toRenderableRowLines(normalizedHeaderCells, {\n widths,\n tableLayout: 'per_model_columns',\n modelsColumnIndex: options.modelsColumnIndex,\n }),\n );\n renderedLines.push(\n buildBorderLine(widths, {\n left: '├',\n join: '┼',\n right: '┤',\n }),\n );\n\n normalizedBodyRows.forEach((row, rowIndex) => {\n renderedLines.push(\n ...toRenderableRowLines(row, {\n widths,\n tableLayout: options.tableLayout,\n modelsColumnIndex: options.modelsColumnIndex,\n }),\n );\n\n if (\n rowIndex < normalizedBodyRows.length - 1 &&\n shouldDrawBodySeparator(rowIndex, normalizedUsageRows)\n ) {\n renderedLines.push(\n buildBorderLine(widths, {\n left: '├',\n join: '┼',\n right: '┤',\n }),\n );\n }\n });\n\n renderedLines.push(\n buildBorderLine(widths, {\n left: '╰',\n join: '┴',\n right: '╯',\n }),\n );\n\n return `${renderedLines.join('\\n')}\\n`;\n}\n","import { buildEfficiencyData } from './build-efficiency-data.js';\nimport { emitDiagnostics } from './emit-diagnostics.js';\nimport { emitEnvVarOverrides } from './emit-env-var-overrides.js';\nimport { warnIfTerminalTableOverflows } from './terminal-overflow-warning.js';\nimport type { EfficiencyCommandOptions, EfficiencyDiagnostics } from './usage-data-contracts.js';\nimport {\n renderEfficiencyReport,\n type EfficiencyReportFormat,\n} from '../render/render-efficiency-report.js';\nimport { logger } from '../utils/logger.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\n\ntype PreparedEfficiencyReport = {\n format: EfficiencyReportFormat;\n output: string;\n diagnostics: EfficiencyDiagnostics;\n};\n\nfunction validateOutputFormatOptions(options: EfficiencyCommandOptions): void {\n if (options.markdown && options.json) {\n throw new Error('Choose either --markdown or --json, not both');\n }\n}\n\nfunction resolveReportFormat(options: EfficiencyCommandOptions): EfficiencyReportFormat {\n if (options.json) {\n return 'json';\n }\n\n if (options.markdown) {\n return 'markdown';\n }\n\n return 'terminal';\n}\n\nasync function prepareEfficiencyReport(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n): Promise<PreparedEfficiencyReport> {\n validateOutputFormatOptions(options);\n\n const efficiencyData = await buildEfficiencyData(granularity, options);\n const format = resolveReportFormat(options);\n\n return {\n format,\n diagnostics: efficiencyData.diagnostics,\n output: renderEfficiencyReport(efficiencyData, format, {\n granularity,\n }),\n };\n}\n\nexport async function buildEfficiencyReport(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n): Promise<string> {\n const preparedReport = await prepareEfficiencyReport(granularity, options);\n return preparedReport.output;\n}\n\nexport async function runEfficiencyReport(\n granularity: ReportGranularity,\n options: EfficiencyCommandOptions,\n): Promise<void> {\n const preparedReport = await prepareEfficiencyReport(granularity, options);\n\n emitDiagnostics(preparedReport.diagnostics.usage, logger);\n emitEnvVarOverrides(preparedReport.diagnostics.usage.activeEnvOverrides, logger);\n\n const mergeModeLabel = preparedReport.diagnostics.includeMergeCommits\n ? 'including merge commits'\n : 'excluding merge commits';\n logger.info(\n `Git outcomes (${mergeModeLabel}): ${preparedReport.diagnostics.gitCommitCount} commit(s), +${preparedReport.diagnostics.gitLinesAdded}/-${preparedReport.diagnostics.gitLinesDeleted} lines (${preparedReport.diagnostics.repoDir})`,\n );\n logger.info(\n `Repo-attributed usage events: ${preparedReport.diagnostics.repoMatchedUsageEvents} matched, ${preparedReport.diagnostics.repoExcludedUsageEvents} excluded, ${preparedReport.diagnostics.repoUnattributedUsageEvents} unattributed`,\n );\n\n if (preparedReport.diagnostics.scopeNote) {\n logger.warn(preparedReport.diagnostics.scopeNote);\n }\n\n if (preparedReport.format === 'terminal') {\n warnIfTerminalTableOverflows(preparedReport.output, (message) => {\n logger.warn(message);\n });\n }\n\n console.log(preparedReport.output);\n}\n","import { markdownTable } from 'markdown-table';\nimport pc from 'picocolors';\n\nimport type { OptimizeDataResult } from '../cli/usage-data-contracts.js';\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\nimport type { OptimizeBaselineRow, OptimizeCandidateRow } from '../optimize/optimize-row.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { visibleWidth } from './table-text-layout.js';\nimport { renderReportHeader } from './report-header.js';\nimport { shouldUseColorByDefault } from './terminal-table.js';\nimport { renderUnicodeTable } from './unicode-table.js';\n\nexport type OptimizeReportFormat = 'terminal' | 'markdown' | 'json';\n\nexport type RenderOptimizeReportOptions = {\n granularity: ReportGranularity;\n useColor?: boolean;\n};\n\nconst optimizeTableHeadersWithNotes = [\n 'Period',\n 'Candidate',\n 'Hypothetical Cost',\n 'Baseline Cost',\n 'Savings',\n 'Savings %',\n 'Notes',\n] as const;\n\nconst optimizeTableHeadersWithoutNotes = [\n 'Period',\n 'Candidate',\n 'Hypothetical Cost',\n 'Baseline Cost',\n 'Savings',\n 'Savings %',\n] as const;\n\nconst usdFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n});\n\nfunction getReportTitle(granularity: ReportGranularity): string {\n switch (granularity) {\n case 'daily':\n return 'Daily Optimize Report';\n case 'weekly':\n return 'Weekly Optimize Report';\n case 'monthly':\n return 'Monthly Optimize Report';\n }\n}\n\nfunction formatUsd(value: number | undefined, options: { approximate?: boolean } = {}): string {\n if (value === undefined) {\n return '-';\n }\n\n const formatted = usdFormatter.format(value);\n return options.approximate ? `~${formatted}` : formatted;\n}\n\nfunction formatPercent(value: number | undefined): string {\n if (value === undefined) {\n return '-';\n }\n\n return `${(value * 100).toFixed(2)}%`;\n}\n\nfunction formatNotes(notes: string[] | undefined): string {\n if (!notes || notes.length === 0) {\n return '-';\n }\n\n return notes.join(', ');\n}\n\nfunction styleCandidateCell(\n candidateValue: string,\n rowType: 'baseline' | 'candidate',\n useColor: boolean,\n): string {\n if (!useColor) {\n return candidateValue;\n }\n\n if (rowType === 'baseline') {\n return pc.bold(pc.cyan(candidateValue));\n }\n\n return pc.bold(candidateValue);\n}\n\nfunction styleDeltaCell(\n value: number | undefined,\n formattedValue: string,\n useColor: boolean,\n): string {\n if (!useColor || value === undefined) {\n return formattedValue;\n }\n\n if (value > 0) {\n return pc.green(formattedValue);\n }\n\n if (value < 0) {\n return pc.red(formattedValue);\n }\n\n return pc.dim(formattedValue);\n}\n\nfunction styleNotesCell(\n notes: string[] | undefined,\n formattedNotes: string,\n useColor: boolean,\n): string {\n if (!useColor || !notes || notes.length === 0) {\n return formattedNotes;\n }\n\n return pc.yellow(formattedNotes);\n}\n\nfunction formatAbsoluteUsd(value: number): string {\n return usdFormatter.format(Math.abs(value));\n}\n\nfunction resolveTerminalContextLines(\n optimizeData: OptimizeDataResult,\n options: { useColor: boolean },\n): string[] {\n const allBaselineRow = optimizeData.rows.find(\n (row): row is OptimizeBaselineRow => row.rowType === 'baseline' && row.periodKey === 'ALL',\n );\n const allCandidateRows = optimizeData.rows.filter(\n (row): row is OptimizeCandidateRow => row.rowType === 'candidate' && row.periodKey === 'ALL',\n );\n const lines: string[] = [];\n\n const providerLine = `Provider scope: ${optimizeData.diagnostics.provider}`;\n lines.push(options.useColor ? pc.cyan(providerLine) : providerLine);\n\n if (allBaselineRow) {\n lines.push(\n `ALL baseline cost: ${formatUsd(allBaselineRow.baselineCostUsd, { approximate: allBaselineRow.baselineCostIncomplete })}`,\n );\n }\n\n if (allCandidateRows.length > 0) {\n const rowsWithSavings = allCandidateRows.filter((row) => row.savingsUsd !== undefined);\n const bestRow =\n rowsWithSavings.length > 0\n ? rowsWithSavings.reduce((best, current) =>\n (current.savingsUsd ?? Number.NEGATIVE_INFINITY) >\n (best.savingsUsd ?? Number.NEGATIVE_INFINITY)\n ? current\n : best,\n )\n : undefined;\n\n if (!bestRow || bestRow.savingsUsd === undefined) {\n lines.push('ALL best candidate: unavailable (missing baseline or candidate pricing)');\n } else if (bestRow.savingsUsd > 0) {\n lines.push(\n `ALL best candidate: ${bestRow.candidateModel} saves ${formatAbsoluteUsd(bestRow.savingsUsd)} (${formatPercent(bestRow.savingsPct)})`,\n );\n } else if (bestRow.savingsUsd < 0) {\n lines.push(\n `ALL best candidate: ${bestRow.candidateModel} increases cost by ${formatAbsoluteUsd(bestRow.savingsUsd)} (${formatPercent(bestRow.savingsPct)})`,\n );\n } else {\n lines.push(`ALL best candidate: ${bestRow.candidateModel} matches baseline cost`);\n }\n }\n\n if (optimizeData.diagnostics.candidatesWithMissingPricing.length > 0) {\n const missingLine = `Missing candidate pricing: ${optimizeData.diagnostics.candidatesWithMissingPricing.join(', ')}`;\n lines.push(options.useColor ? pc.yellow(missingLine) : missingLine);\n }\n\n const legendLine = 'Savings = Baseline - Hypothetical (positive means cheaper candidate)';\n lines.push(options.useColor ? pc.dim(legendLine) : legendLine);\n\n return lines;\n}\n\nfunction toTableCells(\n optimizeData: OptimizeDataResult,\n options: { useColor: boolean; includeNotesColumn: boolean },\n): string[][] {\n const baselineByPeriod = new Map(\n optimizeData.rows\n .filter((row) => row.rowType === 'baseline')\n .map((row) => [row.periodKey, row]),\n );\n\n return optimizeData.rows.map((row) => {\n const baselineRow = baselineByPeriod.get(row.periodKey);\n const periodCell =\n options.useColor && row.periodKey === 'ALL' ? pc.bold(row.periodKey) : row.periodKey;\n\n if (row.rowType === 'baseline') {\n const baselineCells = [\n periodCell,\n styleCandidateCell('BASELINE', 'baseline', options.useColor),\n '-',\n formatUsd(row.baselineCostUsd, { approximate: row.baselineCostIncomplete }),\n '-',\n '-',\n ];\n\n return options.includeNotesColumn ? [...baselineCells, '-'] : baselineCells;\n }\n\n const savingsCell = formatUsd(row.savingsUsd);\n const savingsPctCell = formatPercent(row.savingsPct);\n const notesCell = formatNotes(row.notes);\n\n const candidateCells = [\n periodCell,\n styleCandidateCell(row.candidateModel, 'candidate', options.useColor),\n formatUsd(row.hypotheticalCostUsd, { approximate: row.hypotheticalCostIncomplete }),\n formatUsd(baselineRow?.baselineCostUsd, {\n approximate: baselineRow?.baselineCostIncomplete === true,\n }),\n styleDeltaCell(row.savingsUsd, savingsCell, options.useColor),\n styleDeltaCell(row.savingsPct, savingsPctCell, options.useColor),\n ];\n\n return options.includeNotesColumn\n ? [...candidateCells, styleNotesCell(row.notes, notesCell, options.useColor)]\n : candidateCells;\n });\n}\n\nfunction toMarkdownSafeCell(value: string): string {\n return value.replace(/\\r?\\n/gu, '<br>');\n}\n\nfunction toSortingUsageRows(optimizeData: OptimizeDataResult): UsageReportRow[] {\n return optimizeData.rows.map((row) => {\n return {\n rowType: 'period_source',\n periodKey: row.periodKey,\n source: 'combined',\n models: [],\n modelBreakdown: [],\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n costUsd: row.rowType === 'baseline' ? row.baselineCostUsd : row.hypotheticalCostUsd,\n costIncomplete:\n row.rowType === 'baseline' ? row.baselineCostIncomplete : row.hypotheticalCostIncomplete,\n };\n });\n}\n\nfunction resolveCandidateColumnWidth(tableCells: string[][]): number {\n return tableCells.reduce((maxWidth, row) => {\n const candidateValue = row[1] ?? '';\n return Math.max(maxWidth, visibleWidth(candidateValue));\n }, visibleWidth(optimizeTableHeadersWithNotes[1]));\n}\n\nfunction resolveIncludeNotesColumn(optimizeData: OptimizeDataResult): boolean {\n return optimizeData.rows.some(\n (row) => row.rowType === 'candidate' && row.notes !== undefined && row.notes.length > 0,\n );\n}\n\nfunction renderTerminalOptimizeReport(\n optimizeData: OptimizeDataResult,\n options: RenderOptimizeReportOptions,\n): string {\n const useColor = options.useColor ?? shouldUseColorByDefault();\n const includeNotesColumn = resolveIncludeNotesColumn(optimizeData);\n const tableCells = toTableCells(optimizeData, { useColor, includeNotesColumn });\n const candidateColumnWidth = resolveCandidateColumnWidth(tableCells);\n const contextLines = resolveTerminalContextLines(optimizeData, { useColor });\n const headerCells = includeNotesColumn\n ? [...optimizeTableHeadersWithNotes]\n : [...optimizeTableHeadersWithoutNotes];\n const outputLines: string[] = [];\n\n outputLines.push(\n renderReportHeader({\n title: getReportTitle(options.granularity),\n useColor,\n }),\n );\n outputLines.push('');\n outputLines.push(...contextLines);\n outputLines.push('');\n outputLines.push(\n renderUnicodeTable({\n headerCells,\n bodyRows: tableCells,\n measureHeaderCells: headerCells,\n measureBodyRows: tableCells,\n usageRows: toSortingUsageRows(optimizeData),\n tableLayout: 'compact',\n modelsColumnIndex: 1,\n modelsColumnWidth: candidateColumnWidth,\n }),\n );\n\n return outputLines.join('\\n');\n}\n\nfunction renderMarkdownOptimizeReport(optimizeData: OptimizeDataResult): string {\n const includeNotesColumn = resolveIncludeNotesColumn(optimizeData);\n const headerCells = includeNotesColumn\n ? [...optimizeTableHeadersWithNotes]\n : [...optimizeTableHeadersWithoutNotes];\n const bodyRows = toTableCells(optimizeData, {\n useColor: false,\n includeNotesColumn,\n }).map((row) => row.map((cell) => toMarkdownSafeCell(cell)));\n const tableRows = [headerCells, ...bodyRows];\n const alignment = headerCells.map((_, index) => (index <= 1 ? 'l' : 'r')) as ('l' | 'r')[];\n\n return markdownTable(tableRows, { align: alignment });\n}\n\nexport function renderOptimizeReport(\n optimizeData: OptimizeDataResult,\n format: OptimizeReportFormat,\n options: RenderOptimizeReportOptions,\n): string {\n switch (format) {\n case 'json':\n return JSON.stringify(optimizeData.rows, null, 2);\n case 'markdown':\n return renderMarkdownOptimizeReport(optimizeData);\n case 'terminal':\n return renderTerminalOptimizeReport(optimizeData, options);\n }\n}\n","import type { UsageReportRow } from '../domain/usage-report-row.js';\nimport type { UsageEvent } from '../domain/usage-event.js';\nimport { calculateEstimatedCostUsd } from '../pricing/cost-engine.js';\nimport type { PricingSource } from '../pricing/types.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport type { OptimizeBaselineRow, OptimizeCandidateRow, OptimizeRow } from './optimize-row.js';\n\nconst USD_PRECISION_SCALE = 1_000_000_000_000;\n\ntype BaselinePeriodTotals = {\n periodKey: string;\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n totalTokens: number;\n baselineCostUsd: number | undefined;\n baselineCostIncomplete: boolean;\n};\n\ntype CandidateEvaluation = {\n candidateRow: OptimizeCandidateRow;\n missingPricing: boolean;\n hasBaselineTokenMismatch: boolean;\n};\n\nexport type BuildCounterfactualRowsInput = {\n usageRows: UsageReportRow[];\n provider: string;\n candidateModels: string[];\n pricingSource?: PricingSource;\n top?: number;\n};\n\nexport type BuildCounterfactualRowsResult = {\n rows: OptimizeRow[];\n candidatesWithMissingPricing: string[];\n baselineCostIncomplete: boolean;\n warning?: string;\n};\n\nexport function roundUsd(value: number): number {\n return Math.round(value * USD_PRECISION_SCALE) / USD_PRECISION_SCALE;\n}\n\nfunction hasZeroBillableTokenBuckets(totals: {\n inputTokens: number;\n outputTokens: number;\n reasoningTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n}): boolean {\n return (\n totals.inputTokens === 0 &&\n totals.outputTokens === 0 &&\n totals.reasoningTokens === 0 &&\n totals.cacheReadTokens === 0 &&\n totals.cacheWriteTokens === 0\n );\n}\n\nfunction parseCandidateModelsRaw(candidateModel: string | string[] | undefined): string[] {\n if (!candidateModel || (Array.isArray(candidateModel) && candidateModel.length === 0)) {\n throw new Error('At least one --candidate-model is required');\n }\n\n const normalizedCandidates = (Array.isArray(candidateModel) ? candidateModel : [candidateModel])\n .flatMap((candidate) => candidate.split(','))\n .map((candidate) => candidate.trim().toLowerCase())\n .filter((candidate) => candidate.length > 0);\n\n if (normalizedCandidates.length === 0) {\n throw new Error('--candidate-model must contain at least one non-empty model name');\n }\n\n return [...new Set(normalizedCandidates)];\n}\n\nexport function normalizeCandidateModels(candidateModel: string | string[] | undefined): string[] {\n return parseCandidateModelsRaw(candidateModel);\n}\n\nexport function parseTopOption(top: string | undefined): number | undefined {\n if (top === undefined) {\n return undefined;\n }\n\n const normalized = top.trim();\n const parsed = Number.parseInt(normalized, 10);\n\n if (!/^\\d+$/u.test(normalized) || Number.isNaN(parsed) || parsed < 1) {\n throw new Error('--top must be a positive integer');\n }\n\n return parsed;\n}\n\nfunction toBaselineRow(period: BaselinePeriodTotals, provider: string): OptimizeBaselineRow {\n return {\n rowType: 'baseline',\n periodKey: period.periodKey,\n provider,\n inputTokens: period.inputTokens,\n outputTokens: period.outputTokens,\n reasoningTokens: period.reasoningTokens,\n cacheReadTokens: period.cacheReadTokens,\n cacheWriteTokens: period.cacheWriteTokens,\n totalTokens: period.totalTokens,\n baselineCostUsd: period.baselineCostUsd,\n baselineCostIncomplete: period.baselineCostIncomplete,\n };\n}\n\nfunction createSyntheticEvent(period: BaselinePeriodTotals): UsageEvent {\n return {\n source: 'pi',\n sessionId: 'optimize-period',\n timestamp: '1970-01-01T00:00:00.000Z',\n provider: undefined,\n model: 'synthetic',\n inputTokens: period.inputTokens,\n outputTokens: period.outputTokens,\n reasoningTokens: period.reasoningTokens,\n cacheReadTokens: period.cacheReadTokens,\n cacheWriteTokens: period.cacheWriteTokens,\n totalTokens: period.totalTokens,\n costMode: 'estimated',\n costUsd: undefined,\n };\n}\n\nfunction withNotes(notes: Set<string>): string[] | undefined {\n if (notes.size === 0) {\n return undefined;\n }\n\n return [...notes].sort(compareByCodePoint);\n}\n\nfunction evaluateCandidateForPeriod(\n period: BaselinePeriodTotals,\n provider: string,\n candidateModel: string,\n pricingSource: PricingSource | undefined,\n): CandidateEvaluation {\n const notes = new Set<string>();\n const zeroBillableTokens = hasZeroBillableTokenBuckets(period);\n\n const candidateResolvedModel = pricingSource\n ? pricingSource.resolveModelAlias(candidateModel)\n : candidateModel;\n const pricing = pricingSource ? pricingSource.getPricing(candidateResolvedModel) : undefined;\n\n let hypotheticalCostUsd: number | undefined;\n let hypotheticalCostIncomplete = false;\n\n if (!pricing) {\n if (zeroBillableTokens) {\n hypotheticalCostUsd = 0;\n } else {\n hypotheticalCostUsd = undefined;\n hypotheticalCostIncomplete = true;\n notes.add('missing_pricing');\n }\n } else {\n hypotheticalCostUsd = roundUsd(\n calculateEstimatedCostUsd(createSyntheticEvent(period), pricing),\n );\n }\n\n let savingsUsd: number | undefined;\n let savingsPct: number | undefined;\n let hasBaselineTokenMismatch = false;\n\n if (period.baselineCostIncomplete || period.baselineCostUsd === undefined) {\n notes.add('baseline_incomplete');\n } else if (zeroBillableTokens && period.baselineCostUsd > 0) {\n notes.add('baseline_tokens_missing');\n hasBaselineTokenMismatch = true;\n } else if (hypotheticalCostUsd !== undefined) {\n savingsUsd = roundUsd(period.baselineCostUsd - hypotheticalCostUsd);\n savingsPct = period.baselineCostUsd === 0 ? undefined : savingsUsd / period.baselineCostUsd;\n }\n\n return {\n candidateRow: {\n rowType: 'candidate',\n periodKey: period.periodKey,\n provider,\n inputTokens: period.inputTokens,\n outputTokens: period.outputTokens,\n reasoningTokens: period.reasoningTokens,\n cacheReadTokens: period.cacheReadTokens,\n cacheWriteTokens: period.cacheWriteTokens,\n totalTokens: period.totalTokens,\n candidateModel,\n candidateResolvedModel,\n hypotheticalCostUsd,\n hypotheticalCostIncomplete,\n savingsUsd,\n savingsPct,\n notes: withNotes(notes),\n },\n missingPricing: notes.has('missing_pricing'),\n hasBaselineTokenMismatch,\n };\n}\n\nfunction compareCandidateRank(\n left: { candidateModel: string; hypotheticalCostUsd: number | undefined },\n right: { candidateModel: string; hypotheticalCostUsd: number | undefined },\n): number {\n if (left.hypotheticalCostUsd === undefined && right.hypotheticalCostUsd !== undefined) {\n return 1;\n }\n\n if (left.hypotheticalCostUsd !== undefined && right.hypotheticalCostUsd === undefined) {\n return -1;\n }\n\n if (left.hypotheticalCostUsd !== undefined && right.hypotheticalCostUsd !== undefined) {\n if (left.hypotheticalCostUsd !== right.hypotheticalCostUsd) {\n return left.hypotheticalCostUsd - right.hypotheticalCostUsd;\n }\n }\n\n return compareByCodePoint(left.candidateModel, right.candidateModel);\n}\n\nfunction resolveBaselinePeriods(usageRows: UsageReportRow[]): BaselinePeriodTotals[] {\n const periodRows = new Map<string, UsageReportRow>();\n let grandTotalRow: UsageReportRow | undefined;\n\n for (const row of usageRows) {\n if (row.rowType === 'grand_total') {\n grandTotalRow = row;\n continue;\n }\n\n if (row.rowType === 'period_combined') {\n periodRows.set(row.periodKey, row);\n continue;\n }\n\n if (!periodRows.has(row.periodKey)) {\n periodRows.set(row.periodKey, row);\n }\n }\n\n const sortedPeriodKeys = [...periodRows.keys()].sort(compareByCodePoint);\n const periods = sortedPeriodKeys.map((periodKey) => {\n const row = periodRows.get(periodKey);\n\n if (!row) {\n throw new Error(`Missing baseline row for period ${periodKey}`);\n }\n\n return {\n periodKey,\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n reasoningTokens: row.reasoningTokens,\n cacheReadTokens: row.cacheReadTokens,\n cacheWriteTokens: row.cacheWriteTokens,\n totalTokens: row.totalTokens,\n baselineCostUsd: row.costUsd,\n baselineCostIncomplete: row.costIncomplete === true,\n };\n });\n\n const allRow = grandTotalRow;\n\n if (allRow) {\n periods.push({\n periodKey: 'ALL',\n inputTokens: allRow.inputTokens,\n outputTokens: allRow.outputTokens,\n reasoningTokens: allRow.reasoningTokens,\n cacheReadTokens: allRow.cacheReadTokens,\n cacheWriteTokens: allRow.cacheWriteTokens,\n totalTokens: allRow.totalTokens,\n baselineCostUsd: allRow.costUsd,\n baselineCostIncomplete: allRow.costIncomplete === true,\n });\n } else {\n periods.push({\n periodKey: 'ALL',\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n totalTokens: 0,\n baselineCostUsd: 0,\n baselineCostIncomplete: false,\n });\n }\n\n return periods;\n}\n\nfunction buildWarning(periodKeys: string[]): string | undefined {\n if (periodKeys.length === 0) {\n return undefined;\n }\n\n const sortedPeriodKeys = [...new Set(periodKeys)].sort(compareByCodePoint);\n\n return `Baseline cost exists for zero-token periods (${sortedPeriodKeys.join(', ')}); savings were omitted.`;\n}\n\nexport function buildCounterfactualRows(\n input: BuildCounterfactualRowsInput,\n): BuildCounterfactualRowsResult {\n const baselinePeriods = resolveBaselinePeriods(input.usageRows);\n const allPeriod = baselinePeriods.find((period) => period.periodKey === 'ALL');\n\n if (!allPeriod) {\n throw new Error('Missing ALL baseline totals');\n }\n\n const allPeriodEvaluations = input.candidateModels.map((candidateModel) =>\n evaluateCandidateForPeriod(allPeriod, input.provider, candidateModel, input.pricingSource),\n );\n\n const rankedCandidates = allPeriodEvaluations\n .map(({ candidateRow }) => ({\n candidateModel: candidateRow.candidateModel,\n hypotheticalCostUsd: candidateRow.hypotheticalCostUsd,\n }))\n .sort(compareCandidateRank)\n .map((candidate) => candidate.candidateModel);\n\n const selectedCandidates =\n input.top === undefined ? rankedCandidates : rankedCandidates.slice(0, input.top);\n\n const allEvaluationByCandidate = new Map(\n allPeriodEvaluations.map((evaluation) => [evaluation.candidateRow.candidateModel, evaluation]),\n );\n const candidatesWithMissingPricing = input.candidateModels\n .filter(\n (candidateModel) => allEvaluationByCandidate.get(candidateModel)?.missingPricing === true,\n )\n .sort(compareByCodePoint);\n\n const warningPeriods: string[] = [];\n const rows: OptimizeRow[] = [];\n\n for (const period of baselinePeriods) {\n rows.push(toBaselineRow(period, input.provider));\n\n for (const candidateModel of selectedCandidates) {\n const resolvedEvaluation =\n period.periodKey === 'ALL'\n ? allEvaluationByCandidate.get(candidateModel)\n : evaluateCandidateForPeriod(period, input.provider, candidateModel, input.pricingSource);\n\n if (!resolvedEvaluation) {\n continue;\n }\n\n if (resolvedEvaluation.hasBaselineTokenMismatch) {\n warningPeriods.push(period.periodKey);\n }\n\n rows.push(resolvedEvaluation.candidateRow);\n }\n }\n\n return {\n rows,\n candidatesWithMissingPricing,\n baselineCostIncomplete: allPeriod.baselineCostIncomplete,\n warning: buildWarning(warningPeriods),\n };\n}\n","import { aggregateUsage } from '../aggregate/aggregate-usage.js';\nimport { compareByCodePoint } from '../utils/compare-by-code-point.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { normalizeProviderFilter } from './build-usage-data-inputs.js';\nimport { buildUsageDiagnostics } from './build-usage-data-diagnostics.js';\nimport {\n applyPricingToUsageEventDataset,\n buildUsageEventDataset,\n} from './build-usage-event-dataset.js';\nimport type {\n BuildUsageDataDeps,\n OptimizeCommandOptions,\n OptimizeDataResult,\n} from './usage-data-contracts.js';\nimport {\n buildCounterfactualRows,\n normalizeCandidateModels,\n parseTopOption,\n} from '../optimize/aggregate-counterfactual.js';\n\nexport type BuildOptimizeDataDeps = BuildUsageDataDeps;\n\nfunction resolveOptimizeProvider(\n providers: Set<string>,\n providerFilter: string | undefined,\n): string {\n const distinctProviders = [...providers].sort(compareByCodePoint);\n const normalizedProviderFilter = normalizeProviderFilter(providerFilter);\n\n if (distinctProviders.length > 1) {\n if (normalizedProviderFilter) {\n const matchingProviders = distinctProviders.filter((provider) =>\n provider.includes(normalizedProviderFilter),\n );\n\n if (matchingProviders.includes(normalizedProviderFilter)) {\n return normalizedProviderFilter;\n }\n\n if (matchingProviders.length === 1) {\n return matchingProviders[0];\n }\n\n if (matchingProviders.length === 0) {\n throw new Error(\n `Optimize --provider \"${normalizedProviderFilter}\" matched no providers. Available providers: ${distinctProviders.join(', ')}.`,\n );\n }\n\n if (matchingProviders.length > 1) {\n throw new Error(\n `Optimize matched multiple providers for --provider \"${normalizedProviderFilter}\": ${matchingProviders.join(', ')}. Supply a more specific --provider value.`,\n );\n }\n }\n\n throw new Error(\n `Optimize requires a single provider; found providers: ${distinctProviders.join(', ')}. Narrow with --provider.`,\n );\n }\n\n if (distinctProviders.length === 1) {\n return distinctProviders[0];\n }\n\n return normalizedProviderFilter ?? 'unknown';\n}\n\nexport async function buildOptimizeData(\n granularity: ReportGranularity,\n options: OptimizeCommandOptions,\n deps: BuildOptimizeDataDeps = {},\n): Promise<OptimizeDataResult> {\n const candidateModels = normalizeCandidateModels(options.candidateModel);\n const top = parseTopOption(options.top);\n\n const dataset = await buildUsageEventDataset(options, deps);\n const detectedProviders = new Set(\n dataset.filteredEvents\n .map((event) => normalizeProviderFilter(event.provider))\n .filter((provider): provider is string => provider !== undefined),\n );\n const provider = resolveOptimizeProvider(\n detectedProviders,\n dataset.normalizedInputs.providerFilter,\n );\n\n const { pricedEvents, pricingOrigin, pricingWarning, pricingSource } =\n await applyPricingToUsageEventDataset(dataset, deps, 'force');\n\n const usageRows = aggregateUsage(pricedEvents, {\n granularity,\n timezone: dataset.normalizedInputs.timezone,\n sourceOrder: dataset.adaptersToParse.map((adapter) => adapter.id),\n });\n\n const counterfactual = buildCounterfactualRows({\n usageRows,\n provider,\n candidateModels,\n pricingSource,\n top,\n });\n\n const usageDiagnostics = buildUsageDiagnostics({\n adaptersToParse: dataset.adaptersToParse,\n successfulParseResults: dataset.successfulParseResults,\n sourceFailures: dataset.sourceFailures,\n pricingOrigin,\n pricingWarning,\n activeEnvOverrides: dataset.readEnvVarOverrides(),\n timezone: dataset.normalizedInputs.timezone,\n });\n\n return {\n rows: counterfactual.rows,\n diagnostics: {\n usage: usageDiagnostics,\n provider,\n baselineCostIncomplete: counterfactual.baselineCostIncomplete,\n candidatesWithMissingPricing: counterfactual.candidatesWithMissingPricing,\n warning: counterfactual.warning,\n },\n };\n}\n","import { logger } from '../utils/logger.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport {\n renderOptimizeReport,\n type OptimizeReportFormat,\n} from '../render/render-optimize-report.js';\nimport { buildOptimizeData } from './build-optimize-data.js';\nimport { emitDiagnostics } from './emit-diagnostics.js';\nimport { emitEnvVarOverrides } from './emit-env-var-overrides.js';\nimport { warnIfTerminalTableOverflows } from './terminal-overflow-warning.js';\nimport type { OptimizeCommandOptions, OptimizeDiagnostics } from './usage-data-contracts.js';\n\ntype PreparedOptimizeReport = {\n format: OptimizeReportFormat;\n output: string;\n diagnostics: OptimizeDiagnostics;\n candidateCount: number;\n};\n\nfunction validateOutputFormatOptions(options: OptimizeCommandOptions): void {\n if (options.markdown && options.json) {\n throw new Error('Choose either --markdown or --json, not both');\n }\n}\n\nfunction resolveReportFormat(options: OptimizeCommandOptions): OptimizeReportFormat {\n if (options.json) {\n return 'json';\n }\n\n if (options.markdown) {\n return 'markdown';\n }\n\n return 'terminal';\n}\n\nasync function prepareOptimizeReport(\n granularity: ReportGranularity,\n options: OptimizeCommandOptions,\n): Promise<PreparedOptimizeReport> {\n validateOutputFormatOptions(options);\n\n const optimizeData = await buildOptimizeData(granularity, options);\n const format = resolveReportFormat(options);\n\n return {\n format,\n diagnostics: optimizeData.diagnostics,\n candidateCount: optimizeData.rows.filter(\n (row) => row.rowType === 'candidate' && row.periodKey === 'ALL',\n ).length,\n output: renderOptimizeReport(optimizeData, format, {\n granularity,\n }),\n };\n}\n\nexport async function buildOptimizeReport(\n granularity: ReportGranularity,\n options: OptimizeCommandOptions,\n): Promise<string> {\n const preparedReport = await prepareOptimizeReport(granularity, options);\n return preparedReport.output;\n}\n\nexport async function runOptimizeReport(\n granularity: ReportGranularity,\n options: OptimizeCommandOptions,\n): Promise<void> {\n const preparedReport = await prepareOptimizeReport(granularity, options);\n\n emitDiagnostics(preparedReport.diagnostics.usage, logger);\n emitEnvVarOverrides(preparedReport.diagnostics.usage.activeEnvOverrides, logger);\n\n logger.info(\n `Optimize provider scope: ${preparedReport.diagnostics.provider}; candidate(s): ${preparedReport.candidateCount}`,\n );\n\n if (preparedReport.diagnostics.candidatesWithMissingPricing.length > 0) {\n logger.warn(\n `Missing pricing for candidate model(s): ${preparedReport.diagnostics.candidatesWithMissingPricing.join(', ')}`,\n );\n }\n\n if (preparedReport.diagnostics.warning) {\n logger.warn(preparedReport.diagnostics.warning);\n }\n\n if (preparedReport.format === 'terminal') {\n warnIfTerminalTableOverflows(preparedReport.output, (message) => {\n logger.warn(message);\n });\n }\n\n console.log(preparedReport.output);\n}\n","import { markdownTable } from 'markdown-table';\n\nimport type { UsageReportRow } from '../domain/usage-report-row.js';\nimport { toUsageTableCells, type UsageTableLayout, usageTableHeaders } from './row-cells.js';\n\nconst alignment: ('l' | 'r')[] = ['l', 'l', 'l', 'r', 'r', 'r', 'r', 'r', 'r', 'r'];\n\ntype MarkdownRenderOptions = {\n tableLayout?: UsageTableLayout;\n};\n\nfunction toMarkdownSafeCell(value: string): string {\n return value.replace(/\\r?\\n/gu, '<br>');\n}\n\nexport function renderMarkdownTable(\n rows: UsageReportRow[],\n options: MarkdownRenderOptions = {},\n): string {\n const tableLayout = options.tableLayout ?? 'compact';\n const bodyRows = toUsageTableCells(rows, { layout: tableLayout }).map((row) =>\n row.map((cell) => toMarkdownSafeCell(cell)),\n );\n const tableRows = [Array.from(usageTableHeaders), ...bodyRows];\n\n return markdownTable(tableRows, {\n align: alignment,\n });\n}\n","import type { UsageDataResult } from '../cli/usage-data-contracts.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\nimport { renderMarkdownTable } from './markdown-table.js';\nimport { renderReportHeader } from './report-header.js';\nimport type { UsageTableLayout } from './row-cells.js';\nimport { renderTerminalTable, shouldUseColorByDefault } from './terminal-table.js';\n\nexport type UsageReportFormat = 'terminal' | 'markdown' | 'json';\n\nexport type RenderUsageReportOptions = {\n granularity: ReportGranularity;\n useColor?: boolean;\n tableLayout?: UsageTableLayout;\n};\n\nfunction getReportTitle(granularity: ReportGranularity): string {\n switch (granularity) {\n case 'daily':\n return 'Daily Token Usage Report';\n case 'weekly':\n return 'Weekly Token Usage Report';\n case 'monthly':\n return 'Monthly Token Usage Report';\n }\n}\n\nfunction renderTerminalUsageReport(\n usageData: UsageDataResult,\n options: RenderUsageReportOptions,\n): string {\n const outputLines: string[] = [];\n const useColor = options.useColor ?? shouldUseColorByDefault();\n const tableLayout = options.tableLayout ?? 'compact';\n\n outputLines.push(\n renderReportHeader({\n title: getReportTitle(options.granularity),\n useColor,\n }),\n );\n\n outputLines.push('');\n outputLines.push(renderTerminalTable(usageData.rows, { useColor, tableLayout }));\n\n return outputLines.join('\\n');\n}\n\nexport function renderUsageReport(\n usageData: UsageDataResult,\n format: UsageReportFormat,\n options: RenderUsageReportOptions,\n): string {\n const tableLayout = options.tableLayout ?? 'compact';\n\n switch (format) {\n case 'json':\n return JSON.stringify(usageData.rows, null, 2);\n case 'markdown':\n return renderMarkdownTable(usageData.rows, { tableLayout });\n case 'terminal':\n return renderTerminalUsageReport(usageData, options);\n }\n}\n","import { buildUsageData } from './build-usage-data.js';\nimport { emitDiagnostics } from './emit-diagnostics.js';\nimport { emitEnvVarOverrides } from './emit-env-var-overrides.js';\nimport type { ReportCommandOptions, UsageDiagnostics } from './usage-data-contracts.js';\nimport { warnIfTerminalTableOverflows } from './terminal-overflow-warning.js';\nimport { renderUsageReport, type UsageReportFormat } from '../render/render-usage-report.js';\nimport type { UsageTableLayout } from '../render/row-cells.js';\nimport { logger } from '../utils/logger.js';\nimport type { ReportGranularity } from '../utils/time-buckets.js';\n\ntype PreparedUsageReport = {\n format: UsageReportFormat;\n output: string;\n diagnostics: UsageDiagnostics;\n};\n\nfunction validateOutputFormatOptions(options: ReportCommandOptions): void {\n if (options.markdown && options.json) {\n throw new Error('Choose either --markdown or --json, not both');\n }\n}\n\nfunction resolveReportFormat(options: ReportCommandOptions): UsageReportFormat {\n if (options.json) {\n return 'json';\n }\n\n if (options.markdown) {\n return 'markdown';\n }\n\n return 'terminal';\n}\n\nfunction resolveTableLayout(options: ReportCommandOptions): UsageTableLayout {\n return options.perModelColumns ? 'per_model_columns' : 'compact';\n}\n\nasync function prepareUsageReport(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n): Promise<PreparedUsageReport> {\n validateOutputFormatOptions(options);\n\n const usageData = await buildUsageData(granularity, options);\n const format = resolveReportFormat(options);\n\n return {\n format,\n diagnostics: usageData.diagnostics,\n output: renderUsageReport(usageData, format, {\n granularity,\n tableLayout: resolveTableLayout(options),\n }),\n };\n}\n\nexport async function buildUsageReport(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n): Promise<string> {\n const preparedReport = await prepareUsageReport(granularity, options);\n return preparedReport.output;\n}\n\nexport async function runUsageReport(\n granularity: ReportGranularity,\n options: ReportCommandOptions,\n): Promise<void> {\n const preparedReport = await prepareUsageReport(granularity, options);\n emitDiagnostics(preparedReport.diagnostics, logger);\n emitEnvVarOverrides(preparedReport.diagnostics.activeEnvOverrides, logger);\n\n if (preparedReport.format === 'terminal') {\n warnIfTerminalTableOverflows(preparedReport.output, (message) => {\n logger.warn(message);\n });\n }\n\n console.log(preparedReport.output);\n}\n","import { createRequire } from 'node:module';\n\nimport { asRecord } from '../utils/as-record.js';\n\nexport type PackageMetadata = {\n packageName: string;\n packageVersion: string;\n};\n\nconst DEFAULT_PACKAGE_NAME = 'llm-usage-metrics';\nconst DEFAULT_PACKAGE_VERSION = '0.0.0';\n\nconst defaultPackageJsonCandidates = ['../package.json', '../../package.json'] as const;\n\ntype JsonLoader = (path: string) => unknown;\n\nfunction normalizeMetadata(candidate: unknown): PackageMetadata | undefined {\n const packageJson = asRecord(candidate);\n\n if (!packageJson) {\n return undefined;\n }\n\n const packageName = typeof packageJson.name === 'string' ? packageJson.name.trim() : undefined;\n const packageVersion =\n typeof packageJson.version === 'string' ? packageJson.version.trim() : undefined;\n\n if (!packageName || !packageVersion) {\n return undefined;\n }\n\n return {\n packageName,\n packageVersion,\n };\n}\n\nexport function resolvePackageMetadata(\n loadJson: JsonLoader,\n packageJsonCandidates: readonly string[] = defaultPackageJsonCandidates,\n): PackageMetadata {\n for (const candidatePath of packageJsonCandidates) {\n try {\n const metadata = normalizeMetadata(loadJson(candidatePath));\n\n if (metadata) {\n return metadata;\n }\n } catch {\n continue;\n }\n }\n\n return {\n packageName: DEFAULT_PACKAGE_NAME,\n packageVersion: DEFAULT_PACKAGE_VERSION,\n };\n}\n\nexport function loadPackageMetadataFromRuntime(): PackageMetadata {\n const require = createRequire(import.meta.url);\n return resolvePackageMetadata((candidatePath) => require(candidatePath));\n}\n","#!/usr/bin/env node\n\nimport { getUpdateNotifierRuntimeConfig } from '../config/runtime-overrides.js';\nimport { checkForUpdatesAndMaybeRestart } from '../update/update-notifier.js';\nimport { createCli } from './create-cli.js';\nimport { loadPackageMetadataFromRuntime } from './package-metadata.js';\n\nconst { packageName, packageVersion } = loadPackageMetadataFromRuntime();\nconst updateRuntimeConfig = getUpdateNotifierRuntimeConfig();\n\nconst cli = createCli({ version: packageVersion });\n\ntry {\n const updateResult = await checkForUpdatesAndMaybeRestart({\n packageName,\n currentVersion: packageVersion,\n cacheTtlMs: updateRuntimeConfig.cacheTtlMs,\n fetchTimeoutMs: updateRuntimeConfig.fetchTimeoutMs,\n });\n\n if (!updateResult.continueExecution) {\n process.exitCode = updateResult.exitCode ?? 0;\n } else {\n await cli.parseAsync(process.argv);\n }\n} catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exitCode = 1;\n}\n"],"mappings":"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","names":["path","path","packageName","os","path","path","path","createInterface","createInterface","path","os","payload","readFile","os","path","defaultSessionsDir","path","os","readFile","readFile","os","path","path","os","readFile","normalizeTimestamp","os","path","require","UNIX_SECONDS_ABS_CUTOFF","normalizeTimestampCandidate","resolveRepoRoot","hasUsageSignal","isBlankText","sleep","os","path","defaultSessionsDir","path","os","UNIX_SECONDS_ABS_CUTOFF","normalizeTimestampCandidate","resolveTimestamp","toFiniteNumber","getFallbackSessionId","USD_PRECISION_SCALE","addUsd","hasUsageSignal","spawn","createInterface","path","stat","path","getNodeErrorCode","stat","spawn","createInterface","access","constants","path","resolveRepoRoot","resolvedRoot","stat","mkdir","readFile","stat","writeFile","path","toNonNegativeNumber","stat","path","mkdir","writeFile","readFile","stat","mkdir","readFile","writeFile","path","ONE_MILLION","DEFAULT_CACHE_TTL_MS","DEFAULT_FETCH_TIMEOUT_MS","DEFAULT_FETCH_RETRY_COUNT","DEFAULT_FETCH_RETRY_DELAY_MS","isRetryableHttpStatus","isRetryableFetchFailure","sleep","toNonNegativeNumber","path","_","readFile","mkdir","writeFile","resolveRepoRoot","pc","pc","pc","pc","pc","costColumnIndex","integerFormatter","usdFormatter","formatUsd","modelsColumnIndex","alignment","pc","computeColumnWidths","pc","alignment","markdownTable","pc","usdFormatter","getReportTitle","formatUsd","pc","styleDeltaCell","toMarkdownSafeCell","alignment","markdownTable","USD_PRECISION_SCALE","provider","validateOutputFormatOptions","resolveReportFormat","markdownTable","toMarkdownSafeCell","markdownTable","getReportTitle","validateOutputFormatOptions","resolveReportFormat","createRequire","packageName","packageVersion","require","createRequire"]}
|